Mishra Reader–Your brand new RSS reader

I just finished the first alpha of MishraReader, a tool written with WPF 4.0 (so you need to install .NET framework 4.0) which allows you to read your feeds (using a Google reader account).

You can download it here : https://www.catuhe.com/files/MishraReader.zip

This version is an early alpha with a lot of missing features (such as notifications for instance).

In a near future, I will write a blog on some key points of the code used in MishraReader.

Feedback of a graphic development using HTML5 & JavaScript

As a user interface fan, I could not miss the development with HTML 5.

So the goal of this post is to walk through a graphic application that uses JavaScript and HTML 5. We will see through examples one way (among others) to develop this kind of project.

Application overview image_thumb6 
Tools 
The HTML 5 page
Data gathering 
Cards loading & cache handling
Cards display
Mouse management  
State storage
Animations
Handling multi-devices
Conclusion
To go further

Application overview

We will produce an application that will let us display a Magic the Gathering ©(courtesy of www.wizards.com/Magic) cards collection. Users will be able to scroll and zoom using the mouse (like Bing Maps, for example).

You can see the final result here: https://bolaslenses.catuhe.com

The project source files can be downloaded here: https://www.catuhe.com/msdn/bolaslenses.zip

Cards are stored on Windows Azure Storage and use the Azure Content Distribution Network (CDN : a service that deploys data near the final users) in order to achieve maximum performances. An ASP.NET service is used to return cards list (using JSON format). 

Tools

To write our application, we will use Visual Studio 2010 SP1 with Web Standards Update. This extension adds IntelliSense support in HTML 5 page (which is a really important thing Sourire).

So, our solution will contain an HTML 5 page side by side with .js files (these files will contain JavaScript scripts). About debug, it is possible to set a breakpoint directly in the .js files under Visual Studio. It is also possible to use the developer bar of Internet Explorer 9 (use F12 key to display it).




Debug with Visual Studio 2010




Debug with Internet Explorer 9 (F12/Developer bar)

So, we have a modern developer environment with IntelliSense and debug support. Therefore, we are ready to start and first of all, we will write the HTML 5 page.

The HTML 5 page

Our page will be built around an HTML 5 canvas which will be used to draw the cards:






  1. <!DOCTYPE html>


  2. <html>


  3. <head>


  4.     <meta charset=”utf-8″ />


  5.     <title>Bolas Lenses</title>


  6.     <link href=”Content/full.css” rel=”stylesheet” type=”text/css” />


  7.     <link href=”Content/mobile.css” rel=”stylesheet” type=”text/css” media=”screen and (max-width: 480px)” />


  8.     <link href=”Content/mobile.css” rel=”stylesheet” type=”text/css” media=”screen and (max-device-width: 480px)” />


  9.     <script src=”Scripts/jquery-1.5.1.min.js” type=”text/javascript”></script>


  10. </head>


  11. <body>


  12.     <header>


  13.         <div id=”legal”>


  14.             Cards scanned by <a href=”https://www.slightlymagic.net/”>MWSHQ Team</a><br />


  15.             Magic the Gathering official site : <a href=”https://www.wizards.com/Magic/TCG/Article.aspx?x=mtg/tcg/products/allproducts”>


  16.                 https://www.wizards.com/Magic</a>


  17.             <div id=”cardsCount”>


  18.             </div>


  19.         </div>


  20.         <div id=”leftHeader”>


  21.             <img id=”pictureCell” src=”/Content/MTG Black.png” alt=”Bolas logo” id=”bolasLogo” />


  22.             <div id=”title”>


  23.                 Bolas Lenses


  24.             </div>


  25.         </div>


  26.     </header>


  27.     <section>


  28.         <img src=”Content/Back.jpg” style=”display: none” id=”backImage” alt=”backImage”


  29.             width=”128″ height=”128″ />


  30.         <canvas id=”mainCanvas”>


  31.                     Your browser does not support HTML5 canvas.


  32.         </canvas>


  33.         <div id=”stats” class=”tooltip”>


  34.         </div>


  35.         <div id=”waitText” class=”tooltip”>


  36.             Loading data…


  37.         </div>


  38.     </section>


  39.     <!–Scripts–>


  40.     <script src=”Bolas/bolasLenses.animations.js” type=”text/javascript”></script>


  41.     <script src=”Bolas/bolasLenses.mouse.js” type=”text/javascript”></script>


  42.     <script src=”Bolas/bolasLenses.cache.js” type=”text/javascript”></script>


  43.     <script src=”Bolas/bolasLenses.js” type=”text/javascript”></script>


  44. </body>


  45. </html>




If we dissect this page, we can note that it is divided into two parts:

  • The header part with the title, the logo and the special mentions
  • The main part (section) holds the canvas and the tooltips that will display the status of the application. There is also a hidden image (backImage) used as source for not yet loaded cards.

To build the layout of the page, a style sheet (full.css) is applied. Style sheets are a mechanism used to change the tags styles (in HTML, a style defines the entire display options for a tag):






  1. html, body


  2. {


  3.     height: 100%;


  4. }


  5.  


  6. body


  7. {


  8.     background-color: #888888;


  9.     font-size: .85em;


  10.     font-family: “Segoe UI, Trebuchet MS” , Verdana, Helvetica, Sans-Serif;


  11.     margin: ;


  12.     padding: ;


  13.     color: #696969;


  14. }


  15.  


  16. a:link


  17. {


  18.     color: #034af3;


  19.     text-decoration: underline;


  20. }


  21.  


  22. a:visited


  23. {


  24.     color: #505abc;


  25. }


  26.  


  27. a:hover


  28. {


  29.     color: #1d60ff;


  30.     text-decoration: none;


  31. }


  32.  


  33. a:active


  34. {


  35.     color: #12eb87;


  36. }


  37.  


  38. header, footer, nav, section


  39. {


  40.     display: block;


  41. }


  42.  


  43. table


  44. {


  45.     width: 100%;


  46. }


  47.  


  48. header, #header


  49. {


  50.     position: relative;


  51.     margin-bottom: 0px;


  52.     color: #000;


  53.     padding: ;


  54. }


  55.  


  56. #title


  57. {


  58.     font-weight: bold;


  59.     color: #fff;


  60.     border: none;


  61.     font-size: 60px !important;


  62.     vertical-align: middle;


  63.     margin-left: 70px


  64. }


  65.  


  66. #legal


  67. {


  68.     text-align: right;


  69.     color: white;


  70.     font-size: 14px;


  71.     width: 50%;


  72.     position: absolute;


  73.     top: 15px;


  74.     right: 10px


  75. }


  76.  


  77. #leftHeader


  78. {


  79.     width: 50%;


  80.     vertical-align: middle;


  81. }


  82.  


  83. section


  84. {


  85.     margin: 20px 20px 20px 20px;


  86. }


  87.  


  88.     #mainCanvas{


  89.     border: 4px solid #000000;


  90. }


  91.  


  92. #cardsCount


  93. {


  94.     font-weight: bolder;


  95.     font-size: 1.1em;


  96. }


  97.  


  98. .tooltip


  99. {


  100.     position: absolute;


  101.     bottom: 5px;


  102.     color: black;


  103.     background-color: white;


  104.     margin-right: auto;


  105.     margin-left: auto;


  106.     left: 35%;


  107.     right: 35%;


  108.     padding: 5px;


  109.     width: 30%;


  110.     text-align: center;


  111.     border-radius: 10px;


  112.     -webkit-border-radius: 10px;


  113.     -moz-border-radius: 10px;


  114.     box-shadow: 2px 2px 2px #333333;


  115. }


  116.  


  117. #bolasLogo


  118. {


  119.     width: 64px;


  120.     height: 64px;


  121. }


  122.  


  123. #pictureCell


  124. {


  125.     float: left;


  126.     width: 64px;


  127.     margin: 5px 5px 5px 5px;


  128.     vertical-align: middle;


  129. }




Thus, this sheet is responsible for setting up the following display:

untitled

Style sheets are powerful tools that allow an infinite number of displays. However, they are sometimes complicated to setup (for example if a tag is affected by a class, an identifier and its container). To simplify this setup, the development bar of Internet Explorer 9 is particularly useful because we can use it to see styles hierarchy that is applied to a tag.
For example let’s take a look at the waitText tooltip with the development bar. To do this, you must press F12 in Internet Explorer and use the selector to choose the tooltip:

Once the selection is done, we can see the styles hierarchy:

Thus, we can see that our div received its styles from the body tag  and the .tooltip entry of the style sheet.

With this tool, it becomes possible to see the effect of each style (which can be disabled). It is also possible to add new style on the fly.

Another important point of this window is the ability to change the rendering mode of Internet Explorer 9. Indeed, we can test how, for example, Internet Explorer 8 will handle the same page. To do this, go to the [Browser mode] menu and select the engine of Internet Explorer 8. This change will especially impact our tooltip as it uses border-radius (rounded edge) and box-shadow that are features of CSS 3:






















Internet Explorer 9




Internet Explorer 8



Our page provides a graceful degradation  as it still works (with no annoying visual difference) when the browser does not support all the required technologies.

Now that our interface is ready, we will take a look at the data source to retrieve the cards to display.

Data gathering

The server provides the cards list using JSON format on this URL:

https://bolaslenses.catuhe.com/Home/ListOfCards/?colorString=0

It takes one parameter (colorString) to select a specific color (0 = all).

When developing with JavaScript, there is a good reflex to have (reflex also good in other languages too, but really important in JavaScript): one must ask whether what we want to develop has not been already done in an existing framework.

Indeed, there is a multitude of open source projects around JavaScript. One of them is jQuery which provides a plethora of convenient services.

Thus, in our case to connect to the URL of our server and get the cards list, we could go through a XmlHttpRequest and have fun to parse the returned JSON. Or we can use jQuery Sourire.

So we will use the getJSON function which will take care of everything for us:






  1. function getListOfCards() {


  2.     var url = https://bolaslenses.catuhe.com/Home/ListOfCards/?jsoncallback=?&#8221;;


  3.     $.getJSON(url, { colorString: “0” }, function (data) {


  4.         listOfCards = data;


  5.         $(“#cardsCount”).text(listOfCards.length + ” cards displayed”);


  6.         $(“#waitText”).slideToggle(“fast”);


  7.     });


  8. }




As we can see, our function stores the cards list in the listOfCards variable and calls two jQuery functions:

  • text that change the text of a tag
  • slideToggle that hides (or shows) a tag by animating its height

The listOfCards list contains objects whose format is:

  • _ID_: unique identifier of the card
  • Path: relative path of the card (without the extension)

It should be noted that the URL of the server is called with the “?jsoncallback=?” suffix. Indeed, Ajax calls are constrained in terms of security to connect only to the same address as the calling script. However, there is a solution called JSONP that will allow us to make a concerted call to the server (which of course must be aware of the operation). And fortunately, jQuery can handle it all alone by just adding the right suffix.

Once we have our cards list, we can set up the pictures loading and caching.

Cards loading & cache handling

The main trick of our application is to draw only the cards effectively visible on the screen. The display window is defined by a zoom level and an offset (x, y) in the overall system.






  1. var visuControl = { zoom : 0.25, offsetX : 0, offsetY : 0 };




The overall system is defined by 14819 cards that are spread over 200 columns and 75 rows.

Also, we must be aware that each card is available in three versions:

  • High definition: 480×680 without compression (.jpg suffix)
  • Medium definition: 240×340 with standard compression (.50.jpg suffix)
  • Low definition: 120×170 with strong compression (.25.jpg suffix)

Thus, depending on the zoom level, we will load the correct version to optimize networks transfer.

To do this we will develop a function that will give an image for a given card. This function will be configured to download a certain level of quality. In addition it will be linked with lower quality level to return it if the card for the current level is not yet uploaded:






  1. function imageCache(substr, replacementCache) {


  2.     var extension = substr;


  3.     var backImage = document.getElementById(“backImage”);


  4.  


  5.  


  6.     this.load = function (card) {


  7.         var localCache = this;


  8.  


  9.         if (this[card.ID] != undefined)


  10.             return;


  11.  


  12.         var img = new Image();


  13.         localCache[card.ID] = { image: img, isLoaded: false };


  14.         currentDownloads++;


  15.  


  16.         img.onload = function () {


  17.             localCache[card.ID].isLoaded = true;


  18.             currentDownloads–;


  19.         };


  20.  


  21.         img.onerror = function() {


  22.             currentDownloads–;


  23.         };


  24.         


  25.         img.src = https://az30809.vo.msecnd.net/&#8221; + card.Path + extension;


  26.     };


  27.  


  28.     this.getReplacementFromLowerCache = function (card) {


  29.         if (replacementCache == undefined)


  30.             return backImage;


  31.  


  32.         return replacementCache.getImageForCard(card);


  33.     };


  34.  


  35.     this.getImageForCard = function(card) {


  36.         var img;


  37.         if (this[card.ID] == undefined) {


  38.             this.load(card);


  39.  


  40.             img = this.getReplacementFromLowerCache(card);


  41.         }


  42.         else {


  43.             if (this[card.ID].isLoaded)


  44.                 img = this[card.ID].image;


  45.             else


  46.                 img = this.getReplacementFromLowerCache(card);


  47.         }


  48.  


  49.         return img;


  50.     };


  51. }




An ImageCache is built by giving the associated suffix and the underlying cache.

Here you can see two important functions:

  • load: this function will load the right picture and will store it in a cache (the msecnd.net url is the Azure CDN address of the cards)
  • getImageForCard: this function returns the card picture from the cache if already loaded. Otherwise it requests the underlying cache to return its version (and so on)

So to handle our 3 levels of caches, we have to declare three variables:






  1. var imagesCache25 = new imageCache(“.25.jpg”);


  2. var imagesCache50 = new imageCache(“.50.jpg”, imagesCache25);


  3. var imagesCacheFull = new imageCache(“.jpg”, imagesCache50);




Selecting the right cover is only depending on zoom:






  1. function getCorrectImageCache() {


  2.     if (visuControl.zoom <= 0.25)


  3.         return imagesCache25;


  4.  


  5.     if (visuControl.zoom <= 0.8)


  6.         return imagesCache50;


  7.  


  8.     return imagesCacheFull;


  9. }




To give a feedback to the user, we will add a timer that will manage a tooltip that indicates the number of images currently loaded:






  1. function updateStats() {


  2.     var stats = $(“#stats”);


  3.  


  4.     stats.html(currentDownloads + ” card(s) currently downloaded.”);


  5.  


  6.     if (currentDownloads == 0 && statsVisible) {


  7.         statsVisible = false;


  8.         stats.slideToggle(“fast”);


  9.     }


  10.     else if (currentDownloads > 1 && !statsVisible) {


  11.         statsVisible = true;


  12.         stats.slideToggle(“fast”);


  13.     }


  14. }


  15.  


  16. setInterval(updateStats, 200);




Again we note the use of jQuery to simplify animations.

We will now discuss the display of cards.

Cards display

To draw our cards, we need to actually fill the canvas using its 2D context (which exists only if the browser supports HTML 5 canvas):






  1. var mainCanvas = document.getElementById(“mainCanvas”);


  2. var drawingContext = mainCanvas.getContext(‘2d’);




The drawing will be made by processListOfCards function (called 60 times per second):






  1. function processListOfCards() {


  2.  


  3.     if (listOfCards == undefined) {


  4.         drawWaitMessage();


  5.         return;


  6.     }


  7.  


  8.     mainCanvas.width = document.getElementById(“center”).clientWidth;


  9.     mainCanvas.height = document.getElementById(“center”).clientHeight;


  10.     totalCards = listOfCards.length;


  11.  


  12.     var localCardWidth = cardWidth visuControl.zoom;


  13.     var localCardHeight = cardHeight visuControl.zoom;


  14.  


  15.     var effectiveTotalCardsInWidth = colsCount localCardWidth;


  16.  


  17.     var rowsCount = Math.ceil(totalCards / colsCount);


  18.     var effectiveTotalCardsInHeight = rowsCount localCardHeight;


  19.  


  20.     initialX = (mainCanvas.width – effectiveTotalCardsInWidth) / 2.0 – localCardWidth / 2.0;


  21.     initialY = (mainCanvas.height – effectiveTotalCardsInHeight) / 2.0 – localCardHeight / 2.0;


  22.  


  23.     // Clear


  24.     clearCanvas();


  25.  


  26.     // Computing of the viewing area


  27.     var initialOffsetX = initialX + visuControl.offsetX visuControl.zoom;


  28.     var initialOffsetY = initialY + visuControl.offsetY visuControl.zoom;


  29.  


  30.     var startX = Math.max(Math.floor(-initialOffsetX / localCardWidth) – 1, 0);


  31.     var startY = Math.max(Math.floor(-initialOffsetY / localCardHeight) – 1, 0);


  32.  


  33.     var endX = Math.min(startX + Math.floor((mainCanvas.width – initialOffsetX – startX localCardWidth) / localCardWidth) + 1, colsCount);


  34.     var endY = Math.min(startY + Math.floor((mainCanvas.height – initialOffsetY – startY localCardHeight) / localCardHeight) + 1, rowsCount);


  35.  


  36.     // Getting current cache


  37.     var imageCache = getCorrectImageCache();


  38.  


  39.     // Render


  40.     for (var y = startY; y < endY; y++) {


  41.         for (var x = startX; x < endX; x++) {


  42.             var localX = x localCardWidth + initialOffsetX;


  43.             var localY = y localCardHeight + initialOffsetY;


  44.  


  45.             // Clip


  46.             if (localX > mainCanvas.width)


  47.                 continue;


  48.  


  49.             if (localY > mainCanvas.height)


  50.                 continue;


  51.  


  52.             if (localX + localCardWidth < 0)


  53.                 continue;


  54.  


  55.             if (localY + localCardHeight < 0)


  56.                 continue;


  57.  


  58.             var card = listOfCards[x + y * colsCount];


  59.  


  60.             if (card == undefined)


  61.                 continue;


  62.  


  63.             // Get from cache


  64.             var img = imageCache.getImageForCard(card);


  65.  


  66.             // Render


  67.             try {


  68.  


  69.                 if (img != undefined)


  70.                     drawingContext.drawImage(img, localX, localY, localCardWidth, localCardHeight);


  71.             } catch (e) {


  72.                 $.grep(listOfCards, function (item) {


  73.                     return item.image != img;


  74.                 });


  75.  


  76.             }


  77.         }


  78.     };


  79.  


  80.     // Scroll bars


  81.     drawScrollBars(effectiveTotalCardsInWidth, effectiveTotalCardsInHeight, initialOffsetX, initialOffsetY);


  82.  


  83.     // FPS


  84.     computeFPS();


  85. }




This function is built around many key points:

  • If the cards list is not yet loaded, we display a tooltip indicating that download is in progress::





  1. var pointCount = 0;


  2.  


  3. function drawWaitMessage() {


  4.     pointCount++;


  5.  


  6.     if (pointCount > 200)


  7.         pointCount = 0;


  8.  


  9.     var points = “”;


  10.  


  11.     for (var index = 0; index < pointCount / 10; index++)


  12.         points += “.”;


  13.  


  14.     $(“#waitText”).html(“Loading…Please wait
    + points);


  15. }




  • Subsequently, we define the position of the display window (in terms of cards and coordinates), then we proceed to clean the canvas:





  1. function clearCanvas() {


  2.     mainCanvas.width = document.body.clientWidth – 50;


  3.     mainCanvas.height = document.body.clientHeight – 140;


  4.  


  5.     drawingContext.fillStyle = “rgb(0, 0, 0)”;


  6.     drawingContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height);


  7. }




  • Then we browse the cards list and call the drawImage function of the canvas context. The current image is provided by the active cache (depending on the zoom):





  1. // Get from cache


  2. var img = imageCache.getImageForCard(card);


  3.  


  4. // Render


  5. try {


  6.  


  7.     if (img != undefined)


  8.         drawingContext.drawImage(img, localX, localY, localCardWidth, localCardHeight);


  9. } catch (e) {


  10.     $.grep(listOfCards, function (item) {


  11.         return item.image != img;


  12.     });




  • We also have to draw the scroll bar with the RoundedRectangle function that uses quadratic curves:





  1. function roundedRectangle(x, y, width, height, radius) {


  2.     drawingContext.beginPath();


  3.     drawingContext.moveTo(x + radius, y);


  4.     drawingContext.lineTo(x + width – radius, y);


  5.     drawingContext.quadraticCurveTo(x + width, y, x + width, y + radius);


  6.     drawingContext.lineTo(x + width, y + height – radius);


  7.     drawingContext.quadraticCurveTo(x + width, y + height, x + width – radius, y + height);


  8.     drawingContext.lineTo(x + radius, y + height);


  9.     drawingContext.quadraticCurveTo(x, y + height, x, y + height – radius);


  10.     drawingContext.lineTo(x, y + radius);


  11.     drawingContext.quadraticCurveTo(x, y, x + radius, y);


  12.     drawingContext.closePath();


  13.     drawingContext.stroke();


  14.     drawingContext.fill();


  15. }









  1. function drawScrollBars(effectiveTotalCardsInWidth, effectiveTotalCardsInHeight, initialOffsetX, initialOffsetY) {


  2.     drawingContext.fillStyle = “rgba(255, 255, 255, 0.6)”;


  3.     drawingContext.lineWidth = 2;


  4.  


  5.     // Vertical


  6.     var totalScrollHeight = effectiveTotalCardsInHeight + mainCanvas.height;


  7.     var scaleHeight = mainCanvas.height – 20;


  8.     var scrollHeight = mainCanvas.height / totalScrollHeight;


  9.     var scrollStartY = (-initialOffsetY + mainCanvas.height 0.5) / totalScrollHeight;


  10.     roundedRectangle(mainCanvas.width – 8, scrollStartY scaleHeight + 10, 5, scrollHeight scaleHeight, 4);


  11.  


  12.     // Horizontal


  13.     var totalScrollWidth = effectiveTotalCardsInWidth + mainCanvas.width;


  14.     var scaleWidth = mainCanvas.width – 20;


  15.     var scrollWidth = mainCanvas.width / totalScrollWidth;


  16.     var scrollStartX = (-initialOffsetX + mainCanvas.width 0.5) / totalScrollWidth;


  17.     roundedRectangle(scrollStartX scaleWidth + 10, mainCanvas.height – 8, scrollWidth scaleWidth, 5, 4);


  18. }




  • And finally, we need to compute the number of frames per second:





  1. function computeFPS() {


  2.     if (previous.length > 60) {


  3.         previous.splice(0, 1);


  4.     }


  5.     var start = (new Date).getTime();


  6.     previous.push(start);


  7.     var sum = 0;


  8.  


  9.     for (var id = 0; id < previous.length – 1; id++) {


  10.         sum += previous[id + 1] – previous[id];


  11.     }


  12.  


  13.     var diff = 1000.0 / (sum / previous.length);


  14.  


  15.     $(“#cardsCount”).text(diff.toFixed() + ” fps. “ + listOfCards.length + ” cards displayed”);


  16. }




Drawing cards relies heavily on the browser’s ability to speed up canvas rendering. For the record, here are the performances on my machine with the minimum zoom level (0.05):








































Browser




FPS



Internet Explorer 9

30

Firefox 5

30

Chrome 12

17

iPad (with a zoom level of 0.8)

7

Windows Phone Mango (with a zoom level of 0.8)

20 (!!)

The site even works on mobile phones and tablets as long as they support HTML 5.

Here we can see the inner power of HTML 5 browsers that can handle a full screen of cards more than 30 times per second!

Mouse management

To browse our cards collection, we have to manage the mouse (including its wheel).

For the scrolling, we’ll just handle the onmouvemove, onmouseup and onmousedown events.

Onmouseup and onmousedown events will be used to detect if the mouse is clicked or not:






  1. var mouseDown = 0;


  2. document.body.onmousedown = function (e) {


  3.     mouseDown = 1;


  4.     getMousePosition(e);


  5.  


  6.     previousX = posx;


  7.     previousY = posy;


  8. };


  9.  


  10. document.body.onmouseup = function () {


  11.     mouseDown = 0;


  12. };




The onmousemove event is connected to the canvas and used to move the view:






  1. var previousX = 0;


  2. var previousY = 0;


  3. var posx = 0;


  4. var posy = 0;


  5.  


  6. function getMousePosition(eventArgs) {


  7.     var e;


  8.  


  9.     if (!eventArgs)


  10.         e = window.event;


  11.     else {


  12.         e = eventArgs;


  13.     }


  14.  


  15.     if (e.offsetX || e.offsetY) {


  16.         posx = e.offsetX;


  17.         posy = e.offsetY;


  18.     }


  19.     else if (e.clientX || e.clientY) {


  20.         posx = e.clientX;


  21.         posy = e.clientY;


  22.     }        


  23. }


  24.  


  25. function onMouseMove(e) {


  26.     if (!mouseDown)


  27.         return;


  28.     getMousePosition(e);


  29.  


  30.     mouseMoveFunc(posx, posy, previousX, previousY);


  31.  


  32.     previousX = posx;


  33.     previousY = posy;


  34. }




This function (onMouseMove) calculates the current position and provides also the previous value in order to move the offset of the display window:






  1. function Move(posx, posy, previousX, previousY) {


  2.     currentAddX = (posx – previousX) / visuControl.zoom;


  3.     currentAddY = (posy – previousY) / visuControl.zoom;


  4. }


  5. MouseHelper.registerMouseMove(mainCanvas, Move);




Note that jQuery also provides tools to manage mouse events.

For the management of the wheel, we will have to adapt to different browsers that do not behave the same way on this point:






  1. function wheel(event) {


  2.     var delta = 0;


  3.     if (event.wheelDelta) {


  4.         delta = event.wheelDelta / 120;


  5.         if (window.opera)


  6.             delta = -delta;


  7.     } else if (event.detail) { /* Mozilla case. /


  8.         delta = -event.detail / 3;


  9.     }


  10.     if (delta) {


  11.         wheelFunc(delta);


  12.     }


  13.  


  14.     if (event.preventDefault)


  15.         event.preventDefault();


  16.     event.returnValue = false;


  17. }




We can see that everyone does what he wants Sourire.

The function to register with this event is:






  1. MouseHelper.registerWheel = function (func) {


  2.     wheelFunc = func;


  3.  


  4.     if (window.addEventListener)


  5.         window.addEventListener(‘DOMMouseScroll’, wheel, false);


  6.  


  7.     window.onmousewheel = document.onmousewheel = wheel;


  8. };




And we will use this function to change the zoom with the wheel:






  1. // Mouse


  2. MouseHelper.registerWheel(function (delta) {


  3.     currentAddZoom += delta / 500.0;


  4. });




Finally we will add a bit of inertia when moving the mouse (and the zoom) to give some kind of smoothness:






  1. // Inertia


  2. var inertia = 0.92;


  3. var currentAddX = 0;


  4. var currentAddY = 0;


  5. var currentAddZoom = 0;


  6.  


  7. function doInertia() {


  8.     visuControl.offsetX += currentAddX;


  9.     visuControl.offsetY += currentAddY;


  10.     visuControl.zoom += currentAddZoom;


  11.  


  12.     var effectiveTotalCardsInWidth = colsCount cardWidth;


  13.  


  14.     var rowsCount = Math.ceil(totalCards / colsCount);


  15.     var effectiveTotalCardsInHeight = rowsCount cardHeight


  16.  


  17.     var maxOffsetX = effectiveTotalCardsInWidth / 2.0;


  18.     var maxOffsetY = effectiveTotalCardsInHeight / 2.0;


  19.  


  20.     if (visuControl.offsetX < -maxOffsetX + cardWidth)


  21.         visuControl.offsetX = -maxOffsetX + cardWidth;


  22.     else if (visuControl.offsetX > maxOffsetX)


  23.         visuControl.offsetX = maxOffsetX;


  24.  


  25.     if (visuControl.offsetY < -maxOffsetY + cardHeight)


  26.         visuControl.offsetY = -maxOffsetY + cardHeight;


  27.     else if (visuControl.offsetY > maxOffsetY)


  28.         visuControl.offsetY = maxOffsetY;


  29.  


  30.     if (visuControl.zoom < 0.05)


  31.         visuControl.zoom = 0.05;


  32.     else if (visuControl.zoom > 1)


  33.         visuControl.zoom = 1;


  34.  


  35.     processListOfCards();


  36.  


  37.     currentAddX = inertia;


  38.     currentAddY = inertia;


  39.     currentAddZoom *= inertia;


  40.  


  41.     // Epsilon


  42.     if (Math.abs(currentAddX) < 0.001)


  43.         currentAddX = 0;


  44.     if (Math.abs(currentAddY) < 0.001)


  45.         currentAddY = 0;


  46. }




This kind of small function does not cost a lot to implement, but adds a lot to the quality of user experience.

State storage

Also to provide a better user experience, we will save the display window’s position and zoom. To do this, we will use the service of localStorage (which saves pairs of keys / values ​​for the long term (the data is retained after the browser is closed) and only accessible by the current window object):






  1. function saveConfig() {


  2.     if (window.localStorage == undefined)


  3.         return;


  4.  


  5.     // Zoom


  6.     window.localStorage[“zoom”] = visuControl.zoom;


  7.  


  8.     // Offsets


  9.     window.localStorage[“offsetX”] = visuControl.offsetX;


  10.     window.localStorage[“offsetY”] = visuControl.offsetY;


  11. }


  12.  


  13. // Restore data


  14. if (window.localStorage != undefined) {


  15.     var storedZoom = window.localStorage[“zoom”];


  16.     if (storedZoom != undefined)


  17.         visuControl.zoom = parseFloat(storedZoom);


  18.  


  19.     var storedoffsetX = window.localStorage[“offsetX”];


  20.     if (storedoffsetX != undefined)


  21.         visuControl.offsetX = parseFloat(storedoffsetX);


  22.  


  23.     var storedoffsetY = window.localStorage[“offsetY”];


  24.     if (storedoffsetY != undefined)


  25.         visuControl.offsetY = parseFloat(storedoffsetY);


  26. }




Animations

To add even more dynamism to our application we will allow our users to double-click on a card to zoom and focus on it.

Our system should animate three values: the two offsets (X, Y) and the zoom. To do this, we will use a function that will be responsible of animating a variable from a source value to a destination value with a given duration:






  1. var AnimationHelper = function (root, name) {


  2.     var paramName = name;


  3.     this.animate = function (current, to, duration) {


  4.         var offset = (to – current);


  5.         var ticks = Math.floor(duration / 16);


  6.         var offsetPart = offset / ticks;


  7.         var ticksCount = 0;


  8.  


  9.         var intervalID = setInterval(function () {


  10.             current += offsetPart;


  11.             root[paramName] = current;


  12.             ticksCount++;


  13.  


  14.             if (ticksCount == ticks) {


  15.                 clearInterval(intervalID);


  16.                 root[paramName] = to;


  17.             }


  18.         }, 16);


  19.     };


  20. };




The use of this function is:






  1. // Prepare animations parameters


  2. var zoomAnimationHelper = new AnimationHelper(visuControl, “zoom”);


  3. var offsetXAnimationHelper = new AnimationHelper(visuControl, “offsetX”);


  4. var offsetYAnimationHelper = new AnimationHelper(visuControl, “offsetY”);


  5. var speed = 1.1 – visuControl.zoom;


  6. zoomAnimationHelper.animate(visuControl.zoom, 1.0, 1000 speed);


  7. offsetXAnimationHelper.animate(visuControl.offsetX, targetOffsetX, 1000 speed);


  8. offsetYAnimationHelper.animate(visuControl.offsetY, targetOffsetY, 1000 * speed);




The advantage of the AnimationHelper function is that it is able to animate as many parameters as you wish (and that only with the setTimer function!)

Handling multi-devices

Finally we will ensure that our page can also be seen on tablets PC and even on phones.

To do this, we will use a feature of CSS 3: The media-queries. With this technology, we can apply style sheets according to some queries such as a specific display size:






  1. <link href=”Content/full.css” rel=”stylesheet” type=”text/css” />


  2. <link href=”Content/mobile.css” rel=”stylesheet” type=”text/css” media=”screen and (max-width: 480px)” />


  3. <link href=”Content/mobile.css” rel=”stylesheet” type=”text/css” media=”screen and (max-device-width: 480px)” />




Here we see that if the screen width is less than 480 pixels, the following style sheet will be added:






  1. #legal


  2. {


  3.     font-size: 8px;    


  4. }


  5.  


  6. #title


  7. {


  8.     font-size: 30px !important;


  9. }


  10.  


  11. #waitText


  12. {


  13.     font-size: 12px;


  14. }


  15.  


  16. #bolasLogo


  17. {


  18.     width: 48px;


  19.     height: 48px;


  20. }


  21.  


  22. #pictureCell


  23. {


  24.     width: 48px;


  25. }




This sheet will reduce the size of the header to keep the site viewable even when the browser width is less than 480 pixels (for example, on a Windows Phone):

Conclusion

HTML 5 / CSS 3 / JavaScript and Visual Studio 2010 allow to develop portable and efficient solutions (within the limits of browsers that support HTML 5 of course) with some great features such as hardware accelerated rendering.

This kind of development is also simplified by the use of frameworks like jQuery.

Also, I am especially fan of JavaScript that turns out to be a very powerful dynamic language. Of course, C# or VB.NET developers have to change theirs reflexes but for the development of web pages it’s worth.

In conclusion, I think that the best to be convinced is to try!

To go further

Gestures and Tools for Kinect

You have certainly not missed (as a regular reader of this blog Sourire) that the Kinect for Windows SDK is out!

For now, however, no gestures recognition services are available. So throughout this paper we will create our own library that will automatically detect simple movements such as swipe but also movements more complex such as drawing a circle with your hand.


image_thumb6image_thumb8

The detection of such gestures enable Powerpoint control the Jedi way ! (similar to the Kinect Keyboard Simulator demo).

If you are not familiar with the Kinect for Windows SDK, you should read a previous post that addressed the topic: https://blogs.msdn.com/b/eternalcoding/archive/2011/06/13/unleash-the-power-of-kinect-for-windows-sdk.aspx

How to detect gestures ?

There is an infinite number of solutions for detecting a gesture. In this article I will explorer two of them:

  • Algorithmic search
  • Template based search

Note that these two techniques have many variants and refinements.

You can find the code used in this article just here: **[https://kinecttoolbox.codeplex.com**](https://kinecttoolbox.codeplex.com)

image_thumb[15]

GestureDetector class

To standardize the use of our gestures system, we will therefore propose an abstract class GestureDetector inherited by all gesture classes:

image_thumb5

This class provides the Add method used to record the different positions of the skeleton’s joints.

It also provides the abstract method LookForGesture implemented by the children.

It stores a list of Entry in the property Entries whose role is to save the properties and timing of each recorded position.

Drawing stored positions

The Entry class also stores an WPF ellipse that will be used to draw the stored position:image_thumb7

Via the TraceTo method of the GestureDetector class, we will indicate which canvas will be used to draw the stored positions.

In the end, all the work is done in the Add method:






  1. public virtual void Add(Vector position, SkeletonEngine engine)


  2. {


  3.     Entry newEntry = new Entry {Position = position.ToVector3(), Time = DateTime.Now};


  4.     Entries.Add(newEntry);


  5.  


  6.     if (displayCanvas != null)


  7.     {


  8.         newEntry.DisplayEllipse = new Ellipse


  9.         {


  10.             Width = 4,


  11.             Height = 4,


  12.             HorizontalAlignment = HorizontalAlignment.Left,


  13.             VerticalAlignment = VerticalAlignment.Top,


  14.             StrokeThickness = 2.0,


  15.             Stroke = new SolidColorBrush(displayColor),


  16.             StrokeLineJoin = PenLineJoin.Round


  17.         };


  18.  


  19.  


  20.         float x, y;


  21.  


  22.         engine.SkeletonToDepthImage(position, out x, out y);


  23.  


  24.         x = (float)(x displayCanvas.ActualWidth);


  25.         y = (float)(y displayCanvas.ActualHeight);


  26.  


  27.         Canvas.SetLeft(newEntry.DisplayEllipse, x – newEntry.DisplayEllipse.Width / 2);


  28.         Canvas.SetTop(newEntry.DisplayEllipse, y – newEntry.DisplayEllipse.Height / 2);


  29.  


  30.         displayCanvas.Children.Add(newEntry.DisplayEllipse);


  31.     }


  32.  


  33.     if (Entries.Count > WindowSize)


  34.     {


  35.         Entry entryToRemove = Entries[0];


  36.         


  37.         if (displayCanvas != null)


  38.         {


  39.             displayCanvas.Children.Remove(entryToRemove.DisplayEllipse);


  40.         }


  41.  


  42.         Entries.Remove(entryToRemove);


  43.     }


  44.  


  45.     LookForGesture();


  46. }




Note the use of the SkeletonToDepthImage method which converts a 3D coordinate to a 2D coordinate between 0 and 1 on each axis.

So in addition to saving the position of the joints, the GestureDetector class can draw them to give visual feedback that greatly simplifies the development and debug phases:

image_thumb

As we can see above, the positions being analyzed are shown in red above the Kinect image. To activate this service, the developer just needs to put a canvas over the image that shows the stream of the Kinect camera and pass this canvas to the GestureDetector.TraceTo method:






  1. <Viewbox Margin=”5” Grid.RowSpan=”5”>


  2.     <Grid Width=”640” Height=”480” ClipToBounds=”True”>


  3.         <Image x:Name=”kinectDisplay”></Image>


  4.         <Canvas x:Name=”kinectCanvas”></Canvas>


  5.         <Canvas x:Name=”gesturesCanvas”></Canvas>


  6.         <Rectangle Stroke=”Black” StrokeThickness=”1”/>


  7.     </Grid>


  8. </Viewbox>




The Viewbox is used to keep the image and the canvas at the same size. The second canvas (kinectCanvas) is used to display the green skeleton (using a class available in the sample : SkeletonDisplayManager).

Event-based approach

GestureDetector class provides one last service to his children: the RaiseGestureDetected method that reports the detection of a new gesture via an OnGestureDetected event. The SupportedGesture argument of this event contains the following values:

  • SwipeToLeft
  • SwipeToRight
  • Circle

Obviously the solution is extensible and I encourage you to add new gestures to the system.

The RaiseGestureDetected method (with MinimalPeriodBetweenGestures property) also guarantee that a certain time will elapse between two gestures (in order to remove badly executed gestures).

Now that our foundations are laid, we can develop our algorithms.

Algorithmic search

The algorithmic search browses the list of positions and checks that predefined constraints are always valid.

The SwipeGestureDetector class is responsible for this search:

image_thumb3

For the SwipeToRight gesture, we will use the following constraints:

  • Each new position should be to the right of the previous one
  • Each position must not exceed in height the first by more than a given distance (20 cm)
  • The time between the first and last position must be between 250ms and 1500ms
  • The gesture must be at least 40 cm long

The SwipeToLeft gesture is based on the same constraints except for the direction of the movement of course.

To effectively manage these two gestures, we use a generic algorithm that checks the four constraints mentioned above:






  1. bool ScanPositions(Func<Vector3, Vector3, bool> heightFunction, Func<Vector3, Vector3, bool> directionFunction, Func<Vector3, Vector3, bool> lengthFunction, int minTime, int maxTime)


  2. {


  3.     int start = 0;


  4.  


  5.     for (int index = 1; index < Entries.Count – 1; index++)


  6.     {


  7.         if (!heightFunction(Entries[0].Position, Entries[index].Position) || !directionFunction(Entries[index].Position, Entries[index + 1].Position))


  8.         {


  9.             start = index;


  10.         }


  11.  


  12.         if (lengthFunction(Entries[index].Position, Entries[start].Position))


  13.         {


  14.             double totalMilliseconds = (Entries[index].Time – Entries[start].Time).TotalMilliseconds;


  15.             if (totalMilliseconds >= minTime && totalMilliseconds <= maxTime)


  16.             {


  17.                 return true;


  18.             }


  19.         }


  20.     }


  21.  


  22.     return false;


  23. }




To use this method, we must provide three functions and a time-delay to check.

So to manage the two gestures, simply call the following code:






  1. protected override void LookForGesture()


  2. {


  3.     // Swipe to right


  4.     if (ScanPositions((p1, p2) => Math.Abs(p2.Y – p1.Y) < SwipeMaximalHeight, // Height


  5.         (p1, p2) => p2.X – p1.X > -0.01f, // Progression to right


  6.         (p1, p2) => Math.Abs(p2.X – p1.X) > SwipeMinimalLength, // Length


  7.         SwipeMininalDuration, SwipeMaximalDuration)) // Duration


  8.     {


  9.         RaiseGestureDetected(SupportedGesture.SwipeToRight);


  10.         return;


  11.     }


  12.  


  13.     // Swipe to left


  14.     if (ScanPositions((p1, p2) => Math.Abs(p2.Y – p1.Y) < SwipeMaximalHeight,  // Height


  15.         (p1, p2) => p2.X – p1.X < 0.01f, // Progression to right


  16.         (p1, p2) => Math.Abs(p2.X – p1.X) > SwipeMinimalLength, // Length


  17.         SwipeMininalDuration, SwipeMaximalDuration))// Duration


  18.     {


  19.         RaiseGestureDetected(SupportedGesture.SwipeToLeft);


  20.         return;


  21.     }


  22. }




With this class it is really simple to add gestures that are detectable with constraints.

Skeleton stability

To ensure the proper operation for our detection, we must validate that the skeleton is actually static so as not to generate wrong gestures (i.e. detection of movement associated with a swipe of the whole body) .

To do that, we will use the BarycenterHelper class:






  1. public class BarycenterHelper


  2. {


  3.     readonly Dictionary<int, List<Vector3>> positions = new Dictionary<int, List<Vector3>>();


  4.     readonly int windowSize;


  5.  


  6.     public float Threshold { get; set; }


  7.  


  8.     public BarycenterHelper(int windowSize = 20, float threshold = 0.05f)


  9.     {


  10.         this.windowSize = windowSize;


  11.         Threshold = threshold;


  12.     }


  13.  


  14.     public bool IsStable(int trackingID)


  15.     {


  16.         List<Vector3> currentPositions = positions[trackingID];


  17.         if (currentPositions.Count != windowSize)


  18.             return false;


  19.  


  20.         Vector3 current = currentPositions[currentPositions.Count – 1];


  21.  


  22.         for (int index = 0; index < currentPositions.Count – 2; index++)


  23.         {


  24.             Debug.WriteLine((currentPositions[index] – current).Length());


  25.  


  26.             if ((currentPositions[index] – current).Length() > Threshold)


  27.                 return false;


  28.         }


  29.  


  30.         return true;


  31.     }


  32.  


  33.     public void Add(Vector3 position, int trackingID)


  34.     {


  35.         if (!positions.ContainsKey(trackingID))


  36.             positions.Add(trackingID, new List<Vector3>());


  37.  


  38.         positions[trackingID].Add(position);


  39.  


  40.         if (positions[trackingID].Count > windowSize)


  41.             positions[trackingID].RemoveAt(0);


  42.     }


  43. }




By providing to this class the successive positions of the skeleton, it will tell us (via the IsStable method) if the skeleton is moving or static.

Thus, we can use this information to send the positions of the joints to the detection systems only when the skeleton is not in motion:






  1. void ProcessFrame(ReplaySkeletonFrame frame)


  2. {


  3.     Dictionary<int, string> stabilities = new Dictionary<int, string>();


  4.     foreach (var skeleton in frame.Skeletons)


  5.     {


  6.         if (skeleton.TrackingState != SkeletonTrackingState.Tracked)


  7.             continue;


  8.  


  9.         barycenterHelper.Add(skeleton.Position.ToVector3(), skeleton.TrackingID);


  10.  


  11.         stabilities.Add(skeleton.TrackingID, barycenterHelper.IsStable(skeleton.TrackingID) ? “Stable” : “Unstable”);


  12.         if (!barycenterHelper.IsStable(skeleton.TrackingID))


  13.             continue;


  14.  


  15.         foreach (Joint joint in skeleton.Joints)


  16.         {


  17.             if (joint.Position.W < 0.8f || joint.TrackingState != JointTrackingState.Tracked)


  18.                 continue;


  19.  


  20.             if (joint.ID == JointID.HandRight)


  21.             {


  22.                 swipeGestureRecognizer.Add(joint.Position, kinectRuntime.SkeletonEngine);


  23.                 circleGestureRecognizer.Add(joint.Position, kinectRuntime.SkeletonEngine);


  24.             }


  25.         }


  26.  


  27.         postureRecognizer.TrackPostures(skeleton);


  28.     }


  29.  


  30.     skeletonDisplayManager.Draw(frame);


  31.  


  32.     stabilitiesList.ItemsSource = stabilities;


  33.  


  34.     currentPosture.Text = “Current posture: “ + postureRecognizer.CurrentPosture.ToString();


  35. }




Replay & Recording tools

Another important point when developing with the Kinect for Windows SDK is the ability to efficiently test. It may sound silly, but to test you must get up, come in front of the sensor and make the appropriate gesture. And unless you have an assistant, this can quickly become painful.

So we’ll have a record and replay service for the information sent by Kinect.

Recording

The recording part is pretty simple because we only have to take a SkeletonFrame and browse each skeleton to serialize its contents:






  1. public void Record(SkeletonFrame frame)


  2. {


  3.     if (writer == null)


  4.         throw new Exception(“You must call Start before calling Record”);


  5.  


  6.     TimeSpan timeSpan = DateTime.Now.Subtract(referenceTime);


  7.     referenceTime = DateTime.Now;


  8.     writer.Write((long)timeSpan.TotalMilliseconds);


  9.     writer.Write(frame.FloorClipPlane);


  10.     writer.Write((int)frame.Quality);


  11.     writer.Write(frame.NormalToGravity);


  12.  


  13.     writer.Write(frame.Skeletons.Length);


  14.  


  15.     foreach (SkeletonData skeleton in frame.Skeletons)


  16.     {


  17.         writer.Write((int)skeleton.TrackingState);


  18.         writer.Write(skeleton.Position);


  19.         writer.Write(skeleton.TrackingID);


  20.         writer.Write(skeleton.EnrollmentIndex);


  21.         writer.Write(skeleton.UserIndex);


  22.         writer.Write((int)skeleton.Quality);


  23.  


  24.         writer.Write(skeleton.Joints.Count);


  25.         foreach (Joint joint in skeleton.Joints)


  26.         {


  27.             writer.Write((int)joint.ID);


  28.             writer.Write((int)joint.TrackingState);


  29.             writer.Write(joint.Position);


  30.         }


  31.     }


  32. }




Replay

The main problem with the replay mechanism is about data reconstruction. Indeed, Kinect classes are sealed and do not expose their constructor. To work around this problem, we will replicate and mimic the Kinect class hierarchy adding implicit cast operators to Kinect classes:

image_thumb[3]

The SkeletonReplay class is responsible of the replay with its Start method:






  1. public void Start()


  2. {


  3.     context = SynchronizationContext.Current;


  4.  


  5.     CancellationToken token = cancellationTokenSource.Token;


  6.  


  7.     Task.Factory.StartNew(() =>


  8.     {


  9.         foreach (ReplaySkeletonFrame frame in frames)


  10.         {


  11.             Thread.Sleep(TimeSpan.FromMilliseconds(frame.TimeStamp));


  12.  


  13.             if (token.IsCancellationRequested)


  14.                 return;


  15.                                       


  16.             ReplaySkeletonFrame closure = frame;


  17.             context.Send(state =>


  18.                             {


  19.                                 if (SkeletonFrameReady != null)


  20.                                     SkeletonFrameReady(this, new ReplaySkeletonFrameReadyEventArgs {SkeletonFrame = closure});


  21.                             }, null);


  22.         }


  23.     }, token);


  24. }




Finally, we can record and replay gestures to debug our application:

image_thumb[6]

You can download a replay sample here: https://www.catuhe.com/msdn/davca.replay.zip

Know when to start

The last remaining problem to resolve is deciding when to begin the analysis of gestures. We already know that we must do so when the body is stable but it is not enough.

Even if I stay static, I use my hands a lot when I speak and I can inadvertently trigger a gesture.

To protect ourselves from this, it is possible to complete the detection by adding a posture condition.

That’s why we are going to use the PostureDetector class:






  1. public class PostureDetector


  2. {


  3.     const float Epsilon = 0.1f;


  4.     const float MaxRange = 0.25f;


  5.     const int AccumulatorTarget = 10;


  6.  


  7.     Posture previousPosture = Posture.None;


  8.     public event Action<Posture> PostureDetected;


  9.     int accumulator;


  10.     Posture accumulatedPosture = Posture.None;


  11.  


  12.     public Posture CurrentPosture


  13.     {


  14.         get { return previousPosture; }


  15.     }


  16.  


  17.     public void TrackPostures(ReplaySkeletonData skeleton)


  18.     {


  19.         if (skeleton.TrackingState != SkeletonTrackingState.Tracked)


  20.             return;


  21.  


  22.         Vector3? headPosition = null;


  23.         Vector3? leftHandPosition = null;


  24.         Vector3? rightHandPosition = null;


  25.  


  26.         foreach (Joint joint in skeleton.Joints)


  27.         {


  28.             if (joint.Position.W < 0.8f || joint.TrackingState != JointTrackingState.Tracked)


  29.                 continue;


  30.  


  31.             switch (joint.ID)


  32.             {


  33.                 case JointID.Head:


  34.                     headPosition = joint.Position.ToVector3();


  35.                     break;


  36.                 case JointID.HandLeft:


  37.                     leftHandPosition = joint.Position.ToVector3();


  38.                     break;


  39.                 case JointID.HandRight:


  40.                     rightHandPosition = joint.Position.ToVector3();


  41.                     break;


  42.             }


  43.         }


  44.  


  45.         // HandsJoined


  46.         if (CheckHandsJoined(rightHandPosition, leftHandPosition))


  47.             return;


  48.  


  49.         // LeftHandOverHead


  50.         if (CheckHandOverHead(headPosition, leftHandPosition))


  51.         {


  52.             RaisePostureDetected(Posture.LeftHandOverHead);


  53.             return;


  54.         }


  55.  


  56.         // RightHandOverHead


  57.         if (CheckHandOverHead(headPosition, rightHandPosition))


  58.         {


  59.             RaisePostureDetected(Posture.RightHandOverHead);


  60.             return;


  61.         }


  62.  


  63.         // LeftHello


  64.         if (CheckHello(headPosition, leftHandPosition))


  65.         {


  66.             RaisePostureDetected(Posture.LeftHello);


  67.             return;


  68.         }


  69.  


  70.         // RightHello


  71.         if (CheckHello(headPosition, rightHandPosition))


  72.         {


  73.             RaisePostureDetected(Posture.RightHello);


  74.             return;


  75.         }


  76.  


  77.         previousPosture = Posture.None;


  78.         accumulator = 0;


  79.     }


  80.  


  81.     bool CheckHandOverHead(Vector3? headPosition, Vector3? handPosition)


  82.     {


  83.         if (!handPosition.HasValue || !headPosition.HasValue)


  84.             return false;


  85.  


  86.         if (handPosition.Value.Y < headPosition.Value.Y)


  87.             return false;


  88.  


  89.         if (Math.Abs(handPosition.Value.X – headPosition.Value.X) > MaxRange)


  90.             return false;


  91.  


  92.         if (Math.Abs(handPosition.Value.Z – headPosition.Value.Z) > MaxRange)


  93.             return false;


  94.  


  95.         return true;


  96.     }


  97.  


  98.  


  99.     bool CheckHello(Vector3? headPosition, Vector3? handPosition)


  100.     {


  101.         if (!handPosition.HasValue || !headPosition.HasValue)


  102.             return false;


  103.  


  104.         if (Math.Abs(handPosition.Value.X – headPosition.Value.X) < MaxRange)


  105.             return false;


  106.  


  107.         if (Math.Abs(handPosition.Value.Y – headPosition.Value.Y) > MaxRange)


  108.             return false;


  109.  


  110.         if (Math.Abs(handPosition.Value.Z – headPosition.Value.Z) > MaxRange)


  111.             return false;


  112.  


  113.         return true;


  114.     }


  115.  


  116.     bool CheckHandsJoined(Vector3? leftHandPosition, Vector3? rightHandPosition)


  117.     {


  118.         if (!leftHandPosition.HasValue || !rightHandPosition.HasValue)


  119.             return false;


  120.  


  121.         float distance = (leftHandPosition.Value – rightHandPosition.Value).Length();


  122.  


  123.         if (distance > Epsilon)


  124.             return false;


  125.  


  126.         RaisePostureDetected(Posture.HandsJoined);


  127.         return true;


  128.     }


  129.  


  130.     void RaisePostureDetected(Posture posture)


  131.     {


  132.         if (accumulator < AccumulatorTarget)


  133.         {


  134.             if (accumulatedPosture != posture)


  135.             {


  136.                 accumulator = 0;


  137.                 accumulatedPosture = posture;


  138.             }


  139.             accumulator++;


  140.             return;


  141.         }


  142.  


  143.         if (previousPosture == posture)


  144.             return;


  145.  


  146.         previousPosture = posture;


  147.         if (PostureDetected != null)


  148.             PostureDetected(posture);


  149.  


  150.         accumulator = 0;


  151.     }


  152. }




The PostureDetector class is based on a comparative analysis of the positions of each joint. For example, to trigger the Hello posture, we have to know if the hand is at the same height as the head and if it is at least 25cm on the side.

In addition, the system use an accumulator to ensure that the posture is stable during a given number of frames.

Once again this class is highly extensible.

Template-based search

The main drawback of the algorithmic search is that all gestures are not easily describable with constraints. We will therefore consider another more general approach.

We will assume that a gesture can be recorded and subsequently, the system will determine if the current gesture is one that is already known.

Finally, our goal will be to efficiently compare two gestures.

Compare the comparable

Before we start to write a comparison algorithm, we have to standardize our data.

Indeed, a gesture is a sequence of points (for this article we will simply compare 2D gestures such as circles). However, the coordinates of these points define a distance to the sensor and we will have to bring them together to a common reference. To do this we will do the following;

  1. Generate a new gesture with a defined number of points
  2. Rotate the gesture so the first point is at 0 degree
  3. Rescale the gesture to a 1×1 reference graduation
  4. Center the gesture to origin

With these changes, we will be able to compare points array of the same size centered on a common graduation with a common direction.

To pack points array using this technique, we use the following code:






  1. public static List<Vector2> Pack(List<Vector2> positions, int samplesCount)


  2. {


  3.     List<Vector2> locals = ProjectListToDefinedCount(positions, samplesCount);


  4.  


  5.     float angle = GetAngleBetween(locals.Center(), positions[0]);


  6.     locals = locals.Rotate(-angle);


  7.  


  8.     locals.ScaleToReferenceWorld();


  9.     locals.CenterToOrigin();


  10.  


  11.     return locals;


  12. }




Methods and extension methods are available in the GoldenSectionExtensions static class:






  1. public static class GoldenSectionExtensions


  2. {


  3.     // Get length of path


  4.     public static float Length(this List<Vector2> points)


  5.     {


  6.         float length = 0;


  7.  


  8.         for (int i = 1; i < points.Count; i++)


  9.         {


  10.             length += (points[i – 1] – points[i]).Length();


  11.         }


  12.  


  13.         return length;


  14.     }


  15.  


  16.     // Get center of path


  17.     public static Vector2 Center(this List<Vector2> points)


  18.     {


  19.         Vector2 result = points.Aggregate(Vector2.Zero, (current, point) => current + point);


  20.  


  21.         result /= points.Count;


  22.  


  23.         return result;


  24.     }


  25.  


  26.     // Rotate path by given angle


  27.     public static List<Vector2> Rotate(this List<Vector2> positions, float angle)


  28.     {


  29.         List<Vector2> result = new List<Vector2>(positions.Count);


  30.         Vector2 c = positions.Center();


  31.  


  32.         float cos = (float)Math.Cos(angle);


  33.         float sin = (float)Math.Sin(angle);


  34.  


  35.         foreach (Vector2 p in positions)


  36.         {


  37.             float dx = p.X – c.X;


  38.             float dy = p.Y – c.Y;


  39.  


  40.             Vector2 rotatePoint = Vector2.Zero;


  41.             rotatePoint.X = dx cos – dy sin + c.X;


  42.             rotatePoint.Y = dx sin + dy cos + c.Y;


  43.  


  44.             result.Add(rotatePoint);


  45.         }


  46.         return result;


  47.     }


  48.  


  49.     // Average distance betweens paths


  50.     public static float DistanceTo(this List<Vector2> path1, List<Vector2> path2)


  51.     {


  52.         return path1.Select((t, i) => (t – path2[i]).Length()).Average();


  53.     }


  54.  


  55.     // Compute bounding rectangle


  56.     public static Rectangle BoundingRectangle(this List<Vector2> points)


  57.     {


  58.         float minX = points.Min(p => p.X);


  59.         float maxX = points.Max(p => p.X);


  60.         float minY = points.Min(p => p.Y);


  61.         float maxY = points.Max(p => p.Y);


  62.  


  63.         return new Rectangle(minX, minY, maxX – minX, maxY – minY);


  64.     }


  65.  


  66.     // Check bounding rectangle size


  67.     public static bool IsLargeEnough(this List<Vector2> positions, float minSize)


  68.     {


  69.         Rectangle boundingRectangle = positions.BoundingRectangle();


  70.  


  71.         return boundingRectangle.Width > minSize && boundingRectangle.Height > minSize;


  72.     }


  73.  


  74.     // Scale path to 1×1


  75.     public static void ScaleToReferenceWorld(this List<Vector2> positions)


  76.     {


  77.         Rectangle boundingRectangle = positions.BoundingRectangle();


  78.         for (int i = 0; i < positions.Count; i++)


  79.         {


  80.             Vector2 position = positions[i];


  81.  


  82.             position.X = (1.0f / boundingRectangle.Width);


  83.             position.Y = (1.0f / boundingRectangle.Height);


  84.  


  85.             positions[i] = position;


  86.         }


  87.     }


  88.  


  89.     // Translate path to origin (0, 0)


  90.     public static void CenterToOrigin(this List<Vector2> positions)


  91.     {


  92.         Vector2 center = positions.Center();


  93.         for (int i = 0; i < positions.Count; i++)


  94.         {


  95.             positions[i] -= center;


  96.         }


  97.     }


  98. }




Golden Section

The comparison between our data could be done via a simple average distance function between each point. However, this solution is not accurate enough.

So I used a much more powerful algorithm called Golden Section Search. He comes from a paper available here: https://www.math.uic.edu/~jan/mcs471/Lec9/gss.pdf

A JavaScript implementation is available here: https://depts.washington.edu/aimgroup/proj/dollar/

The implementation in C#:






  1. public static float Search(List<Vector2> current, List<Vector2> target, float a, float b, float epsilon)


  2. {


  3.     float x1 = ReductionFactor a + (1 – ReductionFactor) b;


  4.     List<Vector2> rotatedList = current.Rotate(x1);


  5.     float fx1 = rotatedList.DistanceTo(target);


  6.  


  7.     float x2 = (1 – ReductionFactor) a + ReductionFactor b;


  8.     rotatedList = current.Rotate(x2);


  9.     float fx2 = rotatedList.DistanceTo(target);


  10.  


  11.     do


  12.     {


  13.         if (fx1 < fx2)


  14.         {


  15.             b = x2;


  16.             x2 = x1;


  17.             fx2 = fx1;


  18.             x1 = ReductionFactor a + (1 – ReductionFactor) b;


  19.             rotatedList = current.Rotate(x1);


  20.             fx1 = rotatedList.DistanceTo(target);


  21.         }


  22.         else


  23.         {


  24.             a = x1;


  25.             x1 = x2;


  26.             fx1 = fx2;


  27.             x2 = (1 – ReductionFactor) a + ReductionFactor b;


  28.             rotatedList = current.Rotate(x2);


  29.             fx2 = rotatedList.DistanceTo(target);


  30.         }


  31.     }


  32.     while (Math.Abs(b – a) > epsilon);


  33.  


  34.     float min = Math.Min(fx1, fx2);


  35.  


  36.     return 1.0f – 2.0f * min / Diagonal;


  37. }




With this algorithm, we can simply compare a template with the current gesture and get a score (between 0 and 1).

Learning Machine

To improve our success rate, we need to have multiple templates. For this, we will work with the LearningMachine class whose role is precisely to store our templates (i.e. to learn new models) and to compare with the current gesture:






  1. public class LearningMachine


  2. {


  3.     readonly List<RecordedPath> paths;


  4.  


  5.     public LearningMachine(Stream kbStream)


  6.     {


  7.         if (kbStream == null || kbStream.Length == 0)


  8.         {


  9.             paths = new List<RecordedPath>();


  10.             return;


  11.         }


  12.  


  13.         BinaryFormatter formatter = new BinaryFormatter();


  14.  


  15.         paths = (List<RecordedPath>)formatter.Deserialize(kbStream);


  16.     }


  17.  


  18.     public List<RecordedPath> Paths


  19.     {


  20.         get { return paths; }


  21.     }


  22.  


  23.     public bool Match(List<Vector2> entries, float threshold, float minimalScore, float minSize)


  24.     {


  25.         return Paths.Any(path => path.Match(entries, threshold, minimalScore, minSize));


  26.     }


  27.  


  28.     public void Persist(Stream kbStream)


  29.     {


  30.         BinaryFormatter formatter = new BinaryFormatter();


  31.  


  32.         formatter.Serialize(kbStream, Paths);


  33.     }


  34.  


  35.     public void AddPath(RecordedPath path)


  36.     {


  37.         path.CloseAndPrepare();


  38.         Paths.Add(path);


  39.     }


  40. }




Each RecordedPath implements the Match method and therefore call the Golden Section Search:






  1. public bool Match(List<Vector2> positions, float threshold, float minimalScore, float minSize)


  2. {


  3.     if (positions.Count < samplesCount)


  4.         return false;


  5.  


  6.     if (!positions.IsLargeEnough(minSize))


  7.         return false;


  8.  


  9.     List<Vector2> locals = GoldenSection.Pack(positions, samplesCount);


  10.  


  11.     float score = GoldenSection.Search(locals, points, –MathHelper.PiOver4, MathHelper.PiOver4, threshold);


  12.  


  13.     return score > minimalScore;


  14. }




Thus, thanks to our detection algorithm and to our learning machine, we are dealing with a system that is both reliable and very little dependent on the quality of information supplied by Kinect.

You will find below an example of a knowledge base used to recognize a circle: https://www.catuhe.com/msdn/circleKB.zip.

Conclusion

So we have at our disposal a set of tools for working with Kinect. In addition we have two systems to detect a large number of gestures.

It’s now your turn to use these services in your Kinect applications!

To go further

Unleash the power of Kinect for Windows SDK!

This post is a translation of https://blogs.msdn.com/b/eternalcoding/archive/2011/06/14/fr-prenez-le-contr-244-le-avec-kinect-pour-windows-sdk.aspx

image_thumb16

Introductionimage_thumb5[1]

Microsoft Research has released the first beta of Kinect for Windows SDK. You can find resources and download the SDK at:

https://research.microsoft.com/kinectsdk

This SDK also install drivers for the Kinect sensors. However, be aware that the SDK will only install on Windows 7 (x86 and x64).
The first point worth noting is that the latter is actually available in two versions: one for C++ developers and one for managed developers.

So there is no jealousy. As I prefer managed environment, my samples will be presented in C # (matter of taste only).

Regarding the licensing mode, this version released by Microsoft Research, is free for private use (basically, anything that is not commercial).

Architecture

Basically, the Kinect sensors will send a set of three streams:

Image stream can be displayed like with any other camera (for example to do augmented reality). The Kinect video sensor can return a stream with 2 resolutions: one at 640×480 (at 30 frames per second) and one at 1280×1024 (but at 15 frames per second).

The depth stream is the determining factor in our case. It will indeed add to each pixel a depth defined by the sensor. So in addition to the 2D position of each pixel (and color) we now have depth. This will greatly simplify the writing of shapes detection algorithms.

A third stream is sent from the sensor: it is the audio stream from the four microphones (more on this subject at the end of the article).

Therefore, the key point here concerns the ability of Kinect to give us three-dimensional data. Using the NUI library (which comes with the SDK and stand for Natural User Interfaces) you will be able to detect the presence of humans in front of the sensor. Kinect can “see” up to 4 peoples and accurately track both of them.

When Kinect precisely follows a person, it can provide a skeleton made ​​up of key points detected on the user:

As shown in this diagram of the Vitruvian Man, there are 20 key points (which we call joints) that are detected and tracked by the NUI library.

For best results, it is necessary to stand between 4 and 11 feet from the sensor. Beyond these limits, the sensors accuracy decreases quickly. It is also not possible (yet) to follow a user sitting in front of his computer.

Getting started

To use Kinect for Windows SDK in your .Net application, you only have to reference Microsoft.Research.Kinect.dll.

image_thumb9

Then you have two new namespaces, one for accessing video streams and skeletons and one for audio.






  1. using Microsoft.Research.Kinect.Nui;


  2. using Microsoft.Research.Kinect.Audio




To initialize the NUI library, you must instantiate an object from the Runtime class and configure the streams you want to receive:






  1. kinectRuntime = new Runtime();


  2. kinectRuntime.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseColor);




In our example, we initialize the library with the support of depth stream, video stream and tracking of skeletons.

Video buffer

To use the video stream, you must first define the awaited format, To do so, we’ll ask the library to retrieve the data in a given resolution with a defined pixel format:






  1. kinectRuntime.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color);




Here, we ask for a resolution of 640×480 with a RGB pixel format. It is also possible to request a resolution of 1280×1024 (with lower performances) and pixel can be in YUV format. Resolution as mentioned earlier has an impact on performances. This is not the case of pixel format so it can be chosen according to what suits better for your application.

Subsequently, to be informed of the availability of each image, you must subscribe to an event of the library:






  1. kinectRuntime.VideoFrameReady += kinectRuntime_VideoFrameReady;




In the handler of this event, we can simply produce a BitmapSource to display it in a WPF application:






  1. public class ColorStreamManager


  2. {


  3.     public BitmapSource ColorBitmap { get; private set; }


  4.  


  5.     public void Update(ImageFrameReadyEventArgs e)


  6.     {


  7.         PlanarImage Image = e.ImageFrame.Image;


  8.  


  9.         ColorBitmap = BitmapSource.Create(Image.Width, Image.Height, 96, 96, PixelFormats.Bgr32, null, Image.Bits, Image.Width * Image.BytesPerPixel);


  10.     }


  11. }




Depth buffer

Besides the video stream, Kinect can send a stream coming from the infrared sensor that gives depth data.

The initialization is similar to that of the video stream:






  1. kinectRuntime.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex);


  2. kinectRuntime.DepthFrameReady += kinectRuntime_DepthFrameReady;




The depth data are stored as arrays of 16 bits integers. The depth stream can be retrieved at 320×240 or 80×60.

  • The 13 high-order bits of each pixel represent the distance from the depth sensor to the closest object, in millimeters.
  • The 3 low-order bits of each pixel represent the index of the tracked user who is visible at the pixel’s x and y coordinates.

So if you want to view the depth stream while coloring the areas occupied by humans, it is possible to use this code:






  1. void ConvertDepthFrame(ImageFrameReadyEventArgs e)


  2. {


  3.     depthFrame32 = new byte[e.ImageFrame.Image.Width e.ImageFrame.Image.Height 4];


  4.  


  5.     byte[] depthFrame16 = e.ImageFrame.Image.Bits;


  6.  


  7.     for (int i16 = 0, i32 = 0; i16 < depthFrame16.Length && i32 < depthFrame32.Length; i16 += 2, i32 += 4)


  8.     {


  9.         // R?cup?ration de l’utilisateur courant


  10.         int user = depthFrame16[i16] & 0x07;


  11.  


  12.         // Profondeur (en mm)


  13.         int realDepth = (depthFrame16[i16 + 1] << 5) | (depthFrame16[i16] >> 3);


  14.  


  15.         // Profondeur->Intensit?


  16.         byte intensity = (byte)(255 – (255 * realDepth / 0x0fff));


  17.  


  18.         depthFrame32[i32] = 0;


  19.         depthFrame32[i32 + 1] = 0;


  20.         depthFrame32[i32 + 2] = 0;


  21.         depthFrame32[i32 + 3] = 255;


  22.  


  23.         switch (user)


  24.         {


  25.             case 0: // no one


  26.                 depthFrame32[i32] = (byte)(intensity / 2);


  27.                 depthFrame32[i32 + 1] = (byte)(intensity / 2);


  28.                 depthFrame32[i32 + 2] = (byte)(intensity / 2);


  29.                 break;


  30.             case 1:


  31.                 depthFrame32[i32] = intensity;


  32.                 break;


  33.             case 2:


  34.                 depthFrame32[i32 + 1] = intensity;


  35.                 break;


  36.             case 3:


  37.                 depthFrame32[i32 + 2] = intensity;


  38.                 break;


  39.             case 4:


  40.                 depthFrame32[i32] = intensity;


  41.                 depthFrame32[i32 + 1] = intensity;


  42.                 break;


  43.             case 5:


  44.                 depthFrame32[i32] = intensity;


  45.                 depthFrame32[i32 + 2] = intensity;


  46.                 break;


  47.             case 6:


  48.                 depthFrame32[i32 + 1] = intensity;


  49.                 depthFrame32[i32 + 2] = intensity;


  50.                 break;


  51.             case 7:


  52.                 depthFrame32[i32] = intensity;


  53.                 depthFrame32[i32 + 1] = intensity;


  54.                 depthFrame32[i32 + 2] = intensity;


  55.                 break;


  56.         }


  57.     }


  58. }




This stream can be extremely useful to detect shapes. Thus, it is possible to monitor and detect hands or fingers movements to produce new ways to interact with the PC.

Skeleton tracking

One of the big strengths of Kinect for Windows SDK is its ability to discover the skeleton of joints of an human standing in front of the sensor. And unlike the hacks that have sprung up on Internet (like OpenNI), the Kinect for Windows SDK incorporates a very fast recognition system and requires no training to use. This is the result of a long training of a learning machine. Microsoft Research has given many examples to the recognition system to serve its apprenticeship.

So once you pass behind the sensor (at the right distance of course), the NUI library will discover your skeleton and will raise an event with useful data about it.

To enable skeleton tracking system, you must activate the depth stream and handle the appropriate event:






  1. kinectRuntime.DepthFrameReady += kinectRuntime_DepthFrameReady;




In the handler for this event, we can loop through all the skeletons found by the system:






  1. void kinectRuntime_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)


  2. {


  3.     SkeletonFrame skeletonFrame = e.SkeletonFrame;


  4.  


  5.     foreach (SkeletonData data in skeletonFrame.Skeletons)


  6.     {


  7.         if (data.TrackingState == SkeletonTrackingState.Tracked)


  8.         {


  9.  


  10.             foreach (Joint joint in data.Joints)


  11.             {


  12.                 switch (joint.ID)


  13.                 {


  14.                     case JointID.HandLeft:


  15.                         if (joint.Position.W > 0.6f) // Quality check


  16.                             leftHandGestureRecognizer.Add(joint.Position.ToVector3());


  17.                         break;


  18.                     case JointID.HandRight:


  19.                         if (joint.Position.W > 0.6f) // Quality check


  20.                             rightHandGestureRecognizer.Add(joint.Position.ToVector3());


  21.                         break;


  22.                 }


  23.             }


  24.             return;


  25.         }


  26.     }


  27. }




Several points are noteworthy here:

  • The NUI library cannot track more than 2 skeletons. It is the property TrackingState == SkeletntrackingState.Tracked that defines whether a skeleton is ‘tracked’ or not. The untracked skeletons only give their position.
  • Each joint has a Position property that is defined by a Vector4: (x, y, z, w). The first three attributes define the position in camera space. The last attribute (w) gives the quality level (between 0 and 1) of the position. This allows you to filter and take only the data that the library is almost certain.

  • Each skeleton has a property TrackingID which remains the same on every frame. This allows us to uniquely identify the skeletons between each call.
  • Each joint is identified by an enum which define its reference position (hands, head, etc.).

It is also possible to pool the current skeletons with the SkeletonEngine.GetNextFrame() method.

Finally, the NUI library provides an algorithm for filtering and smoothing incoming data from the sensor. Indeed, by default, the skeletons data are sent without smoothing or filtering. However, the Kinect depth sensor has not sufficient resolution to ensure consistent accuracy over time. Thus, the data seem to vibrate around their positions. To correct this problem, you can call this code:






  1. kinectRuntime.SkeletonEngine.TransformSmooth = true;


  2. var parameters = new TransformSmoothParameters


  3. {


  4.     Smoothing = 1.0f,


  5.     Correction = 0.1f,


  6.     Prediction = 0.1f,


  7.     JitterRadius = 0.05f,


  8.     MaxDeviationRadius = 0.05f


  9. };


  10. kinectRuntime.SkeletonEngine.SmoothParameters = parameters;




As we can see, it is possible to smooth and correct data. Depending on what you need, you should manipulate these parameters to provide the best experience possible.

It is now your imagination’s turn to propose future applications. Thus, it is possible to look for gestures to control applications (the famous PowerPoint Jedi control) or even to make fun with augmented reality…

Kinect and sound

Kinect comes with a group of four microphones (microphone array) that capture sound at very high quality. Indeed, directly on the sensor, a signal processor (DSP) is used to remove background noise and cancel echo effects.

Moreover, thanks to its group of microphones, Kinect can provide the direction of the recorded sound source (beamforming). Then it becomes possible to know who is speaking in a meeting for example.

The Kinect for Windows SDK is also able to be a source for Microsoft.Speech API and thus it becomes possible to do voice recognition using Kinect.

So to use all of these services, simply instantiate an object of class KinectAudioSource:






  1. var source = new KinectAudioSource {SystemMode = SystemMode.OptibeamArrayOnly};




This instantiation can select microphone array mode or single microphone mode with or without echo cancellation (Audio Echo Cancellation: AEC).

To start capturing, we’ll just ask our KinectAudioSource to start providing us the audio stream:






  1. byte[] buffer = new byte[16000];


  2. var audioStream = source.Start();


  3. audioStream.Read(buffer, 0, buffer.Length);




The audio is in 16-kHz, 16-bit mono pulse code modulation (PCM).

To use the beamforming services, use this code:






  1. source.MicArrayMode = MicArrayMode.MicArrayAdaptiveBeam;




There are several ways to detect the sound beam. Here, we let the system itself selects the appropriate beam. It would also be possible to make the selection manually, or take only the central beam or use the average of all beams.

Then, the system can raise an event when the beam moves:






  1. source.BeamChanged += source_BeamChanged;









  1. static void source_BeamChanged(object sender, BeamChangedEventArgs e)


  2. {


  3.     Console.WriteLine(“Angle : {0} radians”, e.Angle);


  4. }




The returned angle is in radians and is relative to the center of your Kinect. If you are in front of it: an angle of 0 indicates that the sound comes across the sensor, an angle <0 indicates="" that="" the="" sound="" comes="" from="" left="" and="" an="" angle=""> 0 indicates that the sound comes from the right.

At any time, it is also possible to request the current value of the angle by calling source.SoundSourcePosition:






  1. if (source.SoundSourcePositionConfidence > 0.9)


  2.     Console.Write(“Position (radians): {0}”, source.SoundSourcePosition);




Like the positions of the skeletons joints, we can get a data level of quality to decide if we want to use it.

Regarding filters (anti-echo and noise reduction) the KinectAudioSource class provides updatable parameters to achieve the expected results.

Conclusion

So we could see that the Kinect for Windows SDK provides many tools to play with. We are about to discover a lot of new kinds of interaction between man and machine. Of course it lacks some high level tools (like a library of gestures), but it’s an easy bet that the next few weeks will show up many projects from the community and Microsoft (for example the Coding4Fun Kinect Toolkit on CodePlex).

To go further


Kinect%20Sabre%20Screenshot_thumb[1]_thumb[3]

HTML 5 &#038; Silverlight 5

This post is a translation of https://blogs.msdn.com/b/eternalcoding/archive/2011/06/06/fr-html-5-vs-silverlight-5.aspx.

SVSH

Philosophy

The goal of this paper is to present an objective comparison between Silverlight 5 and HTML 5 (with: JavaScript / ECMAScript 5 + CSS3 + any required additional frameworks and APIs). We will only focus on some features: covering these technologies entirely would require a whole book.
The main idea is to provide a guide to help you choose a technology as part of a planned project.
All decisions elements could not be presented here of course. You should take this document as a help to decide rather than as an absolute truth.

In each chapter we will focus on functionalities but also on ease of implementation and performance. The goal here is not to study in detail the features of HTML 5 or Silverlight 5.

Sample source code is available here.

To install Silverlight 5 beta you can go here.

HTML vs XAML

The two competitors are tied on the philosophy as they are both based on a markup language (HTML and XAML). They also both make extensive use of attributes.

Extensibility

Silverlight 5 allows you to add custom attributes to existing tags via attached properties. It is also feasible in HTML 5, but through the use of an inelegant hack (if HTML 5 does not recognize a tag or an attribute, it will just ignore it. Javascript can then process this information to add the required behavior). An implementation example of this usage is the project KnockOut.

On top of that, Silverlight has the Markup Extensions that add behavior to existing attributes (including Binding or even custom behaviors). Moreover, the list of tags is not fixed since it is possible to develop ones own controls providing a real advantage in the industrialization of a Silverlight solution.

DOM access

In Silverlight, each tag can be accessed directly from the code behind using association by name (x: Name). In HTML 5, it is possible to do the same with the attribute ‘id’ but only in certain browsers. We must therefore go through Javascript’s location services by id, which slightly penalizes ease of development:






  1. var toto = document.getElementById(‘toto’);


  2. toto.style.visibility = ‘hidden’;




Regarding the traversing of logic trees, Silverlight and HTML provide equivalent related services.
It is however worth noting that HTML 5 offers a query tool for its DOM named Selectors API. This enables very efficient search across the objects on the page using selection queries:






  1. var alerts = document.querySelectorAll(“p.warning, p.error”);




In this example, we ask the API to return the list of paragraphs whose class is “warning” or “error”. You can also query for IDs, types and many other criteria.

Code/Tags Separation

Silverlight offers a clear separation between markup and code enabled by Visual Studio and partial classes.

In Javascript, it is possible to leave the code in the html page or use the script tag to outsource the code:






  1. <script type=”text/javascript” src=”canvas.js”></script>




Both competitors thus allow for separation of the design part and the development part, helping worth integration of designers in the project.

Tools

The tooling is an easy fight for Silverlight because Notepad is no match for Visual Studio. Silverlight will indeed benefit from the full power of Microsoft Visual Studio and Microsoft Blend where HTML 5 (for now) virtually has no business tool.

With Blend it is easy to design XAML for Silverlight. It is also easy to debug and to have access to all services (syntax highlights, Intellisense, etc.) with Visual Studio. Not to mention profilers and simple solutions development with drag and drop.

The main tools available today for HTML 5 are browsers development toolbars (F12). They will allow debugging or profiling of your code inside the browser. The result is quite good, but far from the integration and the comfort of Visual Studio.

That will obviously change but for now the productivity champion is Silverlight.

Languages

Development

Silverlight is based on C # or Visual Basic which are strongly typed languages with JIT (Just in Time) compilation. Javascript is an interpreted dynamic language (although it can be compiled on the fly in some browsers). Those are definitely two different approaches.

The absence of compilation can results in late discovery of syntax errors, for example.

Moreover it is more difficult to debug a dynamic language which accepts everything (especially errors). With a strongly typed language, it is not possible (at least, it is hard) to mess up an assignment. With Javascript on the contrary, it is possible to put a table in a variable and two lines below assign an integer to it. Similarly if you make a mistake in an assignment writing for example myobject.prop = 1 and if the property ‘prop’ does not exists, Javascript as a dynamic language will create the property instead of raising an error. This greatly complicates debugging. But it also greatly increases the power of the language and its capabilities. Besides, the new versions of C # have made a step towards the dynamic world with lambdas expressions and other dynamic objects (dynamic).

We don’t want here to criticize the dynamic languages ​​or static languages. It is just important to understand the implications of both.

Performances

The main question though is of course in performance.

So let’s take a simple example: we will calculate a million times a transaction involving the manipulation of strings and mathematical calculation.

We look then the time spent executing our code:













Javascript




Silverlight 5







  <p>
    For Javascript:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6d0e816f-e2e6-4b10-8008-796e473c41f9" class="wlWriterSmartContent">
    <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
      <div style="background: #ddd; max-height: 300px; overflow: auto">
        <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
          <li>
            <span style="color: #0000ff"><</span><span style="color: #800000">p</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">=&#8217;result&#8217;></span>
          </li>
          <li style="background: #f3f3f3">
            <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
          </li>
          <li>
            <span style="color: #0000ff"><</span><span style="color: #800000">script</span> <span style="color: #ff0000">language</span><span style="color: #0000ff">="javascript"></span>
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; <span style="color: #0000ff">var</span> start = (<span style="color: #0000ff">new</span> Date).getTime();
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; <span style="color: #0000ff">var</span> sum = 0;
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < 1000000; index++) {
          </li>
          <li>
            &#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += Math.sqrt((<span style="color: #800000">"coucou"</span> + index).toLowerCase().length);
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; }
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; <span style="color: #0000ff">var</span> diff = (<span style="color: #0000ff">new</span> Date).getTime() &#8211; start;
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; <span style="color: #0000ff">var</span> result = document.getElementById(<span style="color: #800000">&#8216;result&#8217;</span>);
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            &#160;&#160;&#160; result.innerText = sum + <span style="color: #800000">&#8216; &#8216;</span> + diff + <span style="color: #800000">&#8216; ms&#8217;</span>;
          </li>
          <li>
            <span style="color: #0000ff"></</span><span style="color: #800000">script</span><span style="color: #0000ff">></span>
          </li>
        </ol>
      </div></p>
    </div></p>
  </div>

  <p>
    For Silverlight 5:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:be29e944-b990-4783-b267-88d6e73a96d1" class="wlWriterSmartContent">
    <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
      <div style="background: #ddd; max-height: 300px; overflow: auto">
        <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
          <li>
            <span style="color: #2b91af">DateTime</span> start = <span style="color: #2b91af">DateTime</span>.Now;
          </li>
          <li style="background: #f3f3f3">
            &#160;
          </li>
          <li>
            <span style="color: #0000ff">double</span> sum = 0;
          </li>
          <li style="background: #f3f3f3">
            &#160;
          </li>
          <li>
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < 1000000; index++)
          </li>
          <li style="background: #f3f3f3">
            {
          </li>
          <li>
            &#160;&#160;&#160; sum += <span style="color: #2b91af">Math</span>.Sqrt((<span style="color: #a31515">"coucou"</span> + index).ToLower().Length);
          </li>
          <li style="background: #f3f3f3">
            }
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            <span style="color: #2b91af">DateTime</span> end = <span style="color: #2b91af">DateTime</span>.Now;
          </li>
          <li>
            &#160;
          </li>
          <li style="background: #f3f3f3">
            result.Text = <span style="color: #0000ff">string</span>.Format(<span style="color: #a31515">"{0} : {1} ms"</span>, sum, end.Subtract(start).TotalMilliseconds);
          </li>
        </ol>
      </div></p>
    </div></p>
  </div>
</p>

<p>
  The result on my computer is:
</p>

<table border="1" cellspacing="0" cellpadding="2" width="368">
  <tr>
    <td valign="top" width="210">
      <p align="center">
        <strong>System</strong>
      </p>
    </td>

    <td valign="top" width="156">
      <p align="center">
        <strong>Time spent</strong>
      </p>
    </td>
  </tr>

  <tr>
    <td valign="top" width="228">
      <em>Silverlight 5</em>
    </td>

    <td valign="top" width="163">
      <p align="center">
        540 ms
      </p>
    </td>
  </tr>

  <tr>
    <td valign="top" width="231">
      Chrome 12
    </td>

    <td valign="top" width="167">
      <p align="center">
        <span style="text-decoration: underline"><em>230 ms</em></span>
      </p>
    </td>
  </tr>

  <tr>
    <td valign="top" width="229">
      IE 10 PP1
    </td>

    <td valign="top" width="170">
      <blockquote>
        <p align="center">
          402 ms
        </p>
      </blockquote>
    </td>
  </tr>

  <tr>
    <td valign="top" width="227">
      IE 9
    </td>

    <td valign="top" width="172">
      <blockquote>
        <p align="center">
          402 ms
        </p>
      </blockquote>
    </td>
  </tr>

  <tr>
    <td valign="top" width="227">
      Firefox 4
    </td>

    <td valign="top" width="172">
      <p align="center">
        712 ms
      </p>
    </td>
  </tr>

  <tr>
    <td valign="top" width="227">
      Opera 11
    </td>

    <td valign="top" width="172">
      <p align="center">
        290 ms
      </p>
    </td>
  </tr>

  <tr>
    <td valign="top" width="227">
      Safari 5
    </td>

    <td valign="top" width="172">
      <p align="center">
        505 ms
      </p>
    </td>
  </tr>
</table>

<p>
  We can see that HTML 5 performance is comparable to Silverlight. Obviously, based on your browser, your mileage may vary and it is obvious that the JavaScript runtime performance will improve in the future. However, we can already see that some browsers are able to do better than Silverlight. I already know that this result will cause an <strong>outcry</strong> but think about it : the modern Javascript runtimes can compile the code in the same way as the .Net JIT do. And if you don’t want to be convinced that managed code and Javascript can run as fast, you should consider that benchmarks (and especially this one) are not reliable <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sourire" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/5164.wlEmoticon-smile_62DC511A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/5164.wlEmoticon_2D00_smile_5F00_62DC511A.png" />.
</p>

<h1>
  SVG vs Shapes
</h1>

<p>
  Silverlight 5 and HTML 5 both offer the possibility of using vector graphics. A vector drawing is composed of geometric shapes unlike bitmaps whhich work with pixels. <br /><a href="https://www.w3.org/TR/2003/REC-SVG11-20030114/">SVG</a> (Scalable Vector Graphics) is the technology for vector graphics in HTML 5. It has the following basic items:
</p>

<ul>
  <li>
    Rectangle
  </li>
  <li>
    Circle
  </li>
  <li>
    Ellipse
  </li>
  <li>
    Line
  </li>
  <li>
    Polyline
  </li>
  <li>
    Polygon
  </li>
  <li>
    Path (with control system: MoveTo, LineTo, …)
  </li>
</ul>

<p>
  Silverlight uses the classes inherited from the base class Shape to define the basic geometric shapes:
</p>

<ul>
  <li>
    Rectangle
  </li>
  <li>
    Ellipse
  </li>
  <li>
    Line
  </li>
  <li>
    Polyline
  </li>
  <li>
    Polygon
  </li>
  <li>
    Path (with control system: MoveTo, LineTo, …)
  </li>
</ul>

<p>
  As we can see, in terms of options it is a <strong>draw</strong>. The two systems provide a very similar transformation system based on matrices. We will look at performance to try to differentiate our competitors. To do this we will develop a small application that will handle circles (or rounded ellipses) and paths (which we will build out of two Bezier curves).
</p>

<table border="0" cellspacing="0" cellpadding="2" width="820">
  <tr>
    <td valign="top" width="410">
      <p align="center">
        <strong>HTML 5</strong>
      </p>
    </td>

    <td valign="top" width="410">
      <p align="center">
        <strong>Silverlight 5</strong>
      </p>
    </td>
  </tr>

  <tr>
    <td valign="top" width="410">
      <p id="svgPerf">
        &#160;
      </p>

      <p style="width: 70px; height: 30px; cursor: pointer; text-decoration: underline" id="launchSVG">
        Launch
      </p>

      <p>
        <svg id="svgRoot" xmlns="https://www.w3.org/2000/svg" height="400" width="400"><defs><clippath id="c1_1"><rect height="400" width="400" y="0" x="0"></rect></clippath></defs><g id="group" clip-path="url(#c1_1)"><path style="fill: #4444ff; stroke: #4444ff; stroke-width: 2" id="svgPath" d="M0 0 L400 0 L400 200 C 350 150 250 150 200 200 C 150 250 50 250 0 200 Z"></path></g></svg></td> 

        <td valign="top" width="410">
        </td></tr> </tbody> </table> 

        <p>
          For HTML 5:
        </p>

        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9f91399a-8c1c-41f1-b2b8-4a7b5a20212e" class="wlWriterSmartContent">
          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
              HTML 5
            </div>

            <div style="background: #ddd; max-height: 500px; overflow: auto">
              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                <li>
                  <span style="color: #0000ff"><!</span><span style="color: #800000">DOCTYPE</span> <span style="color: #ff0000">html</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff"><</span><span style="color: #800000">html</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="https://www.w3.org/1999/xhtml"></span>
                </li>
                <li>
                  <span style="color: #0000ff"><</span><span style="color: #800000">head</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff"></</span><span style="color: #800000">head</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  <span style="color: #0000ff"><</span><span style="color: #800000">body</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">p</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="svgPerf"></span>
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">p</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">=&#8217;launchSVG&#8217;</span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #ff0000">style</span><span style="color: #0000ff">="</span><span style="color: #ff0000">width</span><span style="color: #0000ff">: 70px; </span><span style="color: #ff0000">height</span><span style="color: #0000ff">: 30px; </span><span style="color: #ff0000">cursor</span><span style="color: #0000ff">: pointer; </span><span style="color: #ff0000">text-decoration</span><span style="color: #0000ff">: underline;"></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Launch
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">svg</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="400"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="400"</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="svgRoot"</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="https://www.w3.org/2000/svg"></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">defs</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">clippath</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="c1_1"></span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">rect</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="400"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="400"/></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">clippath</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">defs</span><span style="color: #0000ff">></span>&#160;&#160;&#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">g</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="group"</span> <span style="color: #ff0000">clip-path</span><span style="color: #0000ff">="url(#c1_1)"></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">path</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="svgPath"</span> <span style="color: #ff0000">d</span><span style="color: #0000ff">="M0 0 L400 0 L400 200 C 350 150 250 150 200 200 C 150 250 50 250 0 200 Z"</span> <span style="color: #ff0000">style</span><span style="color: #0000ff">="</span><span style="color: #ff0000">fill</span><span style="color: #0000ff">:#4444FF;</span><span style="color: #ff0000">stroke</span><span style="color: #0000ff">:#4444FF;</span><span style="color: #ff0000">stroke-width</span><span style="color: #0000ff">:2"</span> <span style="color: #0000ff">/></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">g</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">svg</span><span style="color: #0000ff">></span>&#160;&#160;&#160;&#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">script</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="text/javascript"</span> <span style="color: #ff0000">src</span><span style="color: #0000ff">="svg.js"></</span><span style="color: #800000">script</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160; <span style="color: #0000ff"></</span><span style="color: #800000">body</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff"></</span><span style="color: #800000">html</span><span style="color: #0000ff">></span>
                </li>
              </ol>
            </div></p>
          </div></p>
        </div>

        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4a076e2b-3562-43ba-a081-0d29389932e7" class="wlWriterSmartContent">
          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
              Javascript
            </div>

            <div style="background: #ddd; max-height: 500px; overflow: auto">
              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 3em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                <li>
                  <span style="color: #0000ff">var</span> alpha = 0;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">var</span> particles = [];
                </li>
                <li>
                  <span style="color: #0000ff">var</span> radius = 20;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  <span style="color: #0000ff">function</span> Particle() {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> x = 400 * Math.random();
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> y = 400 + radius;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> velocity = 4 * Math.random() + 0.5;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> opacity = 1.0;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #006400">// Create visual element for the particle</span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> domNode = document.createElementNS(<span style="color: #800000">"https://www.w3.org/2000/svg"</span>, <span style="color: #800000">"circle"</span>);
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> group = document.getElementById(<span style="color: #800000">&#8216;group&#8217;</span>);
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; group.appendChild(domNode);
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #006400">// Set initial position to middle of screen</span>
                </li>
                <li>
                  &#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"cx"</span>, x + radius);
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"cy"</span>, y);
                </li>
                <li>
                  &#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"r"</span>, radius);
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #006400">// Set colour of element</span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> chars = <span style="color: #800000">"0123456789abcdef"</span>;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> color = <span style="color: #800000">"#"</span>;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> i = 0; i < 2; i++) {
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> rnd = Math.floor(16 * Math.random());
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; color += chars.charAt(rnd);
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; color += <span style="color: #800000">"0000"</span>;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"fill"</span>, color);
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">function</span> draw() {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; y -= velocity;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (y < -radius) {
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; x = 400 * Math.random();
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; y = 400 + radius;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; velocity = 4 * Math.random() + 0.5;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"cx"</span>, x + radius);
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; opacity = y / 400.0;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"opacity"</span>, opacity);
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; domNode.setAttribute(<span style="color: #800000">"cy"</span>, y);
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">return</span> {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; draw: draw
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  }
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">var</span> previous = [];
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">function</span> computeFPS() {
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #006400">// FPS</span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">if</span> (previous.length > 60) {
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; previous.splice(0, 1);
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; }
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> start = (<span style="color: #0000ff">new</span> Date).getTime();
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; previous.push(start);
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> sum = 0;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < previous.length &#8211; 1; index++) {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += previous[index + 1] &#8211; previous[index];
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> diff = 1000.0 / (sum / previous.length);
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> result = document.querySelector(<span style="color: #800000">&#8216;#svgPerf&#8217;</span>);
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; result.innerHTML = diff.toFixed() + <span style="color: #800000">&#8216; fps&#8217;</span>;
                </li>
                <li style="background: #f3f3f3">
                  }
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">function</span> animateSVG() {
                </li>
                <li>
                  &#160;&#160;&#160; computeFPS();
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #006400">// SVG</span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> h1 = (200 + 20 * Math.cos(alpha)).toFixed();
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> h2 = (200 &#8211; 20 * Math.cos(alpha)).toFixed();
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; svgPath.setAttribute(<span style="color: #800000">"d"</span>, <span style="color: #800000">"M0 0 L400 0 L400 200 C 350 "</span> + h2 + <span style="color: #800000">" 250 "</span> + h2 + <span style="color: #800000">" 200 200 C 150 "</span> + h1 + <span style="color: #800000">" 50 "</span> + h1 + <span style="color: #800000">" 0 200 Z"</span>);
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> particle <span style="color: #0000ff">in</span> particles) {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; particles[particle].draw();
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; alpha += 0.05;
                </li>
                <li style="background: #f3f3f3">
                  }
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">var</span> intervalID;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">function</span> stopSVG() {
                </li>
                <li>
                  &#160;&#160;&#160; launchSVG.innerHTML = <span style="color: #800000">"Launch"</span>;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; window.clearInterval(intervalID);
                </li>
                <li>
                  &#160;&#160;&#160; launchSVG.onclick = startSVG;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; previous = [];
                </li>
                <li>
                  }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  <span style="color: #0000ff">function</span> startSVG() {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; launchSVG.innerHTML = <span style="color: #800000">"Stop"</span>;
                </li>
                <li>
                  &#160;&#160;&#160; launchSVG.onclick = stopSVG;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> i = 0; i < 100; i++) {
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; particles.push(<span style="color: #0000ff">new</span> Particle());
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; }
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; intervalID = window.setInterval(<span style="color: #800000">"animateSVG()"</span>, 17);
                </li>
                <li>
                  }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  <span style="color: #0000ff">var</span> launchSVG = document.getElementById(<span style="color: #800000">&#8216;launchSVG&#8217;</span>);
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">var</span> svgPath = document.getElementById(<span style="color: #800000">&#8216;svgPath&#8217;</span>);
                </li>
                <li>
                  launchSVG.onclick = startSVG;
                </li>
              </ol>
            </div></p>
          </div></p>
        </div>

        <p>
          For Silverlight 5 :
        </p>

        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4d16a2fb-21d3-4bbd-bb4e-344ff3077804" class="wlWriterSmartContent">
          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
              XAML
            </div>

            <div style="background: #ddd; max-height: 500px; overflow: auto">
              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                <li>
                  <span style="color: #0000ff"><</span><span style="color: #a31515">Grid</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #a31515">&#160;</span><span style="color: #0000ff"><</span><span style="color: #a31515">Grid.RowDefinitions</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515">&#160;</span><span style="color: #0000ff"><</span><span style="color: #a31515">RowDefinition</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="60"/></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515">&#160;</span><span style="color: #0000ff"><</span><span style="color: #a31515">RowDefinition</span><span style="color: #0000ff">/></span>
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #a31515">&#160;</span><span style="color: #0000ff"></</span><span style="color: #a31515">Grid.RowDefinitions</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #a31515">&#160;</span><span style="color: #0000ff"><</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515">&#160;</span><span style="color: #0000ff"><</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="fps"/></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Button</span><span style="color: #ff0000"> Content</span><span style="color: #0000ff">="Launch"</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="launchButton"</span><span style="color: #ff0000"> Click</span><span style="color: #0000ff">="launchButton_Click"</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">="70"</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="30"</span><span style="color: #ff0000"> HorizontalAlignment</span><span style="color: #0000ff">="Left"/></span>
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Grid</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="LayoutRoot"</span><span style="color: #ff0000"> Grid.Row</span><span style="color: #0000ff">="1"></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Grid.Clip</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">RectangleGeometry</span><span style="color: #ff0000"> Rect</span><span style="color: #0000ff">="0 0 400 400"></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">RectangleGeometry</span><span style="color: #0000ff">></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Grid.Clip</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Path</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="path"</span><span style="color: #ff0000"> Data</span><span style="color: #0000ff">="M0 0 L400 0 L400 200 C 350 150 250 150 200 200 C 150 250 50 250 0 200 Z"</span><span style="color: #ff0000"> Fill</span><span style="color: #0000ff">="#4444FF"</span><span style="color: #ff0000"> Stroke</span><span style="color: #0000ff">="#4444FF"</span> <span style="color: #ff0000">StrokeThickness</span><span style="color: #0000ff">="2"/></span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Grid</span><span style="color: #0000ff">></span>
                </li>
                <li>
                  <span style="color: #0000ff"></</span><span style="color: #a31515">Grid</span><span style="color: #0000ff">></span>
                </li>
              </ol>
            </div></p>
          </div></p>
        </div>

        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d9807d8e-74a1-4850-994e-863f1dd77fed" class="wlWriterSmartContent">
          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
              MainPage.xaml.cs
            </div>

            <div style="background: #ddd; max-height: 500px; overflow: auto">
              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                <li>
                  <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">List</span><<span style="color: #2b91af">Particle</span>> particules = <span style="color: #0000ff">new</span> <span style="color: #2b91af">List</span><<span style="color: #2b91af">Particle</span>>();
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #2b91af">DispatcherTimer</span> timer;
                </li>
                <li>
                  <span style="color: #0000ff">double</span> alpha;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">List</span><<span style="color: #2b91af">DateTime</span>> previous = <span style="color: #0000ff">new</span> <span style="color: #2b91af">List</span><<span style="color: #2b91af">DateTime</span>>();
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> Page_Loaded(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RoutedEventArgs</span> e)
                </li>
                <li>
                  {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> index = 0; index < 100; index++)
                </li>
                <li>
                  &#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; particules.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Particle</span>(LayoutRoot));
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; timer = <span style="color: #0000ff">new</span> <span style="color: #2b91af">DispatcherTimer</span> { Interval = <span style="color: #2b91af">TimeSpan</span>.FromMilliseconds(10) };
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; timer.Tick += (s, evt) =>
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; previous.Add(<span style="color: #2b91af">DateTime</span>.Now);
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">double</span> sum = 0;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> index = 0; index < previous.Count &#8211; 1; index++)
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += previous[index + 1].Subtract(previous[index]).TotalMilliseconds;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sum /= previous.Count;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fps.Text = <span style="color: #0000ff">string</span>.Format(<span style="color: #a31515">"{0:0} fps"</span>, 1000.0 / sum);
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> h1 = (<span style="color: #0000ff">int</span>)(200 + 20 * <span style="color: #2b91af">Math</span>.Cos(alpha));
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> h2 = (<span style="color: #0000ff">int</span>)(200 &#8211; 20 * <span style="color: #2b91af">Math</span>.Cos(alpha));
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">PathFigure</span> pathFigure = <span style="color: #0000ff">new</span> <span style="color: #2b91af">PathFigure</span> { StartPoint = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(0, 0) };
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">LineSegment</span> { Point = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(400, 0) });
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">LineSegment</span> { Point = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(400, 200) });
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">BezierSegment</span> { Point1 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(350, h2), Point2 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(250, h2), Point3 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(200, 200) });
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">BezierSegment</span> { Point1 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(150, h1), Point2 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(50, h1), Point3 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(0, 200) });
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.IsClosed = <span style="color: #0000ff">true</span>;
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">PathGeometry</span> pathGeometry = <span style="color: #0000ff">new</span> <span style="color: #2b91af">PathGeometry</span>();
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pathGeometry.Figures.Add(pathFigure);
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; path.Data = pathGeometry;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">var</span> part <span style="color: #0000ff">in</span> particules)
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; part.Update();
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alpha += 0.05;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };
                </li>
                <li>
                  }
                </li>
              </ol>
            </div></p>
          </div></p>
        </div>

        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4bde19e6-5aa1-40e4-82e9-3197be33f365" class="wlWriterSmartContent">
          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
              Particle.cs
            </div>

            <div style="background: #ddd; max-height: 500px; overflow: auto">
              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                <li>
                  <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">Particle</span>
                </li>
                <li style="background: #f3f3f3">
                  {
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">public</span> <span style="color: #0000ff">double</span> Velocity { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">public</span> <span style="color: #2b91af">Ellipse</span> Ellipse { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">TranslateTransform</span> translate;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">static</span> <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">Random</span> random = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Random</span>();
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">const</span> <span style="color: #0000ff">double</span> Radius = 20;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">public</span> Particle(<span style="color: #2b91af">Grid</span> parent)
                </li>
                <li>
                  &#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">byte</span> red = (<span style="color: #0000ff">byte</span>)random.Next(256);
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Ellipse</span>
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Width = Radius * 2,
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Height = Radius * 2,
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Fill = <span style="color: #0000ff">new</span> <span style="color: #2b91af">SolidColorBrush</span>(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Color{</span>A= 255, B = 0, G = 0, R = red})
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate = <span style="color: #0000ff">new</span> <span style="color: #2b91af">TranslateTransform</span>();
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.RenderTransformOrigin = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(0.5, 0.5);
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.HorizontalAlignment = <span style="color: #2b91af">HorizontalAlignment</span>.Left;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.VerticalAlignment = <span style="color: #2b91af">VerticalAlignment</span>.Top;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Spawn();
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.RenderTransform = translate;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; parent.Children.Add(Ellipse);
                </li>
                <li>
                  &#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160; <span style="color: #0000ff">void</span> Spawn()
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; {
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate.X = 400 * random.NextDouble();
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate.Y = 400 + Radius;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Velocity = 4 * random.NextDouble() + 0.5;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; }
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; <span style="color: #0000ff">internal</span> <span style="color: #0000ff">void</span> Update()
                </li>
                <li>
                  &#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate.Y -= Velocity;
                </li>
                <li>
                  &#160;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (translate.Y < -Radius)
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Spawn();
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                </li>
                <li style="background: #f3f3f3">
                  &#160;
                </li>
                <li>
                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.Opacity = translate.Y / 400.0;
                </li>
                <li style="background: #f3f3f3">
                  &#160;&#160;&#160; }
                </li>
                <li>
                  }
                </li>
              </ol>
            </div></p>
          </div></p>
        </div>

        <p>
          The result on my computer is:
        </p>

        <table border="1" cellspacing="0" cellpadding="2" width="368">
          <tr>
            <td valign="top" width="210">
              <p align="center">
                <strong>System</strong>
              </p>
            </td>

            <td valign="top" width="156">
              <p align="center">
                <strong>FPS</strong>
              </p>
            </td>
          </tr>

          <tr>
            <td valign="top" width="228">
              <em>Silverlight 5</em>
            </td>

            <td valign="top" width="163">
              <p align="center">
                <em><span style="text-decoration: underline">63</span></em>
              </p>
            </td>
          </tr>

          <tr>
            <td valign="top" width="231">
              Chrome 12
            </td>

            <td valign="top" width="167">
              <p align="center">
                <span style="text-decoration: underline"><em>60</em></span>
              </p>
            </td>
          </tr>

          <tr>
            <td valign="top" width="229">
              IE 10 PP1
            </td>

            <td valign="top" width="170">
              <blockquote>
                <p align="center">
                  50
                </p>
              </blockquote>
            </td>
          </tr>

          <tr>
            <td valign="top" width="227">
              IE 9
            </td>

            <td valign="top" width="172">
              <blockquote>
                <p align="center">
                  50
                </p>
              </blockquote>
            </td>
          </tr>

          <tr>
            <td valign="top" width="227">
              Firefox 4
            </td>

            <td valign="top" width="172">
              <p align="center">
                50
              </p>
            </td>
          </tr>

          <tr>
            <td valign="top" width="227">
              Opera 11
            </td>

            <td valign="top" width="172">
              <p align="center">
                Do not work
              </p>
            </td>
          </tr>

          <tr>
            <td valign="top" width="227">
              Safari 5
            </td>

            <td valign="top" width="172">
              <p align="center">
                Do not work
              </p>
            </td>
          </tr>
        </table>

        <p>
          This time it is impossible to differentiate the opponents. The Silverlight code may be cleaner and more pleasant to read but it is a very personal opinion that should not go in. So it&#8217;s a <strong>draw</strong>.
        </p>

        <h1>
          Canvas vs WriteableBitmap
        </h1>

        <p>
          Silverlight 5 and HTML 5 both offer the opportunity to work on 2D surfaces at the pixel level directly. In HTML 5 this surface is called a canvas and we talk about WriteableBitmap in Silverlight 5.
        </p>

        <h2>
          Access to the pixels
        </h2>

        <p>
          The two surfaces are both capable of drawing basic shapes (like SVG / Shape) but mostly they allow direct access to their contents as <strong>RGBA</strong> (in HTML 5 we handle 4 integers per color) or <strong>ARGB</strong> (Silverlight handle 1 integer for each color with each element occupying 8 bits). <br />One can already note that the way to manipulate the pixels of Silverlight is more efficient since it only uses a single integer against four for HTML 5. <br />Again, the features are similar, we will again compare performance to name a winner. For this we will develop an effect that has been around since early technological demos on Amiga or Atari ST computers: the <strong>fire effect</strong>! It is achieved by applying a vertical blur (upward) while generating red color dots on the bottom of the image. In addition we generated flame under the mouse:
        </p>

        <table border="0" cellspacing="0" cellpadding="2" width="820">
          <tr>
            <td valign="top" width="410">
              <p align="center">
                <strong>HTML 5</strong>
              </p>
            </td>

            <td valign="top" width="410">
              <p align="center">
                <strong>Silverlight 5</strong>
              </p>
            </td>
          </tr>

          <tr>
            <td valign="top" width="410">
              <p id="fpsCanvas">
                &#160;
              </p>

              <p style="width: 70px; height: 30px; cursor: pointer; text-decoration: underline" id="launchCanvas">
                Launch
              </p>

              <p>
                <canvas id="canvas" height="200" width="300">Canvas not supported 🙁 </canvas></td> 

                <td valign="top" width="410">
                </td></tr> </tbody> </table> 

                <p>
                  For HTML 5:
                </p>

                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5be436bc-4c21-42c2-b9a1-139c55b1f627" class="wlWriterSmartContent">
                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                    <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                      HTML 5
                    </div>

                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                        <li>
                          <span style="color: #0000ff"><</span><span style="color: #800000">p</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="fpsCanvas"></span>
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                        </li>
                        <li>
                          <span style="color: #0000ff"><</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">p</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">=&#8217;launchCanvas&#8217;</span> <span style="color: #ff0000">style</span><span style="color: #0000ff">="</span><span style="color: #ff0000">width</span><span style="color: #0000ff">: 70px; </span><span style="color: #ff0000">height</span><span style="color: #0000ff">: 30px; </span><span style="color: #ff0000">cursor</span><span style="color: #0000ff">: pointer; </span><span style="color: #ff0000">text-decoration</span><span style="color: #0000ff">: underline;"></span>
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; Launch
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                        </li>
                        <li>
                          <span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff"><</span><span style="color: #800000">canvas</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="canvas"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="300"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="200"></span>
                        </li>
                        <li>
                          &#160;&#160;&#160; Canvas not supported 🙁
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff"></</span><span style="color: #800000">canvas</span><span style="color: #0000ff">></span>
                        </li>
                      </ol>
                    </div></p>
                  </div></p>
                </div>

                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:47df6e67-c3b7-47cb-badf-d32df6d03d2f" class="wlWriterSmartContent">
                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                    <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                      Javascript
                    </div>

                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 3em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                        <li>
                          <span style="color: #0000ff">var</span> context;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">var</span> canvasWidth;
                        </li>
                        <li>
                          <span style="color: #0000ff">var</span> canvasHeight;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">var</span> blurSpeed = 0.04;
                        </li>
                        <li>
                          <span style="color: #0000ff">var</span> flamesCount = 50;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">var</span> flamesWidth = 10;
                        </li>
                        <li>
                          <span style="color: #0000ff">var</span> launchCanvas;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">function</span> putPixel(x, y) {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> clipX = Math.max(0, x &#8211; 4);
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> clipY = Math.max(0, y &#8211; 4);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> imageData = context.getImageData(clipX, clipY, 8, 8);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> pixels = imageData.data;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < pixels.length; index += 4) {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[index] = 255;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[index + 1] = 0;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[index + 2] = 0;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[index + 3] = 255;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; context.putImageData(imageData, x, y);
                        </li>
                        <li>
                          }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">var</span> previous = [];
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">function</span> computeFPSCanvas() {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #006400">// FPS</span>
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">if</span> (previous.length > 60) {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; previous.splice(0, 1);
                        </li>
                        <li>
                          &#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> start = (<span style="color: #0000ff">new</span> Date).getTime();
                        </li>
                        <li>
                          &#160;&#160;&#160; previous.push(start);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> sum = 0;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < previous.length &#8211; 1; index++) {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += previous[index + 1] &#8211; previous[index];
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> diff = 1000.0 / (sum / previous.length);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> fpsCanvas = document.getElementById(<span style="color: #800000">&#8216;fpsCanvas&#8217;</span>);
                        </li>
                        <li>
                          &#160;&#160;&#160; fpsCanvas.innerHTML = diff.toFixed() + <span style="color: #800000">&#8216; fps&#8217;</span>;
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">function</span> blur() {
                        </li>
                        <li>
                          &#160;&#160;&#160; computeFPSCanvas();
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> imageData = context.getImageData(0, 0, canvasWidth, canvasHeight);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> pixels = imageData.data;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #006400">// Generate root flames</span>
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> line = (canvasHeight &#8211; 1) * canvasWidth;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> flameID = 0; flameID < flamesCount; flameID++) {
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> red = 150 + 95 * Math.random();
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> green = 50 * Math.random();
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> x = Math.min(canvasWidth &#8211; flamesWidth, Math.random() * canvasWidth) | 0;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < flamesWidth; index++) {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> base = (x + index + line) * 4;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[base] = red;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[base + 1] = green;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #006400">// Vertical blur</span>
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> x = 0; x < canvasWidth; x++) {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> y = 0; y < canvasHeight; y++) {
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> medR = 0;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> medG = 0;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> samplesCount = 0;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < 4; index++) {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> scanY = y + index;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (scanY >= canvasHeight)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">continue</span>;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> linearPosition = (x + scanY * canvasWidth) * 4;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medR += pixels[linearPosition];
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medG += pixels[linearPosition + 1];
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; samplesCount += 1 + (1 &#8211; index / 4) * blurSpeed;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medR /= samplesCount;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medG /= samplesCount;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> base = (x + y * canvasWidth) * 4;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[base] = medR;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pixels[base + 1] = medG;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; context.putImageData(imageData, 0, 0);
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">function</span> onMouseMove(e) {
                        </li>
                        <li>
                          &#160;&#160;&#160; putPixel(e.offsetX, e.offsetY);
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">var</span> intervalCanvasID;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">function</span> stopCanvas() {
                        </li>
                        <li>
                          &#160;&#160;&#160; launchCanvas.innerHTML = <span style="color: #800000">"Launch"</span>;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; window.clearInterval(intervalCanvasID);
                        </li>
                        <li>
                          &#160;&#160;&#160; launchCanvas.onclick = startCanvas;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; previous = [];
                        </li>
                        <li>
                          }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">function</span> startCanvas() {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; launchCanvas.innerHTML = <span style="color: #800000">"Stop"</span>;
                        </li>
                        <li>
                          &#160;&#160;&#160; launchCanvas.onclick = stopCanvas;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; intervalCanvasID = window.setInterval(<span style="color: #800000">"blur()"</span>, 17);
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">var</span> canvas = document.getElementById(<span style="color: #800000">&#8216;canvas&#8217;</span>);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          context = canvas.getContext(<span style="color: #800000">&#8216;2d&#8217;</span>);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          canvas.onmousemove = onMouseMove;
                        </li>
                        <li>
                          canvasWidth = canvas.width;
                        </li>
                        <li style="background: #f3f3f3">
                          canvasHeight = canvas.height;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          context.fillStyle = <span style="color: #800000">"rgb(0,0,0)"</span>;
                        </li>
                        <li>
                          context.fillRect(0, 0, canvasWidth, canvasHeight);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          launchCanvas = document.getElementById(<span style="color: #800000">&#8216;launchCanvas&#8217;</span>);
                        </li>
                        <li style="background: #f3f3f3">
                          launchCanvas.onclick = startCanvas;
                        </li>
                      </ol>
                    </div></p>
                  </div></p>
                </div>

                <p>
                  For Silverlight 5:
                </p>

                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:45af0b27-a274-455d-be64-ac2e939fc672" class="wlWriterSmartContent">
                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                    <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                      XAML
                    </div>

                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                        <li>
                          <span style="color: #0000ff"><</span><span style="color: #a31515">Grid</span><span style="color: #0000ff">></span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Grid.RowDefinitions</span><span style="color: #0000ff">></span>
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">RowDefinition</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="60"/></span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">RowDefinition</span><span style="color: #0000ff">/></span>
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Grid.RowDefinitions</span><span style="color: #0000ff">></span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">></span>
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="fps"/></span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Button</span><span style="color: #ff0000"> Content</span><span style="color: #0000ff">="Launch"</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="launchButton"</span><span style="color: #ff0000"> Click</span><span style="color: #0000ff">="launchButton_Click"</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">="70"</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="30"</span><span style="color: #ff0000"> HorizontalAlignment</span><span style="color: #0000ff">="Left"/></span>
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">></span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Image</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="renderImage"</span><span style="color: #ff0000"> MouseMove</span><span style="color: #0000ff">="renderImage_MouseMove"</span><span style="color: #ff0000"> Grid.Row</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000"> Stretch</span><span style="color: #0000ff">="Fill"/></span>
                        </li>
                        <li>
                          <span style="color: #0000ff"></</span><span style="color: #a31515">Grid</span><span style="color: #0000ff">></span>
                        </li>
                      </ol>
                    </div></p>
                  </div></p>
                </div>

                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:055f65e3-1a41-47f1-ab52-412663363c7c" class="wlWriterSmartContent">
                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                    <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                      MainPage.xaml.cs
                    </div>

                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 3em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                        <li>
                          <span style="color: #2b91af">DispatcherTimer</span> timer;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">List</span><<span style="color: #2b91af">DateTime</span>> previous = <span style="color: #0000ff">new</span> <span style="color: #2b91af">List</span><<span style="color: #2b91af">DateTime</span>>();
                        </li>
                        <li>
                          <span style="color: #2b91af">WriteableBitmap</span> writeableBitmap;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">const</span> <span style="color: #0000ff">float</span> blurSpeed = 0.04f;
                        </li>
                        <li>
                          <span style="color: #0000ff">const</span> <span style="color: #0000ff">int</span> flamesWidth = 10;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">const</span> <span style="color: #0000ff">int</span> flamesCount = 50;
                        </li>
                        <li>
                          <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">Random</span> random = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Random</span>();
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">public</span> MainPage()
                        </li>
                        <li style="background: #f3f3f3">
                          {
                        </li>
                        <li>
                          &#160;&#160;&#160; InitializeComponent();
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> UserControl_Loaded(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RoutedEventArgs</span> e)
                        </li>
                        <li>
                          {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; writeableBitmap = <span style="color: #0000ff">new</span> <span style="color: #2b91af">WriteableBitmap</span>(300, 200);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; writeableBitmap.Render(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Rectangle</span> { Width = 300, Height = 200, Fill = <span style="color: #0000ff">new</span> <span style="color: #2b91af">SolidColorBrush</span>(<span style="color: #2b91af">Colors</span>.Black) }, <span style="color: #0000ff">null</span>);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; renderImage.Source = writeableBitmap;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; writeableBitmap.Invalidate();
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; timer = <span style="color: #0000ff">new</span> <span style="color: #2b91af">DispatcherTimer</span> { Interval = <span style="color: #2b91af">TimeSpan</span>.FromMilliseconds(10) };
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; timer.Tick += (s, evt) =>
                        </li>
                        <li>
                          &#160;&#160;&#160; {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// FPS</span>
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; previous.Add(<span style="color: #2b91af">DateTime</span>.Now);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">double</span> sum = 0;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> index = 0; index < previous.Count &#8211; 1; index++)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += previous[index + 1].Subtract(previous[index]).TotalMilliseconds;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; sum /= previous.Count;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; fps.Text = <span style="color: #0000ff">string</span>.Format(<span style="color: #a31515">"{0:0} fps"</span>, 1000.0 / sum);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Flames</span>
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> line = (writeableBitmap.PixelHeight &#8211; 1) * writeableBitmap.PixelWidth;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> flameID = 0; flameID < flamesCount; flameID++)
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> red = 150 + random.Next(96);
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> green = random.Next(51);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> x = <span style="color: #2b91af">Math</span>.Min(writeableBitmap.PixelWidth &#8211; flamesWidth, random.Next(writeableBitmap.PixelWidth));
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < flamesWidth; index++)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> basePosition = (x + index + line);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Pixels[basePosition] = GetColor(red, green, 0);
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Vertical blur</span>
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> x = 0; x < writeableBitmap.PixelWidth; x++)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> y = 0; y < writeableBitmap.PixelHeight; y++)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> medR = 0;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> medG = 0;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">float</span> samplesCount = 0;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < 4; index++)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> scanY = y + index;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (scanY >= writeableBitmap.PixelHeight)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">continue</span>;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> linearPosition = (x + scanY * writeableBitmap.PixelWidth);
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">int</span> red, green;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ExtractColor(writeableBitmap.Pixels[linearPosition], <span style="color: #0000ff">out</span> red, <span style="color: #0000ff">out</span> green);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medR += red;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medG += green;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; samplesCount += 1 + (1 &#8211; index / 4) * blurSpeed;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medR = (<span style="color: #0000ff">int</span>)(medR / samplesCount);
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; medG = (<span style="color: #0000ff">int</span>)(medG / samplesCount);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> basePosition = (x + y * writeableBitmap.PixelWidth);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Pixels[basePosition] = GetColor(medR, medG, 0);
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Invalidate();
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; };
                        </li>
                        <li>
                          }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">void</span> launchButton_Click(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RoutedEventArgs</span> e)
                        </li>
                        <li style="background: #f3f3f3">
                          {
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">if</span> (launchButton.Content.ToString() == <span style="color: #a31515">"Launch"</span>)
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; previous.Clear();
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; timer.Start();
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; launchButton.Content = <span style="color: #a31515">"Stop"</span>;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; }
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #0000ff">else</span>
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; {
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; launchButton.Content = <span style="color: #a31515">"Launch"</span>;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; timer.Stop();
                        </li>
                        <li>
                          &#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">static</span> <span style="color: #0000ff">int</span> GetColor(<span style="color: #0000ff">int</span> red, <span style="color: #0000ff">int</span> green, <span style="color: #0000ff">int</span> blue)
                        </li>
                        <li>
                          {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">return</span> (255 << 24) + (red << 16) + (green << 8) + blue;
                        </li>
                        <li>
                          }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> ExtractColor(<span style="color: #0000ff">int</span> value, <span style="color: #0000ff">out</span> <span style="color: #0000ff">int</span> red, <span style="color: #0000ff">out</span> <span style="color: #0000ff">int</span> green)
                        </li>
                        <li style="background: #f3f3f3">
                          {
                        </li>
                        <li>
                          &#160;&#160;&#160; red = ((value & 0x00FF0000) >> 16);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; green = ((value & 0x0000FF00) >> 8);
                        </li>
                        <li>
                          }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          <span style="color: #0000ff">void</span> PutPixel(<span style="color: #0000ff">int</span> x, <span style="color: #0000ff">int</span> y)
                        </li>
                        <li>
                          {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">int</span> red = GetColor(255, 0, 0);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> clipX = <span style="color: #2b91af">Math</span>.Max(0, x &#8211; 4); clipX <= x + 4 && clipX < writeableBitmap.PixelWidth; clipX++)
                        </li>
                        <li>
                          &#160;&#160;&#160; {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> clipY = <span style="color: #2b91af">Math</span>.Max(0, y &#8211; 4); clipY <= y + 4 && clipY < writeableBitmap.PixelHeight; clipY++)
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> basePosition = (clipX + clipY * writeableBitmap.PixelWidth);
                        </li>
                        <li>
                          &#160;
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Pixels[basePosition] = red;
                        </li>
                        <li>
                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;&#160;&#160; }
                        </li>
                        <li>
                          }
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> renderImage_MouseMove(<span style="color: #0000ff">object</span> sender, System.Windows.Input.<span style="color: #2b91af">MouseEventArgs</span> e)
                        </li>
                        <li style="background: #f3f3f3">
                          {
                        </li>
                        <li>
                          &#160;&#160;&#160; <span style="color: #2b91af">Point</span> location = e.GetPosition(renderImage);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; PutPixel((<span style="color: #0000ff">int</span>)location.X, (<span style="color: #0000ff">int</span>)location.Y);
                        </li>
                        <li style="background: #f3f3f3">
                          &#160;
                        </li>
                        <li>
                          &#160;&#160;&#160; writeableBitmap.Invalidate();
                        </li>
                        <li style="background: #f3f3f3">
                          }
                        </li>
                      </ol>
                    </div></p>
                  </div></p>
                </div>

                <p>
                  The result on my computer is
                </p>

                <table border="1" cellspacing="0" cellpadding="2" width="368">
                  <tr>
                    <td valign="top" width="210">
                      <p align="center">
                        <strong>System</strong>
                      </p>
                    </td>

                    <td valign="top" width="156">
                      <p align="center">
                        <strong>FPS</strong>
                      </p>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="228">
                      <em>Silverlight 5</em>
                    </td>

                    <td valign="top" width="163">
                      <p align="center">
                        <em><span style="text-decoration: underline">80</span></em>
                      </p>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="231">
                      Chrome 12
                    </td>

                    <td valign="top" width="167">
                      <p align="center">
                        30
                      </p>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="229">
                      IE 10 PP1
                    </td>

                    <td valign="top" width="170">
                      <blockquote>
                        <p align="center">
                          33
                        </p>
                      </blockquote>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="227">
                      IE 9
                    </td>

                    <td valign="top" width="172">
                      <blockquote>
                        <p align="center">
                          33
                        </p>
                      </blockquote>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="227">
                      Firefox 4
                    </td>

                    <td valign="top" width="172">
                      <p align="center">
                        <span style="text-decoration: underline"><em>60</em></span>
                      </p>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="227">
                      Opera 11
                    </td>

                    <td valign="top" width="172">
                      <p align="center">
                        47
                      </p>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="227">
                      Safari 5
                    </td>

                    <td valign="top" width="172">
                      <p align="center">
                        30 (very jaggy)
                      </p>
                    </td>
                  </tr>
                </table>

                <p>
                  Silverlight gets the best result thanks to its pixel storage system. However, due to their architecture, browsers can not overcome the 60 frames per second barrier. We can therefore conclude that we have a <strong>draw</strong> here (as at least one browser gets the same performance level as Silverlight).
                </p>

                <h2>
                  Drawing shapes
                </h2>

                <p>
                  To be complete, however we must also test the performance of the shape drawing mechanism. We&#8217;ll play the demo used for the SVG vs Shapes comparison but this time we will drawing the shapes in our 2D surfaces:
                </p>

                <table border="0" cellspacing="0" cellpadding="2" width="820">
                  <tr>
                    <td valign="top" width="410">
                      <p align="center">
                        <strong>HTML 5</strong>
                      </p>
                    </td>

                    <td valign="top" width="410">
                      <p align="center">
                        <strong>Silverlight</strong>
                      </p>
                    </td>
                  </tr>

                  <tr>
                    <td valign="top" width="410">
                      <p id="fpsShapesCanvas">
                        &#160;
                      </p>

                      <p style="width: 70px; height: 30px; cursor: pointer; text-decoration: underline" id="launchShapesCanvas">
                        Launch
                      </p>

                      <p>
                        <canvas id="shapescanvas" height="400" width="400">Canvas not supported 🙁 </canvas></td> 

                        <td valign="top" width="410">
                        </td></tr> </tbody> </table> 

                        <p>
                          For HTML 5:
                        </p>

                        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:27d346ba-dded-4ba5-9380-2fc0cff38326" class="wlWriterSmartContent">
                          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                            <div style="background: #ddd; max-height: 500px; overflow: auto">
                              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 3em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                <li>
                                  <span style="color: #0000ff">var</span> shapescontext;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">var</span> launchShapesCanvas;
                                </li>
                                <li>
                                  <span style="color: #0000ff">var</span> radius = 20;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">var</span> shapescanvas;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">var</span> shapesPrevious = [];
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">var</span> shapesparticles = [];
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">var</span> shapesAlpha = 0;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">function</span> computeFPSShapesCanvas() {
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #006400">// FPS</span>
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">if</span> (shapesPrevious.length > 60) {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapesPrevious.splice(0, 1);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; }
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> start = (<span style="color: #0000ff">new</span> Date).getTime();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapesPrevious.push(start);
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> sum = 0;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> index = 0; index < shapesPrevious.length &#8211; 1; index++) {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += shapesPrevious[index + 1] &#8211; shapesPrevious[index];
                                </li>
                                <li>
                                  &#160;&#160;&#160; }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> diff = 1000.0 / (sum / shapesPrevious.length);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> fpsCanvas = document.getElementById(<span style="color: #800000">&#8216;fpsShapesCanvas&#8217;</span>);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; fpsCanvas.innerHTML = diff.toFixed() + <span style="color: #800000">&#8216; fps&#8217;</span>;
                                </li>
                                <li>
                                  }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  <span style="color: #0000ff">function</span> animateShapesCanvas() {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; computeFPSShapesCanvas();
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #006400">// Clear</span>
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.fillStyle = <span style="color: #800000">"rgb(255,255,255)"</span>;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapescontext.fillRect(0, 0, shapescanvas.width, shapescanvas.height);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #006400">// Path</span>
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> h1 = (200 + 20 * Math.cos(shapesAlpha)).toFixed();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> h2 = (200 &#8211; 20 * Math.cos(shapesAlpha)).toFixed();
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapesAlpha += 0.05;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.beginPath();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapescontext.moveTo(0, 0);
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.lineTo(400, 0);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapescontext.lineTo(400, 200);
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.bezierCurveTo(350, h2, 250, h2, 200, 200);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapescontext.bezierCurveTo(150, h1, 50, h1, 0, 200);
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.closePath();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.fillStyle = <span style="color: #800000">"rgb(0, 0, 255)"</span>;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapescontext.fill();
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #006400">// Particles</span>
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapescontext.save();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> particle <span style="color: #0000ff">in</span> shapesparticles) {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160; shapesparticles[particle].draw();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160; }
                                </li>
                                <li>
                                  &#160;&#160; shapescontext.restore();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  <span style="color: #0000ff">var</span> intervalShapesCanvasID;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  <span style="color: #0000ff">function</span> stopShapesCanvas() {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; launchShapesCanvas.innerHTML = <span style="color: #800000">"Launch"</span>;
                                </li>
                                <li>
                                  &#160;&#160;&#160; window.clearInterval(intervalShapesCanvasID);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; launchShapesCanvas.onclick = startShapesCanvas;
                                </li>
                                <li>
                                  &#160;&#160;&#160; shapesPrevious = [];
                                </li>
                                <li style="background: #f3f3f3">
                                  }
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  <span style="color: #0000ff">function</span> startShapesCanvas() {
                                </li>
                                <li>
                                  &#160;&#160;&#160; launchShapesCanvas.innerHTML = <span style="color: #800000">"Stop"</span>;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; launchShapesCanvas.onclick = stopShapesCanvas;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; intervalShapesCanvasID = window.setInterval(<span style="color: #800000">"animateShapesCanvas()"</span>, 17);
                                </li>
                                <li>
                                  }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  <span style="color: #0000ff">function</span> ShapeParticle() {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> x = 400 * Math.random();
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> y = 400 + radius;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> velocity = 4 * Math.random() + 0.5;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> opacity = 1.0;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #006400">// Set colour of element</span>
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">var</span> color = <span style="color: #800000">"rgb("</span> + Math.floor(255 * Math.random()) + <span style="color: #800000">", 0, 0)"</span>;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">function</span> draw() {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; y -= velocity;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (y < -radius) {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; x = 400 * Math.random();
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; y = 400 + radius;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; velocity = 4 * Math.random() + 0.5;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">return</span>;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; opacity = Math.max(0, y / 400.0);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapescontext.globalAlpha = opacity;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapescontext.beginPath();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapescontext.arc(x, y, radius, 0, 2 * Math.PI, <span style="color: #0000ff">false</span>);
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapescontext.closePath();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapescontext.fillStyle = color;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; shapescontext.fill();
                                </li>
                                <li>
                                  &#160;&#160;&#160; }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">return</span> {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; draw: draw
                                </li>
                                <li>
                                  &#160;&#160;&#160; }
                                </li>
                                <li style="background: #f3f3f3">
                                  }
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  shapescanvas = document.getElementById(<span style="color: #800000">&#8216;shapescanvas&#8217;</span>);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  shapescontext = shapescanvas.getContext(<span style="color: #800000">&#8216;2d&#8217;</span>);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  launchShapesCanvas = document.getElementById(<span style="color: #800000">&#8216;launchShapesCanvas&#8217;</span>);
                                </li>
                                <li>
                                  launchShapesCanvas.onclick = startShapesCanvas;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  <span style="color: #0000ff">for</span> (<span style="color: #0000ff">var</span> i = 0; i < 100; i++) {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; shapesparticles.push(<span style="color: #0000ff">new</span> ShapeParticle());
                                </li>
                                <li>
                                  }
                                </li>
                              </ol>
                            </div></p>
                          </div></p>
                        </div>

                        <p>
                          For Silverlight:
                        </p>

                        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e1467d4d-37ba-4714-a62e-e482668a3615" class="wlWriterSmartContent">
                          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                              Particule.cs
                            </div>

                            <div style="background: #ddd; max-height: 500px; overflow: auto">
                              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                <li>
                                  <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">Particle</span>
                                </li>
                                <li style="background: #f3f3f3">
                                  {
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">public</span> <span style="color: #0000ff">double</span> Velocity { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">public</span> <span style="color: #2b91af">Ellipse</span> Ellipse { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">TranslateTransform</span> translate;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">static</span> <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">Random</span> random = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Random</span>();
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">WriteableBitmap</span> root;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">const</span> <span style="color: #0000ff">double</span> Radius = 20;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">public</span> Particle(<span style="color: #2b91af">WriteableBitmap</span> root)
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">this</span>.root = root;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">byte</span> red = (<span style="color: #0000ff">byte</span>)random.Next(256);
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Ellipse</span>
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Width = Radius * 2,
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Height = Radius * 2,
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Fill = <span style="color: #0000ff">new</span> <span style="color: #2b91af">SolidColorBrush</span>(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Color{</span>A= 255, B = 0, G = 0, R = red})
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate = <span style="color: #0000ff">new</span> <span style="color: #2b91af">TranslateTransform</span>();
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.RenderTransformOrigin = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(0.5, 0.5);
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.HorizontalAlignment = <span style="color: #2b91af">HorizontalAlignment</span>.Left;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.VerticalAlignment = <span style="color: #2b91af">VerticalAlignment</span>.Top;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Spawn();
                                </li>
                                <li>
                                  &#160;&#160;&#160; }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">void</span> Spawn()
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate.X = 400 * random.NextDouble();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate.Y = 400 + Radius;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Velocity = 4 * random.NextDouble() + 0.5;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; }
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; <span style="color: #0000ff">internal</span> <span style="color: #0000ff">void</span> Update()
                                </li>
                                <li>
                                  &#160;&#160;&#160; {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; translate.Y -= Velocity;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (translate.Y < -Radius)
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Spawn();
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; Ellipse.Opacity = translate.Y / 400.0;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; root.Render(Ellipse, translate);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; }
                                </li>
                              </ol>
                            </div></p>
                          </div></p>
                        </div>

                        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1c0de69d-9827-4bc2-aab8-224c7eaf854d" class="wlWriterSmartContent">
                          <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                            <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                              MainPage.xaml.cs
                            </div>

                            <div style="background: #ddd; max-height: 500px; overflow: auto">
                              <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                <li>
                                  <span style="color: #0000ff">void</span> UserControl_Loaded(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RoutedEventArgs</span> e)
                                </li>
                                <li style="background: #f3f3f3">
                                  {
                                </li>
                                <li>
                                  &#160;&#160;&#160; writeableBitmap = <span style="color: #0000ff">new</span> <span style="color: #2b91af">WriteableBitmap</span>(400, 400);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; renderImage.Source = writeableBitmap;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; path = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Path</span>();
                                </li>
                                <li>
                                  &#160;&#160;&#160; path.Fill = <span style="color: #0000ff">new</span> <span style="color: #2b91af">SolidColorBrush</span>(<span style="color: #2b91af">Colors</span>.Blue);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> index = 0; index < 100; index++)
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; particules.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Particle</span>(writeableBitmap));
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; }
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160; timer = <span style="color: #0000ff">new</span> <span style="color: #2b91af">DispatcherTimer</span> { Interval = <span style="color: #2b91af">TimeSpan</span>.FromMilliseconds(10) };
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160; timer.Tick += (s, evt) =>
                                </li>
                                <li>
                                  &#160;&#160;&#160; {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// FPS</span>
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; previous.Add(<span style="color: #2b91af">DateTime</span>.Now);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">double</span> sum = 0;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> index = 0; index < previous.Count &#8211; 1; index++)
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sum += previous[index + 1].Subtract(previous[index]).TotalMilliseconds;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; sum /= previous.Count;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; fps.Text = <span style="color: #0000ff">string</span>.Format(<span style="color: #a31515">"{0:0} fps"</span>, 1000.0 / sum);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Render</span>
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Render(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Rectangle</span> { Width = 400, Height = 400, Fill = <span style="color: #0000ff">new</span> <span style="color: #2b91af">SolidColorBrush</span>(<span style="color: #2b91af">Colors</span>.White) }, <span style="color: #0000ff">null</span>);
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> h1 = (<span style="color: #0000ff">int</span>)(200 + 20 * <span style="color: #2b91af">Math</span>.Cos(alpha));
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> h2 = (<span style="color: #0000ff">int</span>)(200 &#8211; 20 * <span style="color: #2b91af">Math</span>.Cos(alpha));
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">PathFigure</span> pathFigure = <span style="color: #0000ff">new</span> <span style="color: #2b91af">PathFigure</span> { StartPoint = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(0, 0) };
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">LineSegment</span> { Point = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(400, 0) });
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">LineSegment</span> { Point = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(400, 200) });
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">BezierSegment</span> { Point1 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(350, h2), Point2 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(250, h2), Point3 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(200, 200) });
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.Segments.Add(<span style="color: #0000ff">new</span> <span style="color: #2b91af">BezierSegment</span> { Point1 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(150, h1), Point2 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(50, h1), Point3 = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Point</span>(0, 200) });
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; pathFigure.IsClosed = <span style="color: #0000ff">true</span>;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">PathGeometry</span> pathGeometry = <span style="color: #0000ff">new</span> <span style="color: #2b91af">PathGeometry</span>();
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; pathGeometry.Figures.Add(pathFigure);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; path.Data = pathGeometry;
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Render(path, <span style="color: #0000ff">null</span>);
                                </li>
                                <li>
                                  &#160;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">var</span> part <span style="color: #0000ff">in</span> particules)
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; part.Update();
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; }
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;
                                </li>
                                <li>
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; alpha += 0.05;
                                </li>
                                <li style="background: #f3f3f3">
                                  &#160;&#160;&#160;&#160;&#160;&#160;&#160; writeableBitmap.Invalidate();
                                </li>
                                <li>
                                  &#160;&#160;&#160; };
                                </li>
                                <li style="background: #f3f3f3">
                                  }
                                </li>
                              </ol>
                            </div></p>
                          </div></p>
                        </div>

                        <p>
                          The result on my computer is :
                        </p>

                        <table border="1" cellspacing="0" cellpadding="2" width="368">
                          <tr>
                            <td valign="top" width="210">
                              <p align="center">
                                <strong>System</strong>
                              </p>
                            </td>

                            <td valign="top" width="156">
                              <p align="center">
                                <strong>FPS</strong>
                              </p>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="228">
                              <em>Silverlight 5</em>
                            </td>

                            <td valign="top" width="163">
                              <p align="center">
                                <em><span style="text-decoration: underline">60</span></em>
                              </p>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="231">
                              Chrome 12
                            </td>

                            <td valign="top" width="167">
                              <p align="center">
                                <span style="text-decoration: underline"><em>60</em></span>
                              </p>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="229">
                              IE 10 PP1
                            </td>

                            <td valign="top" width="170">
                              <blockquote>
                                <p align="center">
                                  <em><span style="text-decoration: underline">60</span></em>
                                </p>
                              </blockquote>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="227">
                              IE 9
                            </td>

                            <td valign="top" width="172">
                              <blockquote>
                                <p align="center">
                                  <em><span style="text-decoration: underline">60</span></em>
                                </p>
                              </blockquote>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="227">
                              Firefox 4
                            </td>

                            <td valign="top" width="172">
                              <p align="center">
                                <em><span style="text-decoration: underline">60</span></em>
                              </p>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="227">
                              Opera 11
                            </td>

                            <td valign="top" width="172">
                              <p align="center">
                                <em><span style="text-decoration: underline">60</span></em>
                              </p>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="227">
                              Safari 5
                            </td>

                            <td valign="top" width="172">
                              <p align="center">
                                <em><span style="text-decoration: underline">60</span></em>
                              </p>
                            </td>
                          </tr>
                        </table>

                        <p>
                          Nothing more to say, both in terms of performance and features both competitors are at the same level.
                        </p>

                        <h1>
                          Brushes
                        </h1>

                        <p>
                          Brushes are used to fill interface elements with a color, gradient or a pattern. <br />In HTML5, it is possible to use them with CSS or directly in a canvas or SVG. It is also possible to use images or videos as brushes. <br />In Silverlight 5, we have the same concept with the added ability of using other controls rendered as a base texture (VisualBrush).
                        </p>

                        <p>
                          Here is an example:
                        </p>

                        <table border="0" cellspacing="0" cellpadding="2" width="820">
                          <tr>
                            <td valign="top" width="410">
                              <p align="center">
                                <strong>HTML 5</strong>
                              </p>
                            </td>

                            <td valign="top" width="410">
                              <p align="center">
                                <strong>Silverlight 5</strong>
                              </p>
                            </td>
                          </tr>

                          <tr>
                            <td valign="top" width="410">
                              <p>
                                Full color :
                              </p>

                              <p>
                                <svg xmlns="https://www.w3.org/2000/svg" height="100" width="100"><rect height="100" width="100" y="0" x="0" fill="#ff00ff"></rect></svg>
                              </p>

                              <p>
                                Radial gradient :
                              </p>

                              <p>
                                <svg xmlns="https://www.w3.org/2000/svg" height="100" width="100"><radialgradient id="radial" cx="50%" cy="50%" r="50%" gradientunits="userSpaceOnUse"><stop stop-color="#FFFFFF" offset="0"></stop><stop stop-color="#470A45" offset="1"></stop></radialgradient><rect height="100" width="100" y="0" x="0" fill="url(#radial)"></rect></svg>
                              </p>

                              <p>
                                Linear gradient :
                              </p>

                              <p>
                                <svg xmlns="https://www.w3.org/2000/svg" height="100" width="100"><lineargradient id="linear" gradientunits="userSpaceOnUse"><stop stop-color="#FFFFFF" offset="0"></stop><stop stop-color="#470A45" offset="1"></stop></lineargradient><rect height="100" width="100" y="0" x="0" fill="url(#linear)"></rect></svg></td> 

                                <td valign="top" width="410">
                                </td></tr> </tbody> </table> 

                                <p>
                                  For HTML 5:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8a04b881-21be-44aa-ad17-f8defb62c7ca" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>Couleur pleine :<span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"><</span><span style="color: #800000">svg</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="https://www.w3.org/2000/svg"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="100"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">rect</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">fill</span><span style="color: #0000ff">="#ff00ff"</span> <span style="color: #0000ff">/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #800000">svg</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>Radial gradient :<span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"><</span><span style="color: #800000">svg</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="https://www.w3.org/2000/svg"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="100"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">radialGradient</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="radial"</span> <span style="color: #ff0000">gradientUnits</span><span style="color: #0000ff">="userSpaceOnUse"</span> <span style="color: #ff0000">cx</span><span style="color: #0000ff">="50%"</span> <span style="color: #ff0000">cy</span><span style="color: #0000ff">="50%"</span> <span style="color: #ff0000">r</span><span style="color: #0000ff">="50%"></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">stop</span> <span style="color: #ff0000">stop-color</span><span style="color: #0000ff">="#FFFFFF"</span> <span style="color: #ff0000">offset</span><span style="color: #0000ff">="0"/></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">stop</span> <span style="color: #ff0000">stop-color</span><span style="color: #0000ff">="#470A45"</span> <span style="color: #ff0000">offset</span><span style="color: #0000ff">="1"/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">radialGradient</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">rect</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">fill</span><span style="color: #0000ff">="url(#radial)"</span> <span style="color: #0000ff">/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #800000">svg</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>Linear gradient :<span style="color: #0000ff"></</span><span style="color: #800000">p</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"><</span><span style="color: #800000">svg</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="https://www.w3.org/2000/svg"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="100"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">linearGradient</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="linear"</span> <span style="color: #ff0000">gradientUnits</span><span style="color: #0000ff">="userSpaceOnUse"></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">stop</span> <span style="color: #ff0000">stop-color</span><span style="color: #0000ff">="#FFFFFF"</span> <span style="color: #ff0000">offset</span><span style="color: #0000ff">="0"/></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">stop</span> <span style="color: #ff0000">stop-color</span><span style="color: #0000ff">="#470A45"</span> <span style="color: #ff0000">offset</span><span style="color: #0000ff">="1"/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">linearGradient</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">rect</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="100"</span> <span style="color: #ff0000">fill</span><span style="color: #0000ff">="url(#linear)"</span> <span style="color: #0000ff">/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #800000">svg</span><span style="color: #0000ff">></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  For Silverlight :
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8fd60cf6-f6f5-4581-a611-6b8ff4bfb54b" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> Text</span><span style="color: #0000ff">="Couleur pleine:"</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">="0,10"></</span><span style="color: #a31515">TextBlock</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Rectangle</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">="100"</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="100"</span><span style="color: #ff0000"> Fill</span><span style="color: #0000ff">="#ff00ff"</span><span style="color: #ff0000"> HorizontalAlignment</span><span style="color: #0000ff">="Left"/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> Text</span><span style="color: #0000ff">="Radial gradient:"</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">="0,10"></</span><span style="color: #a31515">TextBlock</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Rectangle</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">="100"</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="100"</span><span style="color: #ff0000"> HorizontalAlignment</span><span style="color: #0000ff">="Left"></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Rectangle.Fill</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">RadialGradientBrush</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">GradientStop</span><span style="color: #ff0000"> Color</span><span style="color: #0000ff">="#FFFFFF"</span><span style="color: #ff0000"> Offset</span><span style="color: #0000ff">="0"></</span><span style="color: #a31515">GradientStop</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">GradientStop</span><span style="color: #ff0000"> Color</span><span style="color: #0000ff">="#470A45"</span><span style="color: #ff0000"> Offset</span><span style="color: #0000ff">="1"></</span><span style="color: #a31515">GradientStop</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">RadialGradientBrush</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Rectangle.Fill</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Rectangle</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> Text</span><span style="color: #0000ff">="Linear gradient:"</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">="0,10"></</span><span style="color: #a31515">TextBlock</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Rectangle</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">="100"</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">="100"</span><span style="color: #ff0000"> HorizontalAlignment</span><span style="color: #0000ff">="Left"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Rectangle.Fill</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">LinearGradientBrush</span><span style="color: #ff0000"> StartPoint</span><span style="color: #0000ff">="0, 0"</span><span style="color: #ff0000"> EndPoint</span><span style="color: #0000ff">="1, 0"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">GradientStop</span><span style="color: #ff0000"> Color</span><span style="color: #0000ff">="#FFFFFF"</span><span style="color: #ff0000"> Offset</span><span style="color: #0000ff">="0"></</span><span style="color: #a31515">GradientStop</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">GradientStop</span><span style="color: #ff0000"> Color</span><span style="color: #0000ff">="#470A45"</span><span style="color: #ff0000"> Offset</span><span style="color: #0000ff">="1"></</span><span style="color: #a31515">GradientStop</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">LinearGradientBrush</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Rectangle.Fill</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Rectangle</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  For once the syntax is very similar. We can therefore consider it a <strong>draw</strong>.
                                </p>

                                <h1>
                                  Controls
                                </h1>

                                <p>
                                  In Silverlight 5, it is both possible to define ones own controls from scratch or by aggregation (UserControl and CustomControl). It is also possible to inherit from the basic controls or even modify the associated templates to modify their appearance. In brief, <strong>Silverlight is extremely powerful for dealing with user interface</strong>.
                                </p>

                                <p>
                                  HTML 5 does not offer any integrated solution for creating controls except basic copy/pasting of code. This is a big minus for business projects looking at industrializing their developments. We are far from the plethora of controls that can be simply referenced in Silverlight.
                                </p>

                                <p>
                                  Note that HTML 5 introduces the concept of validation checks (required, etc.) and drag&#8217;n&#8217;drop.
                                </p>

                                <h1>
                                  Layout
                                </h1>

                                <p>
                                  Layout management (layout of the GUI and customization) is very <strong>rich</strong> in Silverlight. It is possible to position objects:
                                </p>

                                <ul>
                                  <li>
                                    In a grid with cell size in absolute, relative or even adaptable to the content
                                  </li>
                                  <li>
                                    With vertical or horizontal stacking in a StackPanel
                                  </li>
                                  <li>
                                    In a canvas that enables positioning through absolute coordinates
                                  </li>
                                  <li>
                                    With the margins and alignments
                                  </li>
                                  <li>
                                    With overflows exposed by the new control RichTexboxOverflow
                                  </li>
                                </ul>

                                <p>
                                  This system may be extended to infinity by adding usercontrols which can define their own layout. A good example can be found in the <a href="https://www.silverlight.net/content/samples/sl4/toolkitcontrolsamples/run/default.html">Silverlight Toolkit</a>, which adds for example a WrapPanel.
                                </p>

                                <p>
                                  HTML5 also provides <strong>complete</strong> solutions for layout management:
                                </p>

                                <ul>
                                  <li>
                                    Grids with <table> <td> <tr>
                                  </li>
                                  <li>
                                    New system for placing and sizing grids: <a href="https://ie.microsoft.com/testdrive/HTML5/Flexin/Default.html">Alignment Grid CSS Level 3</a>. You will find that this mechanism is almost exactly identical to that of Silverlight (With good reason, as it is a Microsoft proposed specification)
                                  </li>
                                  <li>
                                    System integrated with CSS layout (absolute or relative placement, absolute or relative size, etc..)
                                  </li>
                                  <li>
                                    New <a href="https://www.w3.org/TR/2009/WD-css3-flexbox-20090723/">CSS3 Flexbox</a> system for which you can see a demo right <a href="https://ie.microsoft.com/testdrive/HTML5/Flexin/Default.html">here</a> (if your browser supports it). This specification allows management&#160; of alignments and placement relative to boxes (yes that&#8217;s exactly the same thing for XUL and it&#8217;s not a coincidence <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sourire" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/5164.wlEmoticon-smile_62DC511A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/5164.wlEmoticon_2D00_smile_5F00_62DC511A.png" />)
                                  </li>
                                  <li>
                                    <a href="https://www.w3.org/TR/css3-multicol/">CSS3 Multi-column layout</a> which is a rendering system with multi-column (example <a href="https://ie.microsoft.com/testdrive/HTML5/TweetColumns/Default.html">here</a>).
                                  </li>
                                  <li>
                                    <a href="https://www.w3.org/TR/css3-mediaqueries/">CSS3 Media Queries</a> that define different layouts based on display sizes with an example <a href="https://ie.microsoft.com/testdrive/HTML5/CSS3MediaQueries/Default.html">here</a> (besides Samuel Blanchard&#8217;s had fun doing the same thing in Silverlight <a href="https://blog.naviso.fr/wordpress/?p=776">here</a>).
                                  </li>
                                </ul>

                                <p>
                                  Layout technologies in HTML5 are not well supported by all browsers (the always repeating story of standards under development) but based purely on functionality, this is a fairly <strong>even </strong>game since the two competitors are able to produce easily adaptable and scalable layouts.
                                </p>

                                <h1>
                                  Databinding
                                </h1>

                                <p>
                                  A key feature of Silverlight is the databinding that opens the door to design patterns such as <a href="https://msdn.microsoft.com/fr-fr/magazine/dd419663.aspx">MVVM</a> (Model / View / ViewModel) that can implement effective and modern architectures.
                                </p>

                                <p>
                                  The databinding also enable defining dynamic interfaces without any line of code.
                                </p>

                                <p>
                                  In the land of HTML 5 <strong>there is nothing</strong>. This implies that HTML 5 is heading more towards the production of consumer websites where Silverlight 5 aims at business line type of applications.
                                </p>

                                <p>
                                  To do databinding in HTML 5, we will necessarily go through Javascript code to manually assign values ​​to controls and subscribe to events to retrieve the changed data. Some libraries exist (for example, you can use jQuery or <a href="https://knockoutjs.com/">Knockout</a>) but nothing as <strong>effective</strong> (in terms of implementation and performance) as Silverlight.
                                </p>

                                <h1>
                                  Threading : Web workers vs System.Threading
                                </h1>

                                <p>
                                  Silverlight 5 offers enhanced support for threading through the class System.Threading.Thread and even provides access to the thread pool.
                                </p>

                                <p>
                                  I have even recently published an article on porting the <a href="https://blogs.msdn.com/b/eternalcoding/archive/2011/05/16/tpl-build-your-own-tpl-for-silverlight-wp7-and-xbox-360.aspx">Silverlight Task Parallel Library</a>.
                                </p>

                                <p>
                                  HTML5 has the concept of Web Workers, threads that are independent from the main thread (the one that displays and manipulates the DOM).
                                </p>

                                <p>
                                  These workers are actually totally compartmentalized and so they communicate with the main thread via a messaging mechanism. This prevents having to worry about keeping critical sections on shared data since there is no shared data. Thus the workers can not access the DOM:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e9e5bc1c-10f7-44ce-8b63-b4536e497eac" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                                      Main script
                                    </div>

                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">var</span> worker = <span style="color: #0000ff">new</span> Worker(<span style="color: #800000">"webworker.js"</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          worker.onmessage = <span style="color: #0000ff">function</span>(e) {&#160;&#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; alert(e.data);
                                        </li>
                                        <li>
                                          };
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          worker.onerror = <span style="color: #0000ff">function</span> (e) {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; alert(<span style="color: #800000">"Erreur: "</span> + e.message);
                                        </li>
                                        <li>
                                          };
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          worker.postMessage(<span style="color: #800000">"David"</span>);
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:90b9a636-5a8e-4295-bbb2-29988b64fa3b" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px">
                                      Worker
                                    </div>

                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          self.onmessage = <span style="color: #0000ff">function</span> (e) {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; self.postMessage(e.data.toUpperCase());
                                        </li>
                                        <li>
                                          }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  Communication with Workers passes through strings, it is necessary to serialize objects to JSON which can be painful.
                                </p>

                                <p>
                                  The <a href="https://www.w3.org/TR/workers/">standard</a> is still evolving very rapidly and we cannot know what will be its final state. For example, it has recently adopted the concept of Shared Workers who can communicate with more scripts.
                                </p>

                                <p>
                                  Here is an example of raytracing engine in Javascript using the workers (if your browser supports them): <a href="https://nerget.com/rayjs-mt/rayjs.html">https://nerget.com/rayjs-mt/rayjs.html</a>
                                </p>

                                <p>
                                  For Silverlight, communication with other threads is done by calling methods and passing parameters (in fact, nothing special). There are many more tools to manage concurrency and timing such as ManualResetEvent, AutoResetEvent, Monitor, etc..
                                </p>

                                <p>
                                  You will find below an example of code that uses Silverlight ManualResetEvent to control a thread. It also show the use of the Dispatcher allowing the thread to execute code on the thread of the interface:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:18f656e6-756f-48d0-98dc-19d7a6d29f64" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">readonly</span> <span style="color: #2b91af">ManualResetEvent</span> evt = <span style="color: #0000ff">new</span> <span style="color: #2b91af">ManualResetEvent</span>(<span style="color: #0000ff">false</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff">readonly</span> <span style="color: #0000ff">string</span> textToTransform;
                                        </li>
                                        <li>
                                          &#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff">public</span> MainPage()
                                        </li>
                                        <li>
                                          {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; InitializeComponent();
                                        </li>
                                        <li>
                                          &#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #2b91af">Thread</span> thread = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Thread</span>(DoJob);
                                        </li>
                                        <li>
                                          &#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; textToTransform = textBlock.Text;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; thread.Start();
                                        </li>
                                        <li style="background: #f3f3f3">
                                          }
                                        </li>
                                        <li>
                                          &#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff">void</span> DoJob()
                                        </li>
                                        <li>
                                          {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff">while</span> (<span style="color: #0000ff">true</span>)
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">string</span> result = textToTransform.ToUpper();
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; Dispatcher.BeginInvoke(() => textBlock.Text = result);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; evt.WaitOne();
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; }
                                        </li>
                                        <li style="background: #f3f3f3">
                                          }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  As we can see, Silverlight <strong>outperforms</strong> Web Workers on potential and tools (again, thanks to Visual Studio which provides several debugging tools) but also in terms of control over the threads. The addition of future technologies such as Async Framework will add even more power to Silverlight.
                                </p>

                                <p>
                                  Obviously, the approach of Web workers (even if the standard is far from being done) is different from the conventional threading of Silverlight. It certainly helps to do simple threading but unfortunately it cannot cover all the needs of modern application development.
                                </p>

                                <h1>
                                  Animations
                                </h1>

                                <p>
                                  The Silverlight animation engine can easily manipulate control properties.
                                </p>

                                <p>
                                  These manipulations are done <strong>seamlessly</strong> by an autonomous system that can manage events on simple properties (double, integer, etc..) or complex properties (color, thickness, etc..). These activities are done by a storyboard which handles timing for us.
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a7f4b377-eac4-4a06-a7bc-7f14a0fa466a" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #a31515">Storyboard</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Key</span><span style="color: #0000ff">="monStoryboard"></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">DoubleAnimation</span><span style="color: #ff0000"> Duration</span><span style="color: #0000ff">="0:0:0.1"</span><span style="color: #ff0000"> To</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000"> Storyboard.TargetProperty</span><span style="color: #0000ff">="Opacity"</span><span style="color: #ff0000"> Storyboard.TargetName</span><span style="color: #0000ff">="LayoutRoot"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">DoubleAnimation.EasingFunction</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">BackEase</span><span style="color: #ff0000"> Amplitude</span><span style="color: #0000ff">="0.6"</span><span style="color: #ff0000"> EasingMode</span><span style="color: #0000ff">="EaseInOut"/></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">DoubleAnimation.EasingFunction</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">DoubleAnimation</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          <span style="color: #0000ff"></</span><span style="color: #a31515">Storyboard</span><span style="color: #0000ff">></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  These animations can be created either in XAML or in code. As shown above, it is even possible to define functions to use non-linear animation.
                                </p>

                                <p>
                                  In HTML5, it is possible to use the setInterval and setTimeout to animate (manually) DOM elements:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4b986e8b-c901-4900-a64d-3e4962cd0a27" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">function</span> startCanvas() {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; launchCanvas.innerHTML = <span style="color: #800000">"Stop"</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; launchCanvas.onclick = stopCanvas;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; intervalCanvasID = window.setInterval(<span style="color: #800000">"blur()"</span>, 17);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  Here, no special support by the system. It is up to us to manage everything. But, obviously, anything is possible.
                                </p>

                                <p>
                                  However a new technology has emerged (still poorly supported by browsers) to improve things: <a href="https://www.w3.org/TR/css3-animations/">CSS Animations Module Level 3</a>. <br />With this module, it is possible to animate the CSS styles with a very interesting statement:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:029df557-4c4f-42b6-897d-d3e3b2487294" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">@keyframes</span> &#8216;anim01&#8217; {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; 0% {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160; <span style="color: #ff0000">left</span>: <span style="color: #0000ff">100px</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; }
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; 40% {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160; <span style="color: #ff0000">left</span>: <span style="color: #0000ff">150px</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; }
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; 60% {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160; <span style="color: #ff0000">left</span>: <span style="color: #0000ff">75px</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; }
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; 100% {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160; <span style="color: #ff0000">left</span>: <span style="color: #0000ff">100px</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; }
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160; }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  In this animation, we decided to animate the attribute "left" by labelling key points of the animation. The system will subsequently change the attribute value over time.
                                </p>

                                <p>
                                  The assignment of this animation will be:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fa454071-0a0e-4bcf-a012-9dca29ab926e" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #800000">div</span> {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #ff0000">animation-name</span>: <span style="color: #0000ff">&#8216;anim01&#8217;</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #ff0000">animation-duration</span>: <span style="color: #0000ff">5s</span>;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #ff0000">animation-iteration-count</span>: <span style="color: #0000ff">10</span>;
                                        </li>
                                        <li>
                                          &#160; }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  In Silverlight, it is possible to define functions to set the linearity (or not) of the animation. <br />In addition, HTML5 (actually CSS3) specification also includes <a href="https://www.w3.org/TR/2009/WD-css3-transitions-20090320/">CSS Transitions Module Level 3</a>, which allows you to define animations on a transition, i.e. when an attribute receives a new value:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:383795df-3df3-4339-b98c-5cd763a0de29" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #800000">div</span> {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #ff0000">transition-property</span>: <span style="color: #0000ff">opacity</span>;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #ff0000">transition-duration</span>: <span style="color: #0000ff">2s</span>;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160; }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  In this example, when we change the opacity value, the system will gradually change the current value to the new value in 2 seconds. It is also possible to define how the animation will take place over the period (transition-timing-function).
                                </p>

                                <p>
                                  In Silverlight, we also have a system to manage these transitions: <a href="https://msdn.microsoft.com/fr-fr/library/system.windows.visualstatemanager(VS.95).aspx">VisualStateManager</a>. The latter cannot define the animations when changing the value of a variable, only when changing the state of a control:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:03f2c207-78c7-4f79-b178-b4b22c87ddf1" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #a31515">ControlTemplate</span><span style="color: #ff0000"> TargetType</span><span style="color: #0000ff">="Button"></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Grid</span><span style="color: #0000ff"> ></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">VisualStateGroup</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="CommonStates"></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">VisualStateGroup.Transitions</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">VisualTransition</span><span style="color: #ff0000"> To</span><span style="color: #0000ff">="MouseOver"</span><span style="color: #ff0000"> GeneratedDuration</span><span style="color: #0000ff">="0:0:0.5"/></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">VisualStateGroup.Transitions</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">VisualState</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="Normal" /></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">VisualState</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="MouseOver"></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Storyboard</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">ColorAnimation</span><span style="color: #ff0000"> Storyboard.TargetName</span><span style="color: #0000ff">="ButtonBrush"</span><span style="color: #ff0000"> Storyboard.TargetProperty</span><span style="color: #0000ff">="Color"</span><span style="color: #ff0000"> To</span><span style="color: #0000ff">="Red" /></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Storyboard</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">VisualState</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">VisualStateGroup</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">Grid.Background</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"><</span><span style="color: #a31515">SolidColorBrush</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="ButtonBrush"</span><span style="color: #ff0000"> Color</span><span style="color: #0000ff">="Green"/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Grid.Background</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff"></</span><span style="color: #a31515">Grid</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #a31515">ControlTemplate</span><span style="color: #0000ff">></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  So here we animate the color of our button when the mouse is over it.
                                </p>

                                <p>
                                  Also note that Silverlight can launch animations when the value of a property changes (with some code).
                                </p>

                                <p>
                                  In conclusion, if we ignore the very low support (for now) of animations technologies in browsers, we can consider that both competitors are well equipped in terms of animations with quite similar philosophies.
                                </p>

                                <h1>
                                  Web requests & Web services
                                </h1>

                                <h2>
                                  Web requests
                                </h2>

                                <p>
                                  The Web Requests are requests made to a server from the client application code. They can query a remote resource without changing the user interface.
                                </p>

                                <p>
                                  Eventually the query result can be processed by the code to impact the user interface. <br />In HMTL5 (well, mostly in Javascript), it is possible to make <a href="https://www.w3.org/TR/XMLHttpRequest/">XMLHttpRequest</a>:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:364d803f-da7b-4bc9-aaec-a3c1b359c7fd" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">function</span> write(data) {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> webrequestResult = document.getElementById(<span style="color: #800000">&#8216;webrequestResult&#8217;</span>);
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; webrequestResult.innerHTML = data;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          }
                                        </li>
                                        <li>
                                          &#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff">function</span> handler() {
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff">if</span> (<span style="color: #0000ff">this</span>.readyState == 4 && <span style="color: #0000ff">this</span>.status == 200) {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (<span style="color: #0000ff">this</span>.responseXML != <span style="color: #0000ff">null</span>)
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write(<span style="color: #0000ff">this</span>.responseXML.text);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">else</span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write(<span style="color: #0000ff">null</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; } <span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (<span style="color: #0000ff">this</span>.readyState == 4 && <span style="color: #0000ff">this</span>.status != 200) {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; write(<span style="color: #800000">&#8216;Erreur&#8230;&#8217;</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; }
                                        </li>
                                        <li>
                                          }
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          <span style="color: #0000ff">var</span> client = <span style="color: #0000ff">new</span> XMLHttpRequest();
                                        </li>
                                        <li style="background: #f3f3f3">
                                          client.onreadystatechange = handler;
                                        </li>
                                        <li>
                                          client.open(<span style="color: #800000">"GET"</span>, <span style="color: #800000">"https://www.catuhe.com/files/data.xml"</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          client.send();
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  With this same system it is also possible to make HTTP POST.
                                </p>

                                <p>
                                  In Silverlight, we have two classes to do this kind of request: <a href="https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(v=VS.95).aspx">HttpWebRequest</a> (lower level) and <a href="https://msdn.microsoft.com/en-us/library/tt0f69eh(v=VS.95).aspx">WebClient</a> (high level):
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:34d39455-02db-48c9-9b5a-126fbff82449" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> UserControl_Loaded(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RoutedEventArgs</span> e)
                                        </li>
                                        <li style="background: #f3f3f3">
                                          {
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #2b91af">WebClient</span> webClient = <span style="color: #0000ff">new</span> <span style="color: #2b91af">WebClient</span>();
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; webClient.DownloadStringCompleted += (s, arg) =>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; result.Text = arg.Result;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; webClient.DownloadStringAsync(<span style="color: #0000ff">new</span> <span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"https://www.catuhe.com/files/data.xml"</span>));
                                        </li>
                                        <li style="background: #f3f3f3">
                                          }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  Note that we are not limited to download XML in Silverlight. Indeed, it is possible to send / receive byte arrays so we can transfer anything (in digital form obviously).
                                </p>

                                <h2>
                                  Web services
                                </h2>

                                <p>
                                  Regarding web services, Silverlight with Visual Studio allows us to make a simple [<em>Add Reference</em>]. It generates the local proxy to call a web service (WCF for example) using the HttpWebRequest.
                                </p>

                                <p>
                                  In Javascript, it is less easy because the tools are not (<strong>yet</strong>) available but it is still possible for example to use the <a href="https://www.codeproject.com/KB/aspnet/wcfinjavascript.aspx">AJAX</a> framework. Otherwise you will have to write your own queries and handle the protocol.
                                </p>

                                <p>
                                  We must therefore recognize that Web Services/WCF & Silverlight (thanks to its excellent <strong>integration</strong> with Visual Studio) offers a much easier implementation.
                                </p>

                                <h1>
                                  Media (Audio & Vidéo)
                                </h1>

                                <p>
                                  Silverlight 5 and HTML 5 both offer advanced support for audio and video. The main problem for HTML 5 is at the non-standard codecs (and the war between the H.264 and WebM). Thus, depending on the browser, we have to send a video in one format or another.
                                </p>

                                <p>
                                  However HTML 5 provides an elegant solution, with the possibility to define in a single <video> or <audio> tag several potential sources in order of preference:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e1e253af-e22a-4dff-af23-a4002c71d3a4" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #800000">video</span> <span style="color: #ff0000">controls</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">source</span> <span style="color: #ff0000">src</span><span style="color: #0000ff">="mavideo.mp4"</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="video/mp4"/></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">source</span> <span style="color: #ff0000">src</span><span style="color: #0000ff">="mavideo.webm"</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="video/webm"/></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; Unable to read the video&#8230;
                                        </li>
                                        <li>
                                          <span style="color: #0000ff"></</span><span style="color: #800000">video</span><span style="color: #0000ff">></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  It is also possible to add a Silverlight after all the sources in case the browser does not support HTML 5.
                                </p>

                                <p>
                                  It is of course possible to manipulate audio and video via conventional controls such as Play / Pause / Stop / Seek. It is even possible to capture the video stream into an image that can be used elsewhere in the application.
                                </p>

                                <p>
                                  In Silverlight 5, there is no codecs war (the advantage of being a single decision maker). So as long as Silverlight is supported, we guarantee that our video works. So no need to encode multiple sources. In the same way (as in HTML 5) it is possible to manipulate the video via commands or use the video as a brush to another control.
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d901b156-315b-4515-8bf5-bde0ed92dd5c" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #a31515">MediaElement</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="mediaelement"</span><span style="color: #ff0000"> Source</span><span style="color: #0000ff">="https://monserveur.com/video"</span><span style="color: #ff0000"> AutoPlay</span><span style="color: #0000ff">="True" /></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  In addition, Silverlight 5 supports smooth streaming (broadcast stream that will adapt to the connection and the power of the client) through its associated control:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ef38547a-a877-444c-babe-992ab8a666f7" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #ff0000">SmoothStreamingMediaElement AutoPlay</span><span style="color: #0000ff">="True"</span><span style="color: #ff0000"> x</span><span style="color: #0000ff">:</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="SmoothPlayer"</span><span style="color: #ff0000"> SmoothStreamingSource</span><span style="color: #0000ff">="https://monserveur.com/flux.ism/Manifest" /></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  Silverlight also supports the concept of DRM (<strong>Digital Rights Management</strong>) and can therefore deliver video protected by copyright as HTML 5 not provide the same functionality. Sites using HTML 5 will thus be limited to providing free of rights material.
                                </p>

                                <p>
                                  Again, both players are functionally well-equipped. However Silverlight supports additional services and is not subject to the codecs war. So it is a slight victory for Silverlight 5.
                                </p>

                                <h1>
                                  Isolated Storage
                                </h1>

                                <p>
                                  Silverlight 5 offers local data storage via the API Isolated Storage. The Isolated Storage is a file system accessible only by the application and/or the current user.
                                </p>

                                <p>
                                  Subsequently the use of this storage space is identical to that of a standard file system:
                                </p>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9abf155f-fede-4c5e-b314-e8d631eabe9e" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff">using</span> (<span style="color: #0000ff">var</span> isostore = <span style="color: #2b91af">IsolatedStorageFile</span>.GetUserStoreForApplication())
                                        </li>
                                        <li style="background: #f3f3f3">
                                          {
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #2b91af">IsolatedStorageFileStream</span> stream = isostore.OpenFile(<span style="color: #a31515">"toto.txt"</span>, <span style="color: #2b91af">FileMode</span>.Open);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff">using</span> (<span style="color: #2b91af">StreamReader</span> reader = <span style="color: #0000ff">new</span> <span style="color: #2b91af">StreamReader</span>(stream))
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; {
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.ReadToEnd();
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
                                        </li>
                                        <li style="background: #f3f3f3">
                                          }
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <p>
                                  In HTML 5, there are 2 main solutions for isolated storage:
                                </p>

                                <ul>
                                  <li>
                                    localStorage: This is a solution to save pairs of keys/values ​​for the long term (the data is retained after the browser is closed), accessible only by the current window object:
                                  </li>
                                </ul>

                                <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c1c62fcf-beeb-4032-8e6c-39002219c7e0" class="wlWriterSmartContent">
                                  <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
                                    <div style="background: #ddd; max-height: 500px; overflow: auto">
                                      <ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #800000">body</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff"><</span><span style="color: #800000">div</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">=&#8217;userName&#8217;></span>
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff"></</span><span style="color: #800000">div</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #800000">body</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li>
                                          <span style="color: #0000ff"><</span><span style="color: #800000">script</span><span style="color: #0000ff">></span>
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;&#160;&#160; <span style="color: #0000ff">if</span> (localStorage[<span style="color: #800000">&#8216;user&#8217;</span>] == undefined)
                                        </li>
                                        <li>
                                          &#160;&#160;&#160;&#160;&#160;&#160;&#160; localStorage.setItem(<span style="color: #800000">&#8216;user&#8217;</span>, <span style="color: #800000">&#8216;David&#8217;</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; <span style="color: #0000ff">var</span> div = document.getElementById(<span style="color: #800000">&#8216;userName&#8217;</span>);
                                        </li>
                                        <li style="background: #f3f3f3">
                                          &#160;
                                        </li>
                                        <li>
                                          &#160;&#160;&#160; div.innerHTML = localStorage[<span style="color: #800000">&#8216;user&#8217;</span>];
                                        </li>
                                        <li style="background: #f3f3f3">
                                          <span style="color: #0000ff"></</span><span style="color: #800000">script</span><span style="color: #0000ff">></span>
                                        </li>
                                      </ol>
                                    </div></p>
                                  </div></p>
                                </div>

                                <ul>
                                  <li>
                                    sessionStorage: this can store key/value pair for the lifetime of the current session and is only accessible by the current window object
                                  </li>
                                </ul>

                                <p>
                                  As we can see the two competitors offer solutions philosophically identical but with different implementations: Silverlight with a file system orientation and HTML 5 storage with a structured orientation.
                                </p>

                                <h1>
                                  WebSockets vs System.Net.Sockets
                                </h1>

                                <p>
                                  HTML 5 introduces the concept of <a href="https://dev.w3.org/html5/websockets/">WebSocket</a> for <strong>network</strong> communication. It is an evolution of TCP/HTTP that will allow continuous bi-directional connections between the client and the server. Indeed, the HTTP protocol is stateless and not connected.Therefore it is difficult to use for transient or push type communications.
                                </p>

                                <p>
                                  Currently WebSocket has an issue: they are changing continuously (for example because of some <a href="https://www.adambarth.com/papers/2011/huang-chen-barth-rescorla-jackson.pdf">recently discovered</a> safety problems). So the browsers either: do not support the standard, block the feature temporary, or leave the door open to network vulnerabilities. <br />Moreover, the name is misleading, WebSocket are not sockets for the web. You must indeed connect to server that can handle the protocol. You cannot use them to connect to any TCP server.
                                </p>

                                <p>
                                  Silverlight 5, meanwhile, offer support for <a href="https://msdn.microsoft.com/en-US/library/system.net.sockets.socket(v=VS.95).aspx">sockets</a> on TCP and <a href="https://msdn.microsoft.com/en-US/library/ee707325(v=VS.95).aspx">multicast</a>. There is of course security constraints related to using of these classes (<a href="https://msdn.microsoft.com/en-US/library/cc645032(v=VS.95).aspx">cross-domain policy for example</a>) to prevent opening security gaps in Silverlight. <br />So we can easily attribute the victory to Silverlight both on <strong>functionality</strong> and <strong>availability</strong>.
                                </p>

                                <h1>
                                  Devices (cameras, microphones & printers)
                                </h1>

                                <p>
                                  Silverlight 5 provides access to the datastream from the camera or microphone. It can also send a print job controlling the drawing of each printed page. <br />HTML 5 on the subject is currently a bit light in terms of access to the camera or microphone. Several <strong>specifications</strong> are in progress and for the moment no browser supports them:
                                </p>

                                <ul>
                                  <li>
                                    <a href="https://www.w3.org/TR/2010/WD-media-capture-api-20100928/">Media Capture API</a>
                                  </li>
                                  <li>
                                    <a href="https://www.w3.org/TR/2011/WD-html-media-capture-20110414/">HTML Media Capture</a>
                                  </li>
                                  <li>
                                    <a href="https://html5labs.interoperabilitybridges.com/prototypes/media-capture-api/media-capture-api/info">Microsoft also proposes changes to the standard via Html5Labs</a>
                                  </li>
                                </ul>

                                <p>
                                  It is difficult today to judge the HTML 5 platform on its ability to capture audio and video.
                                </p>

                                <p>
                                  To manage the printer, the only available method is <em>window.print</em>. Now it can just start printing without deciding the behavior of each page. <br />On the topic of devices access, Silverlight 5 wins by a large margin (<strong>for</strong> <strong>now</strong>).
                                </p>

                                <h1>
                                  Business case
                                </h1>

                                <p>
                                  Beyond the technical aspects, there are many other points to consider when choosing a technology.
                                </p>

                                <p>
                                  The first of these is the team skill level with those technologies. If the developers are trained in .NET obviously, Silverlight is an easy choice. Similarly, if the team is already versed in the dark arts of JavaScript, HTML 5 will be a better option.
                                </p>

                                <p>
                                  In a second step, the search for <strong>sustainability</strong> may be a strong factor of selection. And this is not so clear cut. Indeed, one can easily picture Silverlight having beautiful years ahead of it (or at least XAML +. NET). One thing is sure though, we are at the beginning of the adventure of HTML 5. <br />With the onset of tools, ever increasing browsers support or even the finalization of the standard, it does not take a rocket scientist to see that HTML 5 will be a <strong>huge success</strong>.
                                </p>

                                <p>
                                  However, we must remember that HTML 5 is a slow-moving standard where Silverlight can change very quickly and if you ever miss a Silverlight feature in an HTML 5 development, there will be water under the bridge before it actually makes it to the standard.&#160;
                                </p>

                                <p>
                                  Focusing next on <strong>ease of implementation, </strong>I think Silverlight today has clearly a better VS support, debugger, profiler, frameworks and patterns. So for now, there is no match. Of course this could change rapidly especially with the future versions of Visual Studio. In addition for certain takes browsers can help with tools like the developers bar in IE9 (F12) that allows debugging, profiling and analyzing the code.
                                </p>

                                <p>
                                  Finally, there remains the question of portability. From the site <a href="https://riastats.com">https://riastats.com</a>, here are the distributions found worldwide:
                                </p>

                                <p>
                                  <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/4024.image_3D2E5A3A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/4024.image_5F00_3D2E5A3A.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0"  src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/4846.image_thumb_3B7D8E66.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/4846.image_5F00_thumb_5F00_3B7D8E66.png" width="408" height="383" /></a>
                                </p>

                                <p align="center">
                                  <strong>73 % of browsers have Silverlight 4 installed</strong>
                                </p>

                                <p align="center">
                                  <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/4034.image_58A33670.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/4034.image_5F00_58A33670.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0"  src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/5516.image_thumb_04DFBD55.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/5516.image_5F00_thumb_5F00_04DFBD55.png" width="408" height="378" /></a>
                                </p>

                                <p align="center">
                                  <strong>75 % of browsers supports HTML5 (a least a part of it)</strong>
                                </p>

                                <p>
                                  We can see that Silverlight 5 and HTML 5 seem to be supported at the same level. However, it is somewhat more complex in reality. In fact, if your project targets only Windows and Mac OS, Silverlight is as well supported as HTML 5. By contrast, in IOS and Android, only HTML 5 is supported.
                                </p>

                                <p>
                                  Also note that Silverlight can work "<strong>outside the browser</strong>" like a normal application (and therefore with elevated rights) which may be interesting for some projects.&#160;
                                </p>

                                <p>
                                  One should not be lulled by the myth of absolute portability of HTML 5. For now, the standard is evolving and will not be completed until 2014 at best. During this time and certainly for a long time afterwards, the browsers will be trying to support the standard. Thus, it will force us to write more code than necessary sometimes for specific versions (besides there is a JavaScript library that facilitates this work <a href="https://www.modernizr.com/">modernizr</a>).
                                </p>

                                <p>
                                  A final important aspect lies in the protection of intellectual property. There are obfuscators for both technologies (<a href="https://javascript-obfuscator.com/">for example this one for Javascript</a>) but we can see that as a result of compilation, Silverlight (IL) is more difficult to reverse engineer. In addition the XAML is not directly exposed: it is easier to get the HTML (directly sent to the browser).
                                </p>

                                <h1>
                                  Conclusion
                                </h1>

                                <p>
                                  In the end, there is <strong>no winner</strong>. We have two complementary technologies. Even if today there are more boxes with Silverlight 5 than boxes with HTML, the choice is not as simple as it is ultimately project dependent.
                                </p>

                                <p>
                                  Indeed, it is sufficient that the project targets both Windows and Android tablets to push HTML 5 as the best solution.
                                </p>

                                <p>
                                  So in the Web development world, we have to live with both, and know them well enough to provide the <strong>right solution at the right time</strong>.
                                </p>

                                <p>
                                </p>

Babylon.Toolkit 1.0.4

Babylon.Toolkit 1.0.4 was just released with the following features:

  • New Effects
    • BasicEffect3Lights (3 directionals lights instead of 1 position light)
    • CartoonEffect (work in progress)
    • SkinnedEffect (with normal and specular map support)
    • SplattingEffect (for multi-texturing with smooth and precise transitions)
    • VertexColorEffect (very light for non textured meshes)
  • Improved Effects
    • Effects with normal map support now have an “InvertBinormal” property (some tools generate normal maps with binormal pointing upward and others pointing downward)
  • Particle System
    • Basic particle rendering system with basic physics computed on GPU
  • Primitives
    • Facility tools for creating cubes and spheres
  • Modified model system to allow third party tools to create Model / Mesh / MeshPart without using ModelContent hierarchy.
  • Bug fixes

You can grab it at https://babylontoolkit.codeplex.com or you can use NuGet at : Babylon.Toolkit.

Note about samples:
In order to run samples, you need to configure Visual Studio to run them as an “Out-of-browser application”. in order to do that, go to the property page of a sample project, go to the Debug tab, and check the “Out-of-browser application” radio button.

Babylon.Toolkit v1.0.3 &#8211; Simplify 3D development with Silverlight 5

Babylon.Toolkit 1.0.3 is now out on https://babylontoolkit.codeplex.com/.

With this release, you will find:

  • A new Model object model with Vertex and Index buffers sharing
  • A new ModelContent object model to create custom importers. This content pipeline supports vertices re-ordering and optimizations.
  • A new intersection system:
    • ModelMesh now have a BoundingSphere property
    • Rays can intersects ModelMesh and return precise intersections distance
    • Object picking is now supported

Here is a sample using a Viper (From the ubber cool TV show Battlestar Galactica):

TPL : Build your own TPL for Silverlight, WP7 and XBox 360

This blog is a translation of https://blogs.msdn.com/b/eternalcoding/archive/2011/05/16/fr-sous-le-capot-etude-de-la-task-parallel-library.aspx

With this post, we will discover the Task Parallel Library (a library to simply manage your parallel developments with the .Net framework 4.0). But we will do this in a slightly different way. Indeed, we will totally rewrite it from scratch Sourire.

Of course, we will not do as well as the original TPL. We will focus on key concepts in order to understand how the TPL works.

We shall take advantage of writing our version to make it usable with multiple frameworks. To do that, we only need to install the Portable Library Tools. Once the latter installed, a new project appears in Visual Studio that will allow us to develop our TPL:

image_thumb[1]

With this project type, we will develop an assembly usable with .Net 4.0, Silverlight 4 (and 5), Silverlight for Windows Phone 7 and even with XNA 4.0 for XBox 360 !

Of course, this portability will have a price in terms of functionalities.

You can already download the Portable TPL just here : https://portabletpl.codeplex.com.

You can also install it with a NuGet package : https://www.nuget.org/List/Packages/PortableTPL.

However before writing our code, we will study the original TPL to see how we can build our solution.

Task & TaskFactory

TPL is built on a class called Task which is an unity of work to realize.

It is like a ThreadPool.QueueUserWorkItem(). So to realize a work, just create a Task with the action to realize in parameter :





var task = new Task(state =>
{
foreach (int value in data)
{
Thread.Sleep(value
* (int)state);
}
},
100);
task.Start();
task.Wait();




<p>
  Another solution to start a Task is to use the TaskFactory.StartNew() method which is on the static class Task.Factory :
</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:ad999d03-595f-401e-b80c-8c66bc35bec6" class="class">
  <pre style="background-color: white; width: 789px; height: 123px; overflow: auto"><div>

Task task = Task.Factory.StartNew(() =>
{
foreach (int value in data)
{

}
});
task.Wait();

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    We can remark the use of Task.Wait() which allows the synchronization between the task and our current thread.
  </p>

  <p>
    In addition, you need to know there is another class for tasks: Task<T>. This daughter of Task&#160; adds the concept of return value:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:88b9afc0-56a5-41d2-be32-4e6e43dfc918" class="class">
    <pre style="background-color: white; width: 789px; height: 197px; overflow: auto"><div>

Task<int> task = Task.Factory.StartNew<int>(
(limit)
=>
{
int sum = ;
for (int i = ; i < (int)limit; i++)
{
sum
+= i;
}
return sum;
},
100);
task.Wait();
Console.WriteLine(task.Result);

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    Thus Task<T> is designed to retrieve a result where Task executes only an action.
  </p>

  <h1>
    Task continuation
  </h1>

  <p>
    Task continuation is another feature we will cover with our solution. Indeed, the task continuation allows the launch of a secondary task when a primary one is terminated.
  </p>

  <p>
    To do so, we only need to use the ContinueWith() method:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:3df6fae9-5f20-4728-bea7-cc96432e4acd" class="class">
    <pre style="background-color: white; width: 789px; height: 172px; overflow: auto"><div>

Task task = Task.Factory.StartNew(() =>
{
foreach (int value in data)
{

}
});
task.ContinueWith(t
=>
{
// Code de la seconde tâche…
});

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    The secondary task will receive the primary task in parameter in order to process errors (if any).
  </p>

  <h1>
    Schedulers and work stealing
  </h1>

  <p>
    The tasks are managed and organized by schedulers whose role is to dispatch them on worker threads. Indeed, according to the number of processors, TPL will create the right count of working threads. Each task to run would be then treated by one of these worker threads.
  </p>

  <p>
    The allocation of tasks on the worker threads will be made according to different algorithms. In our case we will cover the standard scheduler (which distributes the workload in a uniform manner) and the scheduler of the synchronization context (where all tasks run on the UI thread to allow them to drive the interface).
  </p>

  <p>
    Thus, schedulers each have a queue of the tasks assigned to them.
  </p>

  <p>
    In addition, the TPL handles additional functionality: the work stealing. Indeed, if a worker thread has an empty queue and his colleagues still have work to do, it will gently steal a portion of their remaining work. All of this is done to ensure a constant distribution of the load on each processor.
  </p>

  <p>
    By default, the tasks are launched on the standard scheduler. However if you want to start a task on the scheduler of the synchronization context, you simply need to execute this code:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:fbe17086-e227-4fdb-98e6-25224b011731" class="class">
    <pre style="background-color: white; width: 789px; height: 129px; overflow: auto"><div>

Task task = Task.Factory.StartNew(() =>
{
foreach (int value in data)
{
Thread.Sleep(value
* 100);
}
},CancellationToken.None,
TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    A sample of the use of this type of continuation can be the update of an interface after the execution of a task. Before the launch of the task we can display an hourglass or a wait animation and then start our task. When the task completes, on a second task running on the scheduler of the synchronization context and in continuation of the first we can hide our control to indicate to the user the end of the treatment.
  </p>

  <h1>
    State management
  </h1>

  <p>
    Tasks have a status property to indicate their current state :
  </p>

  <ul>
    <li>
      <strong>TaskStatus.Created</strong> : First state of a task. Task is not yet launched or even scheduled.
    </li>
    <li>
      <strong>TaskStatus.WaitingForActivation</strong> : Task was launched but is not yet assigned to a worker thread by a scheduler.
    </li>
    <li>
      <strong>TaskStatus.WaitingToRun</strong> : Task was assigned to a worker thread but is not yet executed.
    </li>
    <li>
      <strong>TaskStatus.Running</strong> : Task is executed by a worker thread.
    </li>
    <li>
      <strong>TaskStatus.RanToCompletion</strong> : Everything is ok!!! The task was executed successfully.
    </li>
    <li>
      <strong>TaskStatus.Faulted</strong> : An exception was thrown.
    </li>
    <li>
      <strong>TaskStatus.Canceled</strong> : User has cancelled the execution of the task.
    </li>
  </ul>

  <p>
    So we can follow the complete life of the task through its status.
  </p>

  <p>
    In addition, tasks have several properties that bring together some status:
  </p>

  <ul>
    <li>
      <strong>Task.IsCanceled</strong> : Like Status == Canceled
    </li>
    <li>
      <strong>Task.IsFaulted</strong> : Like Status == Faulted
    </li>
    <li>
      <strong>Task.IsCompleted</strong> : Like Status == RanToCompletion or Faulted or Canceled
    </li>
  </ul>

  <h1>
    Cancellation
  </h1>

  <p>
    TPL allows the developer to simply manage the concept of cancellation within the tasks. Indeed, since the framework.NET 4.0, the CancellationTokenSource class has been added to serve as a basis for cancellation. In the TPL, this class will emit a token that will be copied to the task. It allows to know if a cancel has been requested at the level of the CancellationTokenSource class. If this is the case, the token can throw a cancellation exception:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:823a7de3-516a-4e98-90b0-be99f8a9fe81" class="class">
    <pre style="background-color: white; width: 789px; height: 248px; overflow: auto"><div>

var tokenSource = new CancellationTokenSource();
var token
= tokenSource.Token;

var task = Task.Factory.StartNew(limit =>
{
for (int i = ; i < (int)limit; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine(
Processing {0}, i);
}
},
2000, token);

Thread.Sleep(200);

Console.WriteLine(Let’s cut…);
tokenSource.Cancel();

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    We can of course make the choice to not throw an exception but rather to quit the task if we detect the token&#8217;s IsCancellationRequested property set to True.
  </p>

  <p>
    The launch of the cancellation is done on the CancellationTokenSource that issued tokens. This can cancel several tasks at once. It is even possible to register with the token via the Register method to be notified when a cancellation is requested.
  </p>

  <h1>
    The Parallel class
  </h1>

  <p>
    In addition to the notion of tasks, TPL adds support for Parallel class which will allow us to do parallel loops in a really elegant way:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8d183e4e-df49-497d-87fc-ba2ed0fdb0cb" class="class">
    <pre style="background-color: white; width: 789px; height: 72px; overflow: auto"><div>

Parallel.For(, 10, i =>
{
Console.WriteLine(i);
});

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    The same thing with ForEach :
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:0dcacf47-bb1c-47af-8154-b24c044fe8ea" class="class">
    <pre style="background-color: white; width: 789px; height: 27px; overflow: auto"><div>

Parallel.ForEach(new[]{toto, titi}, Console.WriteLine);

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    Of course, with the use of these methods, we must be careful that each loop is really independent to not cause cross-threads access violations.
  </p>

  <h1>
    Exception handling
  </h1>

  <p>
    TPL offers an elegant solution for the management of exceptions. Indeed, if in the body of a task, an exception should be thrown, TPL will catch it for us.
  </p>

  <p>
    It will be subsequently transmitted to the user when:
  </p>

  <ul>
    <li>
      Parallel.For/ForEach returns
    </li>
    <li>
      Calling the Wait method of a Task
    </li>
    <li>
      Calling the Result property of Task <T>.
    </li>
  </ul>

  <p>
    The important point to note here is that TPL will aggregate the exceptions that might occur in a task or a Parallel.For/ForEach to present them on the calling thread:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8cfc5a73-c77c-489e-9ade-a91bfa875b55" class="class">
    <pre style="background-color: white; width: 789px; height: 280px; overflow: auto"><div>

try
{
Parallel.For(
, 10, i =>
{
Console.WriteLine(i);
if (i == 5)
throw new Exception(erf…);
});
}
catch (AggregateException aggEx)
{
foreach (Exception ex in aggEx.InnerExceptions)
{
Console.WriteLine(
string.Format(Caught exception ‘{0}’, ex.Message));
}
}
Console.ReadLine();

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    In this sample, the system write 10 values to the console and then at the exit of the Parallel.For, TPL threw the aggregate exception. We will therefore see appear the superb "caught exception erf…" message.
  </p>

  <p>
    In the same way, we can retrieve the exception on a Task.Wait:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:9a927005-5178-4930-a332-5448a9614ad2" class="class">
    <pre style="background-color: white; width: 789px; height: 369px; overflow: auto"><div>

Task<int> task = Task.Factory.StartNew(
limit
=>
{
int sum = ;
for (int i = ; i < (int)limit; i++)
{
sum
+= i;
if (i == 12)
throw new Exception(Bad trip…);
}
return sum;
},
100);
try
{
task.Wait();
Console.WriteLine(task.Result);
}
catch (AggregateException aggregateException)
{
foreach (Exception ex in aggregateException.InnerExceptions)
{
Console.WriteLine(
string.Format(Caught exception ‘{0}’, ex.Message));
}
}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    If we do not call a method or a property that throws the aggregation exception, then the latter will not be observed. The only way then to know if an error has actually occurred will be watching the value of Task.Status or Task.IsFaulted.
  </p>

  <h1>
    Our architecture
  </h1>

  <p>
    It is therefore now that serious things start! We know what we are talking about, we have the vocabulary, we are now ready to reproduce the same thing with our framework limited by the Portable Library.
  </p>

  <p>
    And foremost, here is our class diagram:
  </p>

  <p>
    <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/2148.image_thumb3_57C43D4B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/2148.image_5F00_thumb3_5F00_57C43D4B.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image_thumb3" border="0" alt="image_thumb3" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/2664.image_thumb3_thumb_69542816.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/2664.image_5F00_thumb3_5F00_thumb_5F00_69542816.png" width="650" height="374" /></a>
  </p>

  <h1>
    Implementation
  </h1>

  <p>
    As a reminder, the current solution is certainly not the true TPL and is only intended to be <u><strong>educational</strong></u>.
  </p>

  <h1>
  </h1>

  <h2>
    Worker threads
  </h2>

  <p>
    The worker threads are THE real workers in our case. They go to the mine to perform tasks. Work is assigned to them by the schedulers.
  </p>

  <p>
    Internally, they have a queue (that must be protected against concurrent access by using locks) of tasks. Their main loop is built around a ManualResetEvent (that will be signaled as soon as a new task is added) :
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8e0e3de1-aa06-4f04-a1b6-965bbef210c4" class="class">
    <pre style="background-color: white; width: 789px; height: 342px; overflow: auto"><div>

internal void AddTask(Task task)
{
task.SetIsScheduled();

</span><span style="color: #0000ff">lock</span><span style="color: #000000"> (workQueue)
{
    workQueue.Enqueue(task);
}
workEvent.Set();

}

internal void AddTasks(Task[] tasks)
{
lock (workQueue)
{
foreach (Task task in tasks)
{
workQueue.Enqueue(task);
}
}
workEvent.Set();
}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    The main work loop will therefore wait passively on the ManualResetEvent and later will process its queue until it is empty:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:f9080579-1199-4366-b3cc-eed1394bd68f" class="class">
    <pre style="background-color: white; width: 789px; height: 475px; overflow: auto"><div>

void ThreadJob()
{
while (true)
{
workEvent.WaitOne();
workEvent.Reset();

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (quitCondition)
        </span><span style="color: #0000ff">return</span><span style="color: #000000">;

    Task task;
    </span><span style="color: #0000ff">bool</span><span style="color: #000000"> noWork </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">false</span><span style="color: #000000">;

    </span><span style="color: #0000ff">do</span><span style="color: #000000">
    {
        </span><span style="color: #0000ff">bool</span><span style="color: #000000"> emptyQueue </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">!</span><span style="color: #000000">workQueue.TryDequeue(</span><span style="color: #0000ff">out</span><span style="color: #000000"> task);

        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (emptyQueue </span><span style="color: #000000">&&</span><span style="color: #000000"> </span><span style="color: #000000">!</span><span style="color: #000000">scheduler.StealWork(</span><span style="color: #0000ff">this</span><span style="color: #000000">))
        {
            noWork </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">true</span><span style="color: #000000">;
        }

        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (task </span><span style="color: #000000">!=</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">)
            task.DoWork();

        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (quitCondition)
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;

    }
    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">noWork);
}

}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    Here we can see the presence of a condition of output (QuitCondition) and the work stealing algorithm (scheduler.StealWork) that we will see later.
  </p>

  <p>
    The task (in order to run its code) provides a DoWork method that calls the delegate defined in its constructor:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:c5dfb89e-fc3c-40ea-a2cc-7dfd75652ff1" class="class">
    <pre style="background-color: white; width: 789px; height: 117px; overflow: auto"><div>

protected virtual void ExecuteDelegate()
{
if (ActionDelegate.Method.GetParameters().Length > )
ActionDelegate.DynamicInvoke(AsyncState);
else
ActionDelegate.DynamicInvoke();
}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <h2>
    Schedulers
  </h2>

  <p>
    A scheduler must at least provide an EnqueueTask method to add a new task to its list of tasks to dispatch on its worker threads.
  </p>

  <p>
    Thus, we have an abstract TaskScheduler class to define this behavior.
  </p>

  <p>
    In addition this class will have a static property ProcessorCount that must be defined by the user. Indeed, the Portable Library prevents us to access Environment.ProcessorCount because the latter is not present on all the targeted frameworks.
  </p>

  <h3>
    Standard Scheduler
  </h3>

  <p>
    It is the main scheduler. It allocates a number of worker threads equal to the number of processors defined by the TaskScheduler.ProcessorCount property.
  </p>

  <p>
    To implement the EnqueueTask method, the scheduler will look for the worker thread whose work queue is the smallest:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:d8e1590b-e961-438b-95d7-fc8e3dce8296" class="class">
    <pre style="background-color: white; width: 789px; height: 247px; overflow: auto"><div>

WorkerThread FindLowestQueue()
{
WorkerThread result
= null;
int currentLevel = int.MaxValue;

</span><span style="color: #0000ff">foreach</span><span style="color: #000000"> (WorkerThread workerThread </span><span style="color: #0000ff">in</span><span style="color: #000000"> workerThreads)
{
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (workerThread.QueueLength </span><span style="color: #000000">&lt;</span><span style="color: #000000"> currentLevel)
    {
        currentLevel </span><span style="color: #000000">=</span><span style="color: #000000"> workerThread.QueueLength;
        result </span><span style="color: #000000">=</span><span style="color: #000000"> workerThread;
    }
}

</span><span style="color: #0000ff">return</span><span style="color: #000000"> result;

}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    Once a worker thread is found, the scheduler will just add it the task to execute.
  </p>

  <h3>
    Synchronization context scheduler
  </h3>

  <p>
    This scheduler is quite simple since it sends all its tasks on the synchronization context (for instance the Dispatcher for WPF):
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:c0e98a26-fe3d-4149-895b-5438c887a31c" class="class">
    <pre style="background-color: white; width: 789px; height: 65px; overflow: auto"><div>

public override void EnqueueTask(Task task)
{
context.Post(state
=> task.DoWork(), null);
}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    This scheduler is built by a static method of the TaskScheduler class:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1f70e950-fca3-4adc-82b2-639225ee50db" class="class">
    <pre style="background-color: white; width: 789px; height: 79px; overflow: auto"><div>

public static TaskScheduler FromCurrentSynchronizationContext()
{
return new SynchronisationContextTaskScheduler(SynchronizationContext.Current);
}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <h2>
    Work stealing
  </h2>

  <p>
    As we have seen above, the scheduler can balance the load of worker threads by moving tasks for one worker thread to another.
  </p>

  <p>
    So the StealWork method is :
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:00f73084-009e-4726-be21-2642046c2f8b" class="class">
    <pre style="background-color: white; width: 789px; height: 411px; overflow: auto"><div>

internal bool StealWork(WorkerThread source)
{
foreach (WorkerThread workerThread in workerThreads)
{
if (workerThread == source)
continue;

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (workerThread.QueueLength </span><span style="color: #000000">&gt;</span><span style="color: #000000"> </span><span style="color: #800080">1</span><span style="color: #000000">)
    {
        </span><span style="color: #0000ff">int</span><span style="color: #000000"> total </span><span style="color: #000000">=</span><span style="color: #000000"> workerThread.QueueLength </span><span style="color: #000000">/</span><span style="color: #000000"> </span><span style="color: #800080">2</span><span style="color: #000000">;
        List</span><span style="color: #000000">&lt;</span><span style="color: #000000">Task</span><span style="color: #000000">&gt;</span><span style="color: #000000"> stolenWork </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> List</span><span style="color: #000000">&lt;</span><span style="color: #000000">Task</span><span style="color: #000000">&gt;</span><span style="color: #000000">();
        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> index </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #800080"></span><span style="color: #000000">; index </span><span style="color: #000000">&lt;</span><span style="color: #000000"> total; index</span><span style="color: #000000">++</span><span style="color: #000000">)
        {
            Task task;
            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (workerThread.TryDequeue(</span><span style="color: #0000ff">out</span><span style="color: #000000"> task))
            {
                stolenWork.Add(task);
            }
        }

        source.AddTasks(stolenWork.ToArray());
        </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">true</span><span style="color: #000000">;
    }
}

</span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">false</span><span style="color: #000000">;

}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    It iterates through the list of the worker threads and as soon as it finds one that still has work (more than a task), it will"steals" half of his work.
  </p>

  <h2>
    The Parallel Class
  </h2>

  <p>
    The static class Parallel is finally an different entry point to generate tasks. Indeed, Parallel will appeal to the services of a standard scheduler which will execute the following code :
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:720999f6-9f40-4702-b754-698968f0d73b" class="class">
    <pre style="background-color: white; width: 789px; height: 442px; overflow: auto"><div>

void Dispatch(int stackSize, int excludedEnd, Func<int, Task> produceTask)
{
List
<Task> totalTasks = new List<Task>();

</span><span style="color: #0000ff">int</span><span style="color: #000000"> index </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #800080"></span><span style="color: #000000">;
</span><span style="color: #0000ff">foreach</span><span style="color: #000000"> (WorkerThread workerThread </span><span style="color: #0000ff">in</span><span style="color: #000000"> workerThreads)
{
    </span><span style="color: #0000ff">int</span><span style="color: #000000"> start </span><span style="color: #000000">=</span><span style="color: #000000"> index </span><span style="color: #000000">*</span><span style="color: #000000"> stackSize;
    </span><span style="color: #0000ff">int</span><span style="color: #000000"> end </span><span style="color: #000000">=</span><span style="color: #000000"> start </span><span style="color: #000000">+</span><span style="color: #000000"> stackSize;

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (index </span><span style="color: #000000">==</span><span style="color: #000000"> ProcessorCount </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #800080">1</span><span style="color: #000000">)
        end </span><span style="color: #000000">=</span><span style="color: #000000"> excludedEnd;

    Task[] tasks </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> Task[end </span><span style="color: #000000">-</span><span style="color: #000000"> start];
    </span><span style="color: #0000ff">int</span><span style="color: #000000"> taskID </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #800080"></span><span style="color: #000000">;

    </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> local </span><span style="color: #000000">=</span><span style="color: #000000"> start; local </span><span style="color: #000000">&lt;</span><span style="color: #000000"> end; local</span><span style="color: #000000">++</span><span style="color: #000000">)
    {
        Task task </span><span style="color: #000000">=</span><span style="color: #000000"> produceTask(local);
        tasks[taskID</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> task;
    }

    totalTasks.AddRange(tasks);
    workerThread.AddTasks(tasks);
    index</span><span style="color: #000000">++</span><span style="color: #000000">;
}

Task.WaitAll(totalTasks.ToArray());

}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    In this method, we divide the number of items to be treated by the number of worker threads available. A bunch of tasks are then created and we just have to wait for their completion.
  </p>

  <h2>
    Exception handling
  </h2>

  <p>
    The management of exceptions will happen at the level of the tasks. We must protect the call to the delegate of a task by using a try/catch block. We must then take the encapsulated exception and store it in our aggregate exception:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:a8924f0a-175d-4d54-98f4-4f622f31e225" class="class">
    <pre style="background-color: white; width: 789px; height: 275px; overflow: auto"><div>

try
{
ExecuteDelegate();
}
catch (TargetInvocationException exception)
{
if (aggregateException == null)
{
aggregateException
= new AggregateException();
}

aggregateException.InnerExceptions.Add(exception.InnerException);
status </span><span style="color: #000000">=</span><span style="color: #000000"> TaskStatus.Faulted;  


</span><span style="color: #0000ff">return</span><span style="color: #000000">;

}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <h2>
    Cancellation
  </h2>

  <p>
    Cancellation management is done through a CancellationToken that will throw an exception if there is a cancellation request:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:5b3ee2ba-d273-467f-b82d-59f02d84510e" class="class">
    <pre style="background-color: white; width: 789px; height: 110px; overflow: auto"><div>

public void ThrowIfCancellationRequested()
{
if (isCancellationRequested)
{
throw new OperationCanceledException(this);
}
}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    Later, we will have to change our management of exceptions to a different behavior when an exception of type OperationCanceledException is thrown:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1ef013aa-83d6-44e8-97e6-cdb8c657752d" class="class">
    <pre style="background-color: white; width: 789px; height: 401px; overflow: auto"><div>

try
{
WaitEvent.Reset();
ExecuteDelegate();
}
catch (TargetInvocationException exception)
{
if (aggregateException == null)
{
aggregateException
= new AggregateException();
}

</span><span style="color: #0000ff">if</span><span style="color: #000000"> (exception.InnerException </span><span style="color: #0000ff">is</span><span style="color: #000000"> OperationCanceledException)
{
    aggregateException.InnerExceptions.Add(</span><span style="color: #0000ff">new</span><span style="color: #000000"> TaskCanceledException());
}

</span><span style="color: #0000ff">if</span><span style="color: #000000"> (status </span><span style="color: #000000">!=</span><span style="color: #000000"> TaskStatus.Canceled)
{
    aggregateException.InnerExceptions.Add(exception.InnerException);
    status </span><span style="color: #000000">=</span><span style="color: #000000"> TaskStatus.Faulted;  
}


</span><span style="color: #0000ff">return</span><span style="color: #000000">;

}

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    Thus, if we encounter a cancellation at the level of exceptions, we must not setting the status to Faulted because the task will set it to Canceled.
  </p>

  <h1>
    Results & benchmarks
  </h1>

  <p>
    Just for fun, I tried to replace TPL in my own raytracer (Bolas) code. Indeed, through a Parallel.For, I treat each line of my image in parallel to speed up the final rendering:
  </p>

  <p>
    <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/1018.image_thumb1_10CAF481.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/1018.image_5F00_thumb1_5F00_10CAF481.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image_thumb1" border="0" alt="image_thumb1" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/0363.image_thumb1_thumb_7E7207F1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-73-metablogapi/0363.image_5F00_thumb1_5F00_thumb_5F00_7E7207F1.png" width="604" height="422" /></a>
  </p>

  <p>
    The relevant code is the following:
  </p>

  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:da20e6e5-0c6a-410f-91c9-ad87b2f16957" class="class">
    <pre style="background-color: white; width: 789px; height: 211px; overflow: auto"><div>

Task task = Task.Factory.StartNew(() =>
{
if (scene == null || scene.Camera == null)
return;
if (IsParallel)
{
Parallel.For(
, RenderHeight, y => ProcessLine(scene, y));
return;
}
for (int y = ; y < RenderHeight; y++)
{
ProcessLine(scene, y);
}
});

<p>
  <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></div> 

  <p>
    As you can see, it is a simple Parallel.For which calls the ProcessLine method for each row.
  </p>

  <p>
    Using the TPL, an image of 800 x 800 with anti-aliasing required 47s to generate.
  </p>

  <p>
    By using our version, it takes 45s to generate the same image. The result is therefore quite acceptable.
  </p>

  <p>
    Then of course, TPL is far better both in terms of stability and reliability and adds many other features.<br />
  </p>

  <p>
    But what it is important to understand here is that there is no magic. By understanding how the TPL works, you will be able to better architect your code by taking the right decisions in terms of parallel management design.
  </p>

Babylon.Toolkit update 1.0.2

A new update for Babylon.Toolkit was deployed.

It includes:

  • StatesManager class : A class that allows developers to affect GraphicsDevice’s states without creating individual objects. A cache system handles duplicates and provides great performances when setting states
  • Peformances updates
  • Effect class now tracks active shaders in order to not reset them when it’s not required
  • Model now has a central vertex and index buffers repository. In the previous version, each ModelMesh had its own buffers. The performance gain is about 15% for a standard model with more than 15 meshes.

  • BasicEffect now support bump and specular maps

  • ModelMesh is now a generic class of T where T is VertexType of the mesh

You can download the latest version of Babylon.Toolkit here: https://babylontoolkit.codeplex.com/

And the NuGet package : https://www.nuget.org/List/Packages/Babylon.Toolkit