<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Rousset</title><link>http://blogs.msdn.com/b/davrous/</link><description>aka Luke CloudWalker</description><dc:language>en-US</dc:language><generator>Telligent Community 5.6.583.20496 (Build: 5.6.583.20496)</generator><item><title>Venez découvrir le parcours Web aux Techdays 2012 avec du Windows 8 dedans !</title><link>http://blogs.msdn.com/b/davrous/archive/2012/01/27/venez-d-233-couvrir-le-parcours-web-aux-techdays-2012.aspx</link><pubDate>Fri, 27 Jan 2012 12:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10252484</guid><dc:creator>David Rousset</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10252484</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2012/01/27/venez-d-233-couvrir-le-parcours-web-aux-techdays-2012.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;span style="color: #804040;" color="#804040"&gt;Mise &amp;agrave; jour du 27/01/2012 sp&amp;eacute;ciale Windows 8 :&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Beaucoup d&amp;rsquo;entre vous ne l&amp;rsquo;ont pas encore remarqu&amp;eacute; mais nous avons la chance de pouvoir vous pr&amp;eacute;senter en 3 sessions le mod&amp;egrave;le de &lt;strong&gt;d&amp;eacute;veloppement de Windows 8 Metro&lt;/strong&gt;. Ces 3 sessions seront jou&amp;eacute;es aux m&amp;ecirc;mes cr&amp;eacute;neaux horaires sur les 3 jours. Les voici :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=340e7a5e-8513-4f0e-b005-68e994e89e92&amp;amp;SessionID=7aca4b18-4c15-4d16-9743-bbed6bc3de74"&gt;Windows 8 : Construire une application au style METRO&lt;/a&gt; : vous d&amp;eacute;couvrirez ici les 8 traits importants constituant les bases d&amp;rsquo;une bonne application Metro. Cette session sera anim&amp;eacute;e par mes amis Eric Verni&amp;eacute; et David Catuhe&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=340e7a5e-8513-4f0e-b005-68e994e89e92&amp;amp;SessionID=a5eeebdd-fd9b-48ed-ad14-7f9cbb5e5507"&gt;Windows 8 : Architecture du nouveau Runtime de Windows&lt;/a&gt; : nous verrons ici les 3 mani&amp;egrave;res de &lt;strong&gt;cr&amp;eacute;er une application Metro &amp;agrave; l&amp;rsquo;aide de C++, C# et HTML5/JavaScript&lt;/strong&gt;. D&amp;eacute;veloppeurs JS : vous verrez ainsi, entre autres, comment cr&amp;eacute;er une application &amp;ldquo;from scratch&amp;rdquo; en 20 min acc&amp;eacute;dant &amp;agrave; l&amp;rsquo;ensemble de la plateforme. J&amp;rsquo;aurais la chance d&amp;rsquo;animer cette session avec mon clone David Catuhe.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=340e7a5e-8513-4f0e-b005-68e994e89e92&amp;amp;SessionID=16d2023c-55c8-4b65-b64e-0a8a85ad1e75"&gt;Windows 8 : Les outils pour construire des applications au style METRO&lt;/a&gt; : nous verrons ici les outils mis &amp;agrave; disposition du d&amp;eacute;veloppeur pour cr&amp;eacute;er des applications Metro. Ici on parlera en d&amp;eacute;tails de &lt;strong&gt;Visual Studio 11 et d&amp;rsquo;Expression Blend 5&lt;/strong&gt;. J&amp;rsquo;aurais la chance d&amp;rsquo;animer cette session avec mon ami Eric Verni&amp;eacute;.&lt;/p&gt;
&lt;p&gt;Donc messieurs, mesdames les d&amp;eacute;veloppeurs &amp;ldquo;web&amp;rdquo;, venez voir comment r&amp;eacute;utiliser vos comp&amp;eacute;tences pour fabriquer des applications Windows 8. Pour cela, inscrivez-vous vite sur le site des Techdays 2012 !&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6378.logo_5F00_mstechdays_5F00_2012_5F00_020EF877.png"&gt;&lt;img title="logo_mstechdays_2012" style="background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 5px 0px 10px; display: inline; padding-right: 0px; border-width: 0px;" border="0" alt="logo_mstechdays_2012" align="right" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0160.logo_5F00_mstechdays_5F00_2012_5F00_thumb_5F00_488BE87F.png" width="197" height="93" /&gt;&lt;/a&gt;Par ailleurs, comme depuis maintenant plusieurs ann&amp;eacute;es, j&amp;rsquo;ai la chance d&amp;rsquo;&amp;ecirc;tre responsable du parcours D&amp;eacute;veloppement Web aux &lt;a href="http://www.mstechdays.fr"&gt;Microsoft Techdays&lt;/a&gt;. Cette mission implique la d&amp;eacute;finition des sujets que je souhaiterais voir traiter, la d&amp;eacute;licate op&amp;eacute;ration de s&amp;eacute;lection des fameux &amp;ldquo;speakers&amp;rdquo; (ou orateurs en bon fran&amp;ccedil;ais) et bien entendu l&amp;rsquo;immense joie de d&amp;eacute;livrer moi-m&amp;ecirc;me certaines sessions. &lt;img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" alt="Sourire" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0830.wlEmoticon_2D00_smile_5F00_4DCF1F7A.png" /&gt;&lt;/p&gt;
&lt;p&gt;Cette ann&amp;eacute;e, je voulais mettre un accent fort sur HTML5 et tout ce qui gravite autour (JavaScript, CSS3, etc.) d&amp;rsquo;une part et les nouveaut&amp;eacute;s de nos frameworks/outils d&amp;rsquo;autre part. J&amp;rsquo;ai &amp;eacute;galement fait appel &amp;agrave; des orateurs issus de communaut&amp;eacute;s que j&amp;rsquo;appr&amp;eacute;cie et dont la qualit&amp;eacute; est reconnue de tous. Au final, je suis particuli&amp;egrave;rement content du programme. A vous de me dire ce que vous en pensez !&lt;/p&gt;
&lt;p&gt;Commen&amp;ccedil;ons par la galaxie HTML5 regroup&amp;eacute;e dans &lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9"&gt;le parcours d&amp;eacute;couverte&lt;/a&gt; sur le site des TechDays.&lt;/p&gt;
&lt;h2&gt;HTML5&lt;/h2&gt;
&lt;h3&gt;Parcours Web&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=3590a981-19ec-4950-a5e3-2afd2f69e20c"&gt;&lt;strong&gt;Introduction &amp;agrave; JavaScript&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://braincracking.org/"&gt;&lt;strong&gt;Jean-Pierre Vincent&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et &lt;/strong&gt;&lt;a href="http://blogs.msdn.com/pierlag"&gt;&lt;strong&gt;Pierre Lagarde&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si vous &amp;ecirc;tes d&amp;rsquo;origine C#, VB.NET, C++, Java ou PHP et que vous souhaitez vous mettre au JavaScript pour de bonnes raisons, voici une excellente session &amp;agrave; suivre que j&amp;rsquo;ai programm&amp;eacute; le 1er cr&amp;eacute;neau du 1er jour. N&amp;rsquo;oubliez pas en effet que derri&amp;egrave;re HTML5, il y a toujours du JavaScript qui tourne ! Mieux vaut donc savoir comment il fonctionne et &amp;eacute;viter de partir sur de mauvais aprioris. Quoi de mieux que des experts tel que Jean-Pierre et Pierre pour cela ? (et non vous n&amp;rsquo;&amp;ecirc;tes pas oblig&amp;eacute; d&amp;rsquo;avoir Pierre dans votre pr&amp;eacute;nom pour faire du JS).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=33b591de-c3c4-4c20-80fa-a23150f14a7a"&gt;&lt;strong&gt;Les nouveaut&amp;eacute;s HTML5 et CSS3 dans Internet Explorer 10&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par moi-m&amp;ecirc;me&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;IE10 a d&amp;eacute;sormais autant de trucs cools que les petits copains comme CSS3 &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/24/fr-introduction-224-css3-transitions.aspx"&gt;Transitions&lt;/a&gt;/&lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-aux-animations-css3.aspx"&gt;Animations&lt;/a&gt; ou IndexedDB et l&amp;rsquo;offline voir m&amp;ecirc;me des trucs en plus comme CSS3 Grid bien pratiques. Je passerais en revue toutes les nouveaut&amp;eacute;s importantes qui vont nous permettre d&amp;rsquo;envisager la construction d&amp;rsquo;applications de plus en plus riches en JavaScript/HTML5.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=0722f37b-1e49-49b7-9d51-fbbc3e8604af"&gt;&lt;strong&gt;D&amp;eacute;veloppement Web pour Mobiles&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://www.wygwam.com/"&gt;&lt;strong&gt;Aur&amp;eacute;lien Verla&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Une session anim&amp;eacute;e par l&amp;rsquo;excellent Aur&amp;eacute;lien qui sera &amp;agrave; cheval entre le d&amp;eacute;veloppement c&amp;ocirc;t&amp;eacute; serveur et c&amp;ocirc;t&amp;eacute; client qui vous montra comme tirer partie d&amp;rsquo;ASP.NET MVC c&amp;ocirc;t&amp;eacute; serveur et d&amp;rsquo;HTML5 et de jQuery Mobile c&amp;ocirc;t&amp;eacute; client pour cr&amp;eacute;er des exp&amp;eacute;riences web mobiles.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=deec50f3-4d86-4170-910e-eebf93e54481"&gt;&lt;strong&gt;Patterns et bonnes pratiques autour de JavaScript&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://braincracking.org/"&gt;&lt;strong&gt;Jean-Pierre Vincent&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ici que je veux que Jean-Pierre vous montre que l&amp;rsquo;on peut bien architecturer son code JavaScript en suivant les bon patterns (module, namespace, etc.) voir m&amp;ecirc;me que l&amp;rsquo;on peut tester unitairement son code ! Bref, les bases indispensables &amp;agrave; avoir pour travailler sur des projets s&amp;eacute;rieux o&amp;ugrave; une &amp;eacute;quipe doit d&amp;eacute;livrer de la qualit&amp;eacute;. Cela tombe bien, Jean-Pierre a justement travaill&amp;eacute; dans ce domaine ! C&amp;rsquo;est &amp;eacute;galement le co-auteur du &lt;a href="http://livre-html5.com"&gt;livre HTML5 : De la page web &amp;agrave; l'application web&lt;/a&gt;. C&amp;rsquo;est donc une session &amp;agrave; suivre derri&amp;egrave;re la session d&amp;rsquo;introduction si vous en avez besoin.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=2ce877b0-f4e0-4173-a2f0-dc553788348d"&gt;&lt;strong&gt;Cr&amp;eacute;ation d'une application HTML5 g&amp;eacute;rant l'offline et le stockage client&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://blogs.msdn.com/eternalcoding"&gt;&lt;strong&gt;David Catuhe&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et moi-m&amp;ecirc;me&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Avec David (l&amp;rsquo;autre), nous souhaitons vous pr&amp;eacute;senter les nouveaut&amp;eacute;s int&amp;eacute;ressantes autour &amp;ldquo;d&amp;rsquo;HTML5&amp;rdquo; pour construire des applications pouvant fonctionner hors connexion (Offline). Nous allons en profiter ainsi pour les d&amp;eacute;montrer &amp;agrave; travers une belle application que nous r&amp;eacute;utiliserons &amp;eacute;galement dans une autre session. Au programme : IndexedDB, Offline APIs, Drag&amp;rsquo;n&amp;rsquo;drop, File APIs, etc. Vous verrez ainsi que lorsque l&amp;rsquo;on utilise les tous derniers standards, on peut vraiment faire de belles choses !&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=5516b79d-804c-487d-b61e-247dd60c3a91"&gt;&lt;strong&gt;Trois avanc&amp;eacute;es majeures en CSS3 : Media Queries, Grid Layout et Animations&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="https://twitter.com/#!/goetter"&gt;&lt;strong&gt;Raphael Goetter&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le Monsieur CSS3 d&amp;rsquo;&lt;a href="http://www.alsacreations.fr"&gt;Alsacr&amp;eacute;ations&lt;/a&gt; auteur du livre &lt;a title="http://www.goetter.fr/livres/css-avancees/" href="http://www.goetter.fr/livres/css-avancees/"&gt;CSS avanc&amp;eacute;es vers HTML5 et CSS3&lt;/a&gt; nous fait le plaisir de venir animer une session autour de 3 avanc&amp;eacute;es majeures dans ce domaine. Je vous conseille donc vivement cette session anim&amp;eacute;e par l&amp;rsquo;une des r&amp;eacute;f&amp;eacute;rences fran&amp;ccedil;aises sur CSS !&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=8d778efa-6481-4190-94dc-5ba271807425"&gt;&lt;strong&gt;D&amp;eacute;veloppement de jeux 2D avec HTML5&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://pierreloicdoulcet.fr/"&gt;&lt;strong&gt;Pierre-Loic Doulcet&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rencontr&amp;eacute; lors du &lt;a href="http://parisjs.org"&gt;ParisJS&lt;/a&gt; h&amp;eacute;berg&amp;eacute; par Microsoft France, Pierre-Loic partage le m&amp;ecirc;me genre de passion que moi. Il s&amp;rsquo;occupera de vous faire r&amp;ecirc;ver avec le d&amp;eacute;veloppement de jeux 2D mobile et web gr&amp;acirc;ce &amp;agrave; HTML5.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=5c43ba8c-badd-43a1-b110-e266ece26ebe"&gt;&lt;strong&gt;Cr&amp;eacute;ation d'une application HTML5 utilisant Canvas, SVG et les animations CSS3&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://blogs.msdn.com/eternalcoding"&gt;&lt;strong&gt;David Catuhe&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et moi-m&amp;ecirc;me&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ici nous allons reprendre l&amp;rsquo;application g&amp;eacute;rant l&amp;rsquo;offline et mettre l&amp;rsquo;accent sur la partie &amp;ldquo;graphique&amp;rdquo; de l&amp;rsquo;application. Nous reverrons rapidement les bases et les diff&amp;eacute;rences entre canvas et SVG puis nous verrons comment nous les avons utilis&amp;eacute;s dans notre application d&amp;rsquo;exemple. Nous verrons &amp;eacute;galement l&amp;rsquo;utilisation des nouveaut&amp;eacute;s de CSS3 pour animer nos &amp;eacute;l&amp;eacute;ments. C&amp;rsquo;est donc une session compl&amp;eacute;mentaire de la pr&amp;eacute;c&amp;eacute;dente.&lt;/p&gt;
&lt;h3&gt;Autres parcours&lt;/h3&gt;
&lt;p&gt;Pour finir sur HTML5, voici 2 autres sessions que je vous recommande issues d&amp;rsquo;autres parcours :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=304845f3-9d01-4599-82e5-179330132b66"&gt;&lt;strong&gt;Accessibilit&amp;eacute; du Web 2.0 : HTML5 et WAI-ARIA&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://twitter.com/goetsu"&gt;&lt;strong&gt;Aur&amp;eacute;lien Levy&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et &lt;/strong&gt;&lt;a href="http://twitter.com/#!/tibolan"&gt;&lt;strong&gt;Thibault Lanssade&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;accessibilit&amp;eacute; est un sujet &amp;eacute;minemment important et HTML5 apportera quelques &amp;eacute;l&amp;eacute;ments de r&amp;eacute;ponses int&amp;eacute;ressants. Venez d&amp;eacute;couvrir ce sujet anim&amp;eacute; par 2 experts en la mati&amp;egrave;re.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=439299ba-f894-423e-a035-2f85d519fce9&amp;amp;SessionID=ee825bb4-91dc-4b47-b8e3-dea68d8bd9af"&gt;&lt;strong&gt;HTML5 sur mobile: le bon, la brute et un gros paquet de truands anim&amp;eacute;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; par &lt;/strong&gt;&lt;a href="http://blogs.msdn.com/pierreca"&gt;&lt;strong&gt;Pierre Cauchois&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;R&amp;eacute;put&amp;eacute; pour avoir les titres de sessions les plus cool des TechDays, Pierre a envie ici de faire un &amp;eacute;tat des lieux sur le d&amp;eacute;veloppement cross-plateformes en HTML5 et de faire sauter certaines croyances erron&amp;eacute;es sur la magie trop souvent associ&amp;eacute;e &amp;agrave; HTML5.&lt;/p&gt;
&lt;h2&gt;Du c&amp;ocirc;t&amp;eacute; du serveur Web&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=b04fa7a6-32fc-4b94-a21a-b0e48697d664&amp;amp;SessionID=a114a0fc-adce-4942-9288-64af58209d2a"&gt;&lt;strong&gt;D&amp;eacute;velopper le potentiel de IIS7.5 pour des sc&amp;eacute;narios de haute disponibilit&amp;eacute;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="https://twitter.com/#!/loic_calvy"&gt;&lt;strong&gt;Lo&amp;iuml;c Calvy&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et &lt;/strong&gt;&lt;a href="https://twitter.com/#!/paulcociuba"&gt;&lt;strong&gt;Paul Cociuba&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Revenons aux bases! Venez d&amp;eacute;couvrir comment tirer au mieux partie d&amp;rsquo;IIS dans plusieurs sc&amp;eacute;narios de haute disponibilit&amp;eacute;. Lo&amp;iuml;c dispose d&amp;rsquo;une exp&amp;eacute;rience et d&amp;rsquo;un recul tr&amp;egrave;s int&amp;eacute;ressant sur de la mise en production sur ce sujet et Paul nous vient de nos &amp;eacute;quipes de support europ&amp;eacute;en en tant qu&amp;rsquo;ing&amp;eacute;nieur d&amp;rsquo;escalade sur IIS. Bref, &amp;agrave; eux 2, vous devriez forc&amp;eacute;ment apprendre plein de choses int&amp;eacute;ressantes!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=b04fa7a6-32fc-4b94-a21a-b0e48697d664&amp;amp;SessionID=6e6f95a3-9430-4c45-8818-f74c6d9a1b9f"&gt;&lt;strong&gt;Quoi de neuf dans ASP.NET 4.5&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://blogs.codes-sources.com/tja/default.aspx"&gt;&lt;strong&gt;Thomas Jaskula&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thomas aura pour mission ici de vous faire d&amp;eacute;couvrir l&amp;rsquo;ensemble des nouveaut&amp;eacute;s de la plateforme ASP.NET 4.5, du c&amp;oelig;ur en passant par WebForms et MVC. Bref, une session assur&amp;eacute;ment &amp;agrave; ne pas louper pour suivre les derni&amp;egrave;res &amp;eacute;volutions de la brique ASP.NET du framework .NET.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=b04fa7a6-32fc-4b94-a21a-b0e48697d664&amp;amp;SessionID=cfeebe6c-a5bf-4cff-9f9c-133d30501bd3"&gt;&lt;strong&gt;Architecture, bonnes pratiques et recettes pour la r&amp;eacute;ussite de vos projets avec ASP.NET MVC&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://www.rui.fr/"&gt;&lt;strong&gt;Rui Carvalho&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et &lt;/strong&gt;&lt;a href="http://www.juliencorioland.net/"&gt;&lt;strong&gt;Julien Corioland&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rui et Julien ont tous les 2 une v&amp;eacute;ritable expertise sur la mise en pratique d&amp;rsquo;ASP.NET MVC. Cette session vous permettra de profiter de leur exp&amp;eacute;rience pour b&amp;eacute;n&amp;eacute;ficier d&amp;rsquo;un cahier de recettes &amp;agrave; mettre en &amp;oelig;uvre dans vos futurs projets utilisant notre framework.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=b04fa7a6-32fc-4b94-a21a-b0e48697d664&amp;amp;SessionID=a9e96174-d1a2-4d80-9a8a-1b0d29b70877"&gt;&lt;strong&gt;WebMatrix 2 : le couteau suisse gratuit pour vos d&amp;eacute;veloppements Web&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://www.smartview.fr/"&gt;&lt;strong&gt;Gilles Pommier&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et &lt;/strong&gt;&lt;a href="http://blog.couzy.com/"&gt;&lt;strong&gt;Pierre Couzy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Une heure sympa pour d&amp;eacute;couvrir WebMatrix 2 et Razor en compagnie de Gilles et de mon coll&amp;egrave;gue Pierre qui vous monteront comment r&amp;eacute;aliser une application de bout en bout. Si vous ne connaissez pas WebMatrix, c&amp;rsquo;est un outil gratuit permettant soit d'&amp;eacute;diter des solutions toutes faites comme Drupal, Wordpress, DotNetNuke tr&amp;egrave;s facilement, soit de d&amp;eacute;velopper avec le langage Razor. Ca vaut vraiment le coup d&amp;rsquo;y jeter un &amp;oelig;il si vous ne connaissez pas d&amp;eacute;j&amp;agrave;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=b04fa7a6-32fc-4b94-a21a-b0e48697d664&amp;amp;SessionID=034efe48-5a21-4ce4-8ed8-c410662accd7"&gt;&lt;strong&gt;Introduction &amp;agrave; DotNetNuke&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="https://twitter.com/#!/6RiL_fr"&gt;&lt;strong&gt;Cyril Plassard&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cela fait justement parti des solutions d&amp;eacute;ployables par WebMatrix. Venez d&amp;eacute;couvrir ce CMS bas&amp;eacute; sur les technologies Microsoft et pr&amp;eacute;sent&amp;eacute; par un membre de sa communaut&amp;eacute;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=b04fa7a6-32fc-4b94-a21a-b0e48697d664&amp;amp;SessionID=16517a28-bddb-4f6b-aed4-3dcf17cb9372"&gt;&lt;strong&gt;PHP dans le monde Microsoft&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; anim&amp;eacute; par &lt;/strong&gt;&lt;a href="http://fr.viadeo.com/profile/00223og1tsxe86u0"&gt;&lt;strong&gt;Christophe Villeneuve&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; et &lt;/strong&gt;&lt;a href="http://blog.couzy.com/"&gt;&lt;strong&gt;Pierre Couzy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Microsoft s&amp;rsquo;est v&amp;eacute;ritablement int&amp;eacute;ress&amp;eacute; au monde PHP ces derni&amp;egrave;res ann&amp;eacute;es et ce n&amp;rsquo;est pas Pierre Couzy qui me dira le contraire ! &lt;img class="wlEmoticon wlEmoticon-winkingsmile" style="border-style: none;" alt="Clignement d'&amp;oelig;il" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5554.wlEmoticon_2D00_winkingsmile_5F00_471A7A57.png" /&gt; Venez justement voir un membre de l&amp;rsquo;AFUP et un employ&amp;eacute; de Microsoft vous partager comment les 2 univers ont travaill&amp;eacute; ensemble pour avancer dans le bon sens avec diff&amp;eacute;rentes illustrations comme Drupal, le driver PDO pour SQL Server, le support de SQL Azure, etc.&lt;/p&gt;
&lt;h2&gt;En r&amp;eacute;sum&amp;eacute;&amp;hellip;&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;esp&amp;egrave;re que ce petit programme sera &amp;agrave; la hauteur de votre soif technique et de ce que vous cherchez en ce moment comme type de sessions, que ce soit pour vos besoins de veilles technologies ou de choix d&amp;rsquo;architectures. Normalement, que vous soyez d&amp;eacute;veloppeurs web &amp;ldquo;front&amp;rdquo; ou &amp;ldquo;back&amp;rdquo;, il devrait y avoir de bonnes choses &amp;agrave; apprendre.&lt;/p&gt;
&lt;p&gt;Allez, bonne ann&amp;eacute;e 2012, bon Techdays 2012 et &amp;agrave; bient&amp;ocirc;t au palais des congr&amp;egrave;s !&lt;/p&gt;
&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10252484" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/ASPNET/">ASPNET</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/CSS3/">CSS3</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/TechDays2012/">TechDays2012</category></item><item><title>AMDEV JavaScript: vidéos, slides et exemples de code des 4 sessions</title><link>http://blogs.msdn.com/b/davrous/archive/2012/01/06/amdev-slides-et-exemples-de-code-de-notre-session-svg-et-canvas.aspx</link><pubDate>Fri, 06 Jan 2012 04:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10235917</guid><dc:creator>David Rousset</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10235917</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2012/01/06/amdev-slides-et-exemples-de-code-de-notre-session-svg-et-canvas.aspx#comments</comments><description>&lt;!-- Include the VideoJS Library --&gt;
&lt;script type="text/javascript" charset="utf-8" src="http://david.blob.core.windows.net/videos/video-js/video.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;// &lt;![CDATA[
    
	VideoJS.setupAllWhenReady();
  
// ]]&gt;&lt;/script&gt;
&lt;p&gt;&lt;link title="Video JS" rel="stylesheet" type="text/css" href="http://david.blob.core.windows.net/videos/video-js/video-js.css" media="screen" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5432.ADDJS_5F00_444675E0.png"&gt;&lt;img style="background-image: none; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; padding-top: 0px; border-width: 0px;" title="ADDJS" border="0" alt="ADDJS" align="left" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3858.ADDJS_5F00_thumb_5F00_32A66548.png" width="150" height="150" /&gt;&lt;/a&gt;Vous &amp;eacute;tiez un peu plus de &lt;strong&gt;200&lt;/strong&gt; &amp;agrave; &amp;ecirc;tre venus &amp;agrave; notre centre de conf&amp;eacute;rence retirer votre T-Shirt et surtout pour assister &amp;agrave; l&amp;rsquo;apr&amp;egrave;s-midi du d&amp;eacute;veloppement consacr&amp;eacute;e &amp;agrave; JavaScript et HTML5. Merci &amp;agrave; vous !&lt;/p&gt;
&lt;p&gt;Je tiens tout d&amp;rsquo;abord &amp;agrave; remercier chaleureusement les 2 orateurs non-Microsoft pour la qualit&amp;eacute; de leur pr&amp;eacute;sentation : &lt;a href="https://twitter.com/theystolemynick"&gt;Jean-Pierre Vincent&lt;/a&gt; pour les fondamentaux de JavaScript et Aur&amp;eacute;lien Verla de &lt;a href="http://www.wygwam.com"&gt;Wygwam&lt;/a&gt; pour sa superbe session sur jQuery.&lt;/p&gt;
&lt;h2&gt;JavaScript&lt;/h2&gt;
&lt;p&gt;Vous pouvez retrouver les slides de Jean-Pierre ici : &lt;a title="http://www.slideshare.net/jpvincent/javascript-fondamentaux-et-oop" href="http://www.slideshare.net/jpvincent/javascript-fondamentaux-et-oop"&gt;les fondamentaux de JavaScript et la programmation orient&amp;eacute; objet&lt;/a&gt; . Vous pourrez donc revoir tout cela calmement &amp;agrave; la maison pour essayer de dig&amp;eacute;rer toutes les bonnes pratiques que Jean-Pierre nous a partag&amp;eacute;es. En compl&amp;eacute;ment, si le sujet vous int&amp;eacute;resse, je ne serais que trop vous conseiller ces 3 livres si vous ne les avez pas d&amp;eacute;j&amp;agrave; lus :&lt;/p&gt;
&lt;p&gt;- &lt;a href="http://www.amazon.fr/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&amp;amp;qid=1320954867&amp;amp;sr=8-1"&gt;JavaScript The Good Parts&lt;/a&gt; &lt;br /&gt;- &lt;a href="http://www.amazon.fr/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752/ref=sr_1_1?s=english-books&amp;amp;ie=UTF8&amp;amp;qid=1320954902&amp;amp;sr=1-1"&gt;JavaScript Patterns&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sans compter le livre de Jean-Pierre bien entendu : &lt;a title="http://www.amazon.fr/HTML5-page-web-%C3%A0-lapplication/dp/2100565281/ref=sr_1_cc_2?s=english-books&amp;amp;ie=UTF8&amp;amp;qid=1320954928&amp;amp;sr=1-2-catcorr" href="http://www.amazon.fr/HTML5-page-web-%C3%A0-lapplication/dp/2100565281/ref=sr_1_cc_2?s=english-books&amp;amp;ie=UTF8&amp;amp;qid=1320954928&amp;amp;sr=1-2-catcorr"&gt;HTML5 - De la page web &amp;agrave; l'application web&lt;/a&gt; ! Avec tout &amp;ccedil;a, &amp;agrave; vous la maitrise des closures, prototypage, namespace, POO &amp;agrave; la sauce JavaScript, j&amp;rsquo;en passe et des meilleurs. J&amp;rsquo;esp&amp;egrave;re que les sceptiques seront alors convaincus que l&amp;rsquo;on peut organiser son code, faire du d&amp;eacute;veloppement s&amp;eacute;rieux et maintenable (et m&amp;ecirc;me testable!) avec JavaScript en &amp;eacute;vitant d&amp;rsquo;avoir 480 variables globales par exemple. &lt;img class="wlEmoticon wlEmoticon-smilewithtongueout" alt="Tire la langue" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8461.wlEmoticon_2D00_smilewithtongueout_5F00_50C9CEF4.png" /&gt;&lt;/p&gt;
&lt;p&gt;Voici la vid&amp;eacute;o de session :&lt;/p&gt;
&lt;div class="video-js-box"&gt;&lt;!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody --&gt;&lt;video id="FondamentauxJS" class="video-js" poster="http://david.blob.core.windows.net/videos/1_FondamentauxJavaScript.png" preload="preload" controls="controls" width="512" height="288"&gt;&lt;source type="video/mp4; codecs=&amp;quot;avc1.42E01E, mp4a.40.2&amp;quot;" src="http://david.blob.core.windows.net/videos/1_FondamentauxJavascript.mp4" /&gt;&lt;source type="video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;" src="http://david.blob.core.windows.net/videos/1_FondamentauxJavascript.webm" /&gt;&lt;!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. --&gt;&lt;object id="flash_fallback_1" class="vjs-flash-fallback" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="512" type="application/x-shockwave-flash" height="288"&gt;&lt;param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="flashvars" value="config={&amp;quot;playlist&amp;quot;:[&amp;quot;http://david.blob.core.windows.net/videos/1_FondamentauxJavaScript.png&amp;quot;, {&amp;quot;url&amp;quot;: &amp;quot;http://david.blob.core.windows.net/videos/1_FondamentauxJavascript.mp4&amp;quot;,&amp;quot;autoPlay&amp;quot;:false,&amp;quot;autoBuffering&amp;quot;:true}]}" /&gt;&lt;!-- Image Fallback. Typically the same as the poster image. --&gt; &lt;img title="No video playback capabilities." alt="Poster Image" src="http://david.blob.core.windows.net/videos/1_FondamentauxJavaScript.png" width="512" height="288" /&gt; &lt;/object&gt;&lt;/video&gt;&lt;!-- Download links provided for devices that can't play video in the browser. --&gt;
&lt;p class="vjs-no-video"&gt;&lt;strong&gt;Download Video:&lt;/strong&gt; &lt;a href="http://david.blob.core.windows.net/videos/1_FondamentauxJavascript.mp4"&gt;MP4&lt;/a&gt;, &lt;a href="http://david.blob.core.windows.net/videos/1_FondamentauxJavascript.webm"&gt;WebM&lt;/a&gt;, &lt;!-- Support VideoJS by keeping this link. --&gt;&lt;a href="http://videojs.com"&gt;HTML5 Video Player&lt;/a&gt; by VideoJS&lt;/p&gt;
&lt;p class="vjs-no-video"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;Outils de debug&lt;/h2&gt;
&lt;div class="video-js-box"&gt;&lt;!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody --&gt;&lt;video id="OutilsDebug" class="video-js" poster="http://david.blob.core.windows.net/videos/2_OutilsDeDebug.png" preload="preload" controls="controls" width="512" height="288"&gt;&lt;source type="video/mp4; codecs=&amp;quot;avc1.42E01E, mp4a.40.2&amp;quot;" src="http://david.blob.core.windows.net/videos/2_OutilsDeDebug.mp4" /&gt;&lt;source type="video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;" src="http://david.blob.core.windows.net/videos/2_OutilsDeDebug.webm" /&gt;&lt;!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. --&gt;&lt;object id="Object1" class="vjs-flash-fallback" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="512" type="application/x-shockwave-flash" height="288"&gt;&lt;param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="flashvars" value="config={&amp;quot;playlist&amp;quot;:[&amp;quot;http://david.blob.core.windows.net/videos/2_OutilsDeDebug.png&amp;quot;, {&amp;quot;url&amp;quot;: &amp;quot;http://david.blob.core.windows.net/videos/2_OutilsDeDebug.mp4&amp;quot;,&amp;quot;autoPlay&amp;quot;:false,&amp;quot;autoBuffering&amp;quot;:true}]}" /&gt;&lt;!-- Image Fallback. Typically the same as the poster image. --&gt; &lt;img title="No video playback capabilities." alt="Poster Image" src="http://david.blob.core.windows.net/videos/2_OutilsDeDebug.png" width="512" height="288" /&gt; &lt;/object&gt;&lt;/video&gt;&lt;!-- Download links provided for devices that can't play video in the browser. --&gt;
&lt;p class="vjs-no-video"&gt;&lt;strong&gt;Download Video:&lt;/strong&gt; &lt;a href="http://david.blob.core.windows.net/videos/2_OutilsDeDebug.mp4"&gt;MP4&lt;/a&gt;, &lt;a href="http://david.blob.core.windows.net/videos/2_OutilsDeDebug.webm"&gt;WebM&lt;/a&gt;, &lt;!-- Support VideoJS by keeping this link. --&gt;&lt;a href="http://videojs.com"&gt;HTML5 Video Player&lt;/a&gt; by VideoJS&lt;/p&gt;
&lt;p class="vjs-no-video"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;jQuery&lt;/h2&gt;
&lt;div class="video-js-box"&gt;&lt;!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody --&gt;&lt;video id="IntroductionjQuery" class="video-js" poster="http://david.blob.core.windows.net/videos/3_IntroductionjQuery.png" preload="preload" controls="controls" width="512" height="288"&gt;&lt;source type="video/mp4; codecs=&amp;quot;avc1.42E01E, mp4a.40.2&amp;quot;" src="http://david.blob.core.windows.net/videos/3_IntroductionjQuery.mp4" /&gt;&lt;source type="video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;" src="http://david.blob.core.windows.net/videos/3_IntroductionjQuery.webm" /&gt;&lt;!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. --&gt;&lt;object id="Object2" class="vjs-flash-fallback" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="512" type="application/x-shockwave-flash" height="288"&gt;&lt;param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="flashvars" value="config={&amp;quot;playlist&amp;quot;:[&amp;quot;http://david.blob.core.windows.net/videos/3_IntroductionjQuery.png&amp;quot;, {&amp;quot;url&amp;quot;: &amp;quot;http://david.blob.core.windows.net/videos/3_IntroductionjQuery.mp4&amp;quot;,&amp;quot;autoPlay&amp;quot;:false,&amp;quot;autoBuffering&amp;quot;:true}]}" /&gt;&lt;!-- Image Fallback. Typically the same as the poster image. --&gt; &lt;img title="No video playback capabilities." alt="Poster Image" src="http://david.blob.core.windows.net/videos/3_IntroductionjQuery.png" width="512" height="288" /&gt; &lt;/object&gt;&lt;/video&gt;&lt;!-- Download links provided for devices that can't play video in the browser. --&gt;
&lt;p class="vjs-no-video"&gt;&lt;strong&gt;Download Video:&lt;/strong&gt; &lt;a href="http://david.blob.core.windows.net/videos/3_IntroductionjQuery.mp4"&gt;MP4&lt;/a&gt;, &lt;a href="http://david.blob.core.windows.net/videos/3_IntroductionjQuery.webm"&gt;WebM&lt;/a&gt;, &lt;!-- Support VideoJS by keeping this link. --&gt;&lt;a href="http://videojs.com"&gt;HTML5 Video Player&lt;/a&gt; by VideoJS&lt;/p&gt;
&lt;p class="vjs-no-video"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;C&amp;ocirc;t&amp;eacute; jQuery, je publierais les slides d&amp;rsquo;Aur&amp;eacute;lien d&amp;egrave;s que je les aurais en mettant &amp;agrave; jour ce post. Mais comme il a tout fait avec son plug-in jQuery, je vous zipperais sa solution plut&amp;ocirc;t.&lt;/p&gt;
&lt;h2&gt;Canvas &amp;amp; SVG&lt;/h2&gt;
&lt;p&gt;Les slides de notre session avec &lt;a href="http://blogs.msdn.com/eternalcoding"&gt;David Catuhe&lt;/a&gt; sur Canvas et SVG sont ici (PowerPoint en JavaScript ! &lt;img class="wlEmoticon wlEmoticon-openmouthedsmile" alt="Rire" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5342.wlEmoticon_2D00_openmouthedsmile_5F00_5B6C387F.png" /&gt;) :&lt;/p&gt;
&lt;p&gt;&lt;iframe height="327" src="http://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SDEE4BD0F5EA745C6!2017&amp;amp;p4=&amp;amp;kip=1" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Je les ai mis aussi sur SlideShare : &lt;a href="http://www.slideshare.net/davrous/amdev-graphismes-avec-html5-grce-canvas-et-svg"&gt;http://www.slideshare.net/davrous/amdev-graphismes-avec-html5-grce-canvas-et-svg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La vid&amp;eacute;o :&lt;/p&gt;
&lt;div class="video-js-box"&gt;&lt;!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody --&gt;&lt;video id="Video1" class="video-js" poster="http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.png" preload="preload" controls="controls" width="512" height="288"&gt;&lt;source type="video/mp4; codecs=&amp;quot;avc1.42E01E, mp4a.40.2&amp;quot;" src="http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.mp4" /&gt;&lt;source type="video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;" src="http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.webm" /&gt;&lt;!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. --&gt;&lt;object id="Object3" class="vjs-flash-fallback" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="512" type="application/x-shockwave-flash" height="288"&gt;&lt;param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="flashvars" value="config={&amp;quot;playlist&amp;quot;:[&amp;quot;http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.png&amp;quot;, {&amp;quot;url&amp;quot;: &amp;quot;http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.mp4&amp;quot;,&amp;quot;autoPlay&amp;quot;:false,&amp;quot;autoBuffering&amp;quot;:true}]}" /&gt;&lt;!-- Image Fallback. Typically the same as the poster image. --&gt; &lt;img title="No video playback capabilities." alt="Poster Image" src="http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.png" width="512" height="288" /&gt; &lt;/object&gt;&lt;/video&gt;&lt;!-- Download links provided for devices that can't play video in the browser. --&gt;
&lt;p class="vjs-no-video"&gt;&lt;strong&gt;Download Video:&lt;/strong&gt; &lt;a href="http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.mp4"&gt;MP4&lt;/a&gt;, &lt;a href="http://david.blob.core.windows.net/videos/4_Graphismes%20HTML5_CanvasSVG.webm"&gt;WebM&lt;/a&gt;, &lt;!-- Support VideoJS by keeping this link. --&gt;&lt;a href="http://videojs.com"&gt;HTML5 Video Player&lt;/a&gt; by VideoJS&lt;/p&gt;
&lt;p class="vjs-no-video"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Vous retrouverez quasiment tous les &lt;strong&gt;exemples de code des d&amp;eacute;mos d&amp;eacute;montr&amp;eacute;es&lt;/strong&gt; &amp;agrave; travers ces 4 articles ou s&amp;eacute;ries d&amp;rsquo;articles :&lt;/p&gt;
&lt;p&gt;- &lt;a href="http://blogs.msdn.com/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx"&gt;Introduction aux APIs graphiques d&amp;rsquo;HTML5: SVG &amp;amp; Canvas&lt;/a&gt; (2 articles) &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;HTML5 Platformer: portage complet du jeu XNA vers &amp;lt;canvas&amp;gt; gr&amp;acirc;ce &amp;agrave; EaselJS&lt;/a&gt; (3 articles) &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/eternalcoding/archive/2011/07/13/retours-sur-un-d-233-veloppement-html5-amp-javascript.aspx"&gt;Bolas Lenses : un d&amp;eacute;veloppement HTML5 Canvas &amp;amp; JavaScript&lt;/a&gt; &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/09/02/cahier-de-vacances-html-5-d-233-velopper-son-propre-jeu-de-casse-briques-en-html-5-avec-canvas-et-svg.aspx"&gt;D&amp;eacute;velopper un jeu de casse-briques avec Canvas et SVG&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C&amp;ocirc;t&amp;eacute; &lt;strong&gt;accessibilit&amp;eacute;&lt;/strong&gt;, si le sujet vous int&amp;eacute;resse, j&amp;rsquo;avais &amp;eacute;t&amp;eacute; un peu plus loin que ce que je vous ai montr&amp;eacute; cette apr&amp;egrave;s-midi dans cet article : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/02/21/slides-et-ressources-de-la-session-accessibilit-233-d-html5-et-silverlight-des-techdays-2011.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/02/21/slides-et-ressources-de-la-session-accessibilit-233-d-html5-et-silverlight-des-techdays-2011.aspx"&gt;Techdays 2011 &amp;ndash; slides et ressources de la session Accessibilit&amp;eacute; d&amp;rsquo;HTML5 et Silverlight&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Je finirais par remercier mon acolyte Monsieur Catuhe avec lequel je me suis bien marr&amp;eacute;. Nous avons essay&amp;eacute; de partager notre bonne humeur naturelle et notre humour pourrie de g33k/d&amp;eacute;veloppeur.&lt;/p&gt;
&lt;p&gt;A bient&amp;ocirc;t pour de nouvelles aventures !&lt;/p&gt;
&lt;p&gt;David&amp;sup2;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10235917" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Canvas/">Canvas</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/SVG/">SVG</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/JavaScript/">JavaScript</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/AMDEV/">AMDEV</category></item><item><title>Tutorial: how to create HTML5 applications on Windows Phone thanks to PhoneGap</title><link>http://blogs.msdn.com/b/davrous/archive/2011/12/23/tutorial-how-to-create-html5-applications-on-windows-phone-thanks-to-phonegap.aspx</link><pubDate>Fri, 23 Dec 2011 17:00:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10250721</guid><dc:creator>David Rousset</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10250721</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/12/23/tutorial-how-to-create-html5-applications-on-windows-phone-thanks-to-phonegap.aspx#comments</comments><description>&lt;p&gt;We will first see in this article what the added values of PhoneGap for HTML5 applications are. We’ll then discover how to create our very first project where we will retrieve the accelerometer’s values from our JavaScript code. At last, we will review a complete HTML5 gaming sample almost ported as-is to PhoneGap to use the accelerometer available on the Windows Phones.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#phonegap"&gt;PhoneGap: a framework filling the gap&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#firstproject"&gt;Let’s create our first PhoneGap project&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#accelero"&gt;Getting the accelerometer’s values from JavaScript&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#html5platformer"&gt;Review of a complete sample with the HTML5 Platformer game&lt;/a&gt;       &lt;ol&gt;       &lt;li&gt;Forcing the landscape orientation &lt;/li&gt;        &lt;li&gt;Handling various resolutions &lt;/li&gt;        &lt;li&gt;Loading the levels with calls to the file system instead of using XHR &lt;/li&gt;        &lt;li&gt;Modification of the gameplay to use the accelerometer &lt;/li&gt;        &lt;li&gt;Screenshots of the result and FPS on some phones &lt;/li&gt;        &lt;li&gt;Complete Visual Studio Solution to download &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt; &lt;a name="introduction"&gt;   &lt;h2&gt;Introduction&lt;/h2&gt; &lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1651.image_5F00_679E8583.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 10px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1541.image_5F00_thumb_5F00_05306083.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The Mango update for Windows Phone came with the &lt;strong&gt;support of HTML5 thanks to the embedded IE9 browser&lt;/strong&gt;. As the desktop version, the mobile version of IE9 delivers hardware acceleration through the GPU of your Windows Phone. Thus, combined with JavaScript, IE9 can now serve as a base of interesting user’s experiences usually reserved to “native code”. &lt;/p&gt;  &lt;p&gt;The Pros of using HTML5 as a development platform is a relative promise to easily re-use parts of the code on others compatibles platforms like Android or iOS. HTML5 has then driven a lot of interests from the mobiles developers’ ecosystem during the last months. &lt;/p&gt;  &lt;p&gt;However, even if the HTML5/CSS3/SVG &amp;amp; JavaScript specifications have greatly evolved during the last months, they still &lt;strong&gt;lack some major features to build mobile applications&lt;/strong&gt;. Indeed, a phone or a tablet exposes specific capabilities like: GPS, accelerometer, camera, sending SMS, accessing contacts, etc.&lt;/p&gt;  &lt;p&gt;To have access to these capabilities from the JavaScript code, the W3C has been working now for a while on what we call “&lt;a href="http://www.w3.org/2009/dap/"&gt;Device APIs&lt;/a&gt;” or &lt;strong&gt;DAP&lt;/strong&gt;. Unfortunately, we can consider that no implementation currently exists of those specifications as this document seems to confirm: &lt;a title="http://www.w3.org/2011/11/mobile-web-app-state.html" href="http://www.w3.org/2011/11/mobile-web-app-state.html"&gt;Standards for Web Applications on Mobile: November 2011 current state and roadmap&lt;/a&gt; . Mozilla has started an interesting work by more or less forking those specifications via what they call &lt;a href="http://hacks.mozilla.org/2011/08/introducing-webapi/"&gt;Web APIs&lt;/a&gt; to support their &lt;a href="http://hacks.mozilla.org/2011/07/announcing-boot-to-gecko-b2g-booting-to-the-web/"&gt;Boot To Gecko&lt;/a&gt; project. This is then a good news as a form of implementation seems to start with an on-going discussions with the W3C. However, even if things start to move slowly, we will probably have to wait for several years before having a stable official W3C specification implemented widely on all platforms.&lt;/p&gt;  &lt;p&gt;So the question is: what should we do in the meantime? Can HTML5 really address those scenarios?&lt;/p&gt; &lt;a name="phonegap"&gt;   &lt;h2&gt;PhoneGap: a framework filling the gap&lt;/h2&gt; &lt;/a&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="right" src="http://phonegap.com/assets/artwork/Build-Diagram-2.png" width="300" height="225" /&gt;&lt;/p&gt;  &lt;p&gt;While waiting on real standardized specifications, we don’t have the choice: we need to create some &lt;strong&gt;bridges between JavaScript and the native code&lt;/strong&gt; of the targeted platform to have access to its capabilities. The idea is then the following one: taking the native languages of each platform (C#, Objective-C and Java) and creating a framework with these languages that will expose interfaces to the JavaScript developer.&lt;/p&gt;  &lt;p&gt;This is exactly what &lt;a href="http://phonegap.com/"&gt;PhoneGap&lt;/a&gt; is doing. Let’s take the Windows Phone case which is the main topic of this article. A Windows Phone’s PhoneGap project is simply a Silverlight application hosting the WebBrowser control (and thus IE9) as well as a Silverlight Assembly written in C# which does the job to access to the accelerometer, GPS, contacts, camera and so on. In this way, as a JavaScript developer, you will use a DLL named &lt;strong&gt;WP7GapClassLib.dll&lt;/strong&gt; (the PhoneGap core runtime) without even knowing it via the usage of the code embedded in the &lt;strong&gt;phonegap-1.3.0.js &lt;/strong&gt;file. This DLL contains some C# code which does calls to the Silverlight runtime available on the phone. As the runtime has access to all the capabilities of the phone, the JavaScript will do also. The JavaScript library will then act as a gateway between both worlds. Moreover, the good point of using this library is that your code will most of the time works as-is on the PhoneGap versions of Android or iOS. PhoneGap offers then an interesting form of portability.&lt;/p&gt;  &lt;p&gt;Please note by the way that the PhoneGap support for Windows Phone is now totally complete since the recent 1.3.0 version:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-46/1362.PhoneGap.jpg"&gt;&lt;img border="0" alt="" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-46/1362.PhoneGap.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;At last, PhoneGap offers also another interesting service. It embeds your .js, .css, .html, .png resources inside its projects to package it as a classical application. In summary, you can use PhoneGap to package your HTML5 application for the various applications' stores. This is for instance the case of the &lt;a href="http://www.windowsphone.com/en-US/apps/09dc9317-0f63-4a98-9042-47c7976b2d88"&gt;SujiQ Windows Phone application&lt;/a&gt; built using this approach. &lt;/p&gt; &lt;a name="firstproject"&gt;   &lt;h2&gt;Let’s create our first PhoneGap project&lt;/h2&gt; &lt;/a&gt;  &lt;h3&gt;Prerequisites&lt;/h3&gt;  &lt;p&gt;Here are the very first steps you need to follow:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Download the Windows Phone SDK: &lt;a href="http://aka.ms/hp-windows-phone"&gt;Windows Phone SDK&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Download the last version of Phone (1.3.0 today) on their site: &lt;a title="http://phonegap.com/" href="http://phonegap.com/"&gt;http://phonegap.com/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Unzip the downloaded file&amp;#160; &lt;/li&gt;    &lt;li&gt;Copy the &lt;strong&gt;PhoneGapStarter.zip &lt;/strong&gt;and&lt;strong&gt; PhoneGapCustom.zip&lt;/strong&gt; files into &lt;font color="#008000"&gt;&lt;strong&gt;\Documents\Visual Studio 2010\Templates\ProjectTemplates&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;File-&amp;gt;New project&lt;/h3&gt;  &lt;p&gt;Once the previous steps are done, you will be able to create your first PhoneGap project. Start Visual Studio 2010, select the “Visual C#” templates and filter them via the “Gap” keyword. You should then see a new type of project named &lt;strong&gt;PhoneGapStarter&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6330.image_5F00_7EB46BEA.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5353.image_5F00_thumb_5F00_59E308D9.png" width="640" height="452" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Name your project “&lt;em&gt;MyFirstPhoneGapProject&lt;/em&gt;”. Once done, you will find the files I was talking about before in the Solution Explorer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5661.image_5F00_21D0EF29.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6242.image_5F00_thumb_5F00_57F26778.png" width="200" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You just now have to insert your HTML5 application into the “www” directory.&lt;/p&gt;  &lt;p&gt;Here are several tips I’d like to share with you about this default project template:&lt;/p&gt;  &lt;p&gt;- &lt;strong&gt;never ever touch the&lt;/strong&gt;&amp;#160;&lt;strong&gt;&lt;em&gt;phonegap-1.3.0.js &lt;/em&gt;file&lt;/strong&gt; if you’d like to keep a portable code on other versions of PhoneGap     &lt;br /&gt;- all files you will add inside the “www” directory must be set as “&lt;strong&gt;Content&lt;/strong&gt;” in the properties window&amp;#160; &lt;br /&gt;- instead of the &lt;em&gt;WP7GapClassLib.dll&lt;/em&gt; binary file, you can add a reference to the &lt;em&gt;WP7GapClassLib.csproj&lt;/em&gt; C# project available in the “&lt;em&gt;Windows Phone\framework&lt;/em&gt;” directory of the downloaded PhoneGap archive. It will help you debugging or discovering the native code of the PhoneGap library if needed.&lt;/p&gt;  &lt;p&gt;Ok, let’s now start by doing something normally impossible by default with IE9 Mango: accessing to the accelerometer’s values from JavaScript.&lt;/p&gt; &lt;a name="accelero"&gt;   &lt;h2&gt;Getting the accelerometer’s values from JavaScript&lt;/h2&gt; &lt;/a&gt;  &lt;p&gt;We’re going to see here how to get the values sent back by the accelerometer (of the emulator or the real device) in a very simple way.&lt;/p&gt;  &lt;p&gt;Open the “&lt;strong&gt;&lt;em&gt;index.html&lt;/em&gt;&lt;/strong&gt;” page and change its default body by this one:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Accelerometer sample&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;valueX&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;valueY&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;valueZ&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We will simply use 3 &amp;lt;div&amp;gt; tags to display the current X, Y &amp;amp; Z values of the accelerometer. &lt;/p&gt;

&lt;p&gt;Next step is to change the last default &amp;lt;script&amp;gt; block by this one:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
    &lt;/span&gt;document.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;deviceready&amp;quot;&lt;/span&gt;, onDeviceReady, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// variable to output the current x, y &amp;amp; z values of the accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;valueX;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;valueY;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;valueZ;

    &lt;span style="color: #006400"&gt;// when PhoneGap tells us everything is ready, start watching the accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onDeviceReady() {
        valueX = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;valueX&amp;quot;&lt;/span&gt;);
        valueY = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;valueY&amp;quot;&lt;/span&gt;);
        valueZ = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;valueZ&amp;quot;&lt;/span&gt;);
        startWatch();
    }

    &lt;span style="color: #006400"&gt;// start monitoring the state of the accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;startWatch() {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;options = { frequency: 500 };
        navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
    }

    &lt;span style="color: #006400"&gt;// if the z-axis has moved outside of our sensitivity threshold, move the aarvark's head in the appropriate direction
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onSuccess(acceleration) {
        valueX.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;X: &amp;quot; &lt;/span&gt;+ acceleration.x;
        valueY.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Y: &amp;quot; &lt;/span&gt;+ acceleration.y;
        valueZ.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Z: &amp;quot; &lt;/span&gt;+ acceleration.z;
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;onError() {
        alert(&lt;span style="color: maroon"&gt;'onError!'&lt;/span&gt;);
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Well the code is relatively self-explicit I think. The very first thing to note is that you need to wait for the “&lt;strong&gt;&lt;em&gt;deviceready&lt;/em&gt;&lt;/strong&gt;” event raised by PhoneGap to be sure to be in a stable state. You then need to subscribe to this event. In our case, we will be call-backed into the &lt;em&gt;OnDeviceReady() &lt;/em&gt;function. This function is getting the references to the 3 &amp;lt;div&amp;gt; tags and then asks to be notified by any changes done inside the accelerometer every 500ms with the &lt;em&gt;startWatch() &lt;/em&gt;function. The notifications will be sent to the &lt;em&gt;onSuccess() &lt;/em&gt;function that will have access to the &lt;em&gt;acceleration &lt;/em&gt;object containing the x, y &amp;amp; z values. You’ll find the complete documentation on the PhoneGap site: &lt;a title="http://docs.phonegap.com/en/1.2.0/phonegap_accelerometer_accelerometer.md.html#Accelerometer" href="http://docs.phonegap.com/en/1.2.0/phonegap_accelerometer_accelerometer.md.html#Accelerometer"&gt;PhoneGap Documentation - API Reference - Accelerometer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is all you need to do on the JavaScript side. However, to make it works, you need to specify in the project’s properties that &lt;strong&gt;you want to request access to the device’s sensor&lt;/strong&gt;. The capabilities needed for the proper execution of our application are listed inside the &lt;strong&gt;&lt;em&gt;WMAppManifest.xml&lt;/em&gt; &lt;/strong&gt;file available in the “&lt;em&gt;Properties&lt;/em&gt;” directory. By default, since 1.3.0, PhoneGap is listing the strict minimum capabilities: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capabilities&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_IDENTITY_DEVICE&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_IDENTITY_USER&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_LOCATION&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_NETWORKING&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_WEBBROWSERCOMPONENT&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capabilities&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;It’s then up to you to add the capabilities you need for your PhoneGap application. In our case, we need to add this line:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_SENSORS&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;To be allowed to access to the accelerometer. You’ll find the complete list of all available capabilities here:&amp;#160; &lt;a title="http://msdn.microsoft.com/en-us/library/ff769509(v=VS.92).aspx#BKMK_Capabilities" href="http://msdn.microsoft.com/en-us/library/ff769509(v=VS.92).aspx#BKMK_Capabilities"&gt;Application Manifest File for Windows Phone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, we’re logically ready to test that inside the emulator as a first phase. Press on the magical “F5” key and let’s have a look to the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3060.image_5F00_5BAEC277.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6746.image_5F00_thumb_5F00_0439B65A.png" width="640" height="386" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By moving the virtual phone in the emulator on the right, you should see the values of the accelerometer updated. Congratulations!&lt;/p&gt;

&lt;p&gt;You can &lt;strong&gt;download the complete source code of this first solution here&lt;/strong&gt;: &lt;a title="http://david.blob.core.windows.net/html5/MyFirstPhoneGapProject.zip" href="http://david.blob.core.windows.net/html5/MyFirstPhoneGapProject.zip"&gt;http://david.blob.core.windows.net/html5/MyFirstPhoneGapProject.zip&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Issues with phones using French locale&lt;/h3&gt;

&lt;p&gt;If you’re testing the very same code on your phone configured to use a French local (as mine for instance! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0020.wlEmoticon_2D00_winkingsmile_5F00_53225FA2.png" /&gt;), you will have the feeling that the application doesn’t work at all…which is indeed the case. I’ve then spent some time debugging the code and I’ve discovered that the following exception was raised inside &lt;em&gt;phonegap-1.3.0.js&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;font color="#800000"&gt;&amp;quot;Error in success callback: Accelerometer = Syntax error&amp;quot;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;After dumping the values, I’ve seen that the error was due to a tentative of de-serialization of the following bad formatted JSON string:&lt;/p&gt;

&lt;p&gt;&lt;font color="#800000"&gt;&lt;strong&gt;&amp;quot;{\&amp;quot;x\&amp;quot;:0,00472,\&amp;quot;y\&amp;quot;:-0,19879,\&amp;quot;z\&amp;quot;:-0,98115}&amp;quot;&lt;/strong&gt;&lt;/font&gt; whereas the proper EN-US is the following one: &lt;font color="#008000"&gt;&lt;strong&gt;&amp;quot;{\&amp;quot;x\&amp;quot;:0.00472,\&amp;quot;y\&amp;quot;:-0.19879,\&amp;quot;z\&amp;quot;:-0.98115}&amp;quot;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Yes, we’re using a coma in France as a numeric separator. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0020.wlEmoticon_2D00_winkingsmile_5F00_53225FA2.png" /&gt;&lt;/p&gt;

&lt;p&gt;2 solutions to solve this problem:&lt;/p&gt;

&lt;p&gt;1 – The lazy one: switch your phone into EN-US (I know, this is not a solution!) 
  &lt;br /&gt;2 – Fix the problem that comes from the C# code. For that, replace the following code from the &lt;em&gt;Accelometer.cs&lt;/em&gt; file of the &lt;em&gt;WP7GalClassLib&lt;/em&gt; library:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Formats current coordinates into JSON format
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Coordinates in JSON format&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;GetCurrentAccelerationFormatted()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;resultCoordinates = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;x\&amp;quot;:{0},\&amp;quot;y\&amp;quot;:{1},\&amp;quot;z\&amp;quot;:{2}&amp;quot;&lt;/span&gt;,
                    accelerometer.CurrentValue.Acceleration.X.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;),
                    accelerometer.CurrentValue.Acceleration.Y.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;),
                    accelerometer.CurrentValue.Acceleration.Z.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;));
    resultCoordinates = &lt;span style="color: #a31515"&gt;&amp;quot;{&amp;quot; &lt;/span&gt;+ resultCoordinates + &lt;span style="color: #a31515"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;resultCoordinates;
}&lt;/pre&gt;

&lt;p&gt;By this one:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;GetCurrentAccelerationFormatted()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;resultCoordinates = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;x\&amp;quot;:{0},\&amp;quot;y\&amp;quot;:{1},\&amp;quot;z\&amp;quot;:{2}&amp;quot;&lt;/span&gt;,
             accelerometer.CurrentValue.Acceleration.X.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture),
             accelerometer.CurrentValue.Acceleration.Y.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture),
             accelerometer.CurrentValue.Acceleration.Z.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture));
    resultCoordinates = &lt;span style="color: #a31515"&gt;&amp;quot;{&amp;quot; &lt;/span&gt;+ resultCoordinates + &lt;span style="color: #a31515"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;resultCoordinates;
}&lt;/pre&gt;

&lt;p&gt;And the sample will now work with all locales. I’ve filled a bug on this topic here: &lt;a title="https://issues.apache.org/jira/browse/CB-141" href="https://issues.apache.org/jira/browse/CB-141"&gt;https://issues.apache.org/jira/browse/CB-141&lt;/a&gt; suggesting the same solution that will normally be shipped with the next version (2.0.0).&lt;/p&gt;

&lt;p&gt;By the way, you’re maybe wondering how I’ve managed to debug the JavaScript part of my PhoneGap project? Well, you can simply use the wonderful &lt;strong&gt;jsConsole&lt;/strong&gt; project. If you want to know more about that, please read one of my colleague’s article: &lt;a title="http://bristowe.com/blog/2011/6/8/jsconsole-remote-debugging-in-ie9-on-windows-phone-mango.html" href="http://bristowe.com/blog/2011/6/8/jsconsole-remote-debugging-in-ie9-on-windows-phone-mango.html"&gt;jsConsole Remote Debugging in IE9 on Windows Phone Mango&lt;/a&gt;&lt;/p&gt;
&lt;a name="html5platformer"&gt;
  &lt;h2&gt;Review of a complete sample with the HTML5 Platformer game&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Let’s now review a more complex sample. My idea was to start from the game I’ve written before. It’s exposed in this article: &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx"&gt;HTML5 Platformer: the complete port of the XNA game to &amp;lt;canvas&amp;gt; with EaselJS&lt;/a&gt; . I wanted to see what I should do to make it works on the phone. &lt;/p&gt;

&lt;p&gt;First step is to simply copy/paste the different .js, .png, .css files into the “www” directory and to mark them as “&lt;strong&gt;Content&lt;/strong&gt;”. Here are the others steps to follow.&lt;/p&gt;

&lt;h3&gt;Forcing the landscape orientation&lt;/h3&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;p&gt;The game has to be played in landscape mode. I’ve then forced this orientation. I’ve also remove the information bar on the side (the System Tray). For that, you need to open the &lt;strong&gt;&lt;em&gt;MainPage.xaml&lt;/em&gt;&lt;/strong&gt; file and change these properties:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: red"&gt;SupportedOrientations&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Landscape&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Orientation&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Landscape&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;shell&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;SystemTray.IsVisible&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;False&amp;quot;
&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;Handling various resolutions&lt;/h3&gt;

&lt;p&gt;As my main goal was to build a game that could run on the highest number of devices, I need to handle a lot of different resolutions.&lt;/p&gt;

&lt;p&gt;For that, I’ve slightly modified the initial code of the Platformer you can download in the &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx"&gt;other article&lt;/a&gt;. The game is now capable on running at any resolution by applying a rescale ratio on the images and sprites to draw. Everything is being redrawn based on a specific ratio that came from the Windows Phone (800x480) which is the 100% ratio. You can test this version in your desktop browser here: &lt;a title="http://david.blob.core.windows.net/html5platformerscale/index.html" href="http://david.blob.core.windows.net/html5platformerscale/index.html"&gt;HTML5 Platformer ReScale&lt;/a&gt; and try to dynamically resize the browser window. Moreover, if your screen resolution has a 16/9 aspect ratio, press the F11 key to play in fullscreen! The experience in this mode is really cool as you can see in this screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://david.blob.core.windows.net/html5platformerscale/index.html"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5125.image_5F00_255E17C3.png" width="640" height="360" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re letting the browser taking care of the anti-aliasing during this scaling operation. Based on the browser you’ll use, you will notice also that the performance could vary a lot related to the size of the window you’ll have. On my machine, IE9/IE10 seems relatively indifferent to the fullscreen mode or small resolutions by maintaining a stable 60 fps framerate. &lt;/p&gt;

&lt;h3&gt;Loading the levels with calls to the file system instead of using XHR&lt;/h3&gt;

&lt;p&gt;In the initial code, the .TXT files linked to the each level were stored on the web server and downloaded via XmlHttpRequest calls. As we’re now running everything client-side in offline mode, XHR local calls are not very appropriated. I’ve then replaced the initial code of the &lt;em&gt;PlatformerGame.prototype.LoadNextLevel &lt;/em&gt;function by this one:&lt;/p&gt;

&lt;pre class="code"&gt;PlatformerGame.prototype.LoadNextLevel = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.levelIndex = (&lt;span style="color: blue"&gt;this&lt;/span&gt;.levelIndex + 1) % numberOfLevels;

    &lt;span style="color: #006400"&gt;// Searching where we are currently hosted
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;nextFileName = &lt;span style="color: maroon"&gt;&amp;quot;app/www/assets/levels/&amp;quot; &lt;/span&gt;+ &lt;span style="color: blue"&gt;this&lt;/span&gt;.levelIndex + &lt;span style="color: maroon"&gt;&amp;quot;.txt&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;try &lt;/span&gt;{
        &lt;span style="color: blue"&gt;var &lt;/span&gt;instance = &lt;span style="color: blue"&gt;this&lt;/span&gt;;
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);

        &lt;span style="color: blue"&gt;function &lt;/span&gt;gotFS(fileSystem) {
            fileSystem.root.getFile(nextFileName, &lt;span style="color: blue"&gt;null&lt;/span&gt;, gotFileEntry, fail);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;gotFileEntry(fileEntry) {
            fileEntry.file(gotFile, fail);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;gotFile(file) {
            readAsText(file);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;readAsText(file) {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;reader = &lt;span style="color: blue"&gt;new &lt;/span&gt;FileReader();
            reader.onloadend = &lt;span style="color: blue"&gt;function &lt;/span&gt;(evt) {
                instance.LoadThisTextLevel(evt.target.result.replace(/[\n\r\t]/g, &lt;span style="color: maroon"&gt;''&lt;/span&gt;));
            };
            reader.readAsText(file);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;fail(evt) {
            console.log(evt.target.error.code);
        }
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(e) {
        console.log(&lt;span style="color: maroon"&gt;&amp;quot;Error loading level: &amp;quot; &lt;/span&gt;+ e.message);
        &lt;span style="color: #006400"&gt;// Probably an access denied if you try to run from the file:// context
        // Loading the hard coded error level to have at least something to play with
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.LoadThisTextLevel(hardcodedErrorTextLevel);
    }
};&lt;/pre&gt;

&lt;p&gt;I’ve just re-used the code available in the PhoneGap documentation: &lt;a title="http://docs.phonegap.com/en/1.3.0/phonegap_file_file.md.html#FileReader" href="http://docs.phonegap.com/en/1.3.0/phonegap_file_file.md.html#FileReader"&gt;FileReader&lt;/a&gt; . As you can see, you have a full access to the Windows Phone file system from JavaScript with PhoneGap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Cool tip:&lt;/u&gt;&lt;/strong&gt; to help you debugging what’s really stored in the Isolated Storage of the phone or not, you should have a look to this awesome tool: &lt;a title="http://isostorespy.codeplex.com/" href="http://isostorespy.codeplex.com/"&gt;IsoStoreSpy&lt;/a&gt; written by Samuel Blanchard. &lt;/p&gt;

&lt;h3&gt;Modification of the gameplay to use the accelerometer&lt;/h3&gt;

&lt;p&gt;Well, last part is just to mix all parts of this article to obtain the final result. For that, I’ve added the following code into the constructor of the &lt;em&gt;Player&lt;/em&gt; object in the &lt;em&gt;Player.js&lt;/em&gt; file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;options = { frequency: 500 };
&lt;span style="color: blue"&gt;var &lt;/span&gt;that = &lt;span style="color: blue"&gt;this&lt;/span&gt;;

navigator.accelerometer.watchAcceleration(
    &lt;span style="color: blue"&gt;function &lt;/span&gt;(accelerometer) { that.moveDirectionAccel(accelerometer); },
    &lt;span style="color: blue"&gt;function &lt;/span&gt;() { console.log(&lt;span style="color: maroon"&gt;&amp;quot;Error with accelerometer&amp;quot;&lt;/span&gt;); }, 
    options);&lt;/pre&gt;

&lt;p&gt;Here is the function that will be call-backed during the accelerometer variations:&lt;/p&gt;

&lt;pre class="code"&gt;Player.prototype.moveDirectionAccel = &lt;span style="color: blue"&gt;function&lt;/span&gt;(acceleration) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;accelValue = -acceleration.y;

    &lt;span style="color: #006400"&gt;// Move the player with accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Math.abs(accelValue) &amp;gt; 0.15) {
        &lt;span style="color: #006400"&gt;// set our movement speed
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = Math.clamp(accelValue * &lt;span style="color: blue"&gt;this&lt;/span&gt;.AccelerometerScale, -1, 1);
    }
    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 0;
    }
};&lt;/pre&gt;

&lt;p&gt;I’ve also added an handler on the “&lt;em&gt;&lt;strong&gt;onmousedown&lt;/strong&gt;&lt;/em&gt;” event on the canvas to jump when the user tap on the screen.&lt;/p&gt;

&lt;h3&gt;Screenshots of the result and FPS on some phones&lt;/h3&gt;

&lt;p&gt;First, let’s review the result within the Windows Phone emulator:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0804.image_5F00_313B39E9.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7652.image_5F00_thumb_5F00_2F865A16.png" width="644" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a framerate varying from 54 to 60 fps on my machine. On a real device, the framerate differs logically between models. Let’s take the first game level. On the &lt;strong&gt;LG E900&lt;/strong&gt;, the framerate is around &lt;strong&gt;22 fps&lt;/strong&gt;. On the &lt;strong&gt;&lt;font color="#800080"&gt;HTC Radar&lt;/font&gt;&lt;/strong&gt;, it’s around &lt;font color="#800080"&gt;&lt;strong&gt;31 fps&lt;/strong&gt;&lt;/font&gt;&lt;font color="#000000"&gt;. On the &lt;strong&gt;&lt;font color="#004080"&gt;Nokia Lumia 800&lt;/font&gt;&lt;/strong&gt;, it’s around &lt;strong&gt;&lt;font color="#004080"&gt;42 fps&lt;/font&gt;&lt;/strong&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7824.DSCF4677_5F00_34684C2B.jpg"&gt;&lt;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="DSCF4677" border="0" alt="DSCF4677" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6648.DSCF4677_5F00_thumb_5F00_34F0B6BB.jpg" width="404" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The gameplay could then be not very convincing in most cases. Indeed, I’m using a fullscreen canvas to draw the whole game. This is not a very good idea for the mobile limited power CPU, even if the Nokia seems powerful enough to handle this approach. A better methodology could be to cut the screen stage into various little canvas that will then be moved by modifying the CSS properties on them. This is what has been done for the HTML5 version of Angry Birds for instance. Some JS gaming frameworks start to think about handling this complexity for you. The idea would then be to code the game once with high level APIs and the framework could switch between a full frame canvas or various little canvas moved via CSS based on the performance. &lt;/p&gt;

&lt;p&gt;Well, you’ll get it: the HTML5 gaming experience on mobile is currently just at its beginning. But its future looks very promising!&lt;/p&gt;

&lt;h3&gt;Complete Visual Studio Solution to download&lt;/h3&gt;

&lt;p&gt;You’ll find the &lt;strong&gt;complete source code of the HTML5 Platformer for PhoneGap here&lt;/strong&gt;: &lt;a title="http://david.blob.core.windows.net/html5/HTML5GapPlatformer.zip" href="http://david.blob.core.windows.net/html5/HTML5GapPlatformer.zip"&gt;HTML5GapPlatformer.zip&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Other useful resources &lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a title="http://blogs.technet.com/b/port25/archive/2011/12/19/full-support-for-phonegap-on-windows-phone-is-now-complete.aspx" href="http://blogs.technet.com/b/port25/archive/2011/12/19/full-support-for-phonegap-on-windows-phone-is-now-complete.aspx"&gt;Full Support for PhoneGap on Windows Phone is Now Complete!&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a title="http://blogs.msdn.com/b/glengordon/archive/2011/11/15/phonegap-on-windows-phone-tips.aspx" href="http://blogs.msdn.com/b/glengordon/archive/2011/11/15/phonegap-on-windows-phone-tips.aspx"&gt;PhoneGap on Windows Phone Tips&lt;/a&gt; from Glen Gardon who has written several very interesting tutorials to follow &lt;/li&gt;

  &lt;li&gt;Lot of good tutorials in the Wiki section of PhoneGap: &lt;a title="http://wiki.phonegap.com/w/page/35501397/Tutorials" href="http://wiki.phonegap.com/w/page/35501397/Tutorials"&gt;http://wiki.phonegap.com/w/page/35501397/Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;a name="conclusion"&gt;
  &lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;PhoneGap offers interesting perspectives to help you writing applications on the phone. It lets you using your existing skills in JavaScript, HTML and CSS. PhoneGap won’t necessary cover all the scenarios currently available with the native development stack (Silverlight or XNA). But this could be something to have a look to if you’d like to capitalize on the HTML skills of one of your team. You will have to pay attention to properly identify the kind of project to work on.&lt;/p&gt;

&lt;p&gt;You can also think about mixing both environments to create hybrid experiences: the main branch would be written using “HTML5” and some specific parts into native code. Using this idea, some plug-ins have been created to push a bit further the integration into the Metro UI: &lt;a title="https://github.com/purplecabbage/phonegap-plugins/tree/master/WindowsPhone" href="https://github.com/purplecabbage/phonegap-plugins/tree/master/WindowsPhone"&gt;PhoneGap Plug-ins for Windows Phone&lt;/a&gt; . You’ll find for instance one of them allowing a JavaScript code to update the Tiles.&lt;/p&gt;

&lt;p&gt;At last, PhoneGap and HTML5 could allow a relative portability to other platforms… with some limitations. But this is a vast subject with passionate debates that would need a complete dedicated article. &lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10250721" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Platformer/">Platformer</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/PhoneGap/">PhoneGap</category></item><item><title>Tutorial: créez des applications avec HTML5 sur Windows Phone grâce à PhoneGap</title><link>http://blogs.msdn.com/b/davrous/archive/2011/12/23/tutorial-cr-233-ez-des-applications-avec-html5-sur-windows-phone-gr-226-ce-224-phonegap.aspx</link><pubDate>Fri, 23 Dec 2011 13:45:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10250681</guid><dc:creator>David Rousset</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10250681</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/12/23/tutorial-cr-233-ez-des-applications-avec-html5-sur-windows-phone-gr-226-ce-224-phonegap.aspx#comments</comments><description>&lt;p&gt;Tout d’abord, nous allons naturellement commencer par voir l’intérêt d’utiliser PhoneGap pour HTML5. Ensuite, nous verrons comment créer son tout 1er projet et récupérer les valeurs de l’accéléromètre en JavaScript. Pour finir, nous allons voir un exemple complet où j’ai repris le code de mon jeu HTML5 Platformer pour le faire fonctionner presque tel quel avec l’accéléromètre d’un Windows Phone.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#phonegap"&gt;PhoneGap : un framework qui comble les manques&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#firstproject"&gt;Création de son 1er projet PhoneGap sur Windows Phone&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#accelero"&gt;Récupération des valeurs de l’accéléromètre&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#html5platformer"&gt;Exemple complet avec le jeu HTML5 Platformer&lt;/a&gt;       &lt;ol&gt;       &lt;li&gt;Forcer le mode paysage &lt;/li&gt;        &lt;li&gt;Adapter le code pour gérer plusieurs résolutions &lt;/li&gt;        &lt;li&gt;Chargement des niveaux via l’appel au système de fichiers plutôt que XHR &lt;/li&gt;        &lt;li&gt;Modification du gameplay pour gérer l’accéléromètre &lt;/li&gt;        &lt;li&gt;Le résultat en images avec quelques FPS sur les téléphones &lt;/li&gt;        &lt;li&gt;Solution complète à télécharger &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt; &lt;a name="introduction"&gt;   &lt;h2&gt;Introduction&lt;/h2&gt; &lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1651.image_5F00_679E8583.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 10px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1541.image_5F00_thumb_5F00_05306083.png" width="132" height="240" /&gt;&lt;/a&gt;La mise à jour Mango sur Windows Phone a apporté &lt;strong&gt;le support d’HTML5 via l’arrivée du navigateur IE9&lt;/strong&gt;. Tout comme sur la version bureau, la version mobile d’IE9 met en place l’accélération matérielle via l’utilisation du GPU embarqué sur votre Windows Phone. Ainsi, couplé à JavaScript, IE9 permet d’envisager la réalisation d’expériences utilisateurs intéressantes autre fois uniquement réservées aux applications dites “natives”. &lt;/p&gt;  &lt;p&gt;L’avantage d’utiliser HTML5 comme plateforme de développement est qu’elle permet une facilité “relative” dans la réutilisation d’une partie du code sur d’autres plateformes comme Android ou iOS. HTML5 suscite donc énormément d’intérêt de l’écosystème ces derniers temps pour les plateformes mobiles. Parfois malheureusement à tord mais j’y reviendrais surement dans un autre billet.&lt;/p&gt;  &lt;p&gt;Cependant, bien que les spécifications HTML5/CSS3/SVG et JavaScript aient nettement évoluées ces derniers mois, il existe des &lt;strong&gt;manques majeurs pour la réalisation d’applications mobiles&lt;/strong&gt;. En effet, un téléphone ou une tablette dispose de capacités spécifiques à leur mobilité : GPS, accéléromètre, caméra, SMS, accès aux contacts, etc. &lt;/p&gt;  &lt;p&gt;Pour accéder à ces spécificités matérielles depuis son code JavaScript, le W3C travaille depuis un moment sur ce que nous appelons les “&lt;a href="http://www.w3.org/2009/dap/"&gt;Device APIs&lt;/a&gt;” ou &lt;strong&gt;DAP&lt;/strong&gt;. Malheureusement, on peut considérer qu’il n’existe à l’heure actuelle aucune implémentation de ces spécifications sur le marché comme le confirme ce document : &lt;a title="http://www.w3.org/2011/11/mobile-web-app-state.html" href="http://www.w3.org/2011/11/mobile-web-app-state.html"&gt;Standards for Web Applications on Mobile: November 2011 current state and roadmap&lt;/a&gt; . Mozilla a commencé un travail intéressant sur une forme de fork de ces spécifications nommées &lt;a href="http://hacks.mozilla.org/2011/08/introducing-webapi/"&gt;Web APIs&lt;/a&gt; pour soutenir son projet &lt;a href="http://hacks.mozilla.org/2011/07/announcing-boot-to-gecko-b2g-booting-to-the-web/"&gt;Boot To Gecko&lt;/a&gt;. C’est donc une bonne nouvelle dans la mesure où une forme d’implémentation commence à voir le jour et un dialogue avec le W3C semble s’installer. Les choses commencent doucement à bouger mais il faudra probablement plusieurs années avant de voir une spécification du W3C implémentée et répandue sur toutes les plateformes. &lt;/p&gt;  &lt;p&gt;Alors comment faire en attendant ? HTML5 peut-il vraiment adresser ce scénario ?&lt;/p&gt; &lt;a name="phonegap"&gt;   &lt;h2&gt;PhoneGap : un framework qui comble les manques&lt;/h2&gt; &lt;/a&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="right" src="http://phonegap.com/assets/artwork/Build-Diagram-2.png" width="300" height="225" /&gt;&lt;/p&gt;  &lt;p&gt;En attendant l’arrivée de réelles spécifications standardisées, nous n’avons donc pas le choix : il faut créer &lt;strong&gt;un pont entre le code JavaScript et le code natif&lt;/strong&gt; de la plateforme visée pour accéder au matériel. L’idée est donc la suivante : on prend le langage natif de chacune des plateformes (Silverlight, Objective-C et Java) et on en créé un framework qui expose des interfaces pour le développeur JavaScript. &lt;/p&gt;  &lt;p&gt;C’est exactement ce que fait &lt;a href="http://phonegap.com/"&gt;PhoneGap&lt;/a&gt;. Prenons le cas de Windows Phone qui nous intéresse dans cet article. Un projet PhoneGap expose tout simplement une application Silverlight hébergeant le contrôle WebBrowser (et donc IE9) ainsi qu’une DLL écrite en C# s’occupant d’accéder à l’accéléromètre, au GPS, aux contacts, à la caméra, etc. Ainsi, comme on va le voir un peu plus tard, en tant que développeur JavaScript, vous allez donc utiliser indirectement une DLL nommée &lt;strong&gt;WP7GapClassLib.dll&lt;/strong&gt; (le coeur de PhoneGap) à travers le code exposé dans le fichier &lt;strong&gt;phonegap-1.3.0.js&lt;/strong&gt;. La DLL contient le code C# qui fait appel au runtime Silverlight présent sur le téléphone. Ce dernier peut accéder à l’accéléromètre et au reste du téléphone. La librairie JavaScript contenu dans le .js va faire office d’interface entre les 2 mondes. L’avantage de faire appel à cette librairie est que le code JavaScript que vous allez écrire pour accéder à la caméra du Windows Phone par exemple marchera tel quel sur PhoneGap pour Android ou iOS. PhoneGap offre donc une certaine forme de portabilité. &lt;/p&gt;  &lt;p&gt;Sachez d’ailleurs qu’à ce sujet, le support de PhoneGap pour Windows Phone est désormais aussi complet que sur Android ou iOS depuis la récente version 1.3 :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-46/1362.PhoneGap.jpg"&gt;&lt;img border="0" alt="" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-46/1362.PhoneGap.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pour finir, PhoneGap vous fournit également un autre service intéressant. Il vous permet d’inclure vos fichiers JS, CSS, HTML, PNG &amp;amp; co au sein de son projet pour packager l’ensemble comme une véritable application native. En résumé, vous pouvez donc tout à fait utiliser PhoneGap pour packager une application HTML5 que vous déploierez sur le Store. C’est le cas par exemple de &lt;a href="http://www.windowsphone.com/en-US/apps/09dc9317-0f63-4a98-9042-47c7976b2d88"&gt;l’application SujiQ&lt;/a&gt; qui a été conçue ainsi.&lt;/p&gt; &lt;a name="firstproject"&gt;   &lt;h2&gt;Création de son 1er projet PhoneGap sur Windows Phone&lt;/h2&gt; &lt;/a&gt;  &lt;h3&gt;Pré-requis&lt;/h3&gt;  &lt;p&gt;Voici les étapes à suivre avant toute chose :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Téléchargez le SDK Windows Phone si ce n’est déjà fait ici : &lt;a href="http://aka.ms/hp-windows-phone"&gt;Télécharger le SDK Windows Phone&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Téléchargez la dernière version (1.3 aujourd’hui) de PhoneGap sur leur site : &lt;a title="http://phonegap.com/" href="http://phonegap.com/"&gt;http://phonegap.com/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Décompressez l’archive téléchargée depuis le site de PhoneGap &lt;/li&gt;    &lt;li&gt;Copiez les fichiers &lt;strong&gt;PhoneGapStarter.zip &lt;/strong&gt;et&lt;strong&gt; PhoneGapCustom.zip&lt;/strong&gt; dans &lt;font color="#008000"&gt;&lt;strong&gt;\Documents\Visual Studio 2010\Templates\ProjectTemplates&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Nouveau projet&lt;/h3&gt;  &lt;p&gt;Une fois toutes ces étapes suivies correctement, nous allons pouvoir créer notre 1er projet PhoneGap. Pour cela, démarrez Visual Studio 2010, rendez-vous dans la partie “Visual C#”, filtrez sur le mot clé “Gap” et vous devriez voir un nouveau type de projet nommé &lt;strong&gt;PhoneGapStarter&lt;/strong&gt; :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0753.image_5F00_02DA64DA.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7041.image_5F00_thumb_5F00_3B45395A.png" width="640" height="452" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nommez le projet “&lt;em&gt;MonPremierProjetPhoneGap&lt;/em&gt;”. Une fois créé, vous allez retrouver les fichiers dont je vous parlais avant dans l’explorateur de solution :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6557.image_5F00_45A5C1E0.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8032.image_5F00_thumb_5F00_74A7FDB7.png" width="250" height="353" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vous n’avez donc plus qu’à insérer votre application HTML5 dans le répertoire “www”. &lt;/p&gt;  &lt;p&gt;Au passage, j’ai plusieurs conseils à vous fournir au sujet de ce projet par défaut :&lt;/p&gt;  &lt;p&gt;- &lt;strong&gt;ne touchez jamais au fichier &lt;em&gt;phonegap-1.3.0.js&lt;/em&gt;&lt;/strong&gt; si vous souhaitez garder un code portable sur les autres versions de Phone Gap     &lt;br /&gt;- tous les fichiers que vous rajouterez dans le répertoire “www” devront être marqué en tant que “&lt;strong&gt;Content&lt;/strong&gt;” dans leurs propriétés&amp;#160; &lt;br /&gt;- à la place du binaire &lt;em&gt;WP7GapClassLib.dll&lt;/em&gt;,vous pouvez référencer le projet C# &lt;em&gt;WP7GapClassLib.csproj&lt;/em&gt; contenu dans le répertoire “&lt;em&gt;Windows Phone\framework&lt;/em&gt;” de l’archive PhoneGap téléchargée. Cela vous permettra de débugger ou parcourir le code de la librairie PhoneGap si besoin.&lt;/p&gt;  &lt;p&gt;Allez, commençons par effectuer une action normalement impossible par défaut sous IE9 Mango : récupérer les valeurs de l’accéléromètre en JavaScript.&lt;/p&gt; &lt;a name="accelero"&gt;   &lt;h2&gt;Récupération des valeurs de l’accéléromètre&lt;/h2&gt; &lt;/a&gt;  &lt;p&gt;Nous allons voir comment, de manière très simple, récupérer les valeurs renvoyées par l’accéléromètre (de l’émulateur ou du vrai périphérique). &lt;/p&gt;  &lt;p&gt;Rendez-vous dans “&lt;em&gt;&lt;strong&gt;index.html&lt;/strong&gt;&lt;/em&gt;” et changer le contenu du body par défaut par celui-ci :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Démo accéléromètre&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;valueX&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;valueY&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;valueZ&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;On va simplement utiliser 3 &amp;lt;div&amp;gt; qui afficheront les valeurs courantes X, Y et Z de l’accéléromètre. &lt;/p&gt;

&lt;p&gt;Ensuite, changer le dernier bloc de &amp;lt;script&amp;gt; par celui-ci :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
    &lt;/span&gt;document.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;deviceready&amp;quot;&lt;/span&gt;, onDeviceReady, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// variable to output the current x, y &amp;amp; z values of the accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;valueX;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;valueY;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;valueZ;

    &lt;span style="color: #006400"&gt;// when PhoneGap tells us everything is ready, start watching the accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onDeviceReady() {
        valueX = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;valueX&amp;quot;&lt;/span&gt;);
        valueY = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;valueY&amp;quot;&lt;/span&gt;);
        valueZ = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;valueZ&amp;quot;&lt;/span&gt;);
        startWatch();
    }

    &lt;span style="color: #006400"&gt;// start monitoring the state of the accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;startWatch() {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;options = { frequency: 500 };
        navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
    }

    &lt;span style="color: #006400"&gt;// if the z-axis has moved outside of our sensitivity threshold, move the aarvark's head in the appropriate direction
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onSuccess(acceleration) {
        valueX.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;X: &amp;quot; &lt;/span&gt;+ acceleration.x;
        valueY.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Y: &amp;quot; &lt;/span&gt;+ acceleration.y;
        valueZ.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Z: &amp;quot; &lt;/span&gt;+ acceleration.z;
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;onError() {
        alert(&lt;span style="color: maroon"&gt;'onError!'&lt;/span&gt;);
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Le code est assez simple à lire je pense. Avant toute chose, vous devez attendre que l’évènement “&lt;em&gt;&lt;strong&gt;deviceready&lt;/strong&gt;&lt;/em&gt;” soit levé par PhoneGap pour être de vous retrouver dans un état stable. On commence donc par s’abonner à cet évènement et nous serons rappelé sur la fonction &lt;em&gt;OnDeviceReady()&lt;/em&gt;.Dans celle-ci, on récupère les 3 instances de &amp;lt;div&amp;gt; qui nous intéresse et on demande ensuite à être notifié des changements de l’accéléromètre toutes les 500ms dans la fonction &lt;em&gt;startWatch()&lt;/em&gt;. Si de nouvelles valeurs sont générées, la fonction &lt;em&gt;onSuccess()&lt;/em&gt; sera appelée avec les valeurs x, y et z fournies dans l’object &lt;em&gt;acceleration&lt;/em&gt;. Vous trouverez toute la documentation sur le site de PhoneGap : &lt;a title="http://docs.phonegap.com/en/1.2.0/phonegap_accelerometer_accelerometer.md.html#Accelerometer" href="http://docs.phonegap.com/en/1.2.0/phonegap_accelerometer_accelerometer.md.html#Accelerometer"&gt;PhoneGap Documentation - API Reference - Accelerometer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C’est tout ce qu’il faut faire du côté code JavaScript. Mais pour que cela fonctionne, il faut indiquer dans les propriétés du projet que l’on a &lt;strong&gt;besoin d’accéder aux capteurs (sensors) de l’appareil&lt;/strong&gt;. La liste des capacités nécessaires au bon fonctionnement de notre application se trouve dans le fichier &lt;strong&gt;&lt;em&gt;WMAppManifest.xml&lt;/em&gt; &lt;/strong&gt;présent dans le répertoire “&lt;em&gt;Properties&lt;/em&gt;”. Par défaut, depuis la version 1.3 de PhoneGap, la liste est limitée au strict nécessaire :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capabilities&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_IDENTITY_DEVICE&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_IDENTITY_USER&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_LOCATION&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_NETWORKING&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_WEBBROWSERCOMPONENT&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capabilities&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;A vous ensuite d’ajouter ce dont vous avez besoin dans votre application PhoneGap. Dans notre cas, ajoutez cette ligne :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Capability &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ID_CAP_SENSORS&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Pour pouvoir autoriser l’accès à l’accéléromètre. Vous retrouverez la liste de toutes ces autorisations ici : &lt;a title="http://msdn.microsoft.com/en-us/library/ff769509(v=VS.92).aspx#BKMK_Capabilities" href="http://msdn.microsoft.com/en-us/library/ff769509(v=VS.92).aspx#BKMK_Capabilities"&gt;Application Manifest File for Windows Phone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bon, on est logiquement prêt à tester tout cela dans l’émulateur dans un 1er temps. Appuyez sur la touche magique “F5” et observons le résultat :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4505.image_5F00_2218E1E5.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7725.image_5F00_thumb_5F00_3C950C97.png" width="640" height="385" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En faisant tourner le téléphone virtuel dans l’émulateur, vous devriez bien voir les valeurs de l’accéléromètre bouger. Félicitations !&lt;/p&gt;

&lt;p&gt;Vous pouvez &lt;strong&gt;récupérer le code complet de cette solution ici&lt;/strong&gt; : &lt;a title="http://david.blob.core.windows.net/html5/MonPremierProjetPhoneGap.zip" href="http://david.blob.core.windows.net/html5/MonPremierProjetPhoneGap.zip"&gt;http://david.blob.core.windows.net/html5/MonPremierProjetPhoneGap.zip&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Petit problème sur les téléphones configurés en français&lt;/h3&gt;

&lt;p&gt;Si vous testez le même code sur votre téléphone et que vous avez une locale en français, vous aurez l’impression que l’application ne fonctionne pas. En débuggant un peu le code, je me suis aperçu que l’exception suivante était levée dans &lt;em&gt;phonegap-1.3.0.js&lt;/em&gt; :&lt;/p&gt;

&lt;p&gt;&lt;font color="#800000"&gt;&amp;quot;Error in success callback: Accelerometer = Syntax error&amp;quot;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Et en dumpant les valeurs, je me suis aperçu que l’erreur venait d’une tentative de dé-sérialisation JSON de la chaine suivante : &lt;/p&gt;

&lt;p&gt;&lt;font color="#800000"&gt;&lt;strong&gt;&amp;quot;{\&amp;quot;x\&amp;quot;:0,00472,\&amp;quot;y\&amp;quot;:-0,19879,\&amp;quot;z\&amp;quot;:-0,98115}&amp;quot;&lt;/strong&gt;&lt;/font&gt; au lieu d’avoir celle-ci en EN-US : &lt;font color="#008000"&gt;&lt;strong&gt;&amp;quot;{\&amp;quot;x\&amp;quot;:0.00472,\&amp;quot;y\&amp;quot;:-0.19879,\&amp;quot;z\&amp;quot;:-0.98115}&amp;quot;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Et oui, notre fameuse virgule de séparation a toujours l’air d’embêter nos chers amis américains… &lt;/p&gt;

&lt;p&gt;2 solutions pour résoudre ce problème :&lt;/p&gt;

&lt;p&gt;1 – Passer votre téléphone en EN-US (oui, je sais, c’est tout pourri comme solution) 
  &lt;br /&gt;2 – Corriger la source du problème dans le code C#. Pour cela, remplacez le code suivant présent dans &lt;em&gt;Accelometer.cs&lt;/em&gt; de la librairie &lt;em&gt;WP7GalClassLib&lt;/em&gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Formats current coordinates into JSON format
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Coordinates in JSON format&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;GetCurrentAccelerationFormatted()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;resultCoordinates = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;x\&amp;quot;:{0},\&amp;quot;y\&amp;quot;:{1},\&amp;quot;z\&amp;quot;:{2}&amp;quot;&lt;/span&gt;,
                    accelerometer.CurrentValue.Acceleration.X.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;),
                    accelerometer.CurrentValue.Acceleration.Y.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;),
                    accelerometer.CurrentValue.Acceleration.Z.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;));
    resultCoordinates = &lt;span style="color: #a31515"&gt;&amp;quot;{&amp;quot; &lt;/span&gt;+ resultCoordinates + &lt;span style="color: #a31515"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;resultCoordinates;
}&lt;/pre&gt;

&lt;p&gt;Par :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;GetCurrentAccelerationFormatted()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;resultCoordinates = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;x\&amp;quot;:{0},\&amp;quot;y\&amp;quot;:{1},\&amp;quot;z\&amp;quot;:{2}&amp;quot;&lt;/span&gt;,
             accelerometer.CurrentValue.Acceleration.X.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture),
             accelerometer.CurrentValue.Acceleration.Y.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture),
             accelerometer.CurrentValue.Acceleration.Z.ToString(&lt;span style="color: #a31515"&gt;&amp;quot;0.00000&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture));
    resultCoordinates = &lt;span style="color: #a31515"&gt;&amp;quot;{&amp;quot; &lt;/span&gt;+ resultCoordinates + &lt;span style="color: #a31515"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;resultCoordinates;
}&lt;/pre&gt;

&lt;p&gt;Et désormais, l’exemple fonctionnera avec toutes les locales. J’ai ouvert un bug à ce sujet ici: &lt;a title="https://issues.apache.org/jira/browse/CB-141" href="https://issues.apache.org/jira/browse/CB-141"&gt;https://issues.apache.org/jira/browse/CB-141&lt;/a&gt; en proposant la solution ci-dessus qui sera intégrée dans la prochaine version (2.0.0). &lt;/p&gt;

&lt;p&gt;Au passage, pour débugger un projet PhoneGap, vous pouvez très bien utiliser &lt;strong&gt;jsConsole&lt;/strong&gt; et toutes les astuces décrites dans mon article précédent : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/12/13/testez-et-d-233-buggez-vos-sites-html5-sous-windows-phone-7-avec-l-233-mulateur-gratuit.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/12/13/testez-et-d-233-buggez-vos-sites-html5-sous-windows-phone-7-avec-l-233-mulateur-gratuit.aspx"&gt;Testez et débuggez vos sites HTML5 sous Windows Phone 7 avec l’émulateur gratuit&lt;/a&gt;&lt;/p&gt;
&lt;a name="html5platformer"&gt;
  &lt;h2&gt;Exemple complet avec le jeu HTML5 Platformer&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Pour conclure, essayons de mixer tout cela avec un jeu complet que j’avais réalisé dans l’article précédent : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;HTML5 Platformer: portage complet du jeu XNA vers &amp;lt;canvas&amp;gt; grâce à EaselJS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voici les étapes que j’ai suivies pour faire fonctionner l’ensemble. La toute première étape consiste simplement à copier/coller les fichiers .js, .png, .css &amp;amp; co dans le répertoire “www” et de bien les marquer comme “&lt;strong&gt;Content&lt;/strong&gt;”. Ensuite, voici les grandes étapes à suivre.&lt;/p&gt;

&lt;h3&gt;Forcer le mode paysage&lt;/h3&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;p&gt;Tout d’abord, j’ai forcé l’orientation en mode portrait et retiré la barre d’informations qui prend de la place sur le côté (System Tray) en me rendant de le fichier&lt;strong&gt; &lt;em&gt;MainPage.xaml&lt;/em&gt;&lt;/strong&gt; et en changeant ces propriétés :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: red"&gt;SupportedOrientations&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Landscape&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Orientation&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Landscape&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;shell&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;SystemTray.IsVisible&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;False&amp;quot;
&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;Adapter le code pour gérer plusieurs résolutions&lt;/h3&gt;

&lt;p&gt;Le but étant d’être portable sur le plus grand nombre de périphériques possibles, il faut envisager de dessiner à des résolutions très différentes. &lt;/p&gt;

&lt;p&gt;Pour cela, j’ai légèrement modifié le code initial du Platformer que vous pouvez retrouver dans &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;l’autre article&lt;/a&gt;. Le jeu est ainsi désormais capable de s’adapter à n’importe quelle résolution en appliquant un ratio sur la manière de dessiner nos images et nos sprites. Tout est calculé pour partir de la résolution d’origine du Windows Phone (800x480) pour ensuite redessiner en fonction de ce ratio d’origine quelque soit la résolution. Vous pouvez le tester dans le navigateur ici : &lt;a title="http://david.blob.core.windows.net/html5platformerscale/index.html" href="http://david.blob.core.windows.net/html5platformerscale/index.html"&gt;HTML5 Platformer ReScale&lt;/a&gt; et vous amusez à redimensionner la fenêtre de votre navigateur. Pour finir, si vous êtes sur une résolution 16/9 sur votre moniteur, appuyez sur la touche F11 pour jouer en plein écran ! L’expérience devient vraiment sympa comme le montre cette copie d’écran :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://david.blob.core.windows.net/html5platformerscale/index.html"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5125.image_5F00_255E17C3.png" width="640" height="360" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On laisse alors le soin au navigateur d’appliquer éventuellement de l’anti-aliasing lors de cette opération de mise à l’échelle. Vous noterez également, selon certains navigateurs, des performances très différentes en fonction de la taille de la fenêtre et donc de la résolution demandée. IE9/IE10 semble, sur ma machine, relativement indifférent au mode plein écran ou aux petites résolutions en affichant un framerate stable de 60 fps. &lt;/p&gt;

&lt;h3&gt;Chargement des niveaux via l’appel au système de fichiers plutôt que XHR&lt;/h3&gt;

&lt;p&gt;Dans le code d’origine, les fichiers .TXT associés à chacun des niveaux étaient stockés sur le serveur et récupérés via des appels XmlHttpRequest. C’est un peu dommage d’effectuer un appel XHR local. Donc j’ai remplacé le code initial de la fonction &lt;em&gt;PlatformerGame.prototype.LoadNextLevel&lt;/em&gt; par :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Loading the next level contained into /level/{x}.txt
&lt;/span&gt;PlatformerGame.prototype.LoadNextLevel = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.levelIndex = (&lt;span style="color: blue"&gt;this&lt;/span&gt;.levelIndex + 1) % numberOfLevels;

    &lt;span style="color: #006400"&gt;// Searching where we are currently hosted
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;nextFileName = &lt;span style="color: maroon"&gt;&amp;quot;app/www/assets/levels/&amp;quot; &lt;/span&gt;+ &lt;span style="color: blue"&gt;this&lt;/span&gt;.levelIndex + &lt;span style="color: maroon"&gt;&amp;quot;.txt&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;try &lt;/span&gt;{
        &lt;span style="color: blue"&gt;var &lt;/span&gt;instance = &lt;span style="color: blue"&gt;this&lt;/span&gt;;
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);

        &lt;span style="color: blue"&gt;function &lt;/span&gt;gotFS(fileSystem) {
            fileSystem.root.getFile(nextFileName, &lt;span style="color: blue"&gt;null&lt;/span&gt;, gotFileEntry, fail);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;gotFileEntry(fileEntry) {
            fileEntry.file(gotFile, fail);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;gotFile(file) {
            readAsText(file);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;readAsText(file) {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;reader = &lt;span style="color: blue"&gt;new &lt;/span&gt;FileReader();
            reader.onloadend = &lt;span style="color: blue"&gt;function &lt;/span&gt;(evt) {
                instance.LoadThisTextLevel(evt.target.result.replace(/[\n\r\t]/g, &lt;span style="color: maroon"&gt;''&lt;/span&gt;));
            };
            reader.readAsText(file);
        }

        &lt;span style="color: blue"&gt;function &lt;/span&gt;fail(evt) {
            console.log(evt.target.error.code);
        }
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(e) {
        console.log(&lt;span style="color: maroon"&gt;&amp;quot;Error loading level: &amp;quot; &lt;/span&gt;+ e.message);
&lt;span style="color: #006400"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.LoadThisTextLevel(hardcodedErrorTextLevel);
    }
};&lt;/pre&gt;

&lt;p&gt;J’ai bêtement repris le code de la documentation de PhoneGap : &lt;a title="http://docs.phonegap.com/en/1.3.0/phonegap_file_file.md.html#FileReader" href="http://docs.phonegap.com/en/1.3.0/phonegap_file_file.md.html#FileReader"&gt;FileReader&lt;/a&gt; . Vous avez donc pleinement accès au système de fichiers du Windows Phone via JavaScript. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Petit tip :&lt;/u&gt;&lt;/strong&gt; pour vous aider à débugger ce qui est présent ou non dans l’Isolated Storage du téléphone, je vous conseille vivement cet outil qui m’a sauvé la vie : &lt;a title="http://isostorespy.codeplex.com/" href="http://isostorespy.codeplex.com/"&gt;IsoStoreSpy&lt;/a&gt; écrit par Samuel Blanchard. Une vraie merveille !&lt;/p&gt;

&lt;h3&gt;Modification du gameplay pour gérer l’accéléromètre&lt;/h3&gt;

&lt;p&gt;Bon il ne reste plus qu’à mixer les différentes parties de cet article pour arriver au résultat escompté. Pour cela, j’ai ajouté le code suivant dans le constructeur de l’objet &lt;em&gt;Player&lt;/em&gt; dans le fichier &lt;em&gt;Player.js&lt;/em&gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;options = { frequency: 500 };
&lt;span style="color: blue"&gt;var &lt;/span&gt;that = &lt;span style="color: blue"&gt;this&lt;/span&gt;;

navigator.accelerometer.watchAcceleration(
    &lt;span style="color: blue"&gt;function &lt;/span&gt;(accelerometer) { that.moveDirectionAccel(accelerometer); },
    &lt;span style="color: blue"&gt;function &lt;/span&gt;() { console.log(&lt;span style="color: maroon"&gt;&amp;quot;Error with accelerometer&amp;quot;&lt;/span&gt;); }, 
    options);&lt;/pre&gt;

&lt;p&gt;Ensuite, voici la fonction qui sera rappelée suite aux variations de l’accéléromètre :&lt;/p&gt;

&lt;pre class="code"&gt;Player.prototype.moveDirectionAccel = &lt;span style="color: blue"&gt;function&lt;/span&gt;(acceleration) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;accelValue = -acceleration.y;

    &lt;span style="color: #006400"&gt;// Move the player with accelerometer
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Math.abs(accelValue) &amp;gt; 0.15) {
        &lt;span style="color: #006400"&gt;// set our movement speed
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = Math.clamp(accelValue * &lt;span style="color: blue"&gt;this&lt;/span&gt;.AccelerometerScale, -1, 1);
    }
    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 0;
    }
};&lt;/pre&gt;

&lt;h3&gt;Le résultat en images avec quelques FPS sur les téléphones&lt;/h3&gt;

&lt;p&gt;Tout d’abord, voici le résultat dans l’émulateur :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0804.image_5F00_313B39E9.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7652.image_5F00_thumb_5F00_2F865A16.png" width="644" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sur un vrai périphérique, l’expérience varie d’un téléphone à l’autre. Prenons l’exemple du tout 1er niveau. Sur le &lt;strong&gt;LG E900&lt;/strong&gt;, le framerate tourne autour de &lt;strong&gt;&lt;font color="#000000"&gt;22 fps&lt;/font&gt;&lt;/strong&gt;, sur le &lt;strong&gt;&lt;font color="#800080"&gt;HTC Radar&lt;/font&gt;&lt;/strong&gt;, nous sommes autour de &lt;strong&gt;&lt;font color="#800080"&gt;31 fps&lt;/font&gt;&lt;/strong&gt; et sur le &lt;strong&gt;&lt;font color="#004080"&gt;Nokia Lumia 800&lt;/font&gt;&lt;/strong&gt; autour de &lt;strong&gt;&lt;font color="#004080"&gt;42 fps&lt;/font&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7824.DSCF4677_5F00_34684C2B.jpg"&gt;&lt;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="DSCF4677" border="0" alt="DSCF4677" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6648.DSCF4677_5F00_thumb_5F00_34F0B6BB.jpg" width="404" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il en résulte un gameplay souvent décevant dans la plupart des cas. En effet, l’utilisation d’un canvas plein écran n’est pour l’instant pas une bonne idée sur ce genre de mobile même si le Nokia semble être le plus à même de gérer ce scénario. J’en avais déjà parlé lors de ma session ParisWeb 2011 sur le développement “cross-device”. Une approche de découpage de la scène de jeux utilisant de plus petits canvas animés ensuite via leurs propriétés CSS serait plus adaptée. C’est ce qui est fait sur la version HTML5 d’Angry Birds par exemple. Certains frameworks de jeux commencent d’ailleurs à envisager de le gérer pour vous. L’idée serait donc de coder 1 fois le jeu avec des APIs de haut niveau et le framework s’occuperait de choisir soit un canvas plein écran, soit un découpage en plusieurs petits canvas. Vous l’aurez compris : l’expérience de jeux HTML5 sur mobile n’en est qu’à ses débuts mais l’avenir s’annonce très intéressant. A suivre donc !&lt;/p&gt;

&lt;h3&gt;Solution complète à télécharger&lt;/h3&gt;

&lt;p&gt;Vous trouverez &lt;strong&gt;le code source complet du jeu HTML5 Platformer pour PhoneGap ici&lt;/strong&gt; : &lt;a title="http://david.blob.core.windows.net/html5/HTML5GapPlatformer.zip" href="http://david.blob.core.windows.net/html5/HTML5GapPlatformer.zip"&gt;HTML5GapPlatformer.zip&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Ressources complémentaires &lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a title="http://blogs.technet.com/b/port25/archive/2011/12/19/full-support-for-phonegap-on-windows-phone-is-now-complete.aspx" href="http://blogs.technet.com/b/port25/archive/2011/12/19/full-support-for-phonegap-on-windows-phone-is-now-complete.aspx"&gt;Full Support for PhoneGap on Windows Phone is Now Complete!&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a title="http://blogs.msdn.com/b/glengordon/archive/2011/11/15/phonegap-on-windows-phone-tips.aspx" href="http://blogs.msdn.com/b/glengordon/archive/2011/11/15/phonegap-on-windows-phone-tips.aspx"&gt;PhoneGap on Windows Phone Tips&lt;/a&gt; de Glen Gardon qui contient plusieurs tutoriaux intéressants à suivre&lt;/li&gt;

  &lt;li&gt;De nombreux tutoriaux excellents à suivre ici: &lt;a title="http://wiki.phonegap.com/w/page/35501397/Tutorials" href="http://wiki.phonegap.com/w/page/35501397/Tutorials"&gt;http://wiki.phonegap.com/w/page/35501397/Tutorials&lt;/a&gt;&amp;#160;&lt;/li&gt;
&lt;/ul&gt;
&lt;a name="conclusion"&gt;
  &lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;PhoneGap ouvre des perspectives intéressantes pour vous aider à écrire des applications pour le téléphone en reprenant vos compétences existantes en JavaScript, HTML et CSS. Il ne pourra pas forcément couvrir tous les scénarios actuellement adressées par un développement natif (Silverlight ou XNA) mais c’est une voie à envisager si vous souhaitez capitaliser sur les compétences de l’une de vos équipes. Il faudra par contre bien faire attention à vérifier que le type de projet retenu se prête bien aux limitations actuelles d’HTML5. &lt;/p&gt;

&lt;p&gt;Il existe aussi la possibilité de mixer les 2 environnements en créant des expériences hybrides : le tronc commun écrit en “HTML5” et le reste par des équipes maitrisant la plateforme native. C’est ainsi que certains plug-ins ont été créés pour pousser un peu loin l’intégration dans l’expérience Metro : &lt;a title="https://github.com/purplecabbage/phonegap-plugins/tree/master/WindowsPhone" href="https://github.com/purplecabbage/phonegap-plugins/tree/master/WindowsPhone"&gt;Plug-ins PhoneGap pour Windows Phone&lt;/a&gt; . Vous y trouverez par exemple la possibilité de mettre à jour les “Tiles” depuis votre code JavaScript.&lt;/p&gt;

&lt;p&gt;Pour finir, PhoneGap et l’usage d’HTML5 permet également une portabilité plus simple vers d’autres plateformes… dans une certaines mesure. Cependant, ce sujet précis étant un vaste et passionnant débat remplis de mauvaises idées reçues, j’y reviendrais peut-être dans un autre billet si j’en ai le temps d’ici les &lt;a href="http://www.mstechdays.fr"&gt;TechDays&lt;/a&gt; ! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7444.wlEmoticon_2D00_smile_5F00_442F71E6.png" /&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10250681" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/JavaScript/">JavaScript</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/PhoneGap/">PhoneGap</category></item><item><title>Testez et débuggez vos sites HTML5 sous Windows Phone 7 avec l’émulateur gratuit</title><link>http://blogs.msdn.com/b/davrous/archive/2011/12/13/testez-et-d-233-buggez-vos-sites-html5-sous-windows-phone-7-avec-l-233-mulateur-gratuit.aspx</link><pubDate>Tue, 13 Dec 2011 10:02:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10247110</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10247110</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/12/13/testez-et-d-233-buggez-vos-sites-html5-sous-windows-phone-7-avec-l-233-mulateur-gratuit.aspx#comments</comments><description>&lt;p&gt;Les internautes arrivent de plus en plus souvent sur vos sites web depuis un périphérique mobile. Il est donc de plus en plus important de leur offrir une bonne expérience sur le navigateur embarqué. Vous ne pouvez plus vous permettre d’ignorer cette population en leur offrant une version trop dégradée. Dans notre cas, depuis la mise à jour nommée “Mango”, &lt;strong&gt;Internet Explorer 9 est arrivé sur Windows Phone&lt;/strong&gt;. Vous pouvez donc lui fournir du HTML5, CSS3 Media Queries &amp;amp; co pour créer une bonne expérience. Je vous propose alors de voir 4 choses dans cet article : &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Comment récupérer &lt;strong&gt;l’émulateur Windows Phone&lt;/strong&gt; et l’utiliser &lt;/li&gt;    &lt;li&gt;Un point sur les &lt;strong&gt;différences entre IE9 Desktop et mobile&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Comment &lt;strong&gt;débugger votre code JavaScript avec jsConsole&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Pour finir, comment &lt;strong&gt;débugger le trafic réseau&lt;/strong&gt; entre l’émulateur et le reste du monde grâce à Fiddler &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Le but principal de cet article étant de vous faire gagner potentiellement du temps. &lt;/p&gt;  &lt;h2&gt;L’émulateur Windows Phone&lt;/h2&gt;  &lt;p&gt;La toute première chose que je vous invite à faire est de télécharger le SDK qui contient l’émulateur ici : &lt;a title="Télécharger SDK Windows Phone" href="http://aka.ms/hp-windows-phone"&gt;Télécharger le SDK Windows Phone&lt;/a&gt; . Vous pouvez l’installer sous Windows Vista ou Windows 7. &lt;/p&gt;  &lt;p&gt;Il contient également les outils (gratuits) de développement. Si le sujet vous intéresse et que vous souhaitez découvrir cette plateforme, rendez-vous ici : &lt;a title="http://msdn.microsoft.com/fr-fr/windowsphone/ff637027" href="http://msdn.microsoft.com/fr-fr/windowsphone/ff637027"&gt;Découvrir la plateforme Windows Phone&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Mais revenons au sujet qui nous intéresse. Une fois le SDK installé, vous trouverez l’émulateur dans votre menu démarrer : &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0131.WPEmulator_5F00_2CB4E7E4.png"&gt;&lt;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="WPEmulator" border="0" alt="WPEmulator" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7571.WPEmulator_5F00_thumb_5F00_35C17365.png" width="400" height="199" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lorsque vous le lancez, vous aurez ce résultat et vous pouvez configurer 2 ou 3 trucs :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2450.image_5F00_360700D1.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3823.image_5F00_thumb_5F00_0FC4A779.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8625.image_5F00_52C075E6.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8625.image_5F00_thumb_5F00_0543D359.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0880.image_5F00_63E42DBC.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7242.image_5F00_thumb_5F00_6F9974EE.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4034.image_5F00_4E39CF52.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8244.image_5F00_thumb_5F00_6BCBAA51.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4024.image_5F00_55958EFF.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6180.image_5F00_thumb_5F00_4C5953BE.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vous pouvez par exemple choisir entre le fait de recevoir par défaut la version mobile du site ou la version bureau.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#800000"&gt;Détail important à connaitre&lt;/font&gt;&lt;/strong&gt; : pour éviter de taper les URLs avec le clavier virtuel, cliquez dans l’émulateur et appuyer sur la &lt;strong&gt;touche “Pause”&lt;/strong&gt;. Vous devriez ensuite être en mesure de taper avec votre clavier dans l’émulateur.&lt;/p&gt;  &lt;p&gt;Voici les autres choses à connaitre sur l’émulateur qui pourront vous aider à créer vos expériences mobiles sur Windows Phone. &lt;strong&gt;Gestion de l’orientation&lt;/strong&gt; présente sur la barre d’options à droite de l’émulateur :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6180.image_5F00_3FEB3095.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7585.image_5F00_thumb_5F00_1E8B8AF9.png" width="240" height="121" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Et voici le résultat :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8156.image_5F00_08556FA7.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1222.image_5F00_thumb_5F00_257B17B1.png" width="240" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Autre détail à connaitre, pour que l’orientation s’effectue correctement et soit prise en compte, il faut ré-appuyer sur la touche “pause” si vous l’avez fait précédemment pour utiliser votre clavier. Sinon, vous aurez l’impression de devoir systématique pencher la tête à gauche ou à droite. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8611.wlEmoticon_2D00_winkingsmile_5F00_1EF3A9EF.png" /&gt;&lt;/p&gt;  &lt;p&gt;Vous pouvez aussi&lt;strong&gt; simuler de votre position&lt;/strong&gt; pour la géolocalisation. Prenons par exemple ce site web de démo : &lt;a title="http://ie.microsoft.com/testdrive/mobile/HTML5/Geolocation/Default.html" href="http://ie.microsoft.com/testdrive/mobile/HTML5/Geolocation/Default.html"&gt;IE Test Drive Mobile avec Géolocalisation HTML5&lt;/a&gt; qui utilise justement l’API de géolocalisation. &lt;/p&gt;  &lt;p&gt;Voici le résultat par défaut dans l’émulateur :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7178.image_5F00_190CF488.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1731.image_5F00_thumb_5F00_36329C92.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3884.image_5F00_1FFC8140.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3884.image_5F00_thumb_5F00_7D5842C4.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2816.image_5F00_42FCCCE3.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1830.image_5F00_thumb_5F00_1E3B8F9F.png" width="132" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On vous localise sur Redmond. Donc si vous voulez changer cela (sauf si vous habitez vraiment à Redmond &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2047.wlEmoticon_2D00_smile_5F00_25E1FD1F.png" /&gt;), vous pouvez le faire en faisant apparaitre une fenêtre supplémentaire. Pour cela, cliquez sur “&amp;gt;&amp;gt;” et mettez une punaise (ou push pin en anglais) à l’endroit souhaité. Voici un exemple où j’en mets un sur la Tour Eiffel et l’application HTML5/JavaScript obtient bien la bonne information :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0184.image_5F00_71B25FB8.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5808.image_5F00_thumb_5F00_5DF55057.png" width="1024" height="596" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Cela peut donc être très pratique pour débugger une application HTML5 basée sur la géolocalisation sans forcément vous balader physiquement dans toute la France… voir la planète ! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8611.wlEmoticon_2D00_winkingsmile_5F00_1EF3A9EF.png" /&gt;&lt;/p&gt;  &lt;p&gt;Pour le reste, testez votre site de manière habituelle et observez les différences entre la version desktop et mobile comme avec le site &lt;a href="http://foodsense.is/"&gt;Food Sense&lt;/a&gt; par exemple mettant en œuvre intelligemment CSS3 Media Queries :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6138.image_5F00_7D6334F0.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6710.image_5F00_thumb_5F00_1C298302.png" width="550" height="284" /&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0383.image_5F00_51DEC85C.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1447.image_5F00_thumb_5F00_55303A37.png" width="350" height="192" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vous pouvez voir ci-dessus le résultat sur IE9 sous Windows 7, IE9 sur Windows Phone en mode portrait puis paysage.&lt;/p&gt;  &lt;p&gt;Donc si tout cela vous intéresse et que vous souhaitez accueillir dans de bonnes conditions les nombreux acheteurs récents du superbe &lt;a href="http://www.nokia.fr/fr-fr/produits/mobiles/lumia800/"&gt;Nokia Lumia 800&lt;/a&gt;, foncez télécharger ici le SDK :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aka.ms/hp-windows-phone"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Télécharger SDK Windows Phone" border="0" alt="Télécharger SDK Windows Phone" src="http://msdn.microsoft.com/ms348103.SDKPhone2_onmouseover(fr-fr,MSDN.10).gif" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Et testez votre site dessus !&lt;/p&gt;  &lt;h2&gt;Différences entre IE9 desktop et mobile&lt;/h2&gt;  &lt;p&gt;Commençons par &lt;strong&gt;&lt;font color="#800000"&gt;les choses en moins&lt;/font&gt;&lt;/strong&gt; classées par ordre d’importance selon moi:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;pas de support des fonts téléchargeables comme EOT, TTF/OTF et WOFF. Bien que le tag font-face soit supporté, le navigateur IE9 mobile n’essaiera pas de télécharger la font. La liste des fonts installées et supportées par Windows Phone se trouve ici : &lt;a title="http://msdn.microsoft.com/fr-fr/library/ff806365%28v=VS.95%29.aspx" href="http://msdn.microsoft.com/fr-fr/library/ff806365%28v=VS.95%29.aspx"&gt;Liste des fonts supportées&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;pas de support de flux multiples avec la balise audio HTML5 &lt;/li&gt;    &lt;li&gt;pas de support de mode de rétro compatibilité avec le mode de document Internet Explorer 8. IE9 mobile rendra les sites forcément avec le moteur de rendu d’IE9. &lt;/li&gt;    &lt;li&gt;assez logiquement, pas de support de communications “cross-window” via JavaScript &lt;/li&gt;    &lt;li&gt;pas de support de VBScript, d’ActiveX, d’extensibilité via les BHO (Browser Helper&amp;#160; Objects) et les barre d’outils, pas de support d’Active Document non plus &lt;/li&gt;    &lt;li&gt;pas de support de vieilles technologies comme les “binary behaviors”, HTCs, HTML+TIME et VML &lt;/li&gt;    &lt;li&gt;pas de compilation JIT &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ainsi, heureusement, la quasi totalité des différences entre la version de bureau d’IE9 et son équivalent mobile représente, je pense, d’excellentes choses.&lt;/p&gt;  &lt;p&gt;Dans&lt;strong&gt; &lt;font color="#008000"&gt;les choses en plus&lt;/font&gt;&lt;/strong&gt;, nous avons :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;support du GPS pour la géolocalisation HTML5. Windows Phone utilise ainsi la couche de localisation du périphérique et utilise donc le GPS s’il est disponible. La version de bureau d’IE9 s’appuyant sur d’autres méthodes n’utilisant pas le GPS car quasiment aucun PC n’en est équipé. &lt;/li&gt;    &lt;li&gt;support du &lt;em&gt;Viewport&lt;/em&gt;. &lt;em&gt;Width&lt;/em&gt;, &lt;em&gt;height&lt;/em&gt; et &lt;em&gt;user-scalable&lt;/em&gt;. Par contre, bien que certaines de ces fonctionnalités soient supportées dans certains navigateurs, les propriétés &lt;em&gt;minimum-scale&lt;/em&gt;, &lt;em&gt;maximum-scale&lt;/em&gt; et &lt;em&gt;initial-scale&lt;/em&gt; sont pour l’instant non supportées &lt;/li&gt;    &lt;li&gt;support de la propriété CSS : -&lt;em&gt;ms-text-size-adjust&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Vous retrouverez tout cela un peu plus en détail et en anglais ici : &lt;a title="http://msdn.microsoft.com/fr-fr/library/ff462082(v=vs.92).aspx" href="http://msdn.microsoft.com/fr-fr/library/ff462082(v=vs.92).aspx"&gt;Web Development for Windows Phone&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pour le reste, reportez vous simplement au &lt;a href="http://msdn.microsoft.com/fr-fr/ie/ff468705.aspx"&gt;guide du développeur Internet Explorer 9&lt;/a&gt; qui contient toutes les fonctionnalités supportées par IE9 desktop et donc mobile. J’attire par exemple votre attention sur &lt;strong&gt;2 points importants lorsque vous allez tester du HTML5 ou CSS3 dans IE9 Mobile &lt;/strong&gt;:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Tout comme IE9 Desktop, il faut absolument avoir créé un document HTML5 standard avec donc la balise &amp;lt;!DOCTYPE html&amp;gt; en tout début de document. Si vous ne la positionnez pas, IE9 Desktop come Mobile basculeront dans un ancien mode de rendu non “compatible” HTML5&lt;/li&gt;    &lt;li&gt;IE9 Mobile gère une liste de compatibilité des sites comme décrit ici : &lt;a title="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/09/29/ie9-s-faster-more-capable-compatibility-view-list-now-on-windows-phone.aspx" href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/09/29/ie9-s-faster-more-capable-compatibility-view-list-now-on-windows-phone.aspx"&gt;IE9’s faster, more capable Compatibility View List… now on Windows Phone!&lt;/a&gt; . Donc si vous vous apercevez que votre code ne se comporte par comme prévu dans IE9 Mobile, c’est peut-être que votre site est hébergé sur un nom de domaine marqué comme non compatible dans la liste mise à jour toutes les 2 semaines. Et tout comme IE9 Desktop, vous pouvez forcer le mode standard via le meta tag X-UA-COMPATIBLE.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Par exemple, j’ai eu une interaction récente sur Twitter avec &lt;a title="@benjamincrozat" href="https://twitter.com/#!/benjamincrozat"&gt;@benjamincrozat&lt;/a&gt; sur du border-radius qui ne marchait pas sous IE9 Mobile. En regardant depuis IE9 Desktop son URL de test, je me suis aperçu de la chose suivante dans la console de debug (via F12) :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3858.image_5F00_7D2044C3.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1212.image_5F00_thumb_5F00_4E7A1614.png" width="640" height="138" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On observe alors que dropbox.com est présent dans la liste de compatibilité, ce qui fait basculer IE9 en mode de compatibilité IE7. Conclusion : n’hésitez pas à tester votre site sous IE9 “normal” avant de tester sous IE9 mobile pour faire une 1ère passe de tests. &lt;/p&gt;  &lt;h2&gt;Débugger le code JavaScript avec jsConsole&lt;/h2&gt;  &lt;p&gt;Dans la mise au point d’un site web pour mobile, la partie la plus pénible est souvent de débugger le code JavaScript sur tournant sur le périphérique. Heureusement, l’excellent &lt;a href="http://remysharp.com/"&gt;Remy Sharp&lt;/a&gt; a eu la bonne idée de travailler sur un projet permettant de piloter à distance le code JS exécuté sur le périphérique. Le fruit de son travail est le projet jsConsole : &lt;a href="http://jsconsole.com"&gt;http://jsconsole.com&lt;/a&gt; . &lt;/p&gt;  &lt;p&gt;Mais plutôt que de vous expliquer en détail son usage, je préfère fortement vous inviter à lire &lt;strong&gt;l’excellent tutoriel présent sur le site d’Alsacréations&lt;/strong&gt; : &lt;a title="http://www.alsacreations.com/tuto/lire/1245-deboguer-son-site-mobile-avec-jsconsole.html" href="http://www.alsacreations.com/tuto/lire/1245-deboguer-son-site-mobile-avec-jsconsole.html"&gt;Déboguer son site mobile avec JsConsole&lt;/a&gt; . Je ne vois pas trop comment je pourrais mieux faire. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8611.wlEmoticon_2D00_winkingsmile_5F00_1EF3A9EF.png" /&gt;&lt;/p&gt;  &lt;p&gt;Par contre, j’ai bien vérifié que cette solution fonctionnait parfaitement avec IE9 sur Windows Phone. Voici un exemple utilisant jsConsole et PhoneGap pour Windows Phone 7 :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6431.image_5F00_242A6D04.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3223.image_5F00_thumb_5F00_1844B46B.png" width="640" height="331" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vous pouvez donc compter dessus pour vous aider à tester et corriger votre site sur la version mobile d’IE9. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#800000"&gt;Attention !&lt;/font&gt;&lt;/strong&gt; Pour des raisons évidentes de sécurité, attention à bien mettre tout cela en place qu’à des fins de debug et à bien retirer son usage avant la mise en production ! Mais ai-je vraiment besoin de le vous rappeler ?&lt;/p&gt;  &lt;h2&gt;Débugger le trafic réseau avec Fiddler&lt;/h2&gt;  &lt;p&gt;Pour finir un peu plus bas dans les couches, nous allons maintenant voir comment capturer le trafic réseau entre l’émulateur Windows Phone et le reste du monde. Voici les étapes à suivre :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Installer la &lt;a href="http://www.fiddler2.com/dl/fiddler2betasetup.exe"&gt;dernière version de Fiddler&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Démarrer Fiddler &lt;/li&gt;    &lt;li&gt;Aller dans les options via les menus “Tools” –&amp;gt; “Fiddler Options” &lt;/li&gt;    &lt;li&gt;Ouvrez l’onglet “&lt;strong&gt;Connections&lt;/strong&gt;” et cochez la case “&lt;strong&gt;Allow remote computers to connect&lt;/strong&gt;”. &lt;/li&gt;    &lt;li&gt;Cliquez sur “OK” pour fermer la fenêtre des options de Fiddler &lt;/li&gt;    &lt;li&gt;Dans la boite de commandes sous la liste des “Web sessions”, tapez la commande suivante :&amp;#160; &lt;strong&gt;prefs set fiddler.network.proxy.registrationhostname &lt;em&gt;HostName &lt;/em&gt;&lt;/strong&gt;où &lt;strong&gt;&lt;em&gt;HostName &lt;/em&gt;&lt;/strong&gt;correspond au nom de votre machine &lt;/li&gt;    &lt;li&gt;Fermer et redémarrer Fiddler &lt;/li&gt;    &lt;li&gt;Démarrer (ou redémarrer) l’émulateur Windows Phone &lt;/li&gt;    &lt;li&gt;Ouvrer Internet Explorer et naviguez vers le site à débugger &lt;/li&gt;    &lt;li&gt;Observez le trafic réseau affiché par Fiddler &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Et voici un résultat de capture en naviguant vers le site d’Alsacréations :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7242.image_5F00_44E8FC4A.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1738.image_5F00_thumb_5F00_524AFB51.png" width="640" height="385" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Avec &lt;a href="http://aka.ms/hp-windows-phone"&gt;notre émulateur gratuit&lt;/a&gt; et toutes ces astuces, j’espère que vous serez maintenant correctement armé pour tester et débugger vos sites sur IE9 mobile !&lt;/p&gt;  &lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10247110" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/CSS3/">CSS3</category></item><item><title>Introduction aux animations CSS3</title><link>http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-aux-animations-css3.aspx</link><pubDate>Mon, 05 Dec 2011 23:28:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10244424</guid><dc:creator>David Rousset</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10244424</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-aux-animations-css3.aspx#comments</comments><description>&lt;meta content="IE=edge" http-equiv="X-UA-Compatible" /&gt;&lt;script&gt;
$(function() {
// run the currently selected effect
function runEffect(target) {
// get effect type from 
var selectedEffect = "clip";

var options = {};

// run the effect
target.toggle(500 );
};

$("#properties").hide();
$("#types").hide();

// set effect from select menu value
$( "#propertiesLink" ).click(function() {
runEffect($("#properties"));
return false;
});

$( "#typesLink" ).click(function() {
runEffect($("#types"));
return false;
});
});
&lt;/script&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="right" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6443.TestAnimations_5F00_4312DF8D.jpg" width="300" height="200" /&gt;&lt;/p&gt;  &lt;p&gt;Les applications HTML5 d’aujourd’hui peuvent désormais fournir des expériences inédites grâces aux nouvelles spécifications CSS3. L’une d’entre elles est nommée &lt;strong&gt;CSS3 Animations&lt;/strong&gt;. Elle vous permet de créer des animations évoluées sur des éléments HTML. Cela ouvre d’intéressantes perspectives afin de fournir des retours pertinents à l’utilisateur et construire des applications rapides &amp;amp; fluides. De plus, comme ces nouvelles animations sont la plupart du temps accélérées matériellement par le GPU, elles permettent de monter la qualité de la nouvelle génération d’applications HTML5 vers de nouveaux sommets.&lt;/p&gt;  &lt;p&gt;Si l’on traduit une partie des spécifications “CSS Animation Module Level 3” du &lt;a href="http://www.w3.org/TR/css3-animations/"&gt;site officiel du W3C&lt;/a&gt;, on découvre que ces spécifications CSS3 &lt;em&gt;introduisent des animations définies, indiquant les propriétés CSS qui évolueront selon un intervalle de temps donné. Cette spécification est une extension du module CSS Transitions.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Comme CSS3 Animations est une &lt;strong&gt;extension des CSS3 Transitions&lt;/strong&gt;, je vous invite à lire dans un 1er temps l’article dédié à ce sujet de mon collègue David Catuhe: &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/24/fr-introduction-224-css3-transitions.aspx"&gt;Introduction aux transitions CSS3&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;A travers cet article, nous allons découvrir une démo intéressante mettant en avant le potentiel des animations CSS3, comment construire des animations simples et finalement comment gérer un éventuel mode dégradé via JavaScript:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="#intro"&gt;CSS3 Animations&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#support"&gt;Support dans les navigateurs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#fallback"&gt;Librairie JavaScript pour simuler les animations CSS3&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Commençons tout d’abord par rapidement découvrir ce que sont les animations CSS3. Voici un exemple d’animation d’un TB-TT (ou AT-AT en anglais) issu de l’univers de StarWars et utilisant CSS3 Animations pour animer les différentes parties du transport. Si votre navigateur ne supporte pas les spécifications CSS3 animations, une librairie JavaScript sera chargée pour simuler son action: &lt;/p&gt; &lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="570" src="http://david.blob.core.windows.net/html5/css3atat/index.htm" width="716" scrolling="no"&gt;&lt;/iframe&gt;  &lt;p&gt;Vous pouvez également tester cet exemple dans une fenêtre séparée ici : &lt;a title="http://david.blob.core.windows.net/html5/css3atat/index.htm" href="http://david.blob.core.windows.net/html5/css3atat/index.htm"&gt;http://david.blob.core.windows.net/html5/css3atat/index.htm&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; cet exemple a été testé avec succès sous IE10 PP3/PP4, Chrome 15, Firefox 8 et iPad 2 pour le support natif des animations. La librairie de “fallback” fonctionne très bien sous IE9 classique et mobile (Windows Phone). Cependant, pour des raisons qui me sont inconnues, elle génère des comportements pour le moins étranges sous Opera 11.50 apparemment résolus sous la 11.60. Par ailleurs, notre chère plateforme de blog force souvent le moteur de rendu IE9 via un meta tag ce qui empêche la démo de fonctionner correctement sous IE10. Pour forcer le moteur IE10 standards, appuyer sur la touche F12 et changer la valeur de “Document Mode”. Sinon, regardez la démo dans une fenêtre séparée. &lt;/p&gt;  &lt;p&gt;Cet exemple est basé sur le super boulot réalisé par &lt;a href="http://twitter.com/acalzadilla"&gt;Anthony Calzadilla&lt;/a&gt;. Vous pouvez découvrir d’autres superbes démos mettant en œuvre CSS3 Animations sur son site ici : &lt;a href="http://www.anthonycalzadilla.com"&gt;http://www.anthonycalzadilla.com&lt;/a&gt; . J’apprécie particulièrement son exemple &lt;a href="http://www.anthonycalzadilla.com/i-twitty-the-fool/"&gt;I twitty the fool&lt;/a&gt; utilisant SVG &amp;amp; CSS3 Animation combinés. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0827.wlEmoticon_2D00_winkingsmile_5F00_475BBE95.png" /&gt;&lt;/p&gt; &lt;a name="intro"&gt;   &lt;h2&gt;CSS3 Animations&lt;/h2&gt; &lt;/a&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;Commençons par analyser sur quelles parties vous pouvez jouer pour fabriquer des animations. CSS3 Animations travaille tout simplement sur les mêmes valeurs que CSS3 Transitions.&lt;/p&gt;  &lt;p&gt;Les voici: &lt;a id="typesLink"&gt;cliquez ici pour les afficher/cacher&lt;/a&gt;&lt;/p&gt;  &lt;ul id="types"&gt;   &lt;li&gt;&lt;strong&gt;couleur &lt;/strong&gt;: interpolée via ses composantes rouge, verte, bleue et alpha (qui sont considérées comme des nombres) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;longueur &lt;/strong&gt;: interpolée comme un nombre &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;pourcentage &lt;/strong&gt;: interpolée comme un nombre &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;entier &lt;/strong&gt;:interpolé de manière discrète (en fait l’interpolation se fait sur une version décimale qui est ensuite tronquée vers un entier en utilisant &lt;code&gt;floor())&lt;/code&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;nombre&lt;/strong&gt;: interpolé directement comme un réel &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;liste de transformation &lt;/strong&gt;: voir la spécification des CSS3 2D Transforms (&lt;a href="http://www.w3.org/TR/css3-2d-transforms"&gt;http://www.w3.org/TR/css3-2d-transforms&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;rectangle&lt;/strong&gt;: interpolé via ses composantes x, y, largeur, hauteur &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;visibilité&lt;/strong&gt;: interpolé de manière discrète (en fait l’interpolation est effectuée sur un nombre réel allant de 0 à 1 ou 0 vaut &lt;em&gt;caché&lt;/em&gt; et 1 vaut &lt;em&gt;visible&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ombre&lt;/strong&gt;: interpolé via ses composantes de couleur, x, y et flou &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;gradient&lt;/strong&gt;: interpolé au travers de la position et la couleur de chacune des étapes. La valeur d’origine et la valeur de destination de la transitions doivent par contre avoir le même type (linéaire ou radial) et le même nombre d’étapes &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;paint server&lt;/strong&gt; (SVG): l’interpolation est uniquement supporté de gradient ver gradient ou de couleur vers couleur &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;liste séparée par des espaces d’un type ci-dessus &lt;/strong&gt;: si les listes d’origine et de destination de la transition ont le même nombre d’éléments, les règles ci-dessus s’applique et l’interpolation a bien lieu. Dans le cas contraire, l’interpolation n’est pas jouée &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;propriété synthétique (shorthand property) &lt;/strong&gt;:&lt;strong&gt; &lt;/strong&gt;si toutes les parties de la synthèse peuvent être animées alors l’interpolation a lieu comme si chaque propriété avait été spécifiée individuellement &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Et les propriétés suivantes doivent être supportées pour les animations: &lt;a id="propertiesLink"&gt;cliquez ici pour les afficher/cacher&lt;/a&gt;&lt;/p&gt;  &lt;ul id="properties"&gt;   &lt;li&gt;background-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;background-image (&lt;i&gt;que les gradients&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;background-position (&lt;i&gt;pourcentage et longueur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;border-bottom-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;border-bottom-width (longueur) &lt;/li&gt;    &lt;li&gt;border-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;border-left-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;border-left-width (longueur) &lt;/li&gt;    &lt;li&gt;border-right-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;border-right-width (longueur) &lt;/li&gt;    &lt;li&gt;border-spacing (longueur) &lt;/li&gt;    &lt;li&gt;border-top-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;border-top-width (longueur) &lt;/li&gt;    &lt;li&gt;border-width (longueur) &lt;/li&gt;    &lt;li&gt;bottom (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;crop (&lt;i&gt;rectangle&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;font-size (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;font-weight (&lt;i&gt;nombre&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;grid-* (&lt;i&gt;divers&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;height (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;left (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;letter-spacing (longueur) &lt;/li&gt;    &lt;li&gt;line-height (&lt;i&gt;nombre, longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;margin-bottom (longueur) &lt;/li&gt;    &lt;li&gt;margin-left (longueur) &lt;/li&gt;    &lt;li&gt;margin-right (longueur) &lt;/li&gt;    &lt;li&gt;margin-top (longueur) &lt;/li&gt;    &lt;li&gt;max-height (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;max-width (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;min-height (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;min-width (longueur et &lt;i&gt;pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;opacity (&lt;i&gt;nombre&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;outline-color (&lt;i&gt;couleur&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;outline-offset (&lt;i&gt;entier&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;outline-width (longueur) &lt;/li&gt;    &lt;li&gt;padding-bottom (longueur) &lt;/li&gt;    &lt;li&gt;padding-left (longueur) &lt;/li&gt;    &lt;li&gt;padding-right (longueur) &lt;/li&gt;    &lt;li&gt;padding-top (longueur) &lt;/li&gt;    &lt;li&gt;right (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;text-indent (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;text-shadow (&lt;i&gt;ombre&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;top (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;vertical-align (&lt;i&gt;keywords, longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;visibility (&lt;i&gt;visibilité)&lt;/i&gt; &lt;/li&gt;    &lt;li&gt;width (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;word-spacing (&lt;i&gt;longueur et pourcentage&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;z-index (&lt;i&gt;entier&lt;/i&gt;) &lt;/li&gt;    &lt;li&gt;zoom (&lt;i&gt;nombre&lt;/i&gt;) &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;SVG&lt;/h3&gt;  &lt;p&gt;Les propriétés des objets SVG sont animables lorsque qu’elles sont définies comme &lt;b&gt;animatable:true&lt;/b&gt; dans les spécifications SVG : &lt;a href="http://www.w3.org/TR/SVG/struct.html"&gt;http://www.w3.org/TR/SVG/struct.html&lt;/a&gt;. Cependant, à l’heure où j’ai écrit cet article, je n’ai pas réussi à combiner avec succès des animations CSS3 directement sur des éléments SVG dans aucune des dernières versions des navigateurs.&amp;#160; Les exemples que vous pourrez trouver utilisent alors une petite astuce: il embarque les ressources SVG dans différents DIV eux-mêmes animés via CSS3 comme l’exemple &lt;a href="http://www.anthonycalzadilla.com/i-twitty-the-fool/"&gt;I twitty the fool&lt;/a&gt; d’Anthony.&lt;/p&gt;  &lt;h3&gt;Déclarations&lt;/h3&gt;  &lt;p&gt;Pour déclarer une animation dans un fichier CSS, voici le type de code générique que vous aurez à taper:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@keyframes &lt;/span&gt;nom_de_l_animation {
  &lt;span style="color: red"&gt;&lt;font color="#000000"&gt;from&lt;/font&gt; &lt;/span&gt;&lt;span style="color: blue"&gt;{
   &lt;font color="#ff0000"&gt;propriété_à_animer:&lt;/font&gt; valeur_initiale&lt;/span&gt;;
  }
  50% {
     &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;propriété&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_à_animer:&lt;/font&gt; valeur_intermédiaire&lt;/span&gt;;
  }
  &lt;span style="color: maroon"&gt;to &lt;/span&gt;{
    &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;propriété&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_à_animer:&lt;/font&gt; valeur_finale&lt;/span&gt;;
  }
}&lt;/pre&gt;

&lt;p&gt;qui pourrait également s’écrire ainsi :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@keyframes &lt;/span&gt;nom_de_l_animation {
    0% {
        &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;propriété&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_à_animer:&lt;/font&gt; valeur_initiale&lt;/span&gt;;
    }
    50% {
        &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;propriété&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_à_animer:&lt;/font&gt; valeur_intermédiaire&lt;/span&gt;;
    }
    100% {
        &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;propriété&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_à_animer:&lt;/font&gt; valeur_finale&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;Cette animation définit 3 étapes 0, 50 &amp;amp; 100%. Pour construire une animation valide, vous devez au moins avoir un &lt;strong&gt;&lt;em&gt;from&lt;/em&gt;&lt;/strong&gt; (ou 0%) et un &lt;strong&gt;&lt;em&gt;to&lt;/em&gt;&lt;/strong&gt; (ou 100%) soit 2 étapes minimum. Après cela, vous pouvez ajouter autant d’étapes (ou keyframes) que vous le souhaitez entre 0 et 100% pour contrôler de manière fine les différentes phases de votre animation.&lt;/p&gt;

&lt;p&gt;Une fois la définition faite, vous pouvez l’affecter à un élément en utilisant les sélecteurs CSS3 classiques et il ne vous restera plus qu’à configurer les options de l’animation. Pour cela, voici le type de bloc qu’il faut utiliser:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;#id_de_l_element_html &lt;/span&gt;{
    &lt;span style="color: red"&gt;animation-name&lt;/span&gt;: &lt;span style="color: blue"&gt;nom_de_l_animation&lt;/span&gt;;
    &lt;span style="color: red"&gt;animation-duration&lt;/span&gt;: &lt;span style="color: blue"&gt;nombre_de_secondes s&lt;/span&gt;;
    &lt;span style="color: red"&gt;animation-iteration-count&lt;/span&gt;: &lt;span style="color: blue"&gt;nombre | infinite&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;Pour mieux comprendre, observons un exemple réel. Tout d’abord, comme la spécification CSS3 Animations est toujours à l’état de brouillon, vous devez utiliser les bons préfixes des éditeurs de navigateurs. Prenons par exemple IE10 dont le préfixe est –ms donc. Regardons maintenant comme la tête de notre TB-TT est animée.&lt;/p&gt;

&lt;p&gt;Voici la déclaration de l’animation:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@-ms-keyframes &lt;/span&gt;rotate-skull {
    0% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(0deg)
    &lt;/span&gt;}
    25% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(15deg)
    &lt;/span&gt;}
    50% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(-5deg)
    &lt;/span&gt;}
    55% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(0deg)
    &lt;/span&gt;}
    75% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(-10deg)
    &lt;/span&gt;}
    100% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(0deg)
    &lt;/span&gt;}
} &lt;/pre&gt;

&lt;p&gt;Nous avons définit 6 étapes (0, 25, 50, 55, 75 &amp;amp; 100%) qui vont agir sur la propriétés CSS3 2D Transform en jouant sur la valeur de la rotation.&lt;/p&gt;

&lt;p&gt;Cette animation est alors appliquée via cette règle CSS:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;#skull 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation-name&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate-skull&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-duration&lt;/span&gt;: &lt;span style="color: blue"&gt;7s&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-iteration-count&lt;/span&gt;: &lt;span style="color: blue"&gt;infinite&lt;/span&gt;;       
}&lt;/pre&gt;

&lt;p&gt;On vise l’élément &amp;lt;div&amp;gt; ayant pour “id=&lt;strong&gt;skull&lt;/strong&gt;” et nous lui appliquons l’animation nommée “&lt;strong&gt;rotate-skull&lt;/strong&gt;” dessus. L’animation devra être terminée en &lt;strong&gt;7s&lt;/strong&gt; et devra être jouée un nombre &lt;strong&gt;infini&lt;/strong&gt; de fois.&lt;/p&gt;

&lt;p&gt;Voici le résultat animé si votre navigateur supporte CSS3 Animations :&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="200" src="http://david.blob.core.windows.net/html5/css3atat/AnimSkullATAT.htm" width="400" scrolling="no"&gt;&lt;/iframe&gt;

&lt;p&gt;Nous aurions très bien pu d’ailleurs écrire cette règle de manière raccourcie ainsi :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;#skull &lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate-skull 7s infinite&lt;/span&gt;;
}&lt;/pre&gt;
L’animation sera lancée dès qu’une règle qui correspond sera appliquée. Vous pouvez donc jouer ou stopper une animation simplement par &lt;strong&gt;JavaScript&lt;/strong&gt; ou via CSS3 en travaillant sur &lt;strong&gt;les classes affectées à un tag&lt;/strong&gt;. 

&lt;h3&gt;Animations non linéaires&lt;/h3&gt;

&lt;p&gt;La propriété “animation-timing-function” doit être utilisée si vous souhaitez mettre en place des animations non linéaires. Vous pouvez même mixer plusieurs types d’animations entre chaque keyframe si vous le souhaitez.&lt;/p&gt;

&lt;p&gt;CSS3 animations va utiliser une &lt;a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves"&gt;courbe de Bézier cubique&lt;/a&gt; pour “fluidifier” la transition en calculant une vitesse de progression différente tout au long de sa durée.&lt;/p&gt;

&lt;p&gt;Les valeurs suivantes sont supportées: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;linear&lt;/em&gt;: Vitesse constante (comportement par défaut) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;cubic-bezier&lt;/em&gt;: La vitesse sera calculée grâce à une courbe de Bézier cubique définie par deux points de contrôles : P0 et P1 (Il faudra donc fournir 4 paramètres : P0x, P0y, P1x et P1y). &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease&lt;/em&gt;: La vitesse sera calculée avec la formule suivante : cubic-bezier(0.25, 0.1, 0.25, 1) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease-in&lt;/em&gt;: La vitesse sera calculée avec la formule suivante : cubic-bezier(0.42, 0, 1, 1) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease-inout&lt;/em&gt;: La vitesse sera calculée avec la formule suivante : cubic-bezier(0.42, 0, 0.58, 1) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease-out&lt;/em&gt;: La vitesse sera calculée avec la formule suivante : cubic-bezier(0, 0, 0.58, 1) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voici un outil de simulation écrit par &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/24/fr-introduction-224-css3-transitions.aspx"&gt;David Catuhe&lt;/a&gt; qui utilise du JavaScript 100% pur jus pour démontrer l’impact de chacune des fonctions non linéaires:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="650" src="http://www.catuhe.com/msdn/transitions/easingfunctions.htm" width="100%"&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; cet outil utilise du SVG “in-line” supporté par Firefox, Chrome, Opera 11.60 &amp;amp; IE9/10. Il ne fonctionnera donc pas correctement sous Opera 11.50 et sous Safari sur iPad.&lt;/p&gt;

&lt;p&gt;Ce super outil utilise donc SVG. Vous pouvez alors même jouer avec votre souris à éditer la courbe de la fonction “custom”. Si vous souhaitez en savoir davantage sur cet outil, rendez-vous à nouveau sur l’article de David Catuhe sur les transitions.&lt;/p&gt;

&lt;p&gt;Si votre navigateur supporte les animations CSS3, regardons maintenant une démo toute simple utilisant &lt;strong&gt;les fonctions non linéaires pour bouger un élément &amp;lt;canvas&amp;gt; via CSS3&lt;/strong&gt; contenant un sprite animé.&lt;/p&gt;

&lt;p&gt;Voici le bloc de CSS3 Animations qui sera utilisé dans cette démo:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@-ms-keyframes &lt;/span&gt;demo {
    &lt;span style="color: red"&gt;&lt;font color="#000000"&gt;from&lt;/font&gt; &lt;/span&gt;&lt;span style="color: blue"&gt;{
    &lt;font color="#ff0000"&gt;-ms-animation-timing-function&lt;/font&gt;: ease&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;translateX(0px)&lt;/span&gt;;
    }
    50% {
    &lt;span style="color: red"&gt;-ms-animation-timing-function&lt;/span&gt;: &lt;span style="color: blue"&gt;ease-in&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;translateX(300px)&lt;/span&gt;;
    }
    &lt;span style="color: maroon"&gt;to &lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation-timing-function&lt;/span&gt;: &lt;span style="color: blue"&gt;ease-inout&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;translateX(900px)&lt;/span&gt;;
    }
}

&lt;span style="color: maroon"&gt;#testCanvas
&lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation-delay&lt;/span&gt;: &lt;span style="color: blue"&gt;0s&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-duration&lt;/span&gt;: &lt;span style="color: blue"&gt;6s&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-iteration-count&lt;/span&gt;: &lt;span style="color: blue"&gt;infinite&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-name&lt;/span&gt;: &lt;span style="color: blue"&gt;demo&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;Ainsi que toutes les variations de préfixes pour pouvoir fonctionner sous Google Chrome &amp;amp; Mozilla Firefox. Voici le résultat en image:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="90" src="http://david.blob.core.windows.net/html5/css3animcanvas/sprites.htm" width="1000"&gt;&lt;/iframe&gt;

&lt;p&gt;Si votre navigateur ne supporte pas CSS3 Animation mais uniquement canvas, l’animation du sprite en train de courir devrait être relativement statique car le personnage ne bougera pas sur toute la largeur de l’écran.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/b&gt; si vous souhaitez en savoir davantage sur &amp;lt;canvas&amp;gt; et l’animation de sprites, je vous invite à lire cet article : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx"&gt;Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Délais&lt;/h3&gt;

&lt;p&gt;Ta propriété “animation-delay” permet tout simplement de lancer l’animation un peu plus tard que prévu. Rien de bien sorcier.&lt;/p&gt;

&lt;h3&gt;Evènements&lt;/h3&gt;

&lt;p&gt;3 &lt;strong&gt;évènements&lt;/strong&gt; peuvent être levés pendant une animation. Ils sont nommés “Animation&lt;em&gt;Start&lt;/em&gt;”, “Animation&lt;i&gt;End&lt;/i&gt;” et “Animation&lt;em&gt;Iteration&lt;/em&gt;”. En fonction du navigateur, le nom correctement préfixé sera alors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Chrome:&lt;i&gt; webkitAnimationEnd&lt;/i&gt; &lt;/li&gt;

  &lt;li&gt;Firefox: &lt;i&gt;mozAnimationEnd&lt;/i&gt; &lt;/li&gt;

  &lt;li&gt;Internet Explorer:&lt;i&gt; MSAnimationEnd&lt;/i&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ces évènements vous donneront les détails suivants:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;i&gt;animationName&lt;/i&gt;: nom de l’animation ayant levée l’évènement &lt;/li&gt;

  &lt;li&gt;&lt;i&gt;elapsedTime&lt;/i&gt;: le temps écoulé depuis le début de l’animation, en secondes &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En voici un exemple d’usage pour IE10 :&lt;/p&gt;

&lt;pre class="code"&gt;elementToAnimate.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;MSAnimationEnd&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    alert(&lt;span style="color: maroon"&gt;&amp;quot;the end !&amp;quot;&lt;/span&gt;);
}, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;h3&gt;D’autres choses à propos des animations CSS3&lt;/h3&gt;

&lt;p&gt;Les animations CSS3 sont vraiment utiles pour 2 raisons principales :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;L’accélération matérielle:&lt;/b&gt; les animations CSS3 sont la plupart du temps gérées directement par le GPU et peuvent donc produire des résultats plus fluides. Cela peut donc être particulièrement intéressant pour les scénarios visant les périphériques mobiles. &lt;/li&gt;

  &lt;li&gt;&lt;b&gt;Meilleure séparation entre le code et le design&lt;/b&gt;: je sais qu’il existe de nombreux débats à ce sujet mais avec David, nous avons tendance à penser qu’un développeur ne devrait pas s’occuper des animations ou de toute autre chose ayant rapport au design autant que possible. De la même manière, un designer/graphiste ne devrait pas s’occuper de JavaScript. CSS3 offre donc cette possibilité et peut permettre aux designers/intégrateurs de travailler avec leurs outils classiques pour générer les animations sur les bons éléments, les changements entre écrans, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour illustrer l’importance des performances, sachez que le jeu HTML5 suivant &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;HTML5 Platformer&lt;/a&gt; que j’ai écrit et utilisant une balise &amp;lt;canvas&amp;gt; en plein écran tourne à 60 fps sous IE9/IE10 sur mon PC mais à maximum 10 fps sur un iPad 2. C’est tout simplement du au fait que le CPU de l’iPad soit bien moins puissant et qu’il n’utilise pas encore l’accélération matérielle sur le tag &amp;lt;canvas&amp;gt;. L’utilisation de transitions ou d’animations CSS3 pour animer plusieurs petits éléments &amp;lt;canvas&amp;gt; pourrait ainsi fournir un gain très net de performance pour ce jeu. Ne l’oubliez donc pas lorsque vous aurez un projet visant les périphériques mobiles !&lt;/p&gt;
&lt;a name="support"&gt;
  &lt;h2&gt;Support dans les navigateurs&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Depuis la Platform Preview 3 d’IE10 disponible au sein de &lt;a href="http://msdn.microsoft.com/en-us/windows/apps/br229516"&gt;Windows 8 Developer Preview&lt;/a&gt;, nous supportons les animations CSS3. Par ailleurs, comme vous pouvez le voir sur le rapport suivi généré depuis le site &lt;a href="http://caniuse.com/#search=CSS3 animation"&gt;caniuse.com&lt;/a&gt;, les animations CSS3 sont désormais supportées dans un large panel de navigateurs :&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8546.clip_5F00_image002_5F00_3DD1FC3C.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;Mais comme la spécification n’est pas encore terminée (&lt;em&gt;working draft&lt;/em&gt;), vous devez utiliser les préfixes tels que –ms, –moz, –webkit et –o pour construire des applications compatibles cross-navigateurs.&lt;/p&gt;

&lt;p&gt;Mais la question qui devrait alors rapidement se poser est la suivante: comment prendre en charge les navigateurs ne supportant pas cette nouvelle fonctionnalité ?&lt;/p&gt;

&lt;p&gt;La première option consiste simplement à ne rien faire. Grâce à la beauté de la dégradation élégante (ou &lt;em&gt;graceful degradation&lt;/em&gt; en anglais), vous pouvez simplement offrir une image statique à l’utilisateur. Cela est par exemple le cas des 2 démonstrations d’Anthony : &lt;a href="http://www.anthonycalzadilla.com/i-twitty-the-fool/"&gt;I Twitty the Fool!&lt;/a&gt; et &lt;a href="http://www.anthonycalzadilla.com/css3-ATAT/"&gt;Pure CSS3 AT-AT Walker&lt;/a&gt; . Lorsqu’affichés sous IE9, vous avez l’impression de n’avoir qu’une image statique. Cependant, lorsque vous les affichez sous IE10, le même code affiche alors de belles animations. Les utilisateurs sous IE10 disposeront d’une version améliorée tant dis que les utilisateurs sous IE9 continueront de pouvoir bénéficier du site. Plus votre navigateur sera moderne, plus vous aurez de bonus visuels.&lt;/p&gt;

&lt;p&gt;La deuxième option consiste à détecter le support de la fonctionnalité via une librairie JavaScript comme Modernizr puis de tenter de fournir la même animation avec une autre librairie JavaScript qui s’occupera de copier les animations CSS3. C’est ce que nous appelons communément un mécanisme de “fallback”. Malheureusement, je n’ai pas réussi à trouver aujourd’hui une librairie fonctionnelle et complète pouvant totalement remplacer les animations CSS3 lorsque non supportées par le navigateur.&lt;/p&gt;

&lt;p&gt;Il n’en fallait pas plus pour me donner l’envie d’en écrire une petite plus ou moins spécialement étudiée pour notre exemple initial de TB-TT.&lt;/p&gt;
&lt;a name="fallback"&gt;
  &lt;h2&gt;Librairie JavaScript pour simuler les animations CSS3&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Les animations ne sont finalement qu’une série de transitions séparées pour une certaine durée définie par les keyframes. J’ai donc ré-utilisé les concepts introduits par David Catuhe dans sa librairie pour palier à l’absence éventuelle de CSS3 Transitions. Je vous laisse donc le soin de revoir son article détaillant les concepts derrière ce code si ce n’est déjà fait.&lt;/p&gt;

&lt;p&gt;De mon côté, j’ai ajouté le support des animations sur les propriétés rotation &amp;amp; translation de CSS3 2D tranform ainsi qu’une manière d’itérer à travers chacun des keyframes.&lt;/p&gt;

&lt;p&gt;Voici la partie principale de la librairie que vous devrez étudier :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Objet Animation 
// Il a besoin de l’élément HTML visé, du nom de l’animation, de sa durée, du nombre de fois qu’il faut la jouer et
// des keyframes contenus au sein d’un tableau
// Imaginez ainsi une animation comme une simple séquence de transitions jouées un certain nombre de fois
&lt;/span&gt;ANIMATIONSHELPER.animation = &lt;span style="color: blue"&gt;function &lt;/span&gt;(target, name, duration, iterationcount, keyframes) {
    &lt;span style="color: #006400"&gt;// on sauvegarde les valeurs de nos propriétés
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.name = name;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.duration = duration;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.iterationcount = iterationcount;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.target = target;

    &lt;span style="color: blue"&gt;var &lt;/span&gt;elapsedtime = 0;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;keyframeduration = 0;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;elapsedtime = 0;

    &lt;span style="color: #006400"&gt;// On transforme les pourcentages de chaque keyframe en une valeur de durée
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; keyframes.length; i++) {
        keyframeduration = ((keyframes[i].percentage * duration) / 100) - elapsedtime;
        keyframes[i].duration = keyframeduration;
        elapsedtime += keyframeduration;
    }

    &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition = { isPlaying: &lt;span style="color: blue"&gt;false &lt;/span&gt;};
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframes = keyframes;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframesCount = keyframes.length;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex = 0;

    &lt;span style="color: #006400"&gt;// La fonction nextTransition() retourne la prochaine transition à jouer
    // en fonction du keyframe courant à lancer
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.nextTransition = &lt;span style="color: blue"&gt;function &lt;/span&gt;(keyframe, ease, customEaseP1X, customEaseP1Y, customEaseP2X, customEaseP2Y) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;properties = [];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;finalValues = [];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;transition;

        &lt;span style="color: #006400"&gt;// Comparé au TRANSITIONSHELPER original de David Catuhe
        // Nous avons besoin de code spécifique supplémentaire pour jouer sur les valeurs de 2D Transform
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(keyframe.propertyToAnimate === &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;) {
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; keyframe.transformType.length; i++) {
                properties.push(keyframe.transformType[i].type);
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(keyframe.transformType[i].type == &lt;span style="color: maroon"&gt;&amp;quot;rotate&amp;quot;&lt;/span&gt;) {
                    finalValues.push({ deg: keyframe.transformType[i].value1 });
                }
                &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                    finalValues.push({ x: keyframe.transformType[i].value1, y: keyframe.transformType[i].value2 });
                }
            }

            &lt;span style="color: #006400"&gt;// Création d’une nouvelle transition
            &lt;/span&gt;transition = {
                name: &lt;span style="color: blue"&gt;this&lt;/span&gt;.name + &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex,
                target: &lt;span style="color: blue"&gt;this&lt;/span&gt;.target,
                properties: properties,
                finalValues: finalValues,
                originalValues: ANIMATIONSHELPER.extractValues(target.style[ANIMATIONSHELPER.currentTransformProperty], &lt;span style="color: blue"&gt;this&lt;/span&gt;.name),
                duration: keyframe.duration,
                startDate: (&lt;span style="color: blue"&gt;new &lt;/span&gt;Date).getTime(),
                currentDate: (&lt;span style="color: blue"&gt;new &lt;/span&gt;Date).getTime(),
                ease: ease,
                customEaseP1X: customEaseP1X,
                customEaseP2X: customEaseP2X,
                customEaseP1Y: customEaseP1Y,
                customEaseP2Y: customEaseP2Y,
                isPlaying: &lt;span style="color: blue"&gt;true&lt;/span&gt;,
                type: &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;
            &lt;/span&gt;};

            &lt;span style="color: blue"&gt;return &lt;/span&gt;transition;
        }
        &lt;span style="color: #006400"&gt;// Si c’est une propriété simple à animer, on peut tout simplement utiliser le TRANSITIONSHELPER presque tel quel
        &lt;/span&gt;&lt;span style="color: blue"&gt;else &lt;/span&gt;{
            &lt;span style="color: blue"&gt;return &lt;/span&gt;TRANSITIONSHELPER.transition(&lt;span style="color: blue"&gt;this&lt;/span&gt;.target, keyframe.propertyToAnimate, keyframe.value, keyframe.duration, TRANSITIONSHELPER.easingFunctions.linear);
        }
    };

    &lt;span style="color: #006400"&gt;// chaque instance d’animation dispose d’une fonction tick
    // qui sera appelée toutes les 17 ms (pour tenter de viser les 60 fps)
    // Ce ticker surveille l’état de la transition en cours et 
    // en créé une nouvelle dès qu’elle est terminée ou morte
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.tick = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.iterationcount &amp;gt; 0) {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition.isPlaying) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition = &lt;span style="color: blue"&gt;this&lt;/span&gt;.nextTransition(&lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframes[&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex], ANIMATIONSHELPER.easingFunctions.linear);
                &lt;span style="color: #006400"&gt;// Nous utilisons le ticker global de ANIMATIONSHELPER uniquement pour les transformations 2D
                // Sinon, on utilise celui de la librairie TRANSITIONSHELPER
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition.type === &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;) {
                    ANIMATIONSHELPER.currentTransitions.push(&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition);
                }
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex++;

                &lt;span style="color: #006400"&gt;// Nous avons atteint le dernier keyframe (100%). On peut recommencer au début donc.
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex &amp;gt;= &lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframesCount) {
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex = 0;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.iterationcount--;
                }
            }
        }
    };
};&lt;/pre&gt;

&lt;p&gt;La 1ère partie du code parcourt la collection des keyframes pour calculer la durée exacte engendrée par chacun des pourcentages. On définit alors une fonction nextTransition() qui va construire dynamiquement la prochaine transition à jouer en se basant sur l’index courant dans la collection de keyframes associés à l’animation en cours. Pour finir, nous avons une function tick() qui surveille l’état de la transition actuellement affectée. Dès que cette dernière se termine, nous demandons la prochaine transition, on la pousse sur la pile des transitions à jouer et on bouge les différents indexes. &lt;/p&gt;

&lt;p&gt;La function tick() est rappelée grâce à ce code :&lt;/p&gt;

&lt;pre class="code"&gt;ANIMATIONSHELPER.launchAnimation = &lt;span style="color: blue"&gt;function &lt;/span&gt;(animation) {
    &lt;span style="color: #006400"&gt;// On lance le service global de ticker si nécessaire
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(ANIMATIONSHELPER.tickIntervalID == 0) {
        ANIMATIONSHELPER.tickIntervalID = setInterval(ANIMATIONSHELPER.tick, 17);
    }

    &lt;span style="color: #006400"&gt;// Petite closure pour lancer la méthode tick sur la bonne instance d’animation
    &lt;/span&gt;setInterval(&lt;span style="color: blue"&gt;function &lt;/span&gt;() { animation.tick(); }, 17);
};&lt;/pre&gt;

&lt;p&gt;Pour finir, nous avons ce type de code pour nous aider à fabriquer les keyframes :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Objet pour construire des keyframes génériques (et pas pour les CSS3 2D Transform donc)
&lt;/span&gt;ANIMATIONSHELPER.keyframe = &lt;span style="color: blue"&gt;function &lt;/span&gt;(percentage, propertyToAnimate, value) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.percentage = percentage;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.propertyToAnimate = propertyToAnimate;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.value = value;
};

&lt;span style="color: #006400"&gt;//Objet pour construire des keyframes dédiés aux rotations
&lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe = &lt;span style="color: blue"&gt;function &lt;/span&gt;(percentage, value) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.percentage = percentage;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.propertyToAnimate = &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.transformType = [];
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.transformType.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.transformType(&lt;span style="color: maroon"&gt;&amp;quot;rotate&amp;quot;&lt;/span&gt;, value));
};&lt;/pre&gt;

&lt;p&gt;Pour illustrer son usage, amusons-nous à refaire le 1er exemple d’animations simples effectuées sur la tête de notre TB-TT avec cette librairie :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// nombre de fois que vous souhaitez voir l’animation tourner
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;iterationsNumber = 100;

&lt;span style="color: blue"&gt;var &lt;/span&gt;skullElement = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;skull&amp;quot;&lt;/span&gt;);
&lt;span style="color: blue"&gt;var &lt;/span&gt;keyframes = [];
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(25, 15));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(50, -5));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(55, 0));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(75, -10));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(100, 0));

&lt;span style="color: blue"&gt;var &lt;/span&gt;animation1 = &lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.animation(skullElement, &lt;span style="color: maroon"&gt;&amp;quot;rotate-skull&amp;quot;&lt;/span&gt;, 7000, 
                                                iterationsNumber, keyframes);

ANIMATIONSHELPER.launchAnimation(animation1, ANIMATIONSHELPER.easingFunctions.linear);&lt;/pre&gt;

&lt;p&gt;Et voici le résultat animé qui devrait maintenant fonctionner dans tous les navigateurs supportant CSS3 2D Transform :&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="200" src="http://david.blob.core.windows.net/html5/css3atat/indexSkullJS.htm" width="400" scrolling="no"&gt;&lt;/iframe&gt;

&lt;p&gt;Pour finir, si l’on revient sur la toute première démonstration au début de cet article, vous verrez qu’elle utilise Modernizr pour vérifier le support des animations CSS3. Si ce n’est pas le cas, on charge le code qui s’occupera de copier le comportement défini par les keyframes présents dans master.css, moz-master.css &amp;amp; ms-master.css :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// On vérifie le support des animations CSS3
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(!Modernizr.cssanimations) {
    &lt;span style="color: #006400"&gt;// Si ce n’est pas le cas, on invoque notre librairie JavaScript de secours 
    &lt;/span&gt;supportElement.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;CSS3 Animations &amp;lt;strong&amp;gt;are not supported&amp;lt;/strong&amp;gt;&amp;quot;&lt;/span&gt;;
    LoadJSAnimationsFallback();
}
&lt;span style="color: blue"&gt;else &lt;/span&gt;{
    &lt;span style="color: #006400"&gt;// Si CSS3 Animations est supportée, nous n’avons rien à faire. 
    // Les feuilles de style *master.css seront automatiquement appliquées et utilisées.
    &lt;/span&gt;supportElement.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;CSS3 Animations &amp;lt;strong&amp;gt;are supported&amp;lt;/strong&amp;gt;&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;La fonction &lt;em&gt;LoadJSAnimationsFallback()&lt;/em&gt; est définie dans le fichier &lt;em&gt;jsfallback-master.js&lt;/em&gt; qui contient simplement les déclarations de keyframes ainsi que les 19 animations nécessaires à recréer le comportement défini par Anthony en pur CSS3. Avec cette approche, le designer doit donc potentiellement ré-écrire toutes ses règles en faisant appel à la librairie JavaScript. Une autre approche pourrait consister à parser l’un des fichiers CSS en le téléchargeant via une requête XHR puis d’en déduire dynamiquement les appels JavaScript à faire vers la librairie. Cela nécessite cependant bien plus de travail car il vous faut quasiment ré-implémenter l’ensemble de la spécification CSS3 Animations en JavaScript !&lt;/p&gt;

&lt;p&gt;Vous avez normalement maintenant une idée de la manière de créer une mécanisme de “fallback” pour supporter le plus grand nombre de navigateurs tout en commençant à utiliser les dernières spécifications CSS3.&lt;/p&gt;

&lt;p&gt;Vous pouvez télécharger les fichiers pour l’exemple principal de cet article ici : &lt;a title="http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip" href="http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip"&gt;http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Il contient les versions non minimisées des fichiers JavaScript animationsHelper.js, transitionsHelper.js, jsfallback-master.js ainsi que les différentes déclinaisons des feuilles de style CSS3 pour les différentes préfixes.&lt;/p&gt;
&lt;a name="conclusion"&gt;
  &lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Les animations CSS3 représente une technologie puissante pour repousser les applications HTML5 vers un nouveau niveau. Elles offrent des scénarios intéressants. Les designers/intégrateurs peuvent les utiliser pour créer une nouvelle génération d’expérience utilisateur avec des écrans rapides et fluides sans avoir besoin de faire appel à un développeur. Comme elles sont la plupart du temps accélérées matériellement, les développeurs doivent également malgré tout y jeter un œil. Pour finir, les 2 populations peuvent collaborer. Les designers pourraient concevoir une série d’animations prédéfinies répondant aux besoins les plus courants et offrant une expérience homogène. Les développeurs pourraient alors récupérer le fruit de ce travail pour en créer des librairies JavaScript qui implémenteront ces animations. Ces librairies pourraient alors offrir une manière transparente de fournir 2 implémentations sous-jacentes : de la génération dynamique d’animations CSS3 à la volée ou une version de secours en pur JavaScript pour les anciens navigateurs. &lt;/p&gt;

&lt;h3&gt;Pour aller plus loin&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Article sur les transitions CSS3 par David Catuhe: &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/24/fr-introduction-224-css3-transitions.aspx"&gt;Introduction aux transitions CSS3&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Les spécifications CSS3 Animations officielles : &lt;a title="http://www.w3.org/TR/css3-animations/" href="http://www.w3.org/TR/css3-animations/"&gt;http://www.w3.org/TR/css3-animations/&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Notre site IE Test Drive pour jouer avec les CSS3 animations: &lt;a title="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm" href="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm"&gt;http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;D’autres articles intéressants : 
    &lt;ul&gt;
      &lt;li&gt;Alsacréations : &lt;a title="http://www.alsacreations.com/tuto/lire/1299-timing-des-animations-et-des-transitions-en-css3.html" href="http://www.alsacreations.com/tuto/lire/1299-timing-des-animations-et-des-transitions-en-css3.html"&gt;Timing des animations et des transitions en CSS3&lt;/a&gt; &lt;/li&gt;

      &lt;li&gt;Les évènements sont relativement limités selon la spécification CSS3 Animations. Joe Lambert propose alors une solution intéressante pour lever un évènement sur chacun des keyframes pour mieux suivre le déroulement de l’animation : &lt;a href="http://blog.joelambert.co.uk/2011/05/20/css-animation-keyframe-events-javascript-solution/"&gt;CSS Animation Keyframe Events (Javascript solution)&lt;/a&gt;&amp;#160; &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;David Rousset&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10244424" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/CSS3/">CSS3</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category></item><item><title>Introduction to CSS3 Animations</title><link>http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx</link><pubDate>Mon, 05 Dec 2011 23:08:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10244420</guid><dc:creator>David Rousset</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10244420</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx#comments</comments><description>&lt;meta content="IE=edge" http-equiv="X-UA-Compatible" /&gt;&lt;script&gt;
$(function() {
// run the currently selected effect
function runEffect(target) {
// get effect type from 
var selectedEffect = "clip";

var options = {};

// run the effect
target.toggle(500 );
};

$("#properties").hide();
$("#types").hide();

// set effect from select menu value
$( "#propertiesLink" ).click(function() {
runEffect($("#properties"));
return false;
});

$( "#typesLink" ).click(function() {
runEffect($("#types"));
return false;
});
});
&lt;/script&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6443.TestAnimations_5F00_4312DF8D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="TestAnimations" border="0" alt="TestAnimations" align="right" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2727.TestAnimations_5F00_thumb_5F00_59194B1F.jpg" width="300" height="201" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Today’s HTML5 applications can provide awesome experiences thanks to the new CSS3 specifications. One of them is &lt;b&gt;CSS3 Animations&lt;/b&gt;. It can help you building rich animations on HTML elements. This can provide interesting feedbacks to the users and enables fast &amp;amp; fluid UIs. As those new animations are most of time hardware accelerated by the GPU, they definitely raise up the quality bar of the new generation of HTML5 applications.&lt;/p&gt;  &lt;p&gt;According to the “CSS Animation Module Level 3” specification on the &lt;a href="http://www.w3.org/TR/css3-animations/"&gt;W3C site&lt;/a&gt;, CSS3 Animations &lt;i&gt;introduces defined animations, which specify the values that CSS properties will take over a given time interval. This specification is an extension to CSS Transitions&lt;/i&gt;.&lt;/p&gt;  &lt;p&gt;As CSS3 Animation is an &lt;b&gt;extension to CSS3 Transitions&lt;/b&gt;, you should first read the article of my colleague David Catuhe on Transitions here: &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/01/css3-transitions.aspx"&gt;Introduction to CSS3 Transitions&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We’ll see in this article an interesting demo highlighting the potential of CSS3 animations, how to build simple animations &amp;amp; how to handle fallback in JavaScript:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="#intro"&gt;CSS3 Animations&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#support"&gt;Browsers Support&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#fallback"&gt;CSS3 Animations JavaScript fallback library&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Let’s first start by quickly demonstrating what CSS3 Animations are. Here is a sample animation of a StarWars AT-AT which uses CSS3 Animations to animate parts of the transport (and which will fall back to JavaScript if your browser doesn’t support CSS3 Animations): &lt;/p&gt; &lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="570" src="http://david.blob.core.windows.net/html5/css3atat/index.htm" width="716" scrolling="no"&gt;&lt;/iframe&gt;  &lt;p&gt;You can test this sample also in a separate window here: &lt;a title="http://david.blob.core.windows.net/html5/css3atat/index.htm" href="http://david.blob.core.windows.net/html5/css3atat/index.htm"&gt;http://david.blob.core.windows.net/html5/css3atat/index.htm&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; this sample has been tested successfully with native animations under IE10 PP3/PP4, Chrome 15, Firefox 8 &amp;amp; iPad 2 and with JS fallback under IE9 desktop &amp;amp; mobile (Windows Phone). For an unknown reason, it behaves in weird way under Opera 11.50 but works fine with the 11.60. Moreover, our lovely blogging platform is most of the time forcing the IE9 rendering engine via a meta tag. To force it back to the IE10 standards mode, press the F12 key and change the value of “Document Mode” back to IE10. Otherwise, view the demo in a separate window.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;This sample is based on the awesome work done by &lt;a href="http://twitter.com/acalzadilla"&gt;Anthony Calzadilla&lt;/a&gt;. You can check other incredible demos on his website here: &lt;a href="http://www.anthonycalzadilla.com"&gt;http://www.anthonycalzadilla.com&lt;/a&gt; . I’m a huge fan of the &lt;a href="http://www.anthonycalzadilla.com/i-twitty-the-fool/"&gt;I twitty the fool&lt;/a&gt; sample using SVG &amp;amp; CSS3 Animation for instance. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4643.wlEmoticon_2D00_winkingsmile_5F00_101C70F9.png" /&gt;&lt;/p&gt; &lt;a name="intro"&gt;   &lt;h2&gt;CSS3 Animations&lt;/h2&gt; &lt;/a&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;Let’s first review on what you can play to build the animations. CSS3 Animations works basically on the same values as CSS3 Transition. &lt;/p&gt;  &lt;p&gt;Here they are: &lt;a id="typesLink"&gt;click here to display/hide them&lt;/a&gt;&lt;/p&gt;  &lt;ul id="types"&gt;   &lt;li&gt;&lt;strong&gt;color&lt;/strong&gt;: interpolated via red, green, blue and alpha components (treating each as a number, see below) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;length&lt;/strong&gt;: interpolated as real numbers. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;percentage&lt;/strong&gt;: interpolated as real numbers. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;integer&lt;/strong&gt;: interpolated via discrete steps (whole numbers). The interpolation happens in real number space and is converted to an integer using &lt;code&gt;floor()&lt;/code&gt;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;number&lt;/strong&gt;: interpolated as real (floating point) numbers. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;transform list&lt;/strong&gt;: see CSS Transforms specification: &lt;a href="http://www.w3.org/TR/css3-2d-transforms/"&gt;http://www.w3.org/TR/css3-2d-transforms/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;rectangle&lt;/strong&gt;: interpolated via the x, y, width and height components (treating each as a number). &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;visibility&lt;/strong&gt;: interpolated via a discrete step. The interpolation happens in real number space between 0 and 1, where 1 is &amp;quot;visible&amp;quot; and all other values are &amp;quot;hidden&amp;quot;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;shadow&lt;/strong&gt;: interpolated via the color, x, y and blur components (treating them as color and numbers where appropriate). In the case where there are lists of shadows, the shorter list is padded at the end with shadows whose color is transparent and all lengths (x, y, blur) are 0. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;gradient&lt;/strong&gt;: interpolated via the positions and colors of each stop. They must have the same type (radial or linear) and same number of stops in order to be animated. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;paint server&lt;/strong&gt; (SVG): interpolation is only supported between: gradient to gradient and color to color. They then work as above. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;space-separated list of above&lt;/strong&gt;: If the lists have the same number of items, each item in the list is interpolated using the rules above. Otherwise, no interpolation. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;a shorthand property&lt;/strong&gt;: If all the parts of a shorthand can be animated, then interpolation is performed as if each property was individually specified. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;And the following properties must be supported for animations: &lt;a id="propertiesLink"&gt;click here to display/hide them&lt;/a&gt;&lt;/p&gt;  &lt;ul id="properties"&gt;   &lt;li&gt;background-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;background-image (&lt;em&gt;only gradients&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;background-position (&lt;em&gt;percentage and length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-bottom-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-bottom-width (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-left-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-left-width (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-right-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-right-width (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-spacing (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-top-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-top-width (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;border-width (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;bottom (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;crop (&lt;em&gt;rectangle&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;font-size (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;font-weight (&lt;em&gt;number&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;grid-* (&lt;em&gt;various&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;height (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;left (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;letter-spacing (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;line-height (&lt;em&gt;number, length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;margin-bottom (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;margin-left (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;margin-right (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;margin-top (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;max-height (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;max-width (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;min-height (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;min-width (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;opacity (&lt;em&gt;number&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;outline-color (&lt;em&gt;color&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;outline-offset (&lt;em&gt;integer&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;outline-width (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;padding-bottom (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;padding-left (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;padding-right (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;padding-top (&lt;em&gt;length&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;right (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;text-indent (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;text-shadow (&lt;em&gt;shadow&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;top (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;vertical-align (&lt;em&gt;keywords, length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;visibility (&lt;em&gt;visibility&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;width (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;word-spacing (&lt;em&gt;length and percentage&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;z-index (&lt;em&gt;integer&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;zoom (&lt;em&gt;number&lt;/em&gt;) &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;SVG&lt;/h3&gt;  &lt;p&gt;The properties of SVG objects are animatable when they are defined as &lt;b&gt;animatable:true&lt;/b&gt; in the SVG specification: &lt;a href="http://www.w3.org/TR/SVG/struct.html"&gt;http://www.w3.org/TR/SVG/struct.html&lt;/a&gt;. But at the time where this article is written, I didn’t manage to combine CSS3 Animation directly on SVG elements in any of the latest browsers versions. Today’s samples on the web are then doing a little trick: they are embedding SVG resources into different DIV animated by CSS3 like the &lt;a href="http://www.anthonycalzadilla.com/i-twitty-the-fool/"&gt;I twitty the fool&lt;/a&gt; sample. &lt;/p&gt;  &lt;h3&gt;Declarations&lt;/h3&gt;  &lt;p&gt;To declare an animation in a CSS file, here is the kind of generic code you’ll need to write:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@keyframes &lt;/span&gt;name_of_the_animation {
  &lt;span style="color: red"&gt;&lt;font color="#000000"&gt;from&lt;/font&gt; &lt;/span&gt;&lt;span style="color: blue"&gt;{
   &lt;font color="#ff0000"&gt;property_to_animate:&lt;/font&gt; initial_value&lt;/span&gt;;
  }
  50% {
     &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_to_animate:&lt;/font&gt; intermediate_value&lt;/span&gt;;
  }
  &lt;span style="color: maroon"&gt;to &lt;/span&gt;{
    &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_to_animate:&lt;/font&gt; final_value&lt;/span&gt;;
  }
}&lt;/pre&gt;

&lt;p&gt;Which could also be written like that:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@keyframes &lt;/span&gt;name_of_the_animation {
  0% {
   &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_to_animate:&lt;/font&gt; initial_value&lt;/span&gt;;
  }
  50% {
     &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_to_animate:&lt;/font&gt; intermediate_value&lt;/span&gt;;
  }
  100% {
    &lt;span style="color: red"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#ff0000"&gt;_to_animate:&lt;/font&gt; final_value&lt;/span&gt;;
  }
}&lt;/pre&gt;

&lt;p&gt;This animation definition declares 3 steps 0, 50 &amp;amp; 100%. You should at least set a &lt;i&gt;&lt;strong&gt;from&lt;/strong&gt;&lt;/i&gt; (or 0%) and a &lt;i&gt;&lt;strong&gt;to&lt;/strong&gt;&lt;/i&gt; (or 100%) steps to build a correct animation (minimum 2 steps thus). Once done, you may add as many keyframes as you’d like between 0 and 100% to handle precisely the various steps of your animations. &lt;/p&gt;

&lt;p&gt;Once the definition declared, you can affect it to an element using the classical CSS3 selectors and you’ll need also to configure the animation options. Here the kind of generic blocks you’ll see:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;#id_of_the_html_element &lt;/span&gt;{
    &lt;span style="color: red"&gt;animation-name&lt;/span&gt;: &lt;span style="color: blue"&gt;name_of_the_animation&lt;/span&gt;;
    &lt;span style="color: red"&gt;animation-duration&lt;/span&gt;: &lt;span style="color: blue"&gt;number_of_seconds s&lt;/span&gt;;
    &lt;span style="color: red"&gt;animation-iteration-count&lt;/span&gt;: &lt;span style="color: blue"&gt;number | infinite&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;To better understand, let’s review a real sample. First of all, as the CSS3 Animations specification is still in a draft stage, you’ll need to use the appropriate vendor prefix. Let’s use IE10 as a sample with the –ms prefix then. Let’s now see how the head of our AT-AT is moving. &lt;/p&gt;

&lt;p&gt;Here’s the animation declaration:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@-ms-keyframes &lt;/span&gt;rotate-skull {
    0% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(0deg)
    &lt;/span&gt;}
    25% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(15deg)
    &lt;/span&gt;}
    50% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(-5deg)
    &lt;/span&gt;}
    55% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(0deg)
    &lt;/span&gt;}
    75% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(-10deg)
    &lt;/span&gt;}
    100% {
        &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate(0deg)
    &lt;/span&gt;}
} &lt;/pre&gt;

&lt;p&gt;We’ve got 6 steps (0, 25, 50, 55, 75 &amp;amp; 100%) working on the CSS3 2D transform attributes by changing the value of the rotation.&lt;/p&gt;

&lt;p&gt;The animation is then applied via this CSS rule:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;#skull 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation-name&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate-skull&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-duration&lt;/span&gt;: &lt;span style="color: blue"&gt;7s&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-iteration-count&lt;/span&gt;: &lt;span style="color: blue"&gt;infinite&lt;/span&gt;;       
}&lt;/pre&gt;

&lt;p&gt;We’re targeting the &amp;lt;div&amp;gt; element having the “id=&lt;strong&gt;skull&lt;/strong&gt;” and we’re applying the animation named “&lt;b&gt;rotate-skull&lt;/b&gt;” on it. The animation will have to be completed in &lt;b&gt;7s&lt;/b&gt; and be played an &lt;b&gt;infinite&lt;/b&gt; number of times.&lt;/p&gt;

&lt;p&gt;Here is the living result if your browser supports CSS3 Animations:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="200" src="http://david.blob.core.windows.net/html5/css3atat/AnimSkullATAT.htm" width="400" scrolling="no"&gt;&lt;/iframe&gt;

&lt;p&gt;We could have written this rule in a shorter manner using the animation shorthand property:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;#skull &lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation&lt;/span&gt;: &lt;span style="color: blue"&gt;rotate-skull 7s infinite&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;The animations will be triggered as soon as a matching rule is applied. You can then play or stop animations simply via &lt;b&gt;JavaScript&lt;/b&gt; or via CSS3 to play with the &lt;b&gt;classes affected to a tag&lt;/b&gt;.&lt;/p&gt;

&lt;h3&gt;Non-linear animations&lt;/h3&gt;

&lt;p&gt;The “animation-timing-function” property can be used if you want non-linear animations. You can even mix the type of timing functions during each keyframe. &lt;/p&gt;

&lt;p&gt;Basically, CSS3 animations will use &lt;a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves"&gt;cubic bezier curve&lt;/a&gt; to smooth the animation by computing different speed over its duration.&lt;/p&gt;

&lt;p&gt;The following functions are supported:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;linear&lt;/em&gt;: Constant speed &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;cubic-bezier&lt;/em&gt;: Speed will be computed according to a cubic bezier curve define by two control points : P0 and P1 (so you will have to define 4 values here : P0x, P0y and P1x, P1y. &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease&lt;/em&gt;: Speed will be computed with cubic-bezier(0.25, 0.1, 0.25, 1) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease-in&lt;/em&gt;: Speed will be computed with cubic-bezier(0.42, 0, 1, 1) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease-inout&lt;/em&gt;: Speed will be computed with cubic-bezier(0.42, 0, 0.58, 1) &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ease-out&lt;/em&gt;: Speed will be computed with cubic-bezier(0, 0, 0.58, 1) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a simulation tool written by &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/01/css3-transitions.aspx"&gt;David Catuhe&lt;/a&gt; that uses pure JavaScript to show the impact of each timing function:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="650" src="http://www.catuhe.com/msdn/transitions/easingfunctions.htm" width="100%"&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; this tool uses in-line SVG supported by Firefox, Chrome, Opera 11.60 &amp;amp; IE9/10. It won’t work properly under Opera 11.50 &amp;amp; Safari on iPad thus.&lt;/p&gt;

&lt;p&gt;This is an awesome tool using SVG. You can even play with your mouse on the custom function to edit the curve. If you’d like to know more about this tool, please again have a look to David’s article.&lt;/p&gt;

&lt;p&gt;If your browser supports CSS3 animations, let’s now see a simple demo using &lt;strong&gt;easing functions to animate a canvas tag&lt;/strong&gt; containing an animated sprite with CSS3.&lt;/p&gt;

&lt;p&gt;Here is the CSS3 animations code that will be used in this demo:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@-ms-keyframes &lt;/span&gt;demo {
    &lt;span style="color: red"&gt;&lt;font color="#000000"&gt;from&lt;/font&gt; &lt;/span&gt;&lt;span style="color: blue"&gt;{
    &lt;font color="#ff0000"&gt;-ms-animation-timing-function&lt;/font&gt;: ease&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;translateX(0px)&lt;/span&gt;;
    }
    50% {
    &lt;span style="color: red"&gt;-ms-animation-timing-function&lt;/span&gt;: &lt;span style="color: blue"&gt;ease-in&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;translateX(300px)&lt;/span&gt;;
    }
    &lt;span style="color: maroon"&gt;to &lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation-timing-function&lt;/span&gt;: &lt;span style="color: blue"&gt;ease-inout&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-transform&lt;/span&gt;: &lt;span style="color: blue"&gt;translateX(900px)&lt;/span&gt;;
    }
}

&lt;span style="color: maroon"&gt;#testCanvas
&lt;/span&gt;{
    &lt;span style="color: red"&gt;-ms-animation-delay&lt;/span&gt;: &lt;span style="color: blue"&gt;0s&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-duration&lt;/span&gt;: &lt;span style="color: blue"&gt;6s&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-iteration-count&lt;/span&gt;: &lt;span style="color: blue"&gt;infinite&lt;/span&gt;;
    &lt;span style="color: red"&gt;-ms-animation-name&lt;/span&gt;: &lt;span style="color: blue"&gt;demo&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;As well as all the vendor prefixes variations to make it works also in Google Chrome &amp;amp; Mozilla Firefox. And here’s the living output:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="90" src="http://david.blob.core.windows.net/html5/css3animcanvas/sprites.htm" width="1000"&gt;&lt;/iframe&gt;

&lt;p&gt;If your browser doesn’t support CSS3 Animation but support canvas, the sprite’s running animation should be displayed but the character won’t move through the width of the screen. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/b&gt; if you’d like to know more about canvas and sprites animation, you can have a look to this article: &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx"&gt;HTML5 Gaming: animating sprites in Canvas with EaselJS&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Delay&lt;/h3&gt;

&lt;p&gt;The “animation-delay” property simply allows an animation to begin execution some time after it is applied.&lt;/p&gt;

&lt;h3&gt;Events&lt;/h3&gt;

&lt;p&gt;3 &lt;b&gt;events&lt;/b&gt; could be raised during an animation. They are named “Animation&lt;em&gt;Start&lt;/em&gt;”, “Animation&lt;i&gt;End&lt;/i&gt;” and “Animation&lt;em&gt;Iteration&lt;/em&gt;”. Depending on your browser, the correct name will be for instance:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Chrome:&lt;i&gt; webkitAnimationEnd&lt;/i&gt; &lt;/li&gt;

  &lt;li&gt;Firefox: &lt;i&gt;mozAnimationEnd&lt;/i&gt; &lt;/li&gt;

  &lt;li&gt;Internet Explorer:&lt;i&gt; MSAnimationEnd&lt;/i&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The event will give you the following details:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;i&gt;animationName&lt;/i&gt;: name of the animation which raised the event &lt;/li&gt;

  &lt;li&gt;&lt;i&gt;elapsedTime&lt;/i&gt;: the amount of time the animation has been running, in seconds &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an usage sample for IE10:&lt;/p&gt;

&lt;pre class="code"&gt;elementToAnimate.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;MSAnimationEnd&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    alert(&lt;span style="color: maroon"&gt;&amp;quot;the end !&amp;quot;&lt;/span&gt;);
}, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;h3&gt;More about CSS3 animations&lt;/h3&gt;

&lt;p&gt;CSS3 animations are really useful for 2 main reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Hardware acceleration:&lt;/b&gt; CSS3 Animations are most of the time directly handled by the GPU and could produce smoother results. This could then be a very interesting approach for mobile devices. &lt;/li&gt;

  &lt;li&gt;&lt;b&gt;Better separation between code and design&lt;/b&gt;: I know there is some debates on this point but with David, we think that a developer shouldn’t be aware of animations or anything related to design as much as possible. In the same way the designer/artist must not be aware of JavaScript. CSS3 offers then this possibility and could let the designers work with their classical tools to generate the appropriate animations on elements, between screens, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To highlight this importance in performance, the following HTML5 game I wrote using a full frame &amp;lt;canvas&amp;gt;: &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx"&gt;HTML5 Platformer&lt;/a&gt; run at 60 fps in IE9/IE10 on my PC but at 10 fps max on a iPad 2. This is because its CPU is much more limited and the iPad is currently not hardware-accelerating &amp;lt;canvas&amp;gt;. Using CSS3 Transitions/Animations to animate several smaller &amp;lt;canvas&amp;gt; elements could provide a huge performance boost for this game. Think about it when you’re targeting mobile devices!&lt;/p&gt;
&lt;a name="support"&gt;
  &lt;h2&gt;Browsers Support&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Since the Platform Preview 3 of IE10 available in the &lt;a href="http://msdn.microsoft.com/en-us/windows/apps/br229516"&gt;Windows Developer Preview&lt;/a&gt;, we’re supporting CSS3 Animations. And as you can see on the following report produced by &lt;a href="http://caniuse.com/#search=CSS3 animation"&gt;caniuse.com&lt;/a&gt;, the CSS3 animations are now supported on a wide range of browsers:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8546.clip_5F00_image002_5F00_3DD1FC3C.jpg"&gt;&lt;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="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6303.clip_5F00_image002_5F00_thumb_5F00_0EBF9A98.jpg" width="761" height="275" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But as the specification is not finished yet (&lt;em&gt;working draft&lt;/em&gt;), you must use vendor’s prefixes such as –ms-, –moz-, –webkit-, –o- to make a cross-browsers compatible application.&lt;/p&gt;

&lt;p&gt;But the question could be: how to handle browsers that don’t support this new feature?&lt;/p&gt;

&lt;p&gt;First option is to just do nothing. Thanks to the beauty of graceful degradation, you could just let the user only see a static image if you’ve worked correctly. This is for instance the case of these 2 original samples of Anthony: &lt;a href="http://www.anthonycalzadilla.com/i-twitty-the-fool/"&gt;I Twitty the Fool!&lt;/a&gt; and &lt;a href="http://www.anthonycalzadilla.com/css3-ATAT/"&gt;Pure CSS3 AT-AT Walker&lt;/a&gt; . When watched in IE9, it looks like we only have a static image. When watched in IE10, the very same code shows nice animations. IE10 users will then have an enhanced version while IE9 will still be able to view and use properly the website. The more modern your browser is, the more visual bonus you will have.&amp;#160; &lt;/p&gt;

&lt;p&gt;The second option is to detect the feature via a JS library like Modernizr and try to offer the same animation via a JavaScript library that will mimic the animations. This is what we usually call a fallback mechanism. Unfortunately, I haven’t found today a working &amp;amp; complete JS library that could replace CSS3 animations when not supported by the browser.&lt;/p&gt;

&lt;p&gt;I have then written a sample JS library more or less specifically designed for the AT-AT sample.&lt;/p&gt;
&lt;a name="fallback"&gt;
  &lt;h2&gt;CSS3 Animations JavaScript fallback library&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;Animations are nothing more than a series of transitions separated by a certain duration defined via the keyframes. I’ve then reused the concepts built by David Catuhe in his transitions helper library. I let you reviewing his article to check the base of the concepts behind the code.&lt;/p&gt;

&lt;p&gt;On my side, I’ve added some support to animate the CSS3 2D Transform rotation &amp;amp; translation values and a way to iterate through the keyframes. &lt;/p&gt;

&lt;p&gt;Here is the main part of the library you need to review:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Animation object
// It need the HTML targeted element, the name of the animation, its duration &amp;amp; iteration count and
// the keyframes contained in an array object
// View the animation simply as a sequence of transitions played a certain number of times
&lt;/span&gt;ANIMATIONSHELPER.animation = &lt;span style="color: blue"&gt;function &lt;/span&gt;(target, name, duration, iterationcount, keyframes) {
    &lt;span style="color: #006400"&gt;// saving the properties values
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.name = name;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.duration = duration;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.iterationcount = iterationcount;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.target = target;

    &lt;span style="color: blue"&gt;var &lt;/span&gt;elapsedtime = 0;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;keyframeduration = 0;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;elapsedtime = 0;

    &lt;span style="color: #006400"&gt;// Transforming the percentage of each keyframe into duration value
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; keyframes.length; i++) {
        keyframeduration = ((keyframes[i].percentage * duration) / 100) - elapsedtime;
        keyframes[i].duration = keyframeduration;
        elapsedtime += keyframeduration;
    }

    &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition = { isPlaying: &lt;span style="color: blue"&gt;false &lt;/span&gt;};
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframes = keyframes;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframesCount = keyframes.length;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex = 0;

    &lt;span style="color: #006400"&gt;// The nextTransition() function return the next transition to run
    // based on the current keyframe to play
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.nextTransition = &lt;span style="color: blue"&gt;function &lt;/span&gt;(keyframe, ease, customEaseP1X, customEaseP1Y, customEaseP2X, customEaseP2Y) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;properties = [];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;finalValues = [];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;transition;

        &lt;span style="color: #006400"&gt;// Compared to the original TRANSITIONSHELPER of David Catuhe
        // We need a specific code to play with the CSS3 2D Transform properties values
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(keyframe.propertyToAnimate === &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;) {
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; keyframe.transformType.length; i++) {
                properties.push(keyframe.transformType[i].type);
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(keyframe.transformType[i].type == &lt;span style="color: maroon"&gt;&amp;quot;rotate&amp;quot;&lt;/span&gt;) {
                    finalValues.push({ deg: keyframe.transformType[i].value1 });
                }
                &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                    finalValues.push({ x: keyframe.transformType[i].value1, y: keyframe.transformType[i].value2 });
                }
            }

            &lt;span style="color: #006400"&gt;// Create a new transition
            &lt;/span&gt;transition = {
                name: &lt;span style="color: blue"&gt;this&lt;/span&gt;.name + &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex,
                target: &lt;span style="color: blue"&gt;this&lt;/span&gt;.target,
                properties: properties,
                finalValues: finalValues,
                originalValues: ANIMATIONSHELPER.extractValues(target.style[ANIMATIONSHELPER.currentTransformProperty], &lt;span style="color: blue"&gt;this&lt;/span&gt;.name),
                duration: keyframe.duration,
                startDate: (&lt;span style="color: blue"&gt;new &lt;/span&gt;Date).getTime(),
                currentDate: (&lt;span style="color: blue"&gt;new &lt;/span&gt;Date).getTime(),
                ease: ease,
                customEaseP1X: customEaseP1X,
                customEaseP2X: customEaseP2X,
                customEaseP1Y: customEaseP1Y,
                customEaseP2Y: customEaseP2Y,
                isPlaying: &lt;span style="color: blue"&gt;true&lt;/span&gt;,
                type: &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;
            &lt;/span&gt;};

            &lt;span style="color: blue"&gt;return &lt;/span&gt;transition;
        }
        &lt;span style="color: #006400"&gt;// If it's a classic property to animate, we're using more or less the TRANSITIONSHELPER as-is
        &lt;/span&gt;&lt;span style="color: blue"&gt;else &lt;/span&gt;{
            &lt;span style="color: blue"&gt;return &lt;/span&gt;TRANSITIONSHELPER.transition(&lt;span style="color: blue"&gt;this&lt;/span&gt;.target, keyframe.propertyToAnimate, keyframe.value, keyframe.duration, TRANSITIONSHELPER.easingFunctions.linear);
        }
    };

    &lt;span style="color: #006400"&gt;// each animation object has a tick function
    // that will be called every 17 ms (to target 60 fps)
    // This ticker is monitoring the current state of the transition and
    // create a new transition as soon as the old one is finished/dead
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.tick = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.iterationcount &amp;gt; 0) {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition.isPlaying) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition = &lt;span style="color: blue"&gt;this&lt;/span&gt;.nextTransition(&lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframes[&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex], ANIMATIONSHELPER.easingFunctions.linear);
                &lt;span style="color: #006400"&gt;// We're using our own global ticker only for the 2D transformations
                // Otherwise, we're using the one from the TRANSITIONSHELPER library
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition.type === &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;) {
                    ANIMATIONSHELPER.currentTransitions.push(&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentTransition);
                }
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex++;

                &lt;span style="color: #006400"&gt;// We've reached the last keyframe (100%). We're starting back from the beginning
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex &amp;gt;= &lt;span style="color: blue"&gt;this&lt;/span&gt;.keyframesCount) {
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.currentKeyFrameIndex = 0;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.iterationcount--;
                }
            }
        }
    };
};&lt;/pre&gt;

&lt;p&gt;The first part of the code is iterating through each keyframe to compute the exact duration specified by each percentage. We’re then defining a nextTransition() function that will dynamically build the next transition to play based on the current index into the keyframes collection. At last, we’ve got a tick() function that will monitor the current state of the transition applied. Once the transition is finished or dead, it asks for the next transition, push it to the stack of transitions to be played and moves the indexes. &lt;/p&gt;

&lt;p&gt;This tick() function is called thanks to this code:&lt;/p&gt;

&lt;pre class="code"&gt;ANIMATIONSHELPER.launchAnimation = &lt;span style="color: blue"&gt;function &lt;/span&gt;(animation) {
    &lt;span style="color: #006400"&gt;// Launching the tick service if required
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(ANIMATIONSHELPER.tickIntervalID == 0) {
        ANIMATIONSHELPER.tickIntervalID = setInterval(ANIMATIONSHELPER.tick, 17);
    }

    &lt;span style="color: #006400"&gt;// Little closure to launch the tick method on the appropriate animation instance
    &lt;/span&gt;setInterval(&lt;span style="color: blue"&gt;function &lt;/span&gt;() { animation.tick(); }, 17);
};&lt;/pre&gt;

&lt;p&gt;At last, we have this kind of code that helps us building the keyframes:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Object to build a new generic keyframe (not working on the CSS3 2D Transform properties thus)
&lt;/span&gt;ANIMATIONSHELPER.keyframe = &lt;span style="color: blue"&gt;function &lt;/span&gt;(percentage, propertyToAnimate, value) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.percentage = percentage;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.propertyToAnimate = propertyToAnimate;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.value = value;
};

&lt;span style="color: #006400"&gt;//Objects to build specific rotation keyframes
&lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe = &lt;span style="color: blue"&gt;function &lt;/span&gt;(percentage, value) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.percentage = percentage;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.propertyToAnimate = &lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.transformType = [];
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.transformType.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.transformType(&lt;span style="color: maroon"&gt;&amp;quot;rotate&amp;quot;&lt;/span&gt;, value));
};&lt;/pre&gt;

&lt;p&gt;To highlight its usage, let’s recreate the previous simple CSS3 Animation skull sample with this library :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// number of times you'd like the animations to be run
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;iterationsNumber = 100;

&lt;span style="color: blue"&gt;var &lt;/span&gt;skullElement = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;skull&amp;quot;&lt;/span&gt;);
&lt;span style="color: blue"&gt;var &lt;/span&gt;keyframes = [];
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(25, 15));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(50, -5));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(55, 0));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(75, -10));
keyframes.push(&lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.rotationkeyframe(100, 0));

&lt;span style="color: blue"&gt;var &lt;/span&gt;animation1 = &lt;span style="color: blue"&gt;new &lt;/span&gt;ANIMATIONSHELPER.animation(skullElement, &lt;span style="color: maroon"&gt;&amp;quot;rotate-skull&amp;quot;&lt;/span&gt;, 7000, 
                                                iterationsNumber, keyframes);

ANIMATIONSHELPER.launchAnimation(animation1, ANIMATIONSHELPER.easingFunctions.linear);&lt;/pre&gt;

&lt;p&gt;And here is the result that will now work in every browser supporting CSS3 2D Transform:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="200" src="http://david.blob.core.windows.net/html5/css3atat/indexSkullJS.htm" width="400" scrolling="no"&gt;&lt;/iframe&gt;

&lt;p&gt;At last, the very first sample demonstrated at the beginning of this article uses Modernizr to check the support for CSS3 Animations. If it’s not the case, it loads the code that will mimic the keyframes defined in the file master.css, moz-master.css &amp;amp; ms-master.css :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Checking if CSS3 animations is supported
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(!Modernizr.cssanimations) {
    &lt;span style="color: #006400"&gt;// if so, we can use our JS fallback library
    &lt;/span&gt;supportElement.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;CSS3 Animations &amp;lt;strong&amp;gt;are not supported&amp;lt;/strong&amp;gt;&amp;quot;&lt;/span&gt;;
    LoadJSAnimationsFallback();
}
&lt;span style="color: blue"&gt;else &lt;/span&gt;{
    &lt;span style="color: #006400"&gt;// if CSS3 animation is supported, we have nothing to do. 
    // The *master.css stylesheets will be automatically applied &amp;amp; used.
    &lt;/span&gt;supportElement.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;CSS3 Animations &amp;lt;strong&amp;gt;are supported&amp;lt;/strong&amp;gt;&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;The &lt;em&gt;LoadJSAnimationsFallback()&lt;/em&gt; function is defined into &lt;em&gt;jsfallback-master.js&lt;/em&gt; which simply contains all the keyframes declarations and the 19 animations needed to mimic the behavior created by Anthony in pure CSS3. In this approach, the designer then needs to rewrite all rules using the library. Another approach could be to parse one of the CSS file using an XHR call and to create dynamically the JavaScript calls to the library. This needs more work as you almost need to reimplement the CSS3 animations specifications in JavaScript! &lt;/p&gt;

&lt;p&gt;You now have an idea on the way to build a fallback mechanism to support more browsers while starting to use the latest CSS3 specifications. &lt;/p&gt;

&lt;p&gt;You can download the files for the main sample here: &lt;a title="http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip" href="http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip"&gt;http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It contains the unminified versions of the animationsHelper.js, transitionsHelper.js, jsfallback-master.js JavaScript files as well as the various CSS3 declinaison files for the main vendors prefixes. &lt;/p&gt;
&lt;a name="conclusion"&gt;
  &lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;/a&gt;

&lt;p&gt;CSS3 Animations is a powerful technology to push HTML5 applications to a new level. It offers interesting scenarios. Designers could use it to create a new generation of UI screens with smooth &amp;amp; fluid animations without the need of developers. As it’s hardware-accelerated most of the time, developers should also pay attention to this specification. At last, both could collaborate. Designers could work on a series of predefined animations covering most scenarios. Developers could then create JavaScript libraries that will implement those animations. This library could offer in a transparent way 2 implementations: a dynamic generation of CSS3 on the fly or a fallback for older browsers. &lt;/p&gt;

&lt;h3&gt;Going further&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Article about CSS3 Transitions by David Catuhe: &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/01/css3-transitions.aspx"&gt;Introduction to CSS3 Transitions&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;CSS3 Animations specifications: &lt;a title="http://www.w3.org/TR/css3-animations/" href="http://www.w3.org/TR/css3-animations/"&gt;http://www.w3.org/TR/css3-animations/&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;IE Test Drive on CSS3 animations: &lt;a title="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm" href="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm"&gt;http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Others useful posts: 
    &lt;ul&gt;
      &lt;li&gt;Events are relatively limited in the CSS3 Animation spec. Joe Lambert is proposing an interesting solution to trigger events on each keyframe: &lt;a href="http://blog.joelambert.co.uk/2011/05/20/css-animation-keyframe-events-javascript-solution/"&gt;CSS Animation Keyframe Events (Javascript solution)&lt;/a&gt;&amp;#160; &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;David Rousset&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10244420" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/CSS3/">CSS3</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category></item><item><title>Vidéo, slides et ressources de ma session sur le développement d’un jeu de plateforme en HTML5</title><link>http://blogs.msdn.com/b/davrous/archive/2011/11/21/vid-233-o-slides-et-ressources-de-ma-session-sur-le-d-233-veloppement-d-un-jeu-de-plateforme-en-html5.aspx</link><pubDate>Mon, 21 Nov 2011 18:14:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10239204</guid><dc:creator>David Rousset</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10239204</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/11/21/vid-233-o-slides-et-ressources-de-ma-session-sur-le-d-233-veloppement-d-un-jeu-de-plateforme-en-html5.aspx#comments</comments><description>&lt;script src="http://david.blob.core.windows.net/videos/video-js/video.js" type="text/javascript" charset="utf-8"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;
    
 VideoJS.setupAllWhenReady();
&lt;/script&gt;&lt;link title="Video JS" rel="stylesheet" type="text/css" href="http://david.blob.core.windows.net/videos/video-js/video-js.css" media="screen" /&gt;  &lt;p&gt;Si vous n’avez pas pu assister à ma session sur le développement d’un jeu de plateforme en HTML5/Canvas pendant notre évènement Microsoft Days 2011 ou si vous souhaitez revoir la session, en voici un enregistrement :&lt;/p&gt; &lt;!-- Begin VideoJS --&gt; &lt;div class="video-js-box"&gt;     &lt;!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody --&gt;     &lt;video id="example_video_1" class="video-js" width="640" height="360" controls="controls"
        preload="auto" poster="http://david.blob.core.windows.net/videos/DevJeuxHTML5.png"&gt;         &lt;source src="http://david.blob.core.windows.net/videos/DevelopperUnJeuEnHTML5.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /&gt;         &lt;source src="http://david.blob.core.windows.net/videos/DevelopperUnJeuEnHTML5.webm" type='video/webm; codecs="vp8, vorbis"' /&gt;         &lt;!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. --&gt;         &lt;object id="flash_fallback_1" class="vjs-flash-fallback" width="640" height="360"
            type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf"&gt;             &lt;param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" /&gt;             &lt;param name="allowfullscreen" value="true" /&gt;             &lt;param name="flashvars" value="config={&amp;quot;playlist&amp;quot;:[&amp;quot;http://david.blob.core.windows.net/videos/DevJeuxHTML5.png&amp;quot;, {&amp;quot;url&amp;quot;: &amp;quot;http://david.blob.core.windows.net/videos/DevelopperUnJeuEnHTML5.mp4&amp;quot;,&amp;quot;autoPlay&amp;quot;:false,&amp;quot;autoBuffering&amp;quot;:true}]}" /&gt;             &lt;!-- Image Fallback. Typically the same as the poster image. --&gt;             &lt;img src="http://david.blob.core.windows.net/videos/DevJeuxHTML5.png" width="640" height="360" alt="Poster Image" title="No video playback capabilities." /&gt;         &lt;/object&gt;     &lt;/video&gt;     &lt;!-- Download links provided for devices that can't play video in the browser. --&gt;     &lt;p class="vjs-no-video"&gt;         &lt;strong&gt;Download Video:&lt;/strong&gt; &lt;a href="http://david.blob.core.windows.net/videos/DevelopperUnJeuEnHTML5.mp4"&gt;             MP4&lt;/a&gt;, &lt;a href="http://david.blob.core.windows.net/videos/DevelopperUnJeuEnHTML5.webm"&gt;WebM&lt;/a&gt;&lt;br&gt;         &lt;!-- Support VideoJS by keeping this link. --&gt;         &lt;a href="http://videojs.com"&gt;HTML5 Video Player&lt;/a&gt; by VideoJS     &lt;/p&gt; &lt;/div&gt; &lt;!-- End VideoJS --&gt;  &lt;p&gt;   &lt;br /&gt;Au format HTML5 &lt;strong&gt;&amp;lt;video&amp;gt;&lt;/strong&gt; h264/webm bien sûr. J’utilise d’ailleurs au passage le player &lt;a href="http://videojs.com/"&gt;VideoJS&lt;/a&gt; que je vous conseille et qui propose de jolies CSS et un fallback automatique pour les anciens navigateurs.&lt;/p&gt;  &lt;p&gt;Voici les &lt;strong&gt;exemples que je vous ai montrés pendant cette heure&lt;/strong&gt; de session :&lt;/p&gt;  &lt;p&gt;- Pour comparer les performances d’animations entre SVG et Canvas sur vos navigateurs : &lt;a href="http://themaninblue.com/experiment/AnimationBenchmark/canvas/?particles=1000"&gt;1000 balles en Canvas&lt;/a&gt; et &lt;a href="http://themaninblue.com/experiment/AnimationBenchmark/svg/?particles=1000"&gt;1000 balles en SVG&lt;/a&gt;.     &lt;br /&gt;- Les framework de jeux &lt;a href="http://www.melonjs.org/"&gt;MelonJS&lt;/a&gt; (qui marche désormais sous IE9), &lt;a href="http://impactjs.com/"&gt;ImpactJS&lt;/a&gt; avec cette &lt;a href="http://html5-benchmark.com/"&gt;démo/benchmark&lt;/a&gt; et &lt;a href="http://easeljs.com/"&gt;EaselJS&lt;/a&gt; avec ce jeu de Tower Defense : &lt;a href="http://www.pirateslovedaisies.com/"&gt;Pirates Love Daisies&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Ensuite, cette session reprenais surtout en très grande partie &lt;strong&gt;les 3 tutoriaux&lt;/strong&gt; que j’ai publiés ici :&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx"&gt;Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS&lt;/a&gt;&amp;#160; &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx"&gt;Jeux HTML5: construction des objets principaux &amp;amp; gestion des collisions avec EaselJS&lt;/a&gt;     &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;HTML5 Platformer: portage complet du jeu XNA vers &amp;lt;canvas&amp;gt; grâce à EaselJS&lt;/a&gt; où vous pouvez d’ailleurs télécharger le source code complet du jeu.&lt;/p&gt;  &lt;p&gt;Pour finir, voici &lt;strong&gt;quelques ressources complémentaires&lt;/strong&gt; que je vous conseille :&lt;/p&gt;  &lt;p&gt;- Pour aller plus loin sur la boucle “d’update”, on pourrait utiliser les Web Workers. Vous trouverez une introduction ici : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx"&gt;Introduction aux Web Workers d’HTML5 : le multithreading version JavaScript&lt;/a&gt;     &lt;br /&gt;- Il existe des moteurs physiques “open source” pour JavaScript dont le plus connu est Box2D que vous pouvez voir ici : &lt;a title="http://box2d-js.sourceforge.net/" href="http://box2d-js.sourceforge.net/"&gt;Box2DJS - Physics Engine for JavaScript&lt;/a&gt;     &lt;br /&gt;- &lt;a href="https://twitter.com/#!/sethladd"&gt;Seth Ladd&lt;/a&gt;, un évangéliste de chez Google, s’est d’ailleurs amusé à combiner Web Workers et Box2D. Je vous conseille son excellente série de tutoriaux sur Box2D dont celui qui traite des Web Workers : &lt;a href="http://blog.sethladd.com/2011/09/box2d-and-web-workers-for-javascript.html"&gt;Box2D and Web workers for JavaScript developers&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pour finir, vous trouverez les slides de cette session ici :&lt;/p&gt; &lt;iframe height="327" src="http://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SDEE4BD0F5EA745C6!2173&amp;amp;p4=&amp;amp;kip=1" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;  &lt;p&gt;   &lt;br /&gt;Et également sur slideshare ici : &lt;a title="Développement d&amp;#39;un jeu de plateforme en html5" href="http://www.slideshare.net/davrous/dveloppement-dun-jeu-de-plateforme-en-html5"&gt;Développement d'un jeu de plateforme en html5&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;J’espère maintenant avoir suscité des vocations pour un jour vous recroiser riche et célèbre grâce à votre jeu vidéo HTML5 ! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4657.wlEmoticon_2D00_winkingsmile_5F00_58DFD0DE.png" /&gt;&lt;/p&gt;  &lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10239204" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Canvas/">Canvas</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/WebWorkers/">WebWorkers</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/MSDays/">MSDays</category></item><item><title>HTML5 Platformer: portage complet du jeu XNA vers &lt;canvas&gt; grâce à EaselJS</title><link>http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx</link><pubDate>Fri, 09 Sep 2011 14:10:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10208530</guid><dc:creator>David Rousset</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10208530</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx#comments</comments><description>&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="left" src="https://david.blob.core.windows.net/html5platformer/icons/Game128.png" width="96" height="96" /&gt;Après quelques heures passées sur le clavier à coder en JavaScript, j’ai finalement complètement porté l’exemple de jeu Platformer issu des samples XNA 4.0 vers HTML5/Canvas à l’aide du framework EaselJS. Vous trouverez dans cet article le jeu en lui-même ainsi qu’un petit retour d’expérience sur les parties qui m’ont fait me poser le plus de questions. Si vous cherchez à savoir comment fonctionne le jeu en interne, le mieux est de tout simplement en lire le code. Il est disponible au téléchargement à la fin de cet article. Avant de rentrer dans le vif du sujet, j’aimerais attirer votre attention sur mes motivations principales à l’écriture de ce jeu. Je cherchais tout simplement à mieux apprendre JavaScript en écrivant du code purement JS (sans aucune forme de dépendance avec le DOM). Je cherchais également à écrire un jeu fonctionnant sur tous les navigateurs ainsi que sur les périphériques “compatible” HTML5 lorsque cela est possible. Cela vous aidera peut-être à mieux comprendre certains choix que j’ai effectués. &lt;/p&gt;  &lt;p&gt;Vous pouvez jouer au jeu directement au sein de cette iframe (avec les flèches droite et gauche &amp;amp; W pour sauter). Il vous suffit d’appuyer sur le bouton “Start” pour lancer la séquence de téléchargement des ressources puis du jeu lui-même. &lt;/p&gt; &lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="530" src="http://david.blob.core.windows.net/html5platformer/index.html" width="830"&gt;&lt;/iframe&gt;  &lt;p&gt;Vous pouvez également jouer au jeu dans une fenêtre séparée en suivant ce lien : &lt;a title="http://david.blob.core.windows.net/html5platformer/index.html" href="http://david.blob.core.windows.net/html5platformer/index.html" target="_blank"&gt;HTML5 Platformer&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; ce jeu a été testé avec succès sous IE9/10, Chrome, Firefox 6+, Opera 11+, IE9 sur WP7 Mango et iPad 2. Les éléments de type texte ne sont pas affichés sous Opera à cause &lt;a href="https://github.com/gskinner/EaselJS/issues/48" target="_blank"&gt;d’un bug en cours dans EaselJS&lt;/a&gt;. Enfin, si vous souhaitez vraiment jouer au jeu, un navigateur utilisant l’accélération matérielle est fortement recommandé. J’ai par exemple un framerate de 60 images/seconde sur mon Sony Vaio Z13 avec IE9.&lt;/p&gt;  &lt;p&gt;Vous trouverez à la fin de cet article le code source complet non compressé (minified) au sein d’une archive ZIP à télécharger. J’ai essayé de commenter le code autant que possible pour le rendre le plus explicite possible. J’espère que vous apprendrez des choses intéressantes en le lisant. Si vous avez d’ailleurs des retours ou suggestions à faire dessus, n’hésitez pas à les faire à travers les commentaires de ce billet de blog.&lt;/p&gt;  &lt;p&gt;Pour rappel, j’ai également déjà écrit 2 articles abordant les bases de la logique se trouvant derrière ce jeu:&lt;/p&gt;  &lt;p&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx"&gt;Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS&lt;/a&gt;&amp;#160; &lt;br /&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx"&gt;Jeux HTML5: construction des objets principaux &amp;amp; gestion des collisions avec EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Construction du gestionnaire de téléchargements&lt;/h2&gt;  &lt;p&gt;Dans mon article précédent, le gestionnaire de téléchargements ne notifiait pas l’utilisateur du niveau de progression globale des téléchargements. C’était très mal. Heureusement, l’ajout de cette fonctionnalité fut un jeu d’enfant. Vous n’avez en effet qu’à ajouter une méthode tick() à votre objet and mettre à jour un élément de type Text présent dans le Stage d’EaselJS pour afficher la progression. Vous pouvez le voir en lisant le code du fichier &lt;em&gt;ContentManager.js&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt;Par ailleurs, mon objectif étant de rendre le jeu compatible avec tous les navigateurs, j’ai encodé la musique et les éléments sonores au format MP3 et OGG. Si vous souhaitez en savoir davantage sur cette histoire de codec autour de la balise audio d’HTML5, je vous recommande chaudement la lecture de l’article de mon collègue Stanislas: &lt;a title="http://blogs.technet.com/b/stanislas/archive/2010/11/22/html5-ce-qu-il-faut-savoir-sur-la-balise-audio.aspx" href="http://blogs.technet.com/b/stanislas/archive/2010/11/22/html5-ce-qu-il-faut-savoir-sur-la-balise-audio.aspx"&gt;HTML5 - ce qu il faut savoir sur la balise Audio&lt;/a&gt; et également son cahier de vacances HTML5 sur audio/video: &lt;a title="http://msdn.microsoft.com/fr-fr/ie/hh237531" href="http://msdn.microsoft.com/fr-fr/ie/hh237531"&gt;Cahiers de vacances HTML5&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Bon du coup, de mon côté, je télécharge soit la version MP3 soit la version OGG en utilisant le code suivant :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;canPlayMp3, canPlayOgg;
&lt;span style="color: blue"&gt;var &lt;/span&gt;audioExtension = &lt;span style="color: maroon"&gt;&amp;quot;.none&amp;quot;&lt;/span&gt;;

&lt;span style="color: #006400"&gt;// Need to check the canPlayType first or an exception
// will be thrown for those browsers that don't support it      
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;myAudio = document.createElement(&lt;span style="color: maroon"&gt;'audio'&lt;/span&gt;);

&lt;span style="color: blue"&gt;if &lt;/span&gt;(myAudio.canPlayType) {
    &lt;span style="color: #006400"&gt;// Currently canPlayType(type) returns: &amp;quot;&amp;quot;, &amp;quot;maybe&amp;quot; or &amp;quot;probably&amp;quot; 
    &lt;/span&gt;canPlayMp3 = !!myAudio.canPlayType &amp;amp;&amp;amp; &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot; &lt;/span&gt;!= myAudio.canPlayType(&lt;span style="color: maroon"&gt;'audio/mpeg'&lt;/span&gt;);
    canPlayOgg = !!myAudio.canPlayType &amp;amp;&amp;amp; &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot; &lt;/span&gt;!= myAudio.canPlayType(&lt;span style="color: maroon"&gt;'audio/ogg; codecs=&amp;quot;vorbis&amp;quot;'&lt;/span&gt;);
}

&lt;span style="color: blue"&gt;if &lt;/span&gt;(canPlayMp3)
    audioExtension = &lt;span style="color: maroon"&gt;&amp;quot;.mp3&amp;quot;&lt;/span&gt;;
&lt;span style="color: blue"&gt;else if &lt;/span&gt;(canPlayOgg) {
    audioExtension = &lt;span style="color: maroon"&gt;&amp;quot;.ogg&amp;quot;&lt;/span&gt;;
}

&lt;span style="color: #006400"&gt;// If the browser supports either MP3 or OGG
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(audioExtension !== &lt;span style="color: maroon"&gt;&amp;quot;.none&amp;quot;&lt;/span&gt;) {
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.globalMusic, &lt;span style="color: maroon"&gt;&amp;quot;sounds/Music&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.playerKilled, &lt;span style="color: maroon"&gt;&amp;quot;sounds/PlayerKilled&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.playerJump, &lt;span style="color: maroon"&gt;&amp;quot;sounds/PlayerJump&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.playerFall, &lt;span style="color: maroon"&gt;&amp;quot;sounds/PlayerFall&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.exitReached, &lt;span style="color: maroon"&gt;&amp;quot;sounds/ExitReached&amp;quot; &lt;/span&gt;+ audioExtension);
}&lt;/pre&gt;

&lt;p&gt;J’ai passé un peu plus de temps à essayer de trouver la meilleure façon de précharger ou de télécharger les fichiers audio avant de démarrer le jeu. Dans le cas des éléments de type image, on ne peut tout simplement pas démarrer le jeu si nous n’avons pas entièrement téléchargé toutes les images localement. Sinon, tenter dessiner sur le canvas avec des images non encore entièrement présentes généra une belle exception. &lt;/p&gt;

&lt;p&gt;Pour les éléments audio, mon souhait était d’avoir également entièrement le fichier son pour être sûr de bien le jouer le moment venu. Si le joueur meurt, je ne veux pas que le son soit soit joué 2 secondes après sa mort. Il faut pas louper l’heure du son de sa mort. Malheureusement, il n’y a pas de réelle manière de faire cela dans tous les navigateurs à l’heure actuelle. L’élément audio d’HTML5 a plutôt été conçu manifestement pour lire un flux audio en streaming. Il joue donc le son dès qu’il y a suffisamment de données disponibles. Nous n’avons pas par exemple un évènement qui nous indiquerait : “&lt;em&gt;le fichier audio a entièrement été téléchargé&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;Ma dernière idée fut alors de télécharger une vesion encodée en base64 du fichier via un appel à XMLHTTPRequest et de passer le résultat à la balise audio ainsi par exemple : &lt;em&gt;&amp;lt;source src=&amp;quot;data:audio/mp3;base64,{base64_string}&amp;quot; /&amp;gt;. &lt;/em&gt;Mais j’avoue ne pas avoir eu le courage/temps de tester si cela fonctionnait ou pas. Si de votre côté, vous avez fait des tests similaires, je suis très curieux du résultat. N’hésitez pas à les partager !&lt;/p&gt;

&lt;p&gt;Finalement, la seule chose que je fais est d’appeler la méthode load() pour tenter de charger autant de données que possible avant de les utiliser. Sur un réseau lent, on pourrait alors tomber dans le cas où le jeu demande à jouer un son avant qu’il ne soit encore tout à fait disponible. Cela ne généra par d’erreurs mais le son ne sera tout simplement pas synchronisé avec l’action en cours.&lt;/p&gt;

&lt;h2&gt;Ruses autour des limitations de la balise audio HTML5&lt;/h2&gt;

&lt;p&gt;Pendant que je codais et testais le jeu, j’ai trouvé un autre souci avec l’élement &amp;lt;audio&amp;gt; d’HTML5 (j’avoue que je n’avais pas pensé passer autant de temps sur la partie audio du jeu!). Si le joueur prenais trop vite plusieurs diamants d’affilé, l’élément audio associé à cet évènement n’était pas capable de le gérer. Par exemple, au début, quand le joueur prenais 8 diamants d’affilé sur la même ligne, je ne pouvais entendre le son “GemCollected.mp3/ogg” qu’une à 3 fois. Il n’y avait pas de son de joué pour les 5 derniers éléments restant. Ensuite, après une certaine attente, le son fonctionnait à nouveau pour un nouveau diamant.&lt;/p&gt;

&lt;p&gt;Après plusieurs expérimentations, je me suis finalement aperçu que tous les tests que j’effectuais étaient détaillés dans cet article : &lt;a title="http://www.phoboslab.org/log/2011/03/multiple-channels-for-html5-audio" href="http://www.phoboslab.org/log/2011/03/multiple-channels-for-html5-audio"&gt;Multiple Channels for HTML5 Audio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;De mon côté, j’ai fini par utiliser une autre méthode de contournement. Dans l’objet ContentManager, je télécharge 8 fois le même son GemCollected au sein d’un tableau contenant des éléments de type Audio() :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Used to simulate multi-channels audio 
// As HTML5 Audio in browsers is today too limited
// Yes, I know, we're forced to download N times to same file...
&lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;a = 0; a &amp;lt; 8; a++) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.gemCollected[a] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Audio();
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.gemCollected[a], &lt;span style="color: maroon"&gt;&amp;quot;sounds/GemCollected&amp;quot; &lt;/span&gt;+ audioExtension);
}&lt;/pre&gt;

&lt;p&gt;Puis pendant le jeu, je tourne de manière cyclique au sein de ce tableau pour simuler plusieurs canaux audio. Vous pouvez trouver cette astuce dans la méthode &lt;em&gt;UpdateGems()&lt;/em&gt; dans le fichier &lt;em&gt;Level.js&lt;/em&gt; :&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: #006400"&gt;Animates each gem and checks to allows the player to collect them.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;Level.prototype.UpdateGems = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems.length; i++) {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems[i].BoundingRectangle().Intersects(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Hero.BoundingRectangle())) {
            &lt;span style="color: #006400"&gt;// We remove it from the drawing surface
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.levelStage.removeChild(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems[i]);
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Score += &lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems[i].PointValue;
            &lt;span style="color: #006400"&gt;// We then remove it from the in memory array
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems.splice(i, 1);
&lt;font style="background-color: #ffff00"&gt;            &lt;/font&gt;&lt;font style="background-color: #ffff00"&gt;&lt;span style="color: #006400"&gt;// And we finally play the gem collected sound using a multichannels trick
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.levelContentManager.gemCollected[audioGemIndex % 8].play();
            audioGemIndex++;&lt;/font&gt;
        }
    }
};&lt;/pre&gt;

&lt;p&gt;Je sais, je sais… Cela n’est pas joli, joli. Peut-être que les nouvelles APIs Audio nous aideront dans le futur à mieux gérer la partie audio de nos jeux. Je sais que Mozilla et Google travaillent sur de bonnes idées à ce sujet mais c’est pour l’instant loin d’être finalisé et adopté par tout le monde.&lt;/p&gt;

&lt;h2&gt;La nature mono-threadée de JavaScript&lt;/h2&gt;

&lt;p&gt;J’ai déjà abordé ce sujet à travers l’un de mes articles précédents : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx"&gt;Introduction aux Web Workers d’HTML5 : le multithreading version JavaScript&lt;/a&gt; . Sans les WebWorkers, JavaScript est par nature mono-threadé. Même si les fonctions setInterval() et setTimeout() essaient de nous faire croire que plusieurs choses peuvent arriver en même temps, ce n’est pas le cas. Tout est sérialisé.&lt;/p&gt;

&lt;p&gt;Dans mon contexte de jeu, cela engendre des problèmes sur la gestion des animations. Nous n’avons pas la garantie d’être appelé toutes les xxx millisecondes dans notre logique de mise à jour de nos éléments de jeu. Pour éviter cela, XNA fournit 2 boucles séparées : la boucle de dessin (Draw) et la boucle de mise à jour (Update). Dans mon cas, elles sont plus ou moins mélangées. Et c’est bien cela le problème. Imaginez par exemple que le temps écoulé entre 2 ticks est trop important (à cause du traitement mono-threadé global). Je pourrais alors louper un appel à ma méthode Update() qui devait normalement empêcher l’un de mes ennemies de sortir de son environnement. Les tests de collisions deviennent donc non prédictibles dans le temps et cela génère des problèmes très étranges… C’est pourquoi dans certaines parties du code, j’ai codé en dur le temps espéré entre 2 appels à 17 ms. Dans la version XNA, le temps écoulé est bien calculé et équivaut souvent à 16 ms environ (60 FPS). Une solution envisageable pour mieux gérer cette boucle de mise à jour (la méthode tick() dans EaselJS) serait d’utiliser des WebWorkers.&lt;/p&gt;

&lt;p&gt;Du côté boucle de dessin, la solution pour gérer correctement les animations dans le jeux HTML5 pourrait venir dans le futur avec requestAnimationFrame(). Cependant, la spécification est aujourd’hui dans un état trop brouillonne et son implémentation varie d’un navigateur à l’autre. Par ailleurs, il y a actuellement des débats intéressants sur son utilisation ou non sur le web. Si le sujet vous intéresse, je vous conseille la lecture de ces 3 articles :&lt;/p&gt;

&lt;p&gt;- &lt;a title="http://www.phoboslab.org/log/2011/08/are-we-fast-yet" href="http://www.phoboslab.org/log/2011/08/are-we-fast-yet"&gt;Are We Fast Yet?&lt;/a&gt; de Dominic Szablewski, l’auteur du test &lt;a href="http://html5-benchmark.com/"&gt;HTML5 Benchmark&lt;/a&gt; (utilisant ImpactJS) : “&lt;em&gt;At the moment &lt;code&gt;requestAnimationFrame()&lt;/code&gt; is truly worthless for games.&lt;/em&gt;”&amp;#160; &lt;br /&gt;- &lt;a href="http://paulirish.com/2011/requestanimationframe-for-smart-animating/"&gt;requestAnimationFrame for smart animating&lt;/a&gt; de Paul Irish. 

  &lt;br /&gt;- &lt;a title="http://ie.microsoft.com/testdrive/Graphics/RequestAnimationFrame/Default.html" href="http://ie.microsoft.com/testdrive/Graphics/RequestAnimationFrame/Default.html"&gt;requestAnimationFrame API&lt;/a&gt; de notre site IE Test Drive démontrant notre implémentation courante dans IE10.&lt;/p&gt;

&lt;h2&gt;Bonus spéciaux pour IE9&lt;/h2&gt;

&lt;p&gt;J’ai ajouté 2 petits bonus pour les utilisateurs d’IE9 venant tester mon petit jeu :&lt;/p&gt;

&lt;p&gt;- un mode épinglé avec une icône haute résolution et une jump list vers des ressources tournant autour du jeu
  &lt;br /&gt;- des boutons présents dans le mode “preview” de Windows 7 pour jouer au jeu d’une manière originale ! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2768.wlEmoticon_2D00_winkingsmile_5F00_1B180398.png" /&gt;&lt;/p&gt;

&lt;p&gt;Vous pouvez ainsi glisser/déposer l’onglet contenant le jeu dans la barre des tâches Windows 7. IE9 prendra alors les couleurs du thème du jeu :&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5824.image_5F00_thumb_5F00_697AA903.png" /&gt;&lt;/p&gt;

&lt;p&gt;Vous disposerez également d’une liste de raccourcis :&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5657.image_5F00_thumb_5F00_0C6E9EC4.png" /&gt;&lt;/p&gt;

&lt;p&gt;Le jeu sera donc présent au sein de la barre des tâches de l’utilisateur comme si c’était une application native.&lt;/p&gt;

&lt;p&gt;Pour finir, vous pouvez même jouer discrètement au jeu en utilisant la fonction de prévisualisation d’une fenêtre de Windows 7 !&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4338.image_5F00_thumb_5F00_358C3758.png" /&gt;&lt;/p&gt;

&lt;p&gt;Il y a 3 petits boutons pour bouger à gauche/droite et même sauter dans ce mode particulier. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-openmouthedsmile" alt="Rire" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8463.wlEmoticon_2D00_openmouthedsmile_5F00_1A3F9DAE.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; il y a une autre dédicace à IE plus ou moins caché dans l’un des niveaux. La trouverez-vous ? &lt;/p&gt;

&lt;h2&gt;Ajoutez de nouveaux niveaux au jeu&lt;/h2&gt;

&lt;p&gt;Les niveaux sont stockés dans le répertoire “/levels” dans des fichiers de type .TXT. Vous aurez 4 niveaux par défaut: 0.txt, 1.txt, 2.txt &amp;amp; 3.txt. Ils sont tout simplement téléchargés via une requête XMLHTTPRequest en mode asynchrone et ils sont parsés afin de construire le système de rendu et de collisions du jeu.&lt;/p&gt;

&lt;p&gt;Voici par exemple le 2ème niveau du jeu :&lt;/p&gt;

&lt;pre&gt;&lt;font color="#008000" size="1"&gt;....................
....................
..........X.........
.......######.......
..G..............G..
####..G.G.G.G....###
.......G.G.GCG......
......--------......
...--...........--..
......GGGG.GGGG.....
.G.G...GG..G....G.G.
####...GG..GGGG.####
.......GG..G........
.1....GGGG.GGGG.....
####################&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Et voici le résultat de son interprétation dans le jeu :&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6567.image_5F00_thumb_5F00_2B8F1D02.png" /&gt;&lt;/p&gt;

&lt;p&gt;Le caractère &lt;strong&gt;1&lt;/strong&gt; indique où commence le joueur, &lt;strong&gt;X&lt;/strong&gt; la sortie, &lt;strong&gt;G&lt;/strong&gt; un diamant, &lt;strong&gt;#&lt;/strong&gt; un bloc d’une plateforme, &lt;strong&gt;-&lt;/strong&gt; un block que l’on peut traverser, &lt;strong&gt;C&lt;/strong&gt; l’un des monstres, etc.&lt;/p&gt;

&lt;p&gt;Donc si vous souhaitez ajouter un nouveau niveau au jeu, ajoutez simplement un nouveau fichier de type texte dans le répertoire et éditez le niveau vous-même avec… Notepad ! Vous devrez aussi modifier la valeur de la variable &lt;em&gt;numberOfLevel&lt;/em&gt; contenue dans le fichier &lt;em&gt;PlateformerGame.js&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Code source non compressé à télécharger&lt;/h2&gt;

&lt;p&gt;Chose promise, chose due, vous pouvez télécharger le code source ainsi que tous les éléments du jeu ici : &lt;a href="http://david.blob.core.windows.net/html5platformer/HTML5Platformer.zip"&gt;HTML5 Platformer Non-minified&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;J’espère que vous aurez apprécié cette série de 3 articles autour du jeu HTML5. Cela vous aidera peut-être à transformer vos idées de jeux en une réalité HTML5 !&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10208530" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/XNA/">XNA</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Platformer/">Platformer</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Game/">Game</category></item><item><title>HTML5 Platformer: the complete port of the XNA game to &lt;canvas&gt; with EaselJS</title><link>http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx</link><pubDate>Fri, 09 Sep 2011 07:56:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10208343</guid><dc:creator>David Rousset</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10208343</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx#comments</comments><description>&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="left" src="https://david.blob.core.windows.net/html5platformer/icons/Game128.png" width="96" height="96" /&gt;After a couple of hours coding with JavaScript, I’ve finally finished porting the XNA 4.0 Platformer game sample to HTML5/Canvas with the help of the EaselJS gaming framework. This article will provide you the game and the story of some of the questions I’ve asked myself while coding it. If you’d like to know how the game works, simply read the JavaScript commented code available at the end of this article. Please note that my main goal was to better learn JavaScript by writing pure JS code (with no form of dependency to the DOM) and to write a cross-browsers working game and cross HTML5 compatible devices when possible also.&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;You can play the game directly inside this iframe (left &amp;amp; right arrows keys to move &amp;amp; W to jump). Just press the “Start” button to launch the download sequence and the game itself. &lt;/p&gt; &lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="530" src="http://david.blob.core.windows.net/html5platformer/index.html" width="830"&gt;&lt;/iframe&gt;  &lt;p&gt;Or you can play with it in a separate window through this link: &lt;a title="http://david.blob.core.windows.net/html5platformer/index.html" href="http://david.blob.core.windows.net/html5platformer/index.html" target="_blank"&gt;HTML5 Platformer&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; this game has been tested with success under IE9/10, Chrome, Firefox 6+, Opera 11+, IE9 on WP7 Mango and iPad 2. The text elements are not displayed under Opera as there is &lt;a href="https://github.com/gskinner/EaselJS/issues/48"&gt;a bug with EaselJS on this topic&lt;/a&gt;. At last, if you really want to play to the game, an hardware accelerated browser is highly recommended. I’ve got 60 FPS in these conditions on my Sony Vaio Z13.&amp;#160; &lt;/p&gt;  &lt;p&gt;At the end of this article, you’ll find the complete non-minified source code of this game inside a ZIP archive to download. I’ve tried to comment as much as possible the code to make it self-explicit. I hope you’ll learn some interesting things while reading it. If you have any feedbacks and/or suggestions on it, feel free to add it as a comment to this blog’s post.&lt;/p&gt;  &lt;p&gt;I’ve also already written 2 articles covering the basics of the logic behind this game here:&lt;/p&gt;  &lt;p&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx"&gt;HTML5 Gaming: animating sprites in Canvas with EaselJS&lt;/a&gt;     &lt;br /&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx"&gt;HTML5 Gaming: building the core objects &amp;amp; handling collisions with EaselJS&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;Building the content manager&lt;/h2&gt;  &lt;p&gt;In the previous article, the download content manager wasn’t notifying the user of the progression of the download process which was very bad. Hopefully, adding this feature was pretty straight forward as you just have to have a tick() method to your object and update a text element on the stage to show the progression. You can find that by reading the &lt;em&gt;ContentManager.js&lt;/em&gt; file. &lt;/p&gt;  &lt;p&gt;Moreover, as my objective was to be compatible with all browsers, I’ve then encoded the music &amp;amp; audio elements both in MP3 and OGG. If you’d like to know more about this HTML5 Audio tag codecs story, I recommend you having a look to my colleague’s article: &lt;a href="http://blogs.msdn.com/b/nigel/archive/2011/04/14/5-things-you-need-to-know-to-start-using-video-and-audio-today.aspx"&gt;5 Things You Need to Know to Start Using Video and Audio Today&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Then, I’m downloading either the MP3 or OGG version using the following code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;canPlayMp3, canPlayOgg;
&lt;span style="color: blue"&gt;var &lt;/span&gt;audioExtension = &lt;span style="color: maroon"&gt;&amp;quot;.none&amp;quot;&lt;/span&gt;;

&lt;span style="color: #006400"&gt;// Need to check the canPlayType first or an exception
// will be thrown for those browsers that don't support it      
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;myAudio = document.createElement(&lt;span style="color: maroon"&gt;'audio'&lt;/span&gt;);

&lt;span style="color: blue"&gt;if &lt;/span&gt;(myAudio.canPlayType) {
    &lt;span style="color: #006400"&gt;// Currently canPlayType(type) returns: &amp;quot;&amp;quot;, &amp;quot;maybe&amp;quot; or &amp;quot;probably&amp;quot; 
    &lt;/span&gt;canPlayMp3 = !!myAudio.canPlayType &amp;amp;&amp;amp; &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot; &lt;/span&gt;!= myAudio.canPlayType(&lt;span style="color: maroon"&gt;'audio/mpeg'&lt;/span&gt;);
    canPlayOgg = !!myAudio.canPlayType &amp;amp;&amp;amp; &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot; &lt;/span&gt;!= myAudio.canPlayType(&lt;span style="color: maroon"&gt;'audio/ogg; codecs=&amp;quot;vorbis&amp;quot;'&lt;/span&gt;);
}

&lt;span style="color: blue"&gt;if &lt;/span&gt;(canPlayMp3)
    audioExtension = &lt;span style="color: maroon"&gt;&amp;quot;.mp3&amp;quot;&lt;/span&gt;;
&lt;span style="color: blue"&gt;else if &lt;/span&gt;(canPlayOgg) {
    audioExtension = &lt;span style="color: maroon"&gt;&amp;quot;.ogg&amp;quot;&lt;/span&gt;;
}

&lt;span style="color: #006400"&gt;// If the browser supports either MP3 or OGG
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(audioExtension !== &lt;span style="color: maroon"&gt;&amp;quot;.none&amp;quot;&lt;/span&gt;) {
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.globalMusic, &lt;span style="color: maroon"&gt;&amp;quot;sounds/Music&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.playerKilled, &lt;span style="color: maroon"&gt;&amp;quot;sounds/PlayerKilled&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.playerJump, &lt;span style="color: maroon"&gt;&amp;quot;sounds/PlayerJump&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.playerFall, &lt;span style="color: maroon"&gt;&amp;quot;sounds/PlayerFall&amp;quot; &lt;/span&gt;+ audioExtension);
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.exitReached, &lt;span style="color: maroon"&gt;&amp;quot;sounds/ExitReached&amp;quot; &lt;/span&gt;+ audioExtension);
}&lt;/pre&gt;

&lt;p&gt;I’ve spent more time trying to figure out what was the best way to preload or download the audio files before starting the game. In the case of the image elements, we can’t start the game at all if we don’t have downloaded all the images locally. Otherwise, trying to draw on the canvas with non-yet downloaded images will fail. &lt;/p&gt;

&lt;p&gt;For the audio elements, my wish was to be sure to play it exactly when I will need it. If the player dies, I don’t want the sound to be played 2 sec after the fatal event. Unfortunately, there is no real way to do that properly in all browsers. The HTML5 Audio element has been made to stream the audio file and plays it as soon as enough data is available. We don’t have an event saying: “&lt;em&gt;the audio file has been completely downloaded&lt;/em&gt;”. My idea was then to download a base64 version of the file using an XMLHTTPRequest and to pass it to the audio tag using &lt;em&gt;&amp;lt;source src=&amp;quot;data:audio/mp3;base64,{base64_string}&amp;quot; /&amp;gt;&lt;/em&gt; for instance. But I didn’t have the time to test if this is working or not. If you have done some similar tests, I’m interested in the results.&lt;/p&gt;

&lt;p&gt;So finally, the only thing I’m doing is calling the load() method to start loading as much data as possible before using it. But on slow network, this won’t prevent the case where the audio won’t be ready while the game asks it. This won’t generate an error, but the sound won’t be synchronized with the action. &lt;/p&gt;

&lt;h2&gt;Working around HTML5 Audio tag limitations&lt;/h2&gt;

&lt;p&gt;While coding and testing the game, I’ve found another issue using the HTML5 &amp;lt;audio&amp;gt; tag (I didn’t expect spending so much time on the audio part!). If the player takes several gems too quickly, the audio element associated to this event can’t handle it. For instance, at the beginning, when the player was taking 8 gems on the same line, I was able to hear only 1 to 3 times the sound “GemCollected.mp3/ogg”. This means that no sound was emitted for the 5 remaining gems. &lt;/p&gt;

&lt;p&gt;I’ve then started several experiments and I’ve finally discover that I’ve done everything already related in this article: &lt;a title="http://www.phoboslab.org/log/2011/03/multiple-channels-for-html5-audio" href="http://www.phoboslab.org/log/2011/03/multiple-channels-for-html5-audio"&gt;Multiple Channels for HTML5 Audio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On my side, I’ve finished by using another workaround. In the content manager object, I’m downloading 8 times the same GemCollected sound into an array of Audio() objects:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Used to simulate multi-channels audio 
// As HTML5 Audio in browsers is today too limited
// Yes, I know, we're forced to download N times to same file...
&lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;a = 0; a &amp;lt; 8; a++) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.gemCollected[a] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Audio();
    SetAudioDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.gemCollected[a], &lt;span style="color: maroon"&gt;&amp;quot;sounds/GemCollected&amp;quot; &lt;/span&gt;+ audioExtension);
}&lt;/pre&gt;

&lt;p&gt;And during the game, I’m cycling inside this array to be able to “simulate” multichannels sound. You can find this trick in the &lt;em&gt;UpdateGems()&lt;/em&gt; method of &lt;em&gt;Level.js&lt;/em&gt;:&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: #006400"&gt;Animates each gem and checks to allows the player to collect them.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;Level.prototype.UpdateGems = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems.length; i++) {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems[i].BoundingRectangle().Intersects(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Hero.BoundingRectangle())) {
            &lt;span style="color: #006400"&gt;// We remove it from the drawing surface
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.levelStage.removeChild(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems[i]);
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Score += &lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems[i].PointValue;
            &lt;span style="color: #006400"&gt;// We then remove it from the in memory array
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.Gems.splice(i, 1);
&lt;font style="background-color: #ffff00"&gt;            &lt;/font&gt;&lt;font style="background-color: #ffff00"&gt;&lt;span style="color: #006400"&gt;// And we finally play the gem collected sound using a multichannels trick
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.levelContentManager.gemCollected[audioGemIndex % 8].play();
            audioGemIndex++;&lt;/font&gt;
        }
    }
};&lt;/pre&gt;

&lt;p&gt;I know this is not efficient at all. Maybe some Audio APIs will help us in the future to better handle the audio in our games. I know Mozilla and Google are working on some good suggestions but this is far from being mainstream for the moment. &lt;/p&gt;

&lt;h2&gt;The mono-threaded JavaScript nature&lt;/h2&gt;

&lt;p&gt;I’ve already covered this topic inside one of my previous articles: &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/15/introduction-to-the-html5-web-workers-the-javascript-multithreading-approach.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/15/introduction-to-the-html5-web-workers-the-javascript-multithreading-approach.aspx"&gt;Introduction to the HTML5 Web Workers: the JavaScript multithreading approach&lt;/a&gt; . Without WebWorkers, JavaScript is by nature mono-threaded. Even if setInterval() and setTimetout() try to make the illusions that multiple things occur at the same time, this is not the case. Everything is serialized.&lt;/p&gt;

&lt;p&gt;In my gaming scenario, this leads to problems while handling the animations. We don’t have the guarantee of being call-backed every xxx milliseconds in our update logic. To avoid that, XNA provides 2 different separate loops: the drawing loop and the update loop. In my case, they are more or less merged. And this is where the problem is. For instance, if the elapsed time between 2 ticks is too important (due to the single threading processing), I could miss an update call that would prevent one of my enemies to hit testing properly its environment. This then leads to very weird results. This is why in some parts of the code, I’ve hard-coded the expected elapsed time to 17 milliseconds. In the XNA version, the elapsed time is compute and often equal to approximately 16 ms (60 FPS). The solution to better handle the update loop (the tick() method in EaselJS) could be to use some WebWorkers. &lt;/p&gt;

&lt;p&gt;On the other side, the solution for HTML5 gaming to properly handle animations could come in the future with requestAnimationFrame(). Unfortunately, the specification is currently in a too draft stage and its implementation varies. Moreover, there are some interesting debates around it on the web. If you’re interested in this topic, I suggest you reading these 2 articles:&lt;/p&gt;

&lt;p&gt;- &lt;a title="http://www.phoboslab.org/log/2011/08/are-we-fast-yet" href="http://www.phoboslab.org/log/2011/08/are-we-fast-yet"&gt;Are We Fast Yet?&lt;/a&gt; by Dominic Szablewski, the author of &lt;a href="http://html5-benchmark.com/"&gt;HTML5 Benchmark&lt;/a&gt; (using ImpactJS) : “&lt;em&gt;At the moment &lt;code&gt;requestAnimationFrame()&lt;/code&gt; is truly worthless for games.&lt;/em&gt;”&amp;#160; &lt;br /&gt;- &lt;a href="http://paulirish.com/2011/requestanimationframe-for-smart-animating/"&gt;requestAnimationFrame for smart animating&lt;/a&gt; from Paul Irish. 

  &lt;br /&gt;- &lt;a title="http://ie.microsoft.com/testdrive/Graphics/RequestAnimationFrame/Default.html" href="http://ie.microsoft.com/testdrive/Graphics/RequestAnimationFrame/Default.html"&gt;requestAnimationFrame API&lt;/a&gt; from our IE Test Drive site to show our current IE10 implementation.&lt;/p&gt;

&lt;h2&gt;Special Kudos for IE9&lt;/h2&gt;

&lt;p&gt;I’ve added 2 Kudos for IE9 users browsing my little game:&lt;/p&gt;

&lt;p&gt;- pinned mode with a high resolution favicon and a jumplist to resources linked to the game 
  &lt;br /&gt;- thumbnail buttons to play the game in an original way! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6888.wlEmoticon_2D00_winkingsmile_5F00_49A9717D.png" /&gt;&lt;/p&gt;

&lt;p&gt;You can then drag’n’drop the tab into your Windows 7 taskbar. IE9 will then reflect the theme of the game:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1122.image_5F00_1AD9B931.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5824.image_5F00_thumb_5F00_697AA903.png" width="850" height="96" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will also have a jumplist available:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2043.image_5F00_09895FDE.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5657.image_5F00_thumb_5F00_0C6E9EC4.png" width="339" height="415" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The game will then be available on the user’s taskbar as if it was a native application.&lt;/p&gt;

&lt;p&gt;At last, you can discretely continue playing the game via the preview mode of Windows7!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3362.image_5F00_309A1F76.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4338.image_5F00_thumb_5F00_358C3758.png" width="309" height="286" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 3 thumbnails buttons to move left/right and jump even in preview mode. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-openmouthedsmile" alt="Rire" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4010.wlEmoticon_2D00_openmouthedsmile_5F00_4CC715FC.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; there is another more or less hidden kudos to IE in one of the levels. Will you find it?&lt;/p&gt;

&lt;h2&gt;Adding new levels to the game&lt;/h2&gt;

&lt;p&gt;The levels are stored inside the “/levels” directory inside .txt files. You’ll find 4 levels by default: 0.txt, 1.txt, 2.txt &amp;amp; 3.txt. They are simply downloaded via an asynchronous XMLHTTPRequest call and they parsed to build the appropriate rendering &amp;amp; collisions system.&lt;/p&gt;

&lt;p&gt;For instance, here is the 2nd level:&lt;/p&gt;

&lt;pre&gt;&lt;font color="#008000" size="1"&gt;....................
....................
..........X.........
.......######.......
..G..............G..
####..G.G.G.G....###
.......G.G.GCG......
......--------......
...--...........--..
......GGGG.GGGG.....
.G.G...GG..G....G.G.
####...GG..GGGG.####
.......GG..G........
.1....GGGG.GGGG.....
####################&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;And here is the output in the game:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6332.image_5F00_6D528E8D.png"&gt;&lt;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" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6567.image_5F00_thumb_5F00_2B8F1D02.png" width="320" height="216" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; is where the player will start the game, &lt;strong&gt;X&lt;/strong&gt; is the exit, &lt;strong&gt;G&lt;/strong&gt; is a Gem, &lt;strong&gt;#&lt;/strong&gt; is a platform block, &lt;strong&gt;-&lt;/strong&gt; is a passable block, &lt;strong&gt;C&lt;/strong&gt; one of the monsters/enemies, etc. &lt;/p&gt;

&lt;p&gt;So, if you’d like to add levels to the game, simply add a new text file and edit the level yourself with… Notepad! You’ll need also to modify the value of the &lt;em&gt;numberOfLevel&lt;/em&gt; variable inside &lt;em&gt;PlatformerGame.js&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Non-minified source code&lt;/h2&gt;

&lt;p&gt;As promised, you can download the source code and all the assets of the game here: &lt;a href="http://david.blob.core.windows.net/html5platformer/HTML5Platformer.zip"&gt;HTML5 Platformer Non-minified&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope you’ve enjoyed this series of 3 articles around HTML5 Gaming. Maybe this will help you transforming your gaming ideas into an HTML5 reality!&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10208343" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/XNA/">XNA</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Platformer/">Platformer</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Game/">Game</category></item><item><title>Tutorial HTML5: découverte des tags sémantiques, d’un soupçon de CSS3 et de Modernizr</title><link>http://blogs.msdn.com/b/davrous/archive/2011/08/25/tutorial-html5-d-233-couverte-des-tags-s-233-mantiques-d-un-soup-231-on-de-css3-et-de-modernizr.aspx</link><pubDate>Thu, 25 Aug 2011 13:33:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10200303</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10200303</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/08/25/tutorial-html5-d-233-couverte-des-tags-s-233-mantiques-d-un-soup-231-on-de-css3-et-de-modernizr.aspx#comments</comments><description>&lt;p&gt;Pendant l’été, avec &lt;a href="http://blogs.technet.com/b/stanislas/"&gt;Stanislas Quastana&lt;/a&gt; et &lt;a href="http://blogs.msdn.com/b/eternalcoding/"&gt;David Catuhe&lt;/a&gt;, nous avons publié 3 cahiers de vacances autour d’HTML5 sur notre plateforme MSDN : &lt;a title="http://msdn.microsoft.com/fr-fr/ie/hh237531" href="http://msdn.microsoft.com/fr-fr/ie/hh237531"&gt;Focus sur HTML5&lt;/a&gt; . Mon cahier abordait les tags sémantiques d’HTML5, un peu de CSS3 et comment rendre le tout compatible même avec IE8 en utilisant Modernizr. Je vous propose de le découvrir ici à nouveau. Vous pouvez télécharger les 2 autres cahiers consacrés à la balise audio/vidéo d’HTML5 et à la création d’un jeu de casse-brique avec Canvas et SVG sur notre &lt;a href="http://msdn.microsoft.com/fr-fr/ie/hh237531"&gt;site MSDN&lt;/a&gt;. Vous pouvez également télécharger ce même tutorial au même endroit aux formats PDF et DOCX. &lt;/p&gt; &lt;a title="Couverture Cahier HTML5" href="http://msdn.microsoft.com/fr-fr/ie/hh237531"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 10px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Couverture Cahier HTML5" src="http://farm7.static.flickr.com/6086/6076482919_55832defdf.jpg" width="354" height="500" /&gt;&lt;/a&gt;   &lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p&gt;L’objectif de cet exercice est de découvrir votre première page HTML5 utilisant quelques tags sémantiques ainsi qu’un peu de CSS3. Nous allons également voir, en utilisant certaines bonnes pratiques, comment commencer à utiliser ces nouvelles technologies tout en continuant de bien supporter d’anciens navigateurs comme IE8. &lt;/p&gt;  &lt;h3&gt;Prérequis à l’atelier&lt;/h3&gt;  &lt;p&gt;1 – Visual Studio 2010 SP1    &lt;br /&gt;2 – Web Standards Update : &lt;a href="http://visualstudiogallery.msdn.microsoft.com/a15c3ce9-f58f-42b7-8668-53f6cdc2cd83"&gt;http://visualstudiogallery.msdn.microsoft.com/a15c3ce9-f58f-42b7-8668-53f6cdc2cd83&lt;/a&gt;     &lt;br /&gt;3 – Internet Explorer 9 ou tout autre navigateur supportant le HTML 5     &lt;br /&gt;4 – Téléchargez les sources pour commencer ce cahier ici : &lt;a href="http://david.blob.core.windows.net/html5/CahierVacancesHTML5.zip"&gt;CahierVacancesHTML5.zip&lt;/a&gt; et rendez-vous dans le répertoire « &lt;b&gt;&lt;i&gt;DebutCahier&lt;/i&gt;&lt;/b&gt; »&lt;/p&gt;  &lt;p&gt;Vous pouvez également bien entendu utiliser votre IDE préféré (VI, Notepad++, etc.) à la place de Visual Studio 2010 pour suivre ces exercices. Vous n’aurez pas beaucoup de mal à vous adapter je pense.&lt;/p&gt;  &lt;h3&gt;Les tags sémantiques&lt;/h3&gt;  &lt;p&gt;Avant l’arrivée des tags sémantiques d’HTML5, nous avions l’habitude de construire notre page avec un entête, un pied de page et une barre de navigation à l’aide de &amp;lt;div&amp;gt; habillée par CSS via l’affectation de classes. &lt;/p&gt;  &lt;p&gt;Cela marchait très bien mais le problème d’une balise &amp;lt;div&amp;gt; est qu’elle n’a pas de sens. Ce n’est pas forcément grave dans de nombreux cas mais ici pour la structure de notre page, cela peut être vite embêtant en terme de sémantique et d’accessibilité. Si l’accessibilité d’HTML5 vous intéresse d’ailleurs, je vous conseille un article que j’ai écrit à ce sujet : &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/02/21/slides-et-ressources-de-la-session-accessibilit-233-d-html5-et-silverlight-des-techdays-2011.aspx"&gt;Techdays 2011 – slides et ressources de la session Accessibilité d’HTML5 et Silverlight&lt;/a&gt; . Je vous conseille vivement aussi l’excellent article de Jean-Pierre Vincent en complément : &lt;a title="http://braincracking.org/2011/02/19/etat-des-lieux-de-l%e2%80%98accessibilite-de-html5/" href="http://braincracking.org/2011/02/19/etat-des-lieux-de-l%e2%80%98accessibilite-de-html5/"&gt;Etat des lieux de l‘accessibilité de HTML5&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En gros, cela donne ce genre de résultat entre HTML4 et HTML5 :&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm6.static.flickr.com/5292/5465134921_7207b230e1.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;Pour avoir une meilleure idée de leurs utilisations, vous pouvez lire les spécifications du W3C: &lt;a title="http://www.w3.org/TR/html5/sections.html#sections" href="http://www.w3.org/TR/html5/sections.html#sections"&gt;http://www.w3.org/TR/html5/sections.html#sections&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Dans notre cas, nous allons partir de cette page nommée « &lt;b&gt;&lt;i&gt;Accueil.html&lt;/i&gt;&lt;/b&gt; » qui utilise ces nouveaux tags sémantiques HTML5 :&lt;/p&gt; &lt;a title="CahierHTML5_001 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/6076555531/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="CahierHTML5_001" src="http://farm7.static.flickr.com/6183/6076555531_d9f66a03c9.jpg" width="500" height="265" /&gt;&lt;/a&gt;   &lt;p&gt;&lt;b&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/b&gt; cette page a été générée à partir du modèle de base proposé par &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC3&lt;/a&gt; qui supporte désormais les tags sémantiques HTML5.&lt;/p&gt;  &lt;h2&gt;1. Parcours de la page avec la barre F12&lt;/h2&gt;  &lt;p&gt;Pour mieux comprendre comment cette page est structurée, nous allons utiliser la barre de développement intégrée à IE9. Pour cela, ouvrez la page « &lt;i&gt;Accueil.html&lt;/i&gt; » dans Internet Explorer 9 et appuyez simplement sur la touche F12. Si vous connaissez l’outil Firebug pour Firefox, c’est tout simplement son équivalent nativement présent avec Internet Explorer. &lt;/p&gt;  &lt;p&gt;Une fois la barre de développement affichée, cliquez sur le pointeur de sélection :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6560.CahierHTML5_5F00_002_5F00_03ED2E1B.png"&gt;&lt;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="CahierHTML5_002" border="0" alt="CahierHTML5_002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/4428.CahierHTML5_5F00_002_5F00_thumb_5F00_74D64F40.png" width="500" height="70" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Puis visez le bas de la page où se trouve notre magnifique développeur sur la plage (ou sur la page si vous voulez !).&lt;/p&gt;  &lt;p&gt;Vous obtiendrez le résultat suivant :&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0702.CahierHTML5_5F00_003_5F00_68DA74E6.png"&gt;&lt;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="CahierHTML5_003" border="0" alt="CahierHTML5_003" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6165.CahierHTML5_5F00_003_5F00_thumb_5F00_17044AD4.png" width="617" height="480" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;La partie que vous avez sélectionnée s’entoure d’un liseré bleu. Ensuite, on voit bien 3 parties différentes qui structurent notre page : &lt;b&gt;&amp;lt;header&amp;gt;&lt;/b&gt;, &lt;b&gt;&amp;lt;section&amp;gt;&lt;/b&gt; et &lt;b&gt;&amp;lt;footer&amp;gt;&lt;/b&gt; où se trouve logiquement notre pied de page. &lt;/p&gt;  &lt;p&gt;Amusez-vous ensuite à parcourir le reste de la page de la même manière. Vous verrez qu’à chaque fois cela vous positionne directement au bon endroit. La structure HTML apparaît à gauche et cela vous affiche également le style CSS actuellement affecté à cet élément sur la droite. &lt;/p&gt;  &lt;p&gt;En parcourant le code de la page, vous noterez un élément indispensable si vous vous lancez dans l’aventure HTML5 :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;La mise en place de cette balise DOCTYPE simplifiée par rapport à ce que vous avez peut-être déjà vu est indispensable si vous souhaitez qu’IE9+ bascule sur son moteur de rendu HTML5. Si vous ne commencez pas par cette balise, en commençant directement avec la balise &amp;lt;html&amp;gt; par exemple, IE9 basculera dans son mode « Quirks » et ne prendra donc pas en charge les nouveaux éléments HTML5 (video, canvas, etc.). &lt;/p&gt;

&lt;p&gt;Pour vérifier le mode de rendu actuellement utilisé par IE9, vous pouvez à nouveau le faire grâce à la touche F12. Vérifiez ensuite le mode de document. Observez cet exemple :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6558.CahierHTML5_5F00_004_5F00_0FA2754D.png"&gt;&lt;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="CahierHTML5_004" border="0" alt="CahierHTML5_004" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0211.CahierHTML5_5F00_004_5F00_thumb_5F00_529E43BA.png" width="500" height="76" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dans cette copie d’écran, nous sommes en mode « &lt;strong&gt;Quirks&lt;/strong&gt; » et nous allons avoir des soucis avec l’affichage d’HTML5. Vous pouvez alors forcer le mode en « &lt;strong&gt;IE9 Standards&lt;/strong&gt; » avec la barre F12 ou corriger le code du site pour utiliser la balise DOCTYPE tout simplement.&lt;/p&gt;

&lt;h2&gt;2. Utilisation de F12 pour modifier dynamiquement le CSS&lt;/h2&gt;

&lt;p&gt;A l’aide de la barre F12, modifiez le style &lt;b&gt;CSS3&lt;/b&gt; actuellement mis en place pour que le coin arrondi inférieur gauche de l’élément &lt;b&gt;&amp;lt;footer&amp;gt;&lt;/b&gt; passe de 4px à 100px. &lt;/p&gt;

&lt;p&gt;Pour cela, via la barre F12, positionnez-vous à nouveau sur l’élément &amp;lt;footer&amp;gt; et cherchez la propriété &lt;b&gt;border-bottom-left-radius &lt;/b&gt;pour passer sa valeur de 4 à 100 pixels. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5670.CahierHTML5_5F00_005_5F00_5159AADB.png"&gt;&lt;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="CahierHTML5_005" border="0" alt="CahierHTML5_005" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3022.CahierHTML5_5F00_005_5F00_thumb_5F00_6C25D0E7.png" width="500" height="102" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous pouvez également cliquez sur l’onglet CSS de la barre de développement et choisir la bonne feuille de style. Cela implique donc que vous sachiez déjà où vous cherchez. Ensuite, utilisez la zone de recherche pour trouver la propriété qui vous intéresse :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5001.CahierHTML5_5F00_006_5F00_1CD8D893.png"&gt;&lt;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="CahierHTML5_006" border="0" alt="CahierHTML5_006" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6562.CahierHTML5_5F00_006_5F00_thumb_5F00_1B280CBF.png" width="500" height="143" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous devriez voir alors instantanément le résultat de votre modification dans la page :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6253.CahierHTML5_5F00_007_5F00_2817DCDD.png"&gt;&lt;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="CahierHTML5_007" border="0" alt="CahierHTML5_007" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3438.CahierHTML5_5F00_007_5F00_thumb_5F00_1894CB0E.png" width="640" height="89" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le coin inférieur gauche du pied de page a bien été davantage arrondi. La barre F12 est donc très pratique pour tester en live quelques modifications. Vous pouvez même ajouter de nouvelles règles CSS ou des attributs à une règle existante via cette même barre.&lt;/p&gt;

&lt;p&gt;Sans le savoir vous avez par ailleurs déjà joué avec l’une des nouveautés de CSS3 présente dans le module &lt;a href="http://www.w3.org/TR/css3-background/"&gt;CSS3 Background &amp;amp; Borders&lt;/a&gt; du W3C. Félicitations ! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5282.wlEmoticon_2D00_winkingsmile_5F00_4262107C.png" /&gt;&lt;/p&gt;

&lt;p&gt;Ce module n’est pas le plus critique de CSS3 mais c’est l’un des plus simples à comprendre et à expérimenter. Il permet tout simplement d’arrondir les coins de n’importe quel élément HTML ainsi que de positionner également une ombre portée via la propriété &lt;b&gt;&lt;i&gt;box-shadow&lt;/i&gt;&lt;/b&gt;. Retrouvez davantage d’informations en Français sur notre site MSDN ici : &lt;a href="http://msdn.microsoft.com/fr-fr/ie/ff468705#_CSS3_BG_Borders"&gt;Module CSS3 Arrière-plans et bordures&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;3. Modification de la feuille de style avec Visual Studio 2010&lt;/h2&gt;

&lt;p&gt;A l’aide de Visual Studio 2010, ouvrez le fichier « &lt;b&gt;&lt;i&gt;Site.css&lt;/i&gt;&lt;/b&gt; ». Commencez par bien vérifier que vous êtes actuellement en train de valider du CSS3 et non pas du CSS 2.1 :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8712.CahierHTML5_5F00_008_5F00_453D84E7.png"&gt;&lt;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="CahierHTML5_008" border="0" alt="CahierHTML5_008" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7144.CahierHTML5_5F00_008_5F00_thumb_5F00_3B28E3BC.png" width="640" height="452" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La validation et auto-complétion d’HTML5 et de CSS3 vous est offerte par l’installation du prérequis &lt;a href="http://visualstudiogallery.msdn.microsoft.com/a15c3ce9-f58f-42b7-8668-53f6cdc2cd83"&gt;Web Standards Update&lt;/a&gt;. Si vous ne l’avez pas installé, ce n’est pas grave. Visual Studio sous-lignera simplement les propriétés CSS3 en rouge puisqu’il ne les connait pas sans cette extension.&lt;/p&gt;

&lt;p&gt;Une fois la feuille de style ouverte, modifiez une fois pour toute le style du &amp;lt;footer&amp;gt; pour avoir notre coin arrondi inférieur gauche de 100 pixels :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;footer&lt;/span&gt;, 
&lt;span style="color: maroon"&gt;#footer 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;url(ImagePiedPage.png) no-repeat left bottom&lt;/span&gt;;
    &lt;span style="color: red"&gt;background-color&lt;/span&gt;: &lt;span style="color: blue"&gt;#fff&lt;/span&gt;;
    &lt;span style="color: red"&gt;color&lt;/span&gt;: &lt;span style="color: blue"&gt;#999&lt;/span&gt;;
    &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;0&lt;/span&gt;;
    &lt;span style="color: red"&gt;text-align&lt;/span&gt;: &lt;span style="color: blue"&gt;center&lt;/span&gt;;
    &lt;span style="color: red"&gt;line-height&lt;/span&gt;: &lt;span style="color: blue"&gt;10em&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin&lt;/span&gt;: &lt;span style="color: blue"&gt;0 0 30px 0&lt;/span&gt;;
    &lt;font style="background-color: #ffff00"&gt;&lt;span style="color: red"&gt;border-radius&lt;/span&gt;: &lt;span style="color: blue"&gt;0 0 4px 100px&lt;/span&gt;;&lt;/font&gt;
}&lt;/pre&gt;

&lt;p&gt;Au passage, on va en profiter pour faire une ombre portée justement pour faire un effet de halo autour de nos boutons de navigation contenu dans la balise &lt;b&gt;&amp;lt;nav&amp;gt; &lt;/b&gt;du coup. Voici la partie de CSS qui nous intéresse :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;ul#menu li a &lt;/span&gt;{
    &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;10px 20px&lt;/span&gt;;
    &lt;span style="color: red"&gt;font-weight&lt;/span&gt;: &lt;span style="color: blue"&gt;bold&lt;/span&gt;;
    &lt;span style="color: red"&gt;text-decoration&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
    &lt;span style="color: red"&gt;line-height&lt;/span&gt;: &lt;span style="color: blue"&gt;2.8em&lt;/span&gt;;
    &lt;span style="color: red"&gt;background-color&lt;/span&gt;: &lt;span style="color: blue"&gt;#e8eef4&lt;/span&gt;;
    &lt;span style="color: red"&gt;color&lt;/span&gt;: &lt;span style="color: blue"&gt;#034af3&lt;/span&gt;;
    &lt;span style="color: red"&gt;border-radius&lt;/span&gt;: &lt;span style="color: blue"&gt;4px 4px 0 0&lt;/span&gt;;
    &lt;font style="background-color: #ffff00"&gt;&lt;span style="color: red"&gt;box-shadow&lt;/span&gt;: &lt;span style="color: blue"&gt;0 0 20px rgba(0,0,0,0.5)&lt;/span&gt;;&lt;/font&gt;
}&lt;/pre&gt;

&lt;p&gt;Et cela devrait vous donner ce magnifique résultat :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7120.CahierHTML5_5F00_009_5F00_6A2B1F93.png"&gt;&lt;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="CahierHTML5_009" border="0" alt="CahierHTML5_009" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1781.CahierHTML5_5F00_009_5F00_thumb_5F00_276BD45B.png" width="640" height="390" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C’est peut-être subtil mais vous devriez le voir. Amusez-vous par exemple, via la barre F12, à activer/désactiver l’application de cette attribut pour voir la différence.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6746.CahierHTML5_5F00_010_5F00_59AD5A65.png"&gt;&lt;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="CahierHTML5_010" border="0" alt="CahierHTML5_010" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0880.CahierHTML5_5F00_010_5F00_thumb_5F00_1FBE1779.png" width="400" height="116" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;4. Afficher la page correctement sous IE8&lt;/h2&gt;

&lt;p&gt;Si vous testez le rendu sous Internet Explorer 8 en forçant par exemple le moteur de rendu associé avec la barre F12 d’IE9 : &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1362.CahierHTML5_5F00_011_5F00_1E797E9A.png"&gt;&lt;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="CahierHTML5_011" border="0" alt="CahierHTML5_011" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5582.CahierHTML5_5F00_011_5F00_thumb_5F00_24542233.png" width="500" height="130" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Votre page devrait être toute cassée :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1460.CahierHTML5_5F00_012_5F00_6D6C6BA1.png"&gt;&lt;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="CahierHTML5_012" border="0" alt="CahierHTML5_012" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7142.CahierHTML5_5F00_012_5F00_thumb_5F00_51E7699E.png" width="640" height="387" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour quelles raisons ? Tout simplement parce que les balises &lt;strong&gt;&amp;lt;header&amp;gt;&lt;/strong&gt;, &lt;strong&gt;&amp;lt;nav&amp;gt;&lt;/strong&gt; et &lt;strong&gt;&amp;lt;footer&amp;gt;&lt;/strong&gt; que nous utilisons actuellement sont des nouvelles balises HTML5 qu’IE8 ne connait pas. Or, IE8 et inférieurs ont la mauvaise habitude d’ignorer purement et simplement les tags qu’ils ne connaissent pas en ne les créant pas dans le DOM. Du coup, si vous comptiez sur ces tags pour appliquer vos feuilles de style, cela casse tout votre design de page. &lt;/p&gt;

&lt;p&gt;La 1&lt;sup&gt;ère&lt;/sup&gt; solution consiste simplement créer ces nouveaux tags dans le DOM (Document Object Model) d’IE par JavaScript avec un code équivalent à celui-là :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;header&amp;quot;&lt;/span&gt;);
    document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;footer&amp;quot;&lt;/span&gt;);
    document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;section&amp;quot;&lt;/span&gt;);
    document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;nav&amp;quot;&lt;/span&gt;);
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;IE8 ne connaitra pas pour autant leurs significations mais le fait de les rendre présentes dans le DOM nous permettra d’appliquer désormais correctement le style associé à ces nouvelles balises.&lt;/p&gt;

&lt;p&gt;Ainsi, si vous mettez ce code tout en haut de la page « &lt;i&gt;Accueil.html&lt;/i&gt; », l’affichage sous IE8 devient magiquement correct :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3426.CahierHTML5_5F00_013_5F00_62133197.png"&gt;&lt;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="CahierHTML5_013" border="0" alt="CahierHTML5_013" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2330.CahierHTML5_5F00_013_5F00_thumb_5F00_3F02C027.png" width="640" height="387" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nous avons simplement perdus les bords arrondis et les effets d’ombre portée. Ces effets ne seront alors affichés qu’aux navigateurs les plus récents comme « bonus visuels ». Mais notre site continuera d’être fonctionnel pour les navigateurs les plus anciens. Cette approche est la base de ce que nous appelons le &lt;b&gt;« &lt;i&gt;graceful degradation&lt;/i&gt;&lt;/b&gt; » en Anglais ou dégradation élégante. CSS par nature se prête très bien à cet exercice. Cela vous permet ainsi de commencer à utiliser des nouveautés de CSS3 sans pour autant vous couper des navigateurs les plus anciens. &lt;/p&gt;

&lt;h2&gt;5. Moderniser vos sites avec Modernizr&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.modernizr.com"&gt;Modernizr&lt;/a&gt; est une librairie JavaScript qui va nous permettre 2 choses :&lt;/p&gt;

&lt;p&gt;1 – Créer toutes les nouvelles balises HTML5 pour les anciens navigateurs pour nous pour éviter d’avoir à faire ce que nous avons fait juste avant 
  &lt;br /&gt;2 – De faire ce que l’on appelle du « &lt;b&gt;feature detection&lt;/b&gt; » en Anglais ou détection de fonctionnalités supportées par le navigateur.&lt;/p&gt;

&lt;p&gt;Cette librairie est désormais présente par défaut dans les modèles de projets d’ASP.NET MVC3. &lt;/p&gt;

&lt;p&gt;Pour le 1&lt;sup&gt;er&lt;/sup&gt; point, reprenez le code de la page « &lt;i&gt;Accueil.html&lt;/i&gt; » et remplacez ce bloc :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;header&amp;quot;&lt;/span&gt;);
    document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;footer&amp;quot;&lt;/span&gt;);
    document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;section&amp;quot;&lt;/span&gt;);
    document.createElement(&lt;span style="color: maroon"&gt;&amp;quot;nav&amp;quot;&lt;/span&gt;);
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Juste par cette ligne :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;./Scripts/modernizr-1.7.min.js&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Et le tour est joué ! Votre page utilisant les nouveaux tags HTML5 fonctionne toujours bien sous IE8.&lt;/p&gt;

&lt;p&gt;Mais ce n’est pas tout. Modernizr va vous permettre de tester les capacités du navigateur par code JavaScript et d’adapter le rendu en fonction de cela. &lt;/p&gt;

&lt;p&gt;Une fois la librairie chargée, en mode de rendu IE9, appuyez sur la touche F12 et regardez ce qui a été ajouté à l’élément racine &amp;lt;html&amp;gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8713.CahierHTML5_5F00_014_5F00_0E1E06E1.png"&gt;&lt;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="CahierHTML5_014" border="0" alt="CahierHTML5_014" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/6562.CahierHTML5_5F00_014_5F00_thumb_5F00_7AFCDA34.png" width="500" height="69" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On voit que l’attribut « &lt;i&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/i&gt; » a été rempli en fonction de ce que votre navigateur supporte. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/b&gt; il est cependant important de noter que Modernizr n’effectue finalement qu’un simple test binaire. Il répond à la question « votre navigateur supporte-t-il XXX ? » (Oui/Non). Ce n’est pas un test qualitatif pour savoir ensuite si votre navigateur supporte toutes les fonctionnalités associées et surtout si l’implémentation de cette fonctionnalité est correcte ou pas.&lt;/p&gt;

&lt;p&gt;Utilisons maintenant Modernizr pour un cas que je trouve intéressant. IE9 supporte désormais le format vectoriel de dessin SVG. Cela nous permet ainsi d’envisager d’afficher des diagrammes, schéma ou toute autre forme d’image en vectoriel pour augmenter la qualité visuelle de nos pages. Oui mais que se passe-t-il pour les anciens navigateurs ne supportant pas SVG ? Et bah nous allons leur donner une version PNG de la même image. &lt;/p&gt;

&lt;p&gt;Reprenez la page « &lt;i&gt;Accueil.html&lt;/i&gt; » et ajoutez cette déclaration d’image sous l’unique paragraphe de notre section « &lt;i&gt;main&lt;/i&gt; » :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=imageThreadJS &lt;/span&gt;&lt;span style="color: red"&gt;alt&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Diagramme illustrant le cote mono-thread de JavaScript&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Nous préparons ici une zone qui contiendra notre image. Nous allons y stocker l’illustration issue de l’article suivant : &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx"&gt;Introduction aux Web Workers d’HTML5 : le multithreading version JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensuite, insérez ce bloc de code à la fin de la page « &lt;i&gt;Accueil.html&lt;/i&gt; » juste avant la fermeture de la balise &amp;lt;body&amp;gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;var &lt;span style="color: blue"&gt;img&lt;/span&gt;ThreadJS = document.getElementById(&amp;quot;ima&lt;span style="color: maroon"&gt;geThreadJS&amp;quot;);
    &lt;/span&gt;if (Mode&lt;span style="color: blue"&gt;rn&lt;/span&gt;izr.svg) {
        imgThreadJS.src = &amp;quot;http://davi&lt;span style="color: maroon"&gt;d.blob.core.windows.net/html5/SVGSingleThreadJS.svg&amp;quot;;

    }
    &lt;/span&gt;else {
        imgT&lt;span style="color: blue"&gt;hrea&lt;/span&gt;dJS.src = &amp;quot;http://david.blob.core.&lt;span style="color: maroon"&gt;windows.net/html5/SVGSingleThread.png&amp;quot;;
    }
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Ce code s’occupe de retrouver votre élément de type image puis en fonction de ce que Modernizr nous aura indiqué, nous irons chercher soit la version vectorielle de l’image (.SVG) soit la version bitmap de l’image (.PNG). &lt;/p&gt;

&lt;p&gt;Voici ainsi le résultat avec le moteur d’IE9 Standard :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2845.CahierHTML5_5F00_015_5F00_52EA2B15.png"&gt;&lt;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="CahierHTML5_015" border="0" alt="CahierHTML5_015" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5670.CahierHTML5_5F00_015_5F00_thumb_5F00_2FD9B9A5.png" width="500" height="401" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et voici le résultat avec le moteur d’IE8 :&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8625.CahierHTML5_5F00_016_5F00_4005819E.png"&gt;&lt;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="CahierHTML5_016" border="0" alt="CahierHTML5_016" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5008.CahierHTML5_5F00_016_5F00_thumb_5F00_4AE262E6.png" width="500" height="401" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/b&gt; la détection de fonctionnalités est clairement l’approche que vous devez désormais avoir sur toutes vos nouvelles créations. Ne faites surtout plus de détection de version de navigateurs (ou « &lt;i&gt;user-agent sniffing&lt;/i&gt; » en Anglais). &lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;En définitive, si IE9 ou un autre navigateur moderne comme Chrome, Firefox ou Opera arrive sur la page, ils pourront profiter d’une version du site plus moderne visuellement avec du CSS3 et du SVG. &lt;/p&gt;

&lt;p&gt;Si IE8 ou un autre navigateur plus ancien arrive sur la page, l’affichage sera peut-être moins aguichant avec une version PNG des images et moins d’effets visuels mais le site continuera d’être fonctionnel. &lt;/p&gt;

&lt;p&gt;C’est clairement dans cette direction que vous devrez travailler si vous souhaitez commencer à mettre en production du HTML5/CSS3 &amp;amp; Cie sur vos sites. &lt;/p&gt;

&lt;h3&gt;Ressources complémentaires&lt;/h3&gt;

&lt;p&gt;· &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/05/20/slides-et-exemples-de-ma-pr-233-sentation-des-microsoft-days-et-du-remix11-sur-html5.aspx"&gt;HTML5: Etat des lieux et projection vers l’avenir&lt;/a&gt; 

  &lt;br /&gt;· &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx"&gt;Introduction aux APIs graphiques d’HTML5: SVG &amp;amp; Canvas &lt;/a&gt;

  &lt;br /&gt;· &lt;a href="http://blogs.msdn.com/b/iefrance/archive/2011/03/25/microsoft-techdays-2011-la-vid-233-o-de-la-session-introduction-224-html5-est-en-ligne.aspx"&gt;TechDays 2011 : Introduction à HTML5&lt;/a&gt; 

  &lt;br /&gt;· &lt;a href="http://blogs.msdn.com/b/iefrance/archive/2011/02/08/techdays-2011-les-slides-de-la-session-introduction-224-html5.aspx"&gt;TechDays 2011 - les slides de la session Introduction à HTML5&lt;/a&gt; 

  &lt;br /&gt;· &lt;a href="http://blogs.technet.com/b/stanislas/archive/2010/11/04/mais-qui-construit-l-html5.aspx"&gt;Mais qui construit l'HTML5 ?&lt;/a&gt; 

  &lt;br /&gt;· &lt;a href="http://blogs.msdn.com/b/iefrance/archive/2011/02/28/html5-respect-des-standards-tests-et-marketing.aspx"&gt;HTML5 : respect des standards, tests et marketing&lt;/a&gt; 

  &lt;br /&gt;· &lt;a href="http://dev.w3.org/html5/spec/Overview.html"&gt;Site web du W3C pour HTML5&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Fun&lt;/h3&gt;

&lt;p&gt;On s’est bien marrés avec David et Stanislas en réalisant une vidéo de teasing où on fait les andouilles avec chapeaux de paille et shorts de bain. Je ne résiste pas au plaisir de vous la partager à nouveau (en HTML5 h264/WebM bien sûr!) :&lt;/p&gt;
&lt;video poster="http://www.catuhe.com/msdn/poster.png" width="512" controls&gt;&lt;source type="video/mp4" src="http://www.catuhe.com/msdn/teasingcahier.mp4"&gt;&lt;source type="video/webm" src="http://www.catuhe.com/msdn/teasingcahier.webm"&gt;&lt;/video&gt;

&lt;p&gt;&lt;br/&gt;Et spéciale décidasse à ma grand-mère g33k !&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10200303" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Tutorial/">Tutorial</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Visual+Studio+2010/">Visual Studio 2010</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/CSS3/">CSS3</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/SVG/">SVG</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Modernizr/">Modernizr</category></item><item><title>Jeux HTML5: construction des objets principaux &amp; gestion des collisions avec EaselJS</title><link>http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx</link><pubDate>Mon, 22 Aug 2011 16:21:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10198571</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10198571</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx#comments</comments><description>&lt;p&gt;Nous avons vu dans l’article précédent comment animer des sprites avec EaselJS : &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx"&gt;Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nous allons maintenant voir comment créer certains des objets de base de notre jeu comme les ennemies ou le héro de notre jeu de plateforme. Nous verrons aussi comment implémenter un mécanisme basique de collision entre les 2. Cette fois-ci ce tutoriel sera principalement basé sur l’exemple suivant: &lt;a title="http://easeljs.com/examples/game/game.html" href="http://easeljs.com/examples/game/game.html"&gt;EaselJS Game sample&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vous trouverez également &lt;strong&gt;un exemple fonctionnel à la fin de cet article&lt;/strong&gt;. C’est la base d’un petit jeu.&lt;/p&gt;  &lt;p&gt;&lt;a title="PlatformerTutorial2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5987662759/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="PlatformerTutorial2" src="http://farm7.static.flickr.com/6013/5987662759_94c799e39a.jpg" width="500" height="353" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Cette article est le 2ème d’une série de 3 articles :&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx"&gt;Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS&lt;/a&gt;    &lt;br /&gt;- Jeux HTML5: construction des objets principaux &amp;amp; gestion des collisions avec EaselJS    &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;HTML5 Platformer: portage complet du jeu XNA vers &amp;lt;canvas&amp;gt; grâce à EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Construction de l’objet Monster&lt;/h2&gt;  &lt;p&gt;Cet objet dispose de 2 états :&lt;/p&gt;  &lt;p&gt;1 – En train de courir sur la longueur de l’écran    &lt;br /&gt;2 – Etre en état de repos une fois l’un des bords de l’écran atteint avant de courir à nouveau.&lt;/p&gt;  &lt;p&gt;Oui, je sais, la vie d’un monstre n’est pas palpitante. Mais c’est comme ça ! Attention, aussi stupide soit-il, si vous le touchez vous mourrez. &lt;/p&gt;  &lt;p&gt;Cette fois-ci, j’ai fusionné en un unique fichier PNG les sprites venant de l’exemple XNA Platformer définissant les séquences où le personnage court et où il reste immobile. Voici par exemple le PNG associé au monstre MonsterC :&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://david.blob.core.windows.net/easeljstutorial2/img/MonsterB.png" width="950" height="45" /&gt;&lt;/p&gt;  &lt;p&gt;Notre objet monstre est défini au sein du fichier &lt;strong&gt;&lt;em&gt;Monster.js&lt;/em&gt; &lt;/strong&gt;et utilise l’objet &lt;a href="http://easeljs.com/docs/BitmapSequence.html"&gt;BitmapSequence&lt;/a&gt; comme prototype qui se prête en effet très bien à ce genre de scénarios. Il contient tout ce dont nous avons besoin: une méthode &lt;em&gt;tick()&lt;/em&gt;, un mécanisme de “hit testing” pour vérifier les collisions et une manière de gérer nos sprites sous la forme de plusieurs animations séparées. &lt;/p&gt;  &lt;p&gt;Il nous faut juste y ajouter de la logique spécifique à notre monstre comme la gestion d’un timer gérant l’état “au repos” et cela devrait faire l’affaire. Voici ainsi le code du fichier &lt;strong&gt;&lt;em&gt;Monster.js&lt;/em&gt; &lt;/strong&gt;définissant donc nos ennemies dans le jeu :&lt;/p&gt;  &lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function &lt;/span&gt;(window) {
    &lt;span style="color: blue"&gt;function &lt;/span&gt;Monster(monsterName, imgMonster, x_end) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.initialize(monsterName, imgMonster, x_end);
    }
    Monster.prototype = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence();

    &lt;span style="color: #006400"&gt;// propriétés publiques
    &lt;/span&gt;Monster.prototype.IDLEWAITTIME = 40;
    Monster.prototype.bounds = 0; &lt;span style="color: #006400"&gt;//taille du cercle visible
    &lt;/span&gt;Monster.prototype.hit = 0;     &lt;span style="color: #006400"&gt;

    // constructeur:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #006400"&gt;    // unique pour éviter d'écraser celui de la classe de base &lt;br /&gt;    &lt;/span&gt;Monster.prototype.BitmapSequence_initialize = Monster.prototype.initialize; &lt;br /&gt;    Monster.prototype.BitmapSequence_tick = Monster.prototype.tick; &lt;span style="color: #006400"&gt;

    // variables membres pour gérer l’état au repos
    // et le temps à attendre avant de courir à nouveau
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker = 0;

    &lt;span style="color: blue"&gt;var &lt;/span&gt;quaterFrameSize;

    Monster.prototype.initialize = &lt;span style="color: blue"&gt;function &lt;/span&gt;(monsterName, imgMonster, x_end) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;localSpriteSheet = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
                    imgMonster, &lt;span style="color: #006400"&gt;//image à utiliser
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//largeur de chacun des sprites
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//hauteur
            &lt;/span&gt;{
            walk_left: [0, 9],
            idle: [10, 20]
        });

        localSpriteSheet = SpriteSheetUtils.flip(
        localSpriteSheet,
        {
            walk_right: [&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;]
        });

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_initialize(localSpriteSheet);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end = x_end;

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regX = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 2 | 0;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regY = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameHeight / 2 | 0;

        quaterFrameSize = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 4;

        &lt;span style="color: #006400"&gt;// on commence à jouer la 1ère séquence 
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_right&amp;quot;&lt;/span&gt;);     &lt;span style="color: #006400"&gt;

        // mise en place d’une ombre portée. Attention, gros impact sur les performances
        // en fonction des navigateurs/plateformes matérielles.
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.shadow = &lt;span style="color: blue"&gt;new &lt;/span&gt;Shadow(&lt;span style="color: maroon"&gt;&amp;quot;#000&amp;quot;&lt;/span&gt;, 3, 2, 2);

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.name = monsterName;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.speed = 1;
        &lt;span style="color: #006400"&gt;// 1 = droite &amp;amp; -1 = gauche
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 1;
        &lt;span style="color: #006400"&gt;// vitesse
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.vX = 1 | 0.5;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY = 0;
        &lt;span style="color: #006400"&gt;// on saute directement à la 1ère frame de la séquence walk_right
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentFrame = 21;
    }

    Monster.prototype.tick = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: #006400"&gt;// Afin  de ralentir la boucle d’animation du sprite, on ne redessine pas à chaque tick&lt;/span&gt;&lt;span style="color: #006400"&gt;
        // Avec un coup de Modulo 4, on divise la vitesse par 4 (incroyable non ?)
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;speedControl = Ticker.getTicks() % 4;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(speedControl == 0) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_tick();
        }

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode) {
            &lt;span style="color: #006400"&gt;// On bouge le sprite en fonction de la direction et de la vitesse
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.x += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vX * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.y += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;

            &lt;span style="color: #006400"&gt;// On teste les bords de l’écran sinon notre sprite partirait vivre ailleurs (dans le cloud?)
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;gt;= &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end - (quaterFrameSize + 1) || &lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;lt; (quaterFrameSize + 1)) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;idle&amp;quot;&lt;/span&gt;);
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker = &lt;span style="color: blue"&gt;this&lt;/span&gt;.IDLEWAITTIME;
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
            }
        }
        &lt;span style="color: blue"&gt;else &lt;/span&gt;{
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker--;

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker == 0) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;false&lt;/span&gt;;

&lt;span style="color: #006400"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;gt;= &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end - (quaterFrameSize + 1)) {
                    &lt;span style="color: #006400"&gt;// Nous avons atteint le côté droit de l'écran
                    // Nous devons maintenant marcher vers la gauche
                    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = -1;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;);
                }

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;lt; (quaterFrameSize + 1)) {
                    &lt;span style="color: #006400"&gt;// Nous avons atteint le côté gauche de l'écran
                    // Nous devons maintenant marcher vers la droite
                    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 1;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_right&amp;quot;&lt;/span&gt;);
                }
            }
        }
    }

    Monster.prototype.hitPoint = &lt;span style="color: blue"&gt;function &lt;/span&gt;(tX, tY) {
        &lt;span style="color: blue"&gt;return this&lt;/span&gt;.hitRadius(tX, tY, 0);
    }

    Monster.prototype.hitRadius = &lt;span style="color: blue"&gt;function &lt;/span&gt;(tX, tY, tHit) {&lt;span style="color: #006400"&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(tX - tHit &amp;gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x + &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(tX + tHit &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x - &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(tY - tHit &amp;gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y + &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(tY + tHit &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y - &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }

        &lt;span style="color: #006400"&gt;//test basé sur une distance à base de cercle
        &lt;/span&gt;&lt;span style="color: blue"&gt;return this&lt;/span&gt;.hit + tHit &amp;gt; Math.sqrt(Math.pow(Math.abs(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x - tX), 2) &lt;br /&gt;                        + Math.pow(Math.abs(&lt;span style="color: blue"&gt;this&lt;/span&gt;.y - tY), 2));
    }

    window.Monster = Monster;
} (window));&lt;/pre&gt;

&lt;p&gt;La collision est gérée par les méthodes &lt;em&gt;&lt;strong&gt;hitPoint()&lt;/strong&gt;&lt;/em&gt; et &lt;strong&gt;&lt;em&gt;hitRadius()&lt;/em&gt;&lt;/strong&gt;. Le “hit testing” est fait via des cercles ce qui est moins précis qu’un modèle de boites. &lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/u&gt; il y actuellement un bug dans l’objet SpriteSheetUtils&amp;#160; sur la méthode &lt;em&gt;flip()&lt;/em&gt;. Cela a été remonté ici: &lt;a title="https://github.com/gskinner/EaselJS/issues/57" href="https://github.com/gskinner/EaselJS/issues/57"&gt;SpriteSheetUtils working canvas cache&lt;/a&gt; . Le comportement du bug est assez étrange. Dans mon cas, si j’instantie plusieurs montres avec des séquences de sprites bien différentes (MonsterA.png, MonsterB.png, etc.), tous les monstres auront malgré tout le même look comme s’ils avaient partagé qu’un seul et même fichier PNG. Cela semble du à un problème avec un objet canvas servant de cache. Il est simplement résolu en recréant le canvas de travail secondaire à chaque fois que l’on appelle la méthode &lt;em&gt;flip()&lt;/em&gt;. C’est ce que j’ai fait dans la version que vous pouvez tester à la fin.&lt;/p&gt;

&lt;h2&gt;Construction de l’objet Player&lt;/h2&gt;

&lt;p&gt;En tant que digne représentant du joueur humain qui l’anime, la logique associée au personnage principal du jeu est un peu différente des monstres et bien entendu plus évoluée (quoique…) ! &lt;/p&gt;

&lt;p&gt;Par exemple, les positions x &amp;amp; y sont normalement contrôlées par l’utilisateur souhaitant bouger son personnage avec son clavier. Par ailleurs, notre héro dispose de plus d’animations que nos monstres puisqu’il peut mourir, sauter, bouger, célébrer sa victoire et être immobile. &lt;/p&gt;

&lt;p&gt;Voici ainsi le PNG qui lui est dédié :&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://david.blob.core.windows.net/easeljstutorial2/img/Player.png" width="950" height="130" /&gt;&lt;/p&gt;

&lt;p&gt;Bon, dans ce tutoriel, on va rester simple. Nous allons uniquement gérer les séquence où il court, il meurt et où il reste immobile. Cependant, chargeons malgré tout toutes les animations pour un potentiel usage futur. Voici le code du fichier &lt;strong&gt;&lt;em&gt;Player.js&lt;/em&gt;&lt;/strong&gt;. La lecture du code et de ses commentaires devraient vous fournir suffisamment de détails pour en comprendre son fonctionnement :&lt;/p&gt;

&lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function &lt;/span&gt;(window) {
    &lt;span style="color: blue"&gt;function &lt;/span&gt;Player(imgPlayer, x_end) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.initialize(imgPlayer, x_end);
    }
    Player.prototype = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence();

    &lt;span style="color: #006400"&gt;// propriétés publiques
    &lt;/span&gt;Player.prototype.bounds = 0;
    Player.prototype.hit = 0;
    Player.prototype.alive = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

    &lt;span style="color: #006400"&gt;// constructeur:
    // unique pour éviter d'écraser celui de la classe de base     
    &lt;/span&gt;Player.prototype.BitmapSequence_initialize = Player.prototype.initialize;     
    Player.prototype.BitmapSequence_tick = Player.prototype.tick; 

    &lt;span style="color: blue"&gt;var &lt;/span&gt;quaterFrameSize;

    Player.prototype.initialize = &lt;span style="color: blue"&gt;function &lt;/span&gt;(imgPlayer, x_end) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;localSpriteSheet = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
                    imgPlayer, &lt;span style="color: #006400"&gt;// image à utiliser
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//largeur de chacun des sprites
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//hauteur
            &lt;/span&gt;{
            walk_left: [0, 9],
            die_left: [10, 21, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            jump_left: [22, 32],
            celebrate_left: [33, 43],
            idle: [44, 44]
        });

        localSpriteSheet = SpriteSheetUtils.flip(
        localSpriteSheet,
        {
            walk_right: [&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            jump_right: [&lt;span style="color: maroon"&gt;&amp;quot;jump_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            die_right: [&lt;span style="color: maroon"&gt;&amp;quot;die_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            celebrate_right: [&lt;span style="color: maroon"&gt;&amp;quot;celebrate_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;]
        });

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_initialize(localSpriteSheet);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end = x_end;

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regX = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 2 | 0;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regY = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameHeight / 2 | 0;

        quaterFrameSize = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 4;

        &lt;span style="color: #006400"&gt;// La 1ère séquence jouée est celle &amp;quot;au repos&amp;quot;
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;idle&amp;quot;&lt;/span&gt;);    &lt;span style="color: #006400"&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

        &lt;span style="color: #006400"&gt;// mise en place des ombres
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.shadow = &lt;span style="color: blue"&gt;new &lt;/span&gt;Shadow(&lt;span style="color: maroon"&gt;&amp;quot;#000&amp;quot;&lt;/span&gt;, 3, 2, 2);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.name = &lt;span style="color: maroon"&gt;&amp;quot;Hero&amp;quot;&lt;/span&gt;;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.speed = 1;
        &lt;span style="color: #006400"&gt;// 1 = droite &amp;amp; -1 = gauche
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 1;

        &lt;span style="color: #006400"&gt;// vitesse
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.vX = 4 | 0.5;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY = 0;
        &lt;span style="color: #006400"&gt;// on commence directement à la 1ère frame de la séquence walk_right
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentFrame = 66;

        &lt;span style="color: #006400"&gt;// Taille des bords du cercle pour les tests de collisions
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.bounds = 28;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit = &lt;span style="color: blue"&gt;this&lt;/span&gt;.bounds;
    }

    Player.prototype.tick = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: #006400"&gt;// Toujours la division de la vitesse par 4
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;speedControl = Ticker.getTicks() % 4;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(speedControl == 0) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_tick();
        }

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.alive &amp;amp;&amp;amp; !&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode) {
            &lt;span style="color: #006400"&gt;// Test sur les bords de l’écran
            // Le joueur est bloqué sur chacun des bords mais on souhaite qu'il continue &lt;br /&gt;            // de courir quand même
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;((&lt;span style="color: blue"&gt;this&lt;/span&gt;.x + &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction &amp;gt; quaterFrameSize) &amp;amp;&amp;amp; &lt;br /&gt;                (&lt;span style="color: blue"&gt;this&lt;/span&gt;.x + (&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction * 2) &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end - quaterFrameSize + 1)) {
                &lt;span style="color: #006400"&gt;// On bouge le sprite en fonction de sa direction et sa vitesse
                &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.x += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vX * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.y += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;
            }
        }
    }

    window.Player = Player;
} (window));&lt;/pre&gt;

&lt;p&gt;Le héro sera contrôlé à distance depuis la page principale.&lt;/p&gt;

&lt;h2&gt;Construction de l’objet Content Manager &lt;/h2&gt;

&lt;p&gt;En général, la première étape d’un jeu HTML5 est de tout simplement télécharger les ressources dont il a besoin avant de démarrer le jeu. Dans mon cas, vous trouverez un gestionnaire de téléchargements et de ressources très basique au sein du fichier &lt;strong&gt;&lt;em&gt;ContentManager.js&lt;/em&gt;&lt;/strong&gt; : &lt;/p&gt;

&lt;p&gt;En voici le code : &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Utilisé pour télécharger toutes les ressources utiles 
// hébergées sur le serveur web
&lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;ContentManager() {
    &lt;span style="color: #006400"&gt;// fonction qui sera rappelée une fois que tous les éléments
    // auront été téléchargés (fonction de callback)
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;ondownloadcompleted;
    &lt;span style="color: #006400"&gt;// Nombre d'éléments à télécharger
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;NUM_ELEMENTS_TO_DOWNLOAD = 15;

    &lt;span style="color: #006400"&gt;// Pour l'affectation de la méthode de callback
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.SetDownloadCompleted = &lt;span style="color: blue"&gt;function &lt;/span&gt;(callbackMethod) {
        ondownloadcompleted = callbackMethod;
    };

    &lt;span style="color: #006400"&gt;// Nous avons 4 types d’ennemies, 1 héro &amp;amp; 1 type de bloc
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterA = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterB = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image(); 
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterC = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image(); 
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterD = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgTile = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgPlayer = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();

    &lt;span style="color: #006400"&gt;// le fond du jeu peut être créé à partir de 3 claques différents
    // ces 3 calques existent en 3 versions
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers = &lt;span style="color: blue"&gt;new &lt;/span&gt;Array();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;numImagesLoaded = 0;

    &lt;span style="color: #006400"&gt;// méthode publique pour lancer le téléchargement
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.StartDownload = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgPlayer, &lt;span style="color: maroon"&gt;&amp;quot;img/Player.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterA, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterA.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterB, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterB.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterC, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterC.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterD, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterD.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgTile, &lt;span style="color: maroon"&gt;&amp;quot;img/Tiles/BlockA0.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);

        &lt;span style="color: #006400"&gt;// téléchargement des 3 claques * 3 versions
        &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 3; i++) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Array();
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;j = 0; j &amp;lt; 3; j++) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers[i][j] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
                SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers[i][j], &lt;span style="color: maroon"&gt;&amp;quot;img/Backgrounds/Layer&amp;quot; &lt;/span&gt;+ i &lt;br /&gt;                                      + &lt;span style="color: maroon"&gt;&amp;quot;_&amp;quot; &lt;/span&gt;+ j + &lt;span style="color: maroon"&gt;&amp;quot;.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
            }
        }
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;SetDownloadParameters(imgElement, url, loadedHandler, errorHandler) {
        imgElement.src = url;
        imgElement.onload = loadedHandler;
        imgElement.onerror = errorHandler;
    }

    &lt;span style="color: #006400"&gt;// notre gestionnaire d'évènement en cas de succès 
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;handleImageLoad(e) {
        numImagesLoaded++

        &lt;span style="color: #006400"&gt;// Si tous les éléments ont été téléchargés avec succès
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(numImagesLoaded == NUM_ELEMENTS_TO_DOWNLOAD) {
            numImagesLoaded = 0;
            &lt;span style="color: #006400"&gt;// On rappelle la méthode de callback mise en place par SetDownloadCompleted
            &lt;/span&gt;ondownloadcompleted();
        }
    }

    &lt;span style="color: #006400"&gt;// appelée si une erreur survient pendant le téléchargement (une 404 par exemple)
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;handleImageError(e) {
        console.log(&lt;span style="color: maroon"&gt;&amp;quot;Error Loading Image : &amp;quot; &lt;/span&gt;+ e.target.src);
    }
}&lt;/pre&gt;

&lt;p&gt;Je sais. Il manque pas mal de choses pour en faire un vrai bon gestionnaire de contenu : une barre de progression sur l’état des téléchargements, un meilleur gestionnaire d’erreurs, l’utilisation éventuelle du localStorage, un code peut-être plus générique, etc. Mais bon, j’ai essayé d’en faire un le plus simple et facile à comprendre. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0458.wlEmoticon_2D00_winkingsmile_5F00_0495477E.png" /&gt;&lt;/p&gt;

&lt;h2&gt;Rassemblons toutes les pièces dans la page principale&lt;/h2&gt;

&lt;p&gt;Maintenant que nous avons les blocs de base de notre jeu, on peut commencer à s’amuser à les assembler pour construire un jeu de plateforme extrêmement simple. Pour cela, je vous propose de revoir chacune des parties de la page principale hébergeant notre petit jeu. &lt;/p&gt;

&lt;p&gt;Dans la méthode &lt;em&gt;init()&lt;/em&gt;, nous instancions l’objet &lt;a href="http://easeljs.com/docs/Stage.html"&gt;Stage&lt;/a&gt; d’EaselJS puis nous utilisons l’objet &lt;em&gt;ContentManager&lt;/em&gt; vu juste précédemment pour télécharger l’ensemble de nos fichier PNG:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;init() {
    &lt;span style="color: #006400"&gt;// on récupère l’instance du canvas puis on charge les images
    &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;testCanvas&amp;quot;&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// création de l’objet Stage que l’on fait pointer vers notre canvas
    &lt;/span&gt;stage = &lt;span style="color: blue"&gt;new &lt;/span&gt;Stage(canvas);
    &lt;span style="color: #006400"&gt;// on récupère la largeur et la hauteur du canvas pour de futurs calculs savants
    &lt;/span&gt;screen_width = canvas.width;
    screen_height = canvas.height;

    contentManager = &lt;span style="color: blue"&gt;new &lt;/span&gt;ContentManager();
    contentManager.SetDownloadCompleted(startGame);
    contentManager.StartDownload();
}&lt;/pre&gt;

&lt;p&gt;Une fois le téléchargement fini, la fonction &lt;em&gt;startGame()&lt;/em&gt; est appelée. La 1ère chose qu’elle fait est d’appeler la fonction &lt;em&gt;CreateAndAddRandomBackground()&lt;/em&gt;. Cette fonction créée simplement un arrière-plan aléatoire en utilisant les possibilités offertes par les 3 claques. Puis, notre héro est créé et sa position verticale Y est déterminée de manière aléatoire. Juste en dessous du héro, on construit une plateforme très simple sur laquelle notre héro pourra faire son petit jogging. Pour finir, on construit les 4 objets de type &lt;em&gt;Monster()&lt;/em&gt; à l’intérieur du tableau &lt;em&gt;Monsters&lt;/em&gt; et on ajoute l’ensemble au jeu/au stage :&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;startGame() {
    &lt;span style="color: #006400"&gt;// Nombre aléatoire pour positionner verticalement notre 
    // Héro &amp;amp; ses méchants ennemies sur 8 paliers possibles
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;randomY;
    
    CreateAndAddRandomBackground();

    &lt;span style="color: #006400"&gt;// Notre héro peut être déplacé avec les flèches (gauche, droite)
    &lt;/span&gt;document.onkeydown = handleKeyDown;
    document.onkeyup = handleKeyUp;

    &lt;span style="color: #006400"&gt;// On créé le héro
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Hero = &lt;span style="color: blue"&gt;new &lt;/span&gt;Player(contentManager.imgPlayer, screen_width);
    Hero.x = 400;
    Hero.y = randomY;

    &lt;span style="color: #006400"&gt;// Bloc sur lequel notre héro et éventuellement quelques ennemies pourront marcher
    &lt;/span&gt;bmpSeqTile = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence(&lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(contentManager.imgTile, 40, 32));
    bmpSeqTile.regX = bmpSeqTile.frameWidth / 2 | 0;
    bmpSeqTile.regY = bmpSeqTile.frameHeight / 2 | 0;

    &lt;span style="color: #006400"&gt;// On prends le même motif que l'on duplique sur toute la largeur de l'écran
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 20; i++) {
        &lt;span style="color: #006400"&gt;// On clone le motif original
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;bmpSeqTileCloned = bmpSeqTile.clone();

        &lt;span style="color: #006400"&gt;// On positionne ses propriétés d’affichage
        &lt;/span&gt;bmpSeqTileCloned.x = 0 + (i * 40);
        bmpSeqTileCloned.y = randomY + 32;

        &lt;span style="color: #006400"&gt;// puis on l'ajoute dans les objets à afficher
        &lt;/span&gt;stage.addChild(bmpSeqTileCloned);
    }

    &lt;span style="color: #006400"&gt;// Notre collection personnelle de monstres
    &lt;/span&gt;Monsters = &lt;span style="color: blue"&gt;new &lt;/span&gt;Array();

    &lt;span style="color: #006400"&gt;// Création du 1er type de monstres
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[0] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterA&amp;quot;&lt;/span&gt;, contentManager.imgMonsterA, screen_width);
    Monsters[0].x = 20;
    Monsters[0].y = randomY;

    &lt;span style="color: #006400"&gt;// Création du 2nd type de monstres
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[1] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterB&amp;quot;&lt;/span&gt;, contentManager.imgMonsterB, screen_width);
    Monsters[1].x = 750;
    Monsters[1].y = randomY;

    &lt;span style="color: #006400"&gt;// Création du 3eme type de monstres
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[2] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterC&amp;quot;&lt;/span&gt;, contentManager.imgMonsterC, screen_width);
    Monsters[2].x = 100;
    Monsters[2].y = randomY;

    &lt;span style="color: #006400"&gt;// Alors d'après vous, on fait quoi là ? :)
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[3] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterD&amp;quot;&lt;/span&gt;, contentManager.imgMonsterD, screen_width);
    Monsters[3].x = 650;
    Monsters[3].y = randomY;

    &lt;span style="color: #006400"&gt;// On ajoute tous les monstres à l'écran
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i=0; i&amp;lt;Monsters.length;i++){
        stage.addChild(Monsters[i]);
    }&lt;br /&gt;&lt;span style="color: #006400"&gt;    // Puis on ajoute la compagnie  &lt;/span&gt;
    stage.addChild(Hero);
        
&lt;span style="color: #006400"&gt;    &lt;/span&gt;Ticker.addListener(window);
    &lt;span style="color: #006400"&gt;// On vise le meilleur taux possible (60 FPS)
    &lt;/span&gt;Ticker.setInterval(17);
}&lt;/pre&gt;

&lt;p&gt;A la fin de la page, vous trouverez 2 gestionnaires de clavier évident qui s’occupe de jouer les animations walk_left ou walk_right de notre héro en fonction des touches sur lesquelles vous presserez. Pour finir, la logique principale de notre jeu n’est finalement contenue que dans les quelques lignes de code présentes au sein de la méthode &lt;em&gt;tick()&lt;/em&gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;tick() {
    &lt;span style="color: #006400"&gt;// on parcourt notre collection de monstres 
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(monster &lt;span style="color: blue"&gt;in &lt;/span&gt;Monsters) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;m = Monsters[monster];

        &lt;span style="color: #006400"&gt;// Si notre héro est toujours vivant mais s'il est trop proche
        // de l'un des monstres...
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Hero.alive &amp;amp;&amp;amp; m.hitRadius(Hero.x, Hero.y, Hero.hit)) {
            &lt;span style="color: #006400"&gt;//...il doit mourir malheureusement! (la morale des jeux est ignoble)
            &lt;/span&gt;Hero.alive = &lt;span style="color: blue"&gt;false&lt;/span&gt;;

            &lt;span style="color: #006400"&gt;// On joue alors l'animation de mort en fonction de
            // la direction dans laquelle le héro courait 
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Hero.direction == 1) {
                Hero.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;die_right&amp;quot;&lt;/span&gt;);
            }
            &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                Hero.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;die_left&amp;quot;&lt;/span&gt;);
            }

            &lt;span style="color: blue"&gt;continue&lt;/span&gt;;
        }
    }

    &lt;span style="color: #006400"&gt;// Et on met le tout à jour
    &lt;/span&gt;stage.update();
}&lt;/pre&gt;

&lt;p&gt;Ainsi, on vérifie à chaque tick (donc potentiellement toutes les 17 ms) si l’un des monstres ne serait pas en train de toucher notre héro à partir des paramètres de collisions que nous avons vu plus tôt. Si l’un des monstres est trop proche, notre malheureux héro doit alors mourir. &lt;/p&gt;

&lt;h2&gt;Jouez avec l’exemple complet !&lt;/h2&gt;

&lt;p&gt;Si vous avez tout lu jusque ici, je pense que vous avez amplement mérité de pouvoir jouer avec l’exemple qui est juste en dessous. A chaque fois que vous presserez le bouton “Start”, un nouvel arrière-plan sera généré et chacun des personnages (ennemies comme héro) seront placés à des positions différentes de manière aléatoire. Vous pouvez également faire bouger le héro avec les flèches gauche et droite de votre clavier. &lt;/p&gt;

&lt;p&gt;Au fait, ne vous inquiétez pas. Comme vous ne pouvez pas sauter, il y a actuellement aucun moyen de gagner dans ce jeu. C’est donc un jeu 100% looser (le premier du genre ? &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0458.wlEmoticon_2D00_winkingsmile_5F00_0495477E.png" /&gt;). Ce jeu est donc vivement déconseillé aux mauvais perdants. &lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="525" src="http://david.blob.core.windows.net/easeljstutorial2/easelJSCoreObjectsAndCollision.html" width="830"&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; comme je vous l’ai indiqué plus haut, il n’y a pas de barre de progression sur l’état du téléchargement. Vous devrez donc attendre un “certain temps” avant de pouvoir jouer après avoir appuyé sur le bouton “Start”. C’est ce que l’on appelle communément une EUP (expérience utilisateur pourrie). &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7651.wlEmoticon_2D00_smile_5F00_2F5A53FD.png" /&gt; Mais cela sera ensuite immédiat une fois le tout présent dans le cache du navigateur. &lt;/p&gt;

&lt;p&gt;Vous pouvez également y jouer via ce lien : &lt;a title="http://david.blob.core.windows.net/easeljstutorial2/easelJSCoreObjectsAndCollision.html" href="http://david.blob.core.windows.net/easeljstutorial2/easelJSCoreObjectsAndCollision.html"&gt;easelJSCoreObjectsAndCollision&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour finir le jeu, il nous reste à gérer la séquence de saut du héro en utilisant un moteur physique assez simple et des collisions un peu plus poussées, à charger la musique et les effets sonores et finalement à charger les niveaux. Mais la base est bien là si vous souhaitez écrire votre propre petit jeu. Vous avez désormais toutes les cartes en main ! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7651.wlEmoticon_2D00_smile_5F00_2F5A53FD.png" /&gt;&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10198571" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Tutorial/">Tutorial</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Game/">Game</category></item><item><title>HTML5 Gaming: building the core objects &amp; handling collisions with EaselJS</title><link>http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx</link><pubDate>Fri, 29 Jul 2011 16:28:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10191168</guid><dc:creator>David Rousset</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10191168</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx#comments</comments><description>&lt;p&gt;We’ve seen in the previous article how to animate our sprites using EaselJS: &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx"&gt;HTML5 Gaming: animating sprites in Canvas with EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We’re now going to see how to create some of our game objects like ennemies and our platformer hero. We will also see how to implement a simple collision mechanism between them. This time, these tutorials will be mainly based on this sample: &lt;a title="http://easeljs.com/examples/game/game.html" href="http://easeljs.com/examples/game/game.html"&gt;EaselJS Game sample&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You’ll find &lt;strong&gt;a live working sample at the end of this article&lt;/strong&gt;. It’s the base of a simple game.&lt;/p&gt;  &lt;p&gt;&lt;a title="PlatformerTutorial2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5987662759/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="PlatformerTutorial2" src="http://farm7.static.flickr.com/6013/5987662759_94c799e39a.jpg" width="500" height="353" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Pour ceux qui pratiquent la langue de Molière, vous trouverez une version française ici : &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx"&gt;Jeux HTML5: construction des objets principaux &amp;amp; gestion des collisions avec EaselJS&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This article is the 2nd of a serie of 3:&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx"&gt;HTML5 Gaming: animating sprites in Canvas with EaselJS&lt;/a&gt;    &lt;br /&gt;- HTML5 Gaming: building the core objects &amp;amp; handling collisions with EaselJS    &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx"&gt;HTML5 Platformer: the complete port of the XNA game to &amp;lt;canvas&amp;gt; with EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Building the Monster object&lt;/h2&gt;  &lt;p&gt;A monster object has 2 states: &lt;/p&gt;  &lt;p&gt;1 - Running along all the width of the screen    &lt;br /&gt;2 – Being idle once one of the side is reached during a certain amount of time before running again&lt;/p&gt;  &lt;p&gt;It’s very stupid. But if you touch it, you’re dead. This time I’ve merged the sprites coming from the XNA Platformer sample defining the running &amp;amp; the idle sequence inside a unique PNG file. For instance, here is the PNG file for MonsterC:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://david.blob.core.windows.net/easeljstutorial2/img/MonsterB.png" width="950" height="45" /&gt;&lt;/p&gt;  &lt;p&gt;Our Monster object is defined inside &lt;strong&gt;&lt;em&gt;Monster.js&lt;/em&gt;&lt;/strong&gt; and takes the &lt;a href="http://easeljs.com/docs/BitmapSequence.html"&gt;BitmapSequence&lt;/a&gt; object as its prototype which has to be used indeed for such scenarios. It contains everything we need: a &lt;em&gt;tick()&lt;/em&gt; method, some hit testing mechanism for our collisions and a way to handle our sprites into several animations. &lt;/p&gt;  &lt;p&gt;We just need to add some specific logic of our monster like the timing part to handle the idle state and we’re done. Here is the code of our &lt;strong&gt;&lt;em&gt;Monster.js &lt;/em&gt;&lt;/strong&gt;file defining our enemies object:&lt;/p&gt;  &lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function &lt;/span&gt;(window) {
    &lt;span style="color: blue"&gt;function &lt;/span&gt;Monster(monsterName, imgMonster, x_end) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.initialize(monsterName, imgMonster, x_end);
    }
    Monster.prototype = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence();

    &lt;span style="color: #006400"&gt;// public properties:
    &lt;/span&gt;Monster.prototype.IDLEWAITTIME = 40;
    Monster.prototype.bounds = 0; &lt;span style="color: #006400"&gt;//visual radial size
    &lt;/span&gt;Monster.prototype.hit = 0;     &lt;span style="color: #006400"&gt;//average radial disparity

    // constructor:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #006400"&gt;    //unique to avoid overriding base class &lt;br /&gt;    &lt;/span&gt;Monster.prototype.BitmapSequence_initialize = Monster.prototype.initialize; &lt;br /&gt;    Monster.prototype.BitmapSequence_tick = Monster.prototype.tick; &lt;span style="color: #006400"&gt;

    // variable members to handle the idle state
    // and the time to wait before walking again
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker = 0;

    &lt;span style="color: blue"&gt;var &lt;/span&gt;quaterFrameSize;

    Monster.prototype.initialize = &lt;span style="color: blue"&gt;function &lt;/span&gt;(monsterName, imgMonster, x_end) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;localSpriteSheet = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
                    imgMonster, &lt;span style="color: #006400"&gt;//image to use
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//width of each sprite
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//height of each sprite
            &lt;/span&gt;{
            walk_left: [0, 9],
            idle: [10, 20]
        });

        localSpriteSheet = SpriteSheetUtils.flip(
        localSpriteSheet,
        {
            walk_right: [&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;]
        });

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_initialize(localSpriteSheet);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end = x_end;

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regX = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 2 | 0;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regY = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameHeight / 2 | 0;

        quaterFrameSize = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 4;

        &lt;span style="color: #006400"&gt;// start playing the first sequence:
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_right&amp;quot;&lt;/span&gt;);     &lt;span style="color: #006400"&gt;//animate

        // set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
        // of animated monster if you disabled the shadow.
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.shadow = &lt;span style="color: blue"&gt;new &lt;/span&gt;Shadow(&lt;span style="color: maroon"&gt;&amp;quot;#000&amp;quot;&lt;/span&gt;, 3, 2, 2);

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.name = monsterName;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.speed = 1;
        &lt;span style="color: #006400"&gt;// 1 = right &amp;amp; -1 = left
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 1;
        &lt;span style="color: #006400"&gt;// velocity
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.vX = 1 | 0.5;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY = 0;
        &lt;span style="color: #006400"&gt;// starting directly at the first frame of the walk_right sequence
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentFrame = 21;
    }

    Monster.prototype.tick = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: #006400"&gt;// To slow down the animation loop of the sprite, we're not redrawing during each tick
        // With a Modulo 4, we're dividing the speed by 4
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;speedControl = Ticker.getTicks() % 4;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(speedControl == 0) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_tick();
        }

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode) {
            &lt;span style="color: #006400"&gt;// Moving the sprite based on the direction &amp;amp; the speed
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.x += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vX * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.y += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;

            &lt;span style="color: #006400"&gt;// Hit testing the screen width, otherwise our sprite would disappear
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;gt;= &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end - (quaterFrameSize + 1) || &lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;lt; (quaterFrameSize + 1)) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;idle&amp;quot;&lt;/span&gt;);
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker = &lt;span style="color: blue"&gt;this&lt;/span&gt;.IDLEWAITTIME;
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
            }
        }
        &lt;span style="color: blue"&gt;else &lt;/span&gt;{
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker--;

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.idleWaitTicker == 0) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;false&lt;/span&gt;;

                &lt;span style="color: #006400"&gt;// Hit testing the screen width, otherwise our sprite would disappear
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;gt;= &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end - (quaterFrameSize + 1)) {
                    &lt;span style="color: #006400"&gt;// We've reached the right side of our screen
                    // We need to walk left now to go back to our initial position
                    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = -1;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;);
                }

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x &amp;lt; (quaterFrameSize + 1)) {
                    &lt;span style="color: #006400"&gt;// We've reached the left side of our screen
                    // We need to walk right now
                    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 1;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_right&amp;quot;&lt;/span&gt;);
                }
            }
        }
    }

    Monster.prototype.hitPoint = &lt;span style="color: blue"&gt;function &lt;/span&gt;(tX, tY) {
        &lt;span style="color: blue"&gt;return this&lt;/span&gt;.hitRadius(tX, tY, 0);
    }

    Monster.prototype.hitRadius = &lt;span style="color: blue"&gt;function &lt;/span&gt;(tX, tY, tHit) {
        &lt;span style="color: #006400"&gt;//early returns speed it up
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(tX - tHit &amp;gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x + &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(tX + tHit &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x - &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(tY - tHit &amp;gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y + &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(tY + tHit &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y - &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit) { &lt;span style="color: blue"&gt;return&lt;/span&gt;; }

        &lt;span style="color: #006400"&gt;//now do the circle distance test
        &lt;/span&gt;&lt;span style="color: blue"&gt;return this&lt;/span&gt;.hit + tHit &amp;gt; Math.sqrt(Math.pow(Math.abs(&lt;span style="color: blue"&gt;this&lt;/span&gt;.x - tX), 2) &lt;br /&gt;                        + Math.pow(Math.abs(&lt;span style="color: blue"&gt;this&lt;/span&gt;.y - tY), 2));
    }

    window.Monster = Monster;
} (window));&lt;/pre&gt;

&lt;p&gt;The collision part is handled via the &lt;em&gt;&lt;strong&gt;hitPoint()&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;hitRadius()&lt;/strong&gt;&lt;/em&gt; functions. The hit testing is done via circle which is a bit less accurate than a boxing mode. &lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/u&gt; there is a bug in the SpriteSheetUtils object on the&lt;em&gt; flip()&lt;/em&gt; method. It has been logged here: &lt;a title="https://github.com/gskinner/EaselJS/issues/57" href="https://github.com/gskinner/EaselJS/issues/57"&gt;SpriteSheetUtils working canvas cache&lt;/a&gt; . The bug behavior is a bit weird. If you’re instantiating several monsters with different sprite sequences, it may appears that all monsters will have the same look as if they were sharing the exact same PNG file defining their sprites. This is apparently a cache issue simply solved by recreating the working canvas in the &lt;em&gt;flip()&lt;/em&gt; method every time.&lt;/p&gt;

&lt;h2&gt;Building the Player object&lt;/h2&gt;

&lt;p&gt;The logic of the player object is a bit different than the monsters. The x &amp;amp; y position are normally controlled by the user moving the character with the keyboard. Our hero has more animations than the monsters as he can die, jump, move, celebrate and be in the idle mode. &lt;/p&gt;

&lt;p&gt;Here is the PNG associated to him:&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://david.blob.core.windows.net/easeljstutorial2/img/Player.png" width="950" height="130" /&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll keep it simple. We will only handle the walk, idle &amp;amp; die sequence. Still, let’s load all the animations for a futur potential usage. Here is the code available in the &lt;strong&gt;&lt;em&gt;Player.js&lt;/em&gt;&lt;/strong&gt; file. Reading the code and its comments should provide enough details:&lt;/p&gt;

&lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function &lt;/span&gt;(window) {
    &lt;span style="color: blue"&gt;function &lt;/span&gt;Player(imgPlayer, x_end) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.initialize(imgPlayer, x_end);
    }
    Player.prototype = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence();

    &lt;span style="color: #006400"&gt;// public properties:
    &lt;/span&gt;Player.prototype.bounds = 0;
    Player.prototype.hit = 0;
    Player.prototype.alive = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

    &lt;span style="color: #006400"&gt;// constructor:
    //unique to avoid overiding base class    
    &lt;/span&gt;Player.prototype.BitmapSequence_initialize = Player.prototype.initialize;     
    Player.prototype.BitmapSequence_tick = Player.prototype.tick; 

    &lt;span style="color: blue"&gt;var &lt;/span&gt;quaterFrameSize;

    Player.prototype.initialize = &lt;span style="color: blue"&gt;function &lt;/span&gt;(imgPlayer, x_end) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;localSpriteSheet = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
                    imgPlayer, &lt;span style="color: #006400"&gt;//image to use
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//width of each sprite
            &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//height of each sprite
            &lt;/span&gt;{
            walk_left: [0, 9],
            die_left: [10, 21, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            jump_left: [22, 32],
            celebrate_left: [33, 43],
            idle: [44, 44]
        });

        localSpriteSheet = SpriteSheetUtils.flip(
        localSpriteSheet,
        {
            walk_right: [&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            jump_right: [&lt;span style="color: maroon"&gt;&amp;quot;jump_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            die_right: [&lt;span style="color: maroon"&gt;&amp;quot;die_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;],
            celebrate_right: [&lt;span style="color: maroon"&gt;&amp;quot;celebrate_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;]
        });

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_initialize(localSpriteSheet);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end = x_end;

        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regX = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 2 | 0;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.regY = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameHeight / 2 | 0;

        quaterFrameSize = &lt;span style="color: blue"&gt;this&lt;/span&gt;.spriteSheet.frameWidth / 4;

        &lt;span style="color: #006400"&gt;// start playing the first sequence:
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;idle&amp;quot;&lt;/span&gt;);     &lt;span style="color: #006400"&gt;//animate
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

        &lt;span style="color: #006400"&gt;// set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
        // of animated monster if you disabled the shadow.
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.shadow = &lt;span style="color: blue"&gt;new &lt;/span&gt;Shadow(&lt;span style="color: maroon"&gt;&amp;quot;#000&amp;quot;&lt;/span&gt;, 3, 2, 2);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.name = &lt;span style="color: maroon"&gt;&amp;quot;Hero&amp;quot;&lt;/span&gt;;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.speed = 1;
        &lt;span style="color: #006400"&gt;// 1 = right &amp;amp; -1 = left
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction = 1;

        &lt;span style="color: #006400"&gt;// velocity
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.vX = 4 | 0.5;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY = 0;
        &lt;span style="color: #006400"&gt;// starting directly at the first frame of the walk_right sequence
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.currentFrame = 66;

        &lt;span style="color: #006400"&gt;//Size of the Bounds for the collision's tests
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.bounds = 28;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.hit = &lt;span style="color: blue"&gt;this&lt;/span&gt;.bounds;
    }

    Player.prototype.tick = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: #006400"&gt;// To slow down the animation loop of the sprite, we're not redrawing during each tick
        // With a Modulo 4, we're dividing the speed by 4
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;speedControl = Ticker.getTicks() % 4;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(speedControl == 0) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.BitmapSequence_tick();
        }

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.alive &amp;amp;&amp;amp; !&lt;span style="color: blue"&gt;this&lt;/span&gt;.isInIdleMode) {
            &lt;span style="color: #006400"&gt;// Hit testing the screen width, otherwise our sprite would disappear
            // The player is blocked at each side but we keep the walk_right or walk_animation running
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;((&lt;span style="color: blue"&gt;this&lt;/span&gt;.x + &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction &amp;gt; quaterFrameSize) &amp;amp;&amp;amp; &lt;br /&gt;                (&lt;span style="color: blue"&gt;this&lt;/span&gt;.x + (&lt;span style="color: blue"&gt;this&lt;/span&gt;.direction * 2) &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x_end - quaterFrameSize + 1)) {
                &lt;span style="color: #006400"&gt;// Moving the sprite based on the direction &amp;amp; the speed
                &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.x += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vX * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.y += &lt;span style="color: blue"&gt;this&lt;/span&gt;.vY * &lt;span style="color: blue"&gt;this&lt;/span&gt;.direction;
            }
        }
    }

    window.Player = Player;
} (window));&lt;/pre&gt;

&lt;p&gt;The player will be remotely controlled into the main page.&lt;/p&gt;

&lt;h2&gt;Building the Content Manager object&lt;/h2&gt;

&lt;p&gt;Usually, the first step of a HTML5 game is to download all the needed resources before starting the game. In my case, you’ll find a very basic ContentManager available in the &lt;strong&gt;&lt;em&gt;ContentManager.js&lt;/em&gt;&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Here is the code: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// Used to download all needed resources from our
// webserver
&lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;ContentManager() {
    &lt;span style="color: #006400"&gt;// Method called back once all elements
    // have been downloaded
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;ondownloadcompleted;
    &lt;span style="color: #006400"&gt;// Number of elements to download
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;NUM_ELEMENTS_TO_DOWNLOAD = 15;

    &lt;span style="color: #006400"&gt;// setting the callback method
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.SetDownloadCompleted = &lt;span style="color: blue"&gt;function &lt;/span&gt;(callbackMethod) {
        ondownloadcompleted = callbackMethod;
    };

    &lt;span style="color: #006400"&gt;// We have 4 type of enemies, 1 hero &amp;amp; 1 type of tile
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterA = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterB = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image(); 
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterC = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image(); 
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterD = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgTile = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgPlayer = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();

    &lt;span style="color: #006400"&gt;// the background can be created with 3 different layers
    // those 3 layers exist in 3 versions
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers = &lt;span style="color: blue"&gt;new &lt;/span&gt;Array();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;numImagesLoaded = 0;

    &lt;span style="color: #006400"&gt;// public method to launch the download process
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.StartDownload = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgPlayer, &lt;span style="color: maroon"&gt;&amp;quot;img/Player.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterA, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterA.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterB, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterB.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterC, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterC.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgMonsterD, &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterD.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
        SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgTile, &lt;span style="color: maroon"&gt;&amp;quot;img/Tiles/BlockA0.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);

        &lt;span style="color: #006400"&gt;// download the 3 layers * 3 versions
        &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 3; i++) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Array();
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;j = 0; j &amp;lt; 3; j++) {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers[i][j] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
                SetDownloadParameters(&lt;span style="color: blue"&gt;this&lt;/span&gt;.imgBackgroundLayers[i][j], &lt;span style="color: maroon"&gt;&amp;quot;img/Backgrounds/Layer&amp;quot; &lt;/span&gt;+ i &lt;br /&gt;                                      + &lt;span style="color: maroon"&gt;&amp;quot;_&amp;quot; &lt;/span&gt;+ j + &lt;span style="color: maroon"&gt;&amp;quot;.png&amp;quot;&lt;/span&gt;, handleImageLoad, handleImageError);
            }
        }
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;SetDownloadParameters(imgElement, url, loadedHandler, errorHandler) {
        imgElement.src = url;
        imgElement.onload = loadedHandler;
        imgElement.onerror = errorHandler;
    }

    &lt;span style="color: #006400"&gt;// our global handler 
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;handleImageLoad(e) {
        numImagesLoaded++

        &lt;span style="color: #006400"&gt;// If all elements have been downloaded
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(numImagesLoaded == NUM_ELEMENTS_TO_DOWNLOAD) {
            numImagesLoaded = 0;
            &lt;span style="color: #006400"&gt;// we're calling back the method set by SetDownloadCompleted
            &lt;/span&gt;ondownloadcompleted();
        }
    }

    &lt;span style="color: #006400"&gt;//called if there is an error loading the image (usually due to a 404)
    &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;handleImageError(e) {
        console.log(&lt;span style="color: maroon"&gt;&amp;quot;Error Loading Image : &amp;quot; &lt;/span&gt;+ e.target.src);
    }
}&lt;/pre&gt;

&lt;p&gt;It lacks several things to be a good content manager: a download progress indicator, a better error handler, localStorage usage, a more generic code, etc. But I’ve tried to build a basic &amp;amp; easy to understand game. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5466.wlEmoticon_2D00_winkingsmile_5F00_621EDBCD.png" /&gt;&lt;/p&gt;

&lt;h2&gt;Setting up all the pieces inside the main page&lt;/h2&gt;

&lt;p&gt;Now that we have the core parts of our game, we can start to use them to build a very basic platformer game. Let’s review each part of our main page hosting our game. In the&lt;em&gt; init()&lt;/em&gt; method, we’re creating the stage and we’re using the &lt;em&gt;ContentManager&lt;/em&gt; object to download our PNG files:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;init() {
    &lt;span style="color: #006400"&gt;//find canvas and load images, wait for last image to load
    &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;testCanvas&amp;quot;&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// create a new stage and point it at our canvas:
    &lt;/span&gt;stage = &lt;span style="color: blue"&gt;new &lt;/span&gt;Stage(canvas);
    &lt;span style="color: #006400"&gt;// grab canvas width and height for later calculations:
    &lt;/span&gt;screen_width = canvas.width;
    screen_height = canvas.height;

    contentManager = &lt;span style="color: blue"&gt;new &lt;/span&gt;ContentManager();
    contentManager.SetDownloadCompleted(startGame);
    contentManager.StartDownload();
}&lt;/pre&gt;

&lt;p&gt;Once done, the &lt;em&gt;startGame()&lt;/em&gt; function is called. It first uses the &lt;em&gt;CreateAndAddRandomBackground()&lt;/em&gt; function which create a random background based on 3 different layers. Then, it creates our &lt;em&gt;Hero&lt;/em&gt; and set its Y position in a random place. Just under the hero, we’re building a very basic platform where our hero will be able to walk on to. Finally, we’re building 4 &lt;em&gt;Monster()&lt;/em&gt; objects inside the &lt;em&gt;Monsters&lt;/em&gt; array and we add them also to the stage. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;startGame() {
    &lt;span style="color: #006400"&gt;// Random number to set the Y position
    // of our Hero &amp;amp; Enemies
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;randomY;
    
    CreateAndAddRandomBackground();

    &lt;span style="color: #006400"&gt;// Our hero can be moved with the arrow keys (left, right)
    &lt;/span&gt;document.onkeydown = handleKeyDown;
    document.onkeyup = handleKeyUp;

    &lt;span style="color: #006400"&gt;// Creating the Hero
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Hero = &lt;span style="color: blue"&gt;new &lt;/span&gt;Player(contentManager.imgPlayer, screen_width);
    Hero.x = 400;
    Hero.y = randomY;

    &lt;span style="color: #006400"&gt;//Tile where the hero &amp;amp; the ennemies will be able to walk on to
    &lt;/span&gt;bmpSeqTile = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence(&lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(contentManager.imgTile, 40, 32));
    bmpSeqTile.regX = bmpSeqTile.frameWidth / 2 | 0;
    bmpSeqTile.regY = bmpSeqTile.frameHeight / 2 | 0;

    &lt;span style="color: #006400"&gt;// Taking the same tile all over the width of the game
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 20; i++) {
        &lt;span style="color: #006400"&gt;// clone the original tile, so we don't need to set shared properties:
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;bmpSeqTileCloned = bmpSeqTile.clone();

        &lt;span style="color: #006400"&gt;// set display properties:
        &lt;/span&gt;bmpSeqTileCloned.x = 0 + (i * 40);
        bmpSeqTileCloned.y = randomY + 32;

        &lt;span style="color: #006400"&gt;// add to the display list:
        &lt;/span&gt;stage.addChild(bmpSeqTileCloned);
    }

    &lt;span style="color: #006400"&gt;// Our Monsters collection
    &lt;/span&gt;Monsters = &lt;span style="color: blue"&gt;new &lt;/span&gt;Array();

    &lt;span style="color: #006400"&gt;// Creating the first type of monster
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[0] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterA&amp;quot;&lt;/span&gt;, contentManager.imgMonsterA, screen_width);
    Monsters[0].x = 20;
    Monsters[0].y = randomY;

    &lt;span style="color: #006400"&gt;// Creating the second type of monster
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[1] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterB&amp;quot;&lt;/span&gt;, contentManager.imgMonsterB, screen_width);
    Monsters[1].x = 750;
    Monsters[1].y = randomY;

    &lt;span style="color: #006400"&gt;// Creating the third type of monster
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[2] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterC&amp;quot;&lt;/span&gt;, contentManager.imgMonsterC, screen_width);
    Monsters[2].x = 100;
    Monsters[2].y = randomY;

    &lt;span style="color: #006400"&gt;// Creating the forth type of monster
    &lt;/span&gt;randomY = 32 + (Math.floor(Math.random() * 7) * 64);
    Monsters[3] = &lt;span style="color: blue"&gt;new &lt;/span&gt;Monster(&lt;span style="color: maroon"&gt;&amp;quot;MonsterD&amp;quot;&lt;/span&gt;, contentManager.imgMonsterD, screen_width);
    Monsters[3].x = 650;
    Monsters[3].y = randomY;

    &lt;span style="color: #006400"&gt;// Adding all the monsters to the stage
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i=0; i&amp;lt;Monsters.length;i++){
        stage.addChild(Monsters[i]);
    }
    stage.addChild(Hero);
        
    &lt;span style="color: #006400"&gt;// we want to do some work before we update the canvas,
    // otherwise we could use Ticker.addListener(stage);
    &lt;/span&gt;Ticker.addListener(window);
    &lt;span style="color: #006400"&gt;// Best Framerate targeted (60 FPS)
    &lt;/span&gt;Ticker.setInterval(17);
}&lt;/pre&gt;

&lt;p&gt;And the end, there are 2 obvious keyboard handler that simply play the walk_left or walk_right animation of our hero based on the arrows keys. And finally, the core logic of our game is contained in a few line of code inside the tick() method of course:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;tick() {
    &lt;span style="color: #006400"&gt;// looping inside the Monsters collection
    &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(monster &lt;span style="color: blue"&gt;in &lt;/span&gt;Monsters) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;m = Monsters[monster];

        &lt;span style="color: #006400"&gt;// If the Hero is still alive and if he's too near
        // from one of the monster...
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Hero.alive &amp;amp;&amp;amp; m.hitRadius(Hero.x, Hero.y, Hero.hit)) {
            &lt;span style="color: #006400"&gt;//...he must die unfortunately!
            &lt;/span&gt;Hero.alive = &lt;span style="color: blue"&gt;false&lt;/span&gt;;

            &lt;span style="color: #006400"&gt;// Playing the proper animation based on
            // the current direction of our hero
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Hero.direction == 1) {
                Hero.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;die_right&amp;quot;&lt;/span&gt;);
            }
            &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                Hero.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;die_left&amp;quot;&lt;/span&gt;);
            }

            &lt;span style="color: blue"&gt;continue&lt;/span&gt;;
        }
    }

    &lt;span style="color: #006400"&gt;// update the stage:
    &lt;/span&gt;stage.update();
}&lt;/pre&gt;

&lt;p&gt;We’re just checking during each tick if one of the monsters is not currently hitting our hero based on their collision parameters. If one monster is too near of our hero, our poor hero must die.&lt;/p&gt;

&lt;h2&gt;Play with the live sample&lt;/h2&gt;

&lt;p&gt;You can now play with the live sample just below. Every time you’ll press the start button a new background will be generated and each character (enemies &amp;amp; hero) will be placed at a different position. You can also move right or left using the keyboard. By the way, don’t panic. As you can’t jump, there is currently no way to win in this game. This is a 100% looser game (first of genre?). &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5466.wlEmoticon_2D00_winkingsmile_5F00_621EDBCD.png" /&gt;&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="525" src="http://david.blob.core.windows.net/easeljstutorial2/easelJSCoreObjectsAndCollision.html" width="830"&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; as there is no progress bar, you need to wait a bit before playing after pressing the “Start” button.&lt;/p&gt;

&lt;p&gt;You can play it also via this link: &lt;a title="http://david.blob.core.windows.net/easeljstutorial2/easelJSCoreObjectsAndCollision.html" href="http://david.blob.core.windows.net/easeljstutorial2/easelJSCoreObjectsAndCollision.html"&gt;easelJSCoreObjectsAndCollision&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next part will be to handle the jump sequence using a simple physics engine, loading the music &amp;amp; sound effects and finally loading the levels. But the core is here if you’d like to create your own simple game, you now have all the cards in your hand! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1157.wlEmoticon_2D00_smile_5F00_1A5D52E6.png" /&gt;&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10191168" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Tutorial/">Tutorial</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Game/">Game</category></item><item><title>Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS</title><link>http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx</link><pubDate>Fri, 22 Jul 2011 08:29:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10188857</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10188857</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx#comments</comments><description>&lt;p&gt;Si vous souhaitez écrire un petit jeu dit “casual” en utilisant l’élément Canvas d’HTML5, vous devrez trouver un moyen de gérer vos sprites. Il existe plusieurs librairies susceptibles de vous aider pour écrire des jeux en “HTML5” comme &lt;a href="http://impactjs.com/"&gt;ImpactJS&lt;/a&gt; ou &lt;a href="http://craftyjs.com/"&gt;CraftyJS&lt;/a&gt; par exemple. De mon côté, j’ai décidé de me pencher sur la librairie &lt;a href="http://easeljs.com/"&gt;EaselJS&lt;/a&gt; qui a été utilisée pour écrire &lt;a href="http://www.pirateslovedaisies.com/"&gt;PiratesLoveDaisies&lt;/a&gt; : un jeu en HTML5 de “Tower Defense”. Nous allons donc voir dans cet article à travers 3 petits tutoriels &lt;strong&gt;comment utiliser vos sprites existants et comment les animer&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Cette article est le 1er d’une série de 3 articles :&lt;/p&gt;  &lt;p&gt;- Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS   &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx"&gt;Jeux HTML5: construction des objets principaux &amp;amp; gestion des collisions avec EaselJS&lt;/a&gt;    &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-portage-complet-du-jeu-xna-vers-lt-canvas-gt-gr-226-ce-224-easeljs.aspx"&gt;HTML5 Platformer: portage complet du jeu XNA vers &amp;lt;canvas&amp;gt; grâce à EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p&gt;Sur le site officiel &lt;a href="http://easeljs.com/"&gt;EaselJS&lt;/a&gt;, vous pouvez parcourir quelques exemples intéressants à décortiquer et une &lt;a href="http://easeljs.com/docs/"&gt;documentation assez sommaire&lt;/a&gt;. Nous allons prendre l’exemple nommé &lt;a title="sprites" href="http://easeljs.com/examples/bitmapSequences.html"&gt;sprites&lt;/a&gt; comme base de travail. Nous allons également utiliser les ressources disponibles dans l’exemple &lt;a href="http://create.msdn.com/en-US/education/catalog/sample/platformer"&gt;XNA 4.0 Platformer&lt;/a&gt;. Pour ceux qui suivent régulièrement mon blog, vous savez peut-être que j’affectionne particulièrement ce petit jeu et que j’aime jouer avec son code pour apprendre. Voici quelques articles que j’ai déjà écrit à ce sujet :&lt;/p&gt;  &lt;p&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2010/03/29/portage-du-platformer-starter-kit-xna-3-1-vers-xna-4-0-pour-windows-phone-7.aspx" href="http://blogs.msdn.com/b/davrous/archive/2010/03/29/portage-du-platformer-starter-kit-xna-3-1-vers-xna-4-0-pour-windows-phone-7.aspx"&gt;Portage du Platformer Starter Kit XNA 3.1 vers XNA 4.0 pour Windows Phone 7&lt;/a&gt;     &lt;br /&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2010/07/22/silverlight-4-xna-platformer-level-editor-pour-windows-phone-7-introduction-1-4.aspx" href="http://blogs.msdn.com/b/davrous/archive/2010/07/22/silverlight-4-xna-platformer-level-editor-pour-windows-phone-7-introduction-1-4.aspx"&gt;Silverlight 4 XNA Platformer Level Editor pour Windows Phone 7&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Entre temps, cet exemple de code a été mis à jour par nos équipes XNA et est désormais disponible pour les plateformes Xbox 360, PC &amp;amp; Windows Phone 7 ici: &lt;a title="http://create.msdn.com/en-US/education/catalog/sample/platformer" href="http://create.msdn.com/en-US/education/catalog/sample/platformer"&gt;App Hub – platformer&lt;/a&gt; . Vous pouvez le télécharger pour jouer avec le jeu et surtout pour extraire les sprites afin de les utiliser avec EaselJS. &lt;/p&gt;  &lt;p&gt;Dans cet article, nous allons ainsi utiliser ces 2 images PNG comme source de nos séquences de sprites:&lt;/p&gt;  &lt;p&gt;Notre ennemi/monstre en train de courir:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://david.blob.core.windows.net/easeljstutorials/img/MonsterARun.png" /&gt;&lt;/p&gt;  &lt;p&gt;qui contient &lt;strong&gt;10&lt;/strong&gt; images/sprites différents. &lt;/p&gt;  &lt;p&gt;Notre monstre au repos:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://david.blob.core.windows.net/easeljstutorials/img/MonsterAIdle.png" /&gt;&lt;/p&gt;  &lt;p&gt;qui contient une séquence de &lt;strong&gt;11&lt;/strong&gt; sprites différents.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; ces exemples ne fonctionnent pas correctement dans Firefox 5.0 du apparemment à un &lt;a href="https://github.com/gskinner/EaselJS/issues/65"&gt;bug dans leur implémentation de canvas&lt;/a&gt;. Ils ont été testés avec succès par votre serviteur dans IE9/IE10/Chrome 12/Opera 11 &amp;amp; Firefox Aurora 7.0.&lt;/p&gt;  &lt;h2&gt;Tutoriel 1 : construction des objets SpriteSheet et BitmapSequence&lt;/h2&gt;  &lt;p&gt;Nous allons commencer par faire bouger notre monstre en train de courir sur toute la largeur du canvas. &lt;/p&gt;  &lt;p&gt;La 1ère étape consiste donc à charger la séquence complète contenue dans l’image PNG via ce code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;imgMonsterARun = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();

&lt;span style="color: blue"&gt;function &lt;/span&gt;init() {
    &lt;span style="color: #006400"&gt;//récupère le canvas et charge les images, attention à bien attendre la fin de tous les téléchargements
    &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;testCanvas&amp;quot;&lt;/span&gt;);

    imgMonsterARun.onload = handleImageLoad;
    imgMonsterARun.onerror = handleImageError;
    imgMonsterARun.src = &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterARun.png&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;Ce code sera donc appelé en premier pour initialiser le contenu de notre jeu. Une fois chargé, nous pouvons démarrer le jeu. EaselJS expose un objet de type &lt;a href="http://easeljs.com/docs/SpriteSheet.html"&gt;&lt;em&gt;SpriteSheet&lt;/em&gt;&lt;/a&gt;&lt;em&gt; &lt;/em&gt;pour gérer nos sprites. Ainsi en utilisant ce code :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;spriteSheet  = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
        imgMonsterARun, &lt;span style="color: #006400"&gt;//image à utiliser
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//largeur de chaque sprite
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//hauteur de chaque sprite
        &lt;/span&gt;{    
            walk_left: [0, 9]
        });&lt;/pre&gt;

&lt;p&gt;Nous indiquons que nous souhaitons créer une nouvelle séquence appelée “&lt;em&gt;walk_left&lt;/em&gt;”&lt;em&gt; &lt;/em&gt;qui sera fabriquée à partir de l’image appelée &lt;em&gt;imgMonsterARun&lt;/em&gt;. Cette image sera divisée en 10 sous-images ayant une taille de 64x64 pixels chacune. Il constitue notre objet de base pour charger nos sprites et en créer des séquences. A noter que vous pouvez créer plusieurs séquences à partir de même fichier PNG si vous le souhaitez. C’est le cas de l’exemple avec les rats sur le site officiel d’EaselJS. &lt;/p&gt;

&lt;p&gt;Maintenant, il nous faut utiliser l’objet &lt;em&gt;&lt;a href="http://easeljs.com/docs/BitmapSequence.html"&gt;BitmapSequence&lt;/a&gt;&lt;/em&gt;. Cet objet va nous aider à animer notre séquence et à la positionner à l’écran. Revoyons ensemble le code d’initialisation de cette &lt;em&gt;BitmapSequence&lt;/em&gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// crée une instance de BitmapSequence pour afficher et animer une instance de SpriteSheet:
&lt;/span&gt;bmpSeq = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence(spriteSheet);
    
&lt;span style="color: #006400"&gt;// on fixe un point de registration (le point où l’objet sera positionné et autour duquel il tournera)
// au centre des dimensions d’une frame/sous-image
&lt;/span&gt;bmpSeq.regX = bmpSeq.spriteSheet.frameWidth/2|0;
bmpSeq.regY = bmpSeq.spriteSheet.frameHeight / 2 | 0;

&lt;span style="color: #006400"&gt;// On lance la séquence d’animation
&lt;/span&gt;bmpSeq.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;);     &lt;span style="color: #006400"&gt;//animation
    
// mise en place d’une ombre portée. Cela peut couter cher en FPS en fonction du navigateur.
&lt;/span&gt;bmpSeq.shadow = &lt;span style="color: blue"&gt;new &lt;/span&gt;Shadow(&lt;span style="color: maroon"&gt;&amp;quot;#454&amp;quot;&lt;/span&gt;, 0, 5, 4);

bmpSeq.name = &lt;span style="color: maroon"&gt;&amp;quot;monster1&amp;quot;&lt;/span&gt;;
bmpSeq.speed = 1;
bmpSeq.direction = 90;
bmpSeq.vX = 3|0.5;
bmpSeq.vY = 0;
bmpSeq.x = 16;
bmpSeq.y = 32;
        
&lt;span style="color: #006400"&gt;// On peut choisir exactement à quelle frame démarrer l’animation
&lt;/span&gt;bmpSeq.currentFrame = 0;
stage.addChild(bmpSeq);&lt;/pre&gt;

&lt;p&gt;Le constructeur de l’objet &lt;em&gt;BitmapSequence&lt;/em&gt; a simplement besoin d’un élément de type &lt;em&gt;SpriteSheet&lt;/em&gt; comme paramètre. Ensuite, on donne un nom à la séquence, positionne quelques paramètres comme la vitesse et la position initiale de notre 1ère étape d’animation. Pour finir, on ajoute cette séquence aux éléments affichables à l’écran avec l’objet &lt;a href="http://easeljs.com/docs/Stage.html"&gt;&lt;em&gt;Stage&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;#160;&lt;/em&gt;et sa méthode &lt;em&gt;addChild()&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;La dernière étape consiste maintenant à décider ce que l’on souhaite faire dans la boucle d’animation. Cette boucle est appelée toutes les xxx millisecondes et vous permet de mettre à jour la position de vos sprites. Pour cela, EaselJS expose un objet &lt;a href="http://easeljs.com/docs/Ticker.html"&gt;&lt;em&gt;Ticker&lt;/em&gt;&lt;/a&gt; qui nous fournit une horloge centralisée diffusée à un intervalle précis à tous les éléments souhaitant l’écouter. Tout ce que vous avez à faire, c’est de vous abonner à l’évènement tick et d’implémenter une méthode &lt;em&gt;.tick()&lt;/em&gt; qui sera rappelée pour vous. Ce code s’abonne par exemple à cet évènement:&lt;/p&gt;

&lt;pre class="code"&gt;Ticker.addListener(window);
&lt;span style="color: #006400"&gt;// Nous visons ici le meilleur taux d’images par secondes (60 FPS)
&lt;/span&gt;Ticker.setInterval(17);&lt;/pre&gt;

&lt;p&gt;Et voici le code qui sera rappelé toutes les 17 ms (lorsque cela sera possible) pour mettre à jour la position de notre monstre: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;tick() {
    &lt;span style="color: #006400"&gt;// On teste si le personnage n’arrive pas en bout d’écran à droite avant qu’il ne disparaisse à jamais!
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;gt;= screen_width - 16) {
        &lt;span style="color: #006400"&gt;// Nous avons atteint le côté droit de notre écran
        // Nous devons maintenant marcher vers la gauche pour retourner à la positon initiale
        &lt;/span&gt;bmpSeq.direction = -90;
    }

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;lt; 16) {
        &lt;span style="color: #006400"&gt;// Nous avons atteint le côté gauche de notre écran
        // Nous devons maintenant marcher vers la droite
        &lt;/span&gt;bmpSeq.direction = 90;
    }

    &lt;span style="color: #006400"&gt;// On bouge le sprite en fonction de la direction et de la vitesse demandée
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.direction == 90) {
        bmpSeq.x += bmpSeq.vX;
        bmpSeq.y += bmpSeq.vY;
    }
    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
        bmpSeq.x -= bmpSeq.vX;
        bmpSeq.y -= bmpSeq.vY;
    }

    &lt;span style="color: #006400"&gt;// mise à jour de la scène de jeu
    &lt;/span&gt;stage.update();
}&lt;/pre&gt;

&lt;p&gt;Vous pouvez tester le résultat final ici :&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="120" src="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html" width="700"&gt;&lt;/iframe&gt;

&lt;p&gt;Vous pouvez aussi naviguer vers cette URL : &lt;a title="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html" href="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html"&gt;easelJSSpritesTutorial01&lt;/a&gt; si vous souhaitez voir l’exemple de code complet.&lt;/p&gt;

&lt;p&gt;Eh, mais elle est bizarre cette animation non ? Effectivement, il y a 2 problèmes :&lt;/p&gt;

&lt;p&gt;1 – les étapes d’animation sont un peu étrange car le personnage semble boucler trop vite au sein de sa séquence de sprites. 
  &lt;br /&gt;2 – le personnage ne peut marcher normalement que de la droite vers la gauche. On a l’impression sinon qu’il se la raconte un peu en effectuant un Moonwalk dans l’autre sens. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5415.wlEmoticon_2D00_winkingsmile_5F00_624D63DC.png" /&gt;&lt;/p&gt;

&lt;p&gt;Regardons comment le calmer un petit peu et fixer tout cela dans le 2ème tutoriel. .&lt;/p&gt;

&lt;h2&gt;Tutorial 2: contrôle de la vitesse d’animation et inversion des sprites&lt;/h2&gt;

&lt;p&gt;Pour corriger la vitesse de l’animation, la méthode la plus simple que j’ai trouvée consiste à utiliser l’opérateur modulo afin d’éviter de dessiner ma séquence à chaque appel de l’horloge. Il y a d’ailleurs une discussion actuellement ouverte en version 0.3.2 pour savoir comment éventuellement intégrer le principe dans la librairie même: &lt;a title="https://github.com/gskinner/EaselJS/issues/60" href="https://github.com/gskinner/EaselJS/issues/60"&gt;https://github.com/gskinner/EaselJS/issues/60&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Pour ajouter de nouvelles frames afin de permettre au personnage de marcher normalement de la gauche vers la droite, nous devons inverser horizontalement chacune des frames du sprite. Cela tombe bien, EaselJS expose un objet &lt;em&gt;&lt;a href="http://easeljs.com/docs/SpriteSheetUtils.html"&gt;SpriteSheetUtils&lt;/a&gt;&lt;/em&gt; qui contient une méthode &lt;em&gt;flip()&lt;/em&gt;. Voici le code permettant de les utiliser :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// {nomDeLaSequenceInversée:[&amp;quot;sequenceOrigine&amp;quot;, flipHorizontal, flipVertical, optionnelNomDeLaProchaineSequence]}
&lt;/span&gt;spriteSheet = SpriteSheetUtils.flip(
spriteSheet,
{
    walk_right: [&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;]
});&lt;/pre&gt;

&lt;p&gt;Nous créons ainsi une nouvelle séquence nommée “&lt;em&gt;walk_right&lt;/em&gt;” basée sur la séquence “&lt;em&gt;walk_left&lt;/em&gt;” que nous avons inversée horizontalement. Pour finir, voici le code qui ralentit l’animation et qui s’occupe de savoir quelle séquence jouer en fonction de la position actuelle du personnage :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;tick() {
    &lt;span style="color: #006400"&gt;// Pour ralentir l'animation du sprite, il suffit de ne pas le redessiner à chaque fois
    // Avec un modulo 4, on divise la vitesse par 4 puisque l’on ne dessine plus qu’1 fois sur 4
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;speedControl = Ticker.getTicks() % 4;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(speedControl == 0) {
        &lt;span style="color: #006400"&gt;// On teste si le personnage n’arrive pas en bout d’écran à droite avant qu’il ne disparaisse
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;gt;= screen_width - 16) {
            &lt;span style="color: #006400"&gt;// Nous avons atteint le côté droit de notre écran
            // Nous devons maintenant marcher vers la gauche pour retourner à la positon initiale
            &lt;/span&gt;bmpSeq.direction = -90;
            bmpSeq.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;)
        }

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;lt; 16) {
            &lt;span style="color: #006400"&gt;// Nous avons atteint le côté gauche de notre écran
            // Nous devons maintenant marcher vers la droite 
            &lt;/span&gt;bmpSeq.direction = 90;
            bmpSeq.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_right&amp;quot;&lt;/span&gt;);
        }

        &lt;span style="color: #006400"&gt;// On bouge le sprite en fonction de la direction et de la vitesse demandée
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.direction == 90) {
            bmpSeq.x += bmpSeq.vX;
            bmpSeq.y += bmpSeq.vY;
        }
        &lt;span style="color: blue"&gt;else &lt;/span&gt;{
            bmpSeq.x -= bmpSeq.vX;
            bmpSeq.y -= bmpSeq.vY;
        }

        &lt;span style="color: #006400"&gt;// mise à jour de la scène de jeu
        &lt;/span&gt;stage.update();
    }
}&lt;/pre&gt;

&lt;p&gt;Vous pouvez tester le résultat final ici :&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="120" src="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial02.html" width="700"&gt;&lt;/iframe&gt;

&lt;p&gt;Vous pouvez aussi naviguer vers cette URL : &lt;a title="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial02.html" href="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial02.html"&gt;easelJSSpritesTutorial02&lt;/a&gt; si vous souhaitez voir l’exemple de code complet.&lt;/p&gt;

&lt;h2&gt;Tutoriel 3 : chargement de plusieurs sprites et utilisation de plusieurs animations&lt;/h2&gt;

&lt;p&gt;Il est temps désormais de charger l’état “au repos” de notre monstre préféré. L’idée est donc de jouer l’animation où il court sur un aller/retour complet. Ensuite, fatigué, le monstre passera à l’état “au repos” à jamais.&lt;/p&gt;

&lt;p&gt;Nous allons donc devoir charger plusieurs images PNG depuis le serveur web. Il est d’ailleurs très important d’attendre que toutes les ressources soient totalement téléchargées afin de commencer les opérations de dessin. Voici une manière très simple de s’en assurer :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;numberOfImagesLoaded = 0;

&lt;span style="color: blue"&gt;var &lt;/span&gt;imgMonsterARun = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
&lt;span style="color: blue"&gt;var &lt;/span&gt;imgMonsterAIdle = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();

&lt;span style="color: blue"&gt;function &lt;/span&gt;init() {
    &lt;span style="color: #006400"&gt;//récupère le canvas et charge les images, attention à bien attendre la fin de tous les téléchargements 
    &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;testCanvas&amp;quot;&lt;/span&gt;);

    imgMonsterARun.onload = handleImageLoad;
    imgMonsterARun.onerror = handleImageError;
    imgMonsterARun.src = &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterARun.png&amp;quot;&lt;/span&gt;;

    imgMonsterAIdle.onload = handleImageLoad;
    imgMonsterAIdle.onerror = handleImageError;
    imgMonsterAIdle.src = &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterAIdle.png&amp;quot;&lt;/span&gt;;
}

&lt;span style="color: blue"&gt;function &lt;/span&gt;handleImageLoad(e) {
    numberOfImagesLoaded++;

    &lt;span style="color: #006400"&gt;// Nous ne démarrons pas le jeu tant que toutes les images ne sont pas téléchargées
    // Sinon vous risquez de commencer à dessiner sans la bonne ressource et de lever 
    // cet exception du DOM: INVALID_STATE_ERR (11) sur l’appel de la méthode drawImage
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(numberOfImagesLoaded == 2) {
        numberOfImagesLoaded = 0;
        startGame();
    }
}&lt;/pre&gt;

&lt;p&gt;Ce code est très basique. Par exemple, il ne gère pas les erreurs correctement en tentant de télécharger à nouveau l’image problématique en cas de 1er échec. Si vous fabriquez un jeu, vous aurez besoin d’écrire votre propre gestionnaire de téléchargements de contenus si la librairie JavaScript que vous utilisez de l’implémente pas encore.&lt;/p&gt;

&lt;p&gt;Pour ajouter la séquence “au repos” et positionner ses différents paramètres, il nous suffit d’utiliser le même type de code vu précédemment :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;spriteSheetIdle = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
        imgMonsterAIdle, &lt;span style="color: #006400"&gt;//image à utiliser
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//largeur du sprite
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//hauteur du sprite
        &lt;/span&gt;{    
            idle: [0, 10]
        });

bmpSeqIdle = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence(spriteSheetIdle);

bmpSeqIdle.name = &lt;span style="color: maroon"&gt;&amp;quot;monsteridle1&amp;quot;&lt;/span&gt;;
bmpSeqIdle.speed = 1;
bmpSeqIdle.direction = 0;
bmpSeqIdle.x = 16;
bmpSeqIdle.y = 32;&lt;/pre&gt;

&lt;p&gt;Ensuite, au sein de la méthode &lt;em&gt;tick()&lt;/em&gt;, nous devons stopper l’animation où le monstre court une fois que ce dernier atteint à nouveau le côté gauche de l’écran. Puis ensuite, il suffit de jouer l’animation “au repos” à la place. Voici le code qui fait exactement cela :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;lt; 16) {
    &lt;span style="color: #006400"&gt;// Nous avons atteint le côté gauche de notre écran, il est temps de se reposer 
    &lt;/span&gt;bmpSeq.direction = 90;
    bmpSeq.gotoAndStop(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;);
    stage.removeChild(bmpSeq);
    bmpSeqIdle.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;idle&amp;quot;&lt;/span&gt;);
    stage.addChild(bmpSeqIdle);
}&lt;/pre&gt;

&lt;p&gt;Vous pouvez tester le résultat final ici :&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="120" src="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial03.html" width="700"&gt;&lt;/iframe&gt;

&lt;p&gt;Vous pouvez aussi naviguer vers cette URL : &lt;a title="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial03.html" href="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial03.html"&gt;easelJSSpritesTutorial03&lt;/a&gt; si vous souhaitez voir l’exemple de code complet.&lt;/p&gt;

&lt;p&gt;Voilà, c’est tout pour aujourd’hui ! Vous pouvez reprendre une activité normale. Mais si l’envie vous en prend, n’hésitez pas à jeter un œil à la suite ici : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/08/22/jeux-html5-construction-des-objets-principaux-amp-gestion-des-collisions-avec-easeljs.aspx"&gt;Jeux HTML5: construction des objets principaux &amp;amp; gestion des collisions avec EaselJS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10188857" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Game/">Game</category></item><item><title>HTML5 Gaming: animating sprites in Canvas with EaselJS</title><link>http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx</link><pubDate>Thu, 21 Jul 2011 15:12:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10188613</guid><dc:creator>David Rousset</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10188613</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx#comments</comments><description>&lt;p&gt;When you want to write casual games using the HTML5 Canvas element, you’ll need to find a way to handle your sprites. There are several libraries available to help you writing games such as &lt;a href="http://impactjs.com/"&gt;ImpactJS&lt;/a&gt;, &lt;a href="http://craftyjs.com/"&gt;CraftyJS&lt;/a&gt; and so on. On my side, I’ve decided to use &lt;a href="http://easeljs.com/"&gt;EaselJS&lt;/a&gt; which has been used to write &lt;a href="http://www.pirateslovedaisies.com/"&gt;PiratesLoveDaisies&lt;/a&gt;: an HTML5 Tower Defense game. We’re going to see in this tutorial &lt;strong&gt;how to use your existing sprite elements and animate them&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Pour ceux qui pratiquent la langue de Molière, vous trouverez une version française ici : &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/22/jeux-html5-animation-de-sprites-dans-l-233-l-233-ment-canvas-gr-226-ce-224-easeljs.aspx"&gt;Jeux HTML5: animation de sprites dans l’élément Canvas grâce à EaselJS&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This article is the first of a serie of 3:&lt;/p&gt;  &lt;p&gt;- HTML5 Gaming: animating sprites in Canvas with EaselJS   &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx"&gt;HTML5 Gaming: building the core objects &amp;amp; handling collisions with EaselJS&lt;/a&gt;    &lt;br /&gt;- &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx"&gt;HTML5 Platformer: the complete port of the XNA game to &amp;lt;canvas&amp;gt; with EaselJS&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p&gt;On the official &lt;a href="http://easeljs.com/"&gt;EaselJS&lt;/a&gt; site, you’ll find some interesting samples and some &lt;a href="http://easeljs.com/docs/"&gt;basic documentation&lt;/a&gt;. We will use the &lt;a title="sprites" href="http://easeljs.com/examples/bitmapSequences.html"&gt;sprites&lt;/a&gt; sample as a base. We will use also the resources available in the &lt;a href="http://create.msdn.com/en-US/education/catalog/sample/platformer"&gt;XNA 4.0 Platformer sample&lt;/a&gt;. For those of you who are following my blog, you may remember that I love playing with this sample. Here are the previous attached articles:&lt;/p&gt;  &lt;p&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2010/03/29/windows-phone-7-platformer-starter-kit-for-xna-studio-4-0.aspx" href="http://blogs.msdn.com/b/davrous/archive/2010/03/29/windows-phone-7-platformer-starter-kit-for-xna-studio-4-0.aspx"&gt;Windows Phone 7 Platformer Starter Kit for XNA Studio 4.0&lt;/a&gt;     &lt;br /&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2010/07/22/silverlight-4-xna-platformer-level-editor-for-windows-phone-7-overview-1-4.aspx" href="http://blogs.msdn.com/b/davrous/archive/2010/07/22/silverlight-4-xna-platformer-level-editor-for-windows-phone-7-overview-1-4.aspx"&gt;Silverlight 4 XNA Platformer Level Editor for Windows Phone 7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The platformer sample have been updated in the meantime by our XNA team and is available here for Xbox 360, PC &amp;amp; Windows Phone 7: &lt;a title="http://create.msdn.com/en-US/education/catalog/sample/platformer" href="http://create.msdn.com/en-US/education/catalog/sample/platformer"&gt;App Hub – platformer&lt;/a&gt; . You can download it to play with it and extract the sprites to use them with EaselJS.&lt;/p&gt;  &lt;p&gt;In this article, we’re going to use these 2 PNG files as source of our sprite sequences:&lt;/p&gt;  &lt;p&gt;Our monster running:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://david.blob.core.windows.net/easeljstutorials/img/MonsterARun.png" /&gt;&lt;/p&gt;  &lt;p&gt;which contains &lt;strong&gt;10&lt;/strong&gt; different sprites.&lt;/p&gt;  &lt;p&gt;Our monster in idle mode:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://david.blob.core.windows.net/easeljstutorials/img/MonsterAIdle.png" /&gt;&lt;/p&gt;  &lt;p&gt;which contains &lt;strong&gt;11&lt;/strong&gt; different sprites.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; these samples don’t work properly in Firefox 5.0 due apparently to &lt;a href="https://github.com/gskinner/EaselJS/issues/65"&gt;a bug in their canvas implementation&lt;/a&gt;. It has been tested ok in IE9/IE10/Chrome 12/Opera 11 &amp;amp; Firefox Aurora 7.0.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;h2&gt;Tutorial 1: building the SpriteSheet and the BitmapSequence&lt;/h2&gt;  &lt;p&gt;We’ll start by moving the running monster between the beginning and the end of the width of our canvas.&lt;/p&gt;  &lt;p&gt;First step is to load the complete sequence contained in the PNG file via this code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;imgMonsterARun = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();

&lt;span style="color: blue"&gt;function &lt;/span&gt;init() {
    &lt;span style="color: #006400"&gt;//find canvas and load images, wait for last image to load
    &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;testCanvas&amp;quot;&lt;/span&gt;);

    imgMonsterARun.onload = handleImageLoad;
    imgMonsterARun.onerror = handleImageError;
    imgMonsterARun.src = &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterARun.png&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;This code will be called first to initialize our game’s content. Once loaded, we can start the game. EaselJS expose a &lt;em&gt;&lt;a href="http://easeljs.com/docs/SpriteSheet.html"&gt;SpriteSheet&lt;/a&gt; &lt;/em&gt;object to handle the sprite. Thus, by using this code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;spriteSheet  = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
        imgMonsterARun, &lt;span style="color: #006400"&gt;//image to use
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//width of each sprite
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//height of each sprite
        &lt;/span&gt;{    
            walk_left: [0, 9]
        });&lt;/pre&gt;

&lt;p&gt;We’re indicating that we’d like to create a new sequence named “&lt;em&gt;walk_left&lt;/em&gt;” that will be made of the &lt;em&gt;imgMonsterARun&lt;/em&gt; image. This image will be split into 10 frames with a size of 64x64 pixels. This is the core object to load our sprite and create our sequences. There could be several sequences created from the same PNG file if you want to, like in the rats sprite sample of the EaselJS site. &lt;/p&gt;

&lt;p&gt;After that, we need to use the &lt;em&gt;&lt;a href="http://easeljs.com/docs/BitmapSequence.html"&gt;BitmapSequence&lt;/a&gt;&lt;/em&gt; object. It helps us animating our sequence and positioning our sprites on the screen. Let’s review the initializing code of this BitmapSequence:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// create a BitmapSequence instance to display and play back the sprite sheet:
&lt;/span&gt;bmpSeq = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence(spriteSheet);
    
&lt;span style="color: #006400"&gt;// set the registration point (the point it will be positioned and rotated around)
// to the center of the frame dimensions:
&lt;/span&gt;bmpSeq.regX = bmpSeq.spriteSheet.frameWidth/2|0;
bmpSeq.regY = bmpSeq.spriteSheet.frameHeight / 2 | 0;

&lt;span style="color: #006400"&gt;// start playing the first sequence:
&lt;/span&gt;bmpSeq.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;);     &lt;span style="color: #006400"&gt;//animate
    
// set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
// of animated rats if you disabled the shadow.
&lt;/span&gt;bmpSeq.shadow = &lt;span style="color: blue"&gt;new &lt;/span&gt;Shadow(&lt;span style="color: maroon"&gt;&amp;quot;#454&amp;quot;&lt;/span&gt;, 0, 5, 4);

bmpSeq.name = &lt;span style="color: maroon"&gt;&amp;quot;monster1&amp;quot;&lt;/span&gt;;
bmpSeq.speed = 1;
bmpSeq.direction = 90;
bmpSeq.vX = 3|0.5;
bmpSeq.vY = 0;
bmpSeq.x = 16;
bmpSeq.y = 32;
        
&lt;span style="color: #006400"&gt;// have each monster start at a specific frame
&lt;/span&gt;bmpSeq.currentFrame = 0;
stage.addChild(bmpSeq);&lt;/pre&gt;

&lt;p&gt;The constructor of the &lt;em&gt;BitmapSequence&lt;/em&gt; object simply needs the &lt;em&gt;SpriteSheet&lt;/em&gt; element as a parameter. We’re then giving a name to the sequence, setting some parameters like the speed and the initial position of our first frame. Finally, we add this sequence to the display list by using the &lt;em&gt;&lt;a href="http://easeljs.com/docs/Stage.html"&gt;Stage&lt;/a&gt;&lt;/em&gt; object and its &lt;em&gt;addChild()&lt;/em&gt; method.&lt;/p&gt;

&lt;p&gt;Next step is now to decide what we’d like to do in our animation loop. This animation loop is called every xxx milliseconds and let you update the position of your sprites. For that, EaselJS exposes a &lt;em&gt;&lt;a href="http://easeljs.com/docs/Ticker.html"&gt;Ticker&lt;/a&gt;&lt;/em&gt; object which provides a centralized tick or heartbeat broadcast at a set interval. All you’ve got to do is to subscribe to the tick event and implement a .tick() method that will be called back. This code is for instance registering the event:&lt;/p&gt;

&lt;pre class="code"&gt;Ticker.addListener(window);
&lt;span style="color: #006400"&gt;// Best Framerate targeted (60 FPS)
&lt;/span&gt;Ticker.setInterval(17);&lt;/pre&gt;

&lt;p&gt;And here is the code that will be called every 17ms (when possible) to update the position of our monster:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;tick() {
    &lt;span style="color: #006400"&gt;// Hit testing the screen width, otherwise our sprite would disappear
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;gt;= screen_width - 16) {
        &lt;span style="color: #006400"&gt;// We've reached the right side of our screen
        // We need to walk left now to go back to our initial position
        &lt;/span&gt;bmpSeq.direction = -90;
    }

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;lt; 16) {
        &lt;span style="color: #006400"&gt;// We've reached the left side of our screen
        // We need to walk right now
        &lt;/span&gt;bmpSeq.direction = 90;
    }

    &lt;span style="color: #006400"&gt;// Moving the sprite based on the direction &amp;amp; the speed
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.direction == 90) {
        bmpSeq.x += bmpSeq.vX;
        bmpSeq.y += bmpSeq.vY;
    }
    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
        bmpSeq.x -= bmpSeq.vX;
        bmpSeq.y -= bmpSeq.vY;
    }

    &lt;span style="color: #006400"&gt;// update the stage:
    &lt;/span&gt;stage.update();
}&lt;/pre&gt;

&lt;p&gt;You can test the final result here:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="120" src="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html" width="700"&gt;&lt;/iframe&gt;

&lt;p&gt;You can also browse this sample here: &lt;a title="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html" href="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html"&gt;easelJSSpritesTutorial01&lt;/a&gt; if you’d like to view the complete source code.&lt;/p&gt;

&lt;p&gt;But wait! There are 2 problems in this animation:&lt;/p&gt;

&lt;p&gt;1 – the animation steps are weird as the character seems to loop through its different sprites sequence too fast 
  &lt;br /&gt;2 – the character can only walk normally from right to left otherwise it looks like it tries to achieve a kind of Moonwalk dance. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8640.wlEmoticon_2D00_winkingsmile_5F00_1E4AD1B1.png" /&gt;&lt;/p&gt;

&lt;p&gt;Let’s see how to fix that in the second tutorial.&lt;/p&gt;

&lt;h2&gt;Tutorial 2: controlling the animation speed and flipping the sprites&lt;/h2&gt;

&lt;p&gt;To fix the animation’s speed, the simplest way I’ve found is to use a modulus operator to avoid drawing/updating my sequence during each tick. There is currently an opened issue on this topic: &lt;a title="https://github.com/gskinner/EaselJS/issues/60" href="https://github.com/gskinner/EaselJS/issues/60"&gt;https://github.com/gskinner/EaselJS/issues/60&lt;/a&gt; with EaselJS 0.3.2. &lt;/p&gt;

&lt;p&gt;To add new animation frames to let the character walking normally from left to right, we need to flip each frame. EaselJS exposes a &lt;em&gt;&lt;a href="http://easeljs.com/docs/SpriteSheetUtils.html"&gt;SpriteSheetUtils&lt;/a&gt;&lt;/em&gt; object for that and a &lt;em&gt;flip()&lt;/em&gt; method. Here is the code that uses them:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// {nameOfFlippedSequence:[&amp;quot;derivativeSequence&amp;quot;, flipHorizontally, flipVertically, optionNameOfNextSequence]}
&lt;/span&gt;spriteSheet = SpriteSheetUtils.flip(
spriteSheet,
{
    walk_right: [&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;]
});&lt;/pre&gt;

&lt;p&gt;We’re creating a derivative sequence named “&lt;em&gt;walk_right&lt;/em&gt;”&lt;em&gt;&amp;#160;&lt;/em&gt;based on the “walk_left” sequence that we flip horizontally. At last, here is the code that slows down the speed animation and which handles which sequence to play based on the character position:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;tick() {
    &lt;span style="color: #006400"&gt;// To slow down the animation loop of the sprite, we're not redrawing during each tick
    // With a Modulo 4, we're dividing the speed by 4
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;speedControl = Ticker.getTicks() % 4;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(speedControl == 0) {
        &lt;span style="color: #006400"&gt;// Hit testing the screen width, otherwise our sprite would disappear
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;gt;= screen_width - 16) {
            &lt;span style="color: #006400"&gt;// We've reached the right side of our screen
            // We need to walk left now to go back to our initial position
            &lt;/span&gt;bmpSeq.direction = -90;
            bmpSeq.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;)
        }

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;lt; 16) {
            &lt;span style="color: #006400"&gt;// We've reached the left side of our screen
            // We need to walk right now
            &lt;/span&gt;bmpSeq.direction = 90;
            bmpSeq.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;walk_right&amp;quot;&lt;/span&gt;);
        }

        &lt;span style="color: #006400"&gt;// Moving the sprite based on the direction &amp;amp; the speed
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.direction == 90) {
            bmpSeq.x += bmpSeq.vX;
            bmpSeq.y += bmpSeq.vY;
        }
        &lt;span style="color: blue"&gt;else &lt;/span&gt;{
            bmpSeq.x -= bmpSeq.vX;
            bmpSeq.y -= bmpSeq.vY;
        }

        &lt;span style="color: #006400"&gt;// update the stage:
        &lt;/span&gt;stage.update();
    }
}&lt;/pre&gt;

&lt;p&gt;You can test the final result here:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="120" src="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial02.html" width="700"&gt;&lt;/iframe&gt;

&lt;p&gt;You can also browse this sample here: &lt;a title="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html" href="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial02.html"&gt;easelJSSpritesTutorial02&lt;/a&gt; if you’d like to view the complete source code.&lt;/p&gt;

&lt;h2&gt;Tutorial 3: loading multiple sprites and playing with multiple animations&lt;/h2&gt;

&lt;p&gt;It’s time now to load the idle state of the monster. The idea here is to play the animation state to achieve a single round-trip. Once achieved, we will play the idle state.&lt;/p&gt;

&lt;p&gt;We will then now load multiple PNG files from the web server. It’s then very important to wait until all resources are loaded otherwise you may try to draw non-yet downloaded resources. Here is a very simple way to do it:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;numberOfImagesLoaded = 0;

&lt;span style="color: blue"&gt;var &lt;/span&gt;imgMonsterARun = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();
&lt;span style="color: blue"&gt;var &lt;/span&gt;imgMonsterAIdle = &lt;span style="color: blue"&gt;new &lt;/span&gt;Image();

&lt;span style="color: blue"&gt;function &lt;/span&gt;init() {
    &lt;span style="color: #006400"&gt;//find canvas and load images, wait for last image to load
    &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;testCanvas&amp;quot;&lt;/span&gt;);

    imgMonsterARun.onload = handleImageLoad;
    imgMonsterARun.onerror = handleImageError;
    imgMonsterARun.src = &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterARun.png&amp;quot;&lt;/span&gt;;

    imgMonsterAIdle.onload = handleImageLoad;
    imgMonsterAIdle.onerror = handleImageError;
    imgMonsterAIdle.src = &lt;span style="color: maroon"&gt;&amp;quot;img/MonsterAIdle.png&amp;quot;&lt;/span&gt;;
}

&lt;span style="color: blue"&gt;function &lt;/span&gt;handleImageLoad(e) {
    numberOfImagesLoaded++;

    &lt;span style="color: #006400"&gt;// We're not starting the game until all images are loaded
    // Otherwise, you may start to draw without the resource and raise 
    // this DOM Exception: INVALID_STATE_ERR (11) on the drawImage method
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(numberOfImagesLoaded == 2) {
        numberOfImagesLoaded = 0;
        startGame();
    }
}&lt;/pre&gt;

&lt;p&gt;This code is very simple. For instance, it doesn’t handle the errors properly by trying to re-download the image in case of a first failure. If you’re building a game, you will need to write your own content download manager if the JS library you’re using doesn’t implement it. &lt;/p&gt;

&lt;p&gt;To add the idle sequence and setting the position parameters, we just need to use the same kind of code previously seen:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;spriteSheetIdle = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpriteSheet(
        imgMonsterAIdle, &lt;span style="color: #006400"&gt;//image to use
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//width of each sprite
        &lt;/span&gt;64, &lt;span style="color: #006400"&gt;//height of each sprite
        &lt;/span&gt;{    
            idle: [0, 10]
        });

bmpSeqIdle = &lt;span style="color: blue"&gt;new &lt;/span&gt;BitmapSequence(spriteSheetIdle);

bmpSeqIdle.name = &lt;span style="color: maroon"&gt;&amp;quot;monsteridle1&amp;quot;&lt;/span&gt;;
bmpSeqIdle.speed = 1;
bmpSeqIdle.direction = 0;
bmpSeqIdle.x = 16;
bmpSeqIdle.y = 32;&lt;/pre&gt;

&lt;p&gt;Now, in the tick() method, we need to stop the walking animation once we’ve reached back the left side of the screen and to play the idle animation instead. Here is the code which does that:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bmpSeq.x &amp;lt; 16) {
    &lt;span style="color: #006400"&gt;// We've reached the left side of our screen
    // We need to walk right now
    &lt;/span&gt;bmpSeq.direction = 90;
    bmpSeq.gotoAndStop(&lt;span style="color: maroon"&gt;&amp;quot;walk_left&amp;quot;&lt;/span&gt;);
    stage.removeChild(bmpSeq);
    bmpSeqIdle.gotoAndPlay(&lt;span style="color: maroon"&gt;&amp;quot;idle&amp;quot;&lt;/span&gt;);
    stage.addChild(bmpSeqIdle);
}&lt;/pre&gt;

&lt;p&gt;You can test the final result here:&lt;/p&gt;
&lt;iframe style="border-bottom: #ffffff 0px solid; border-left: #ffffff 0px solid; border-top: #ffffff 0px solid; border-right: #ffffff 0px solid" height="120" src="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial03.html" width="700"&gt;&lt;/iframe&gt;

&lt;p&gt;You can also browse this sample here: &lt;a title="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial01.html" href="http://david.blob.core.windows.net/easeljstutorials/easelJSSpritesTutorial03.html"&gt;easelJSSpritesTutorial03&lt;/a&gt; if you’d like to view the complete source code.&lt;/p&gt;

&lt;p&gt;That’s all folks! But if you want to go further, you can read the next part here: &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/29/html5-gaming-building-the-core-objects-amp-handling-collisions-with-easeljs.aspx"&gt;HTML5 Gaming: building the core objects &amp;amp; handling collisions with EaselJS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10188613" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/EaselJS/">EaselJS</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Game/">Game</category></item><item><title>Introduction to the HTML5 Web Workers: the JavaScript multithreading approach</title><link>http://blogs.msdn.com/b/davrous/archive/2011/07/15/introduction-to-the-html5-web-workers-the-javascript-multithreading-approach.aspx</link><pubDate>Fri, 15 Jul 2011 13:56:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10186905</guid><dc:creator>David Rousset</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10186905</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/07/15/introduction-to-the-html5-web-workers-the-javascript-multithreading-approach.aspx#comments</comments><description>&lt;p&gt;An HTML5 application is obviously written using JavaScript. But compared to other kind of development environments (like native one), &lt;strong&gt;JavaScript&lt;/strong&gt; historically suffers from an important limitation: &lt;strong&gt;all its execution process remains inside a unique thread&lt;/strong&gt;. This could be pretty annoying with today multi-cores processors like the i5/i7 containing up to 8 logical CPUs and even with the latest ARM mobile processors being dual or even quad-cores. Hopefully, we’re going to see that HTML5 offers to the web a way to better handle these new marvelous processors to help you embrace a new generation of web applications.&lt;/p&gt; &lt;a title="Web Workers" href="http://www.flickr.com/photos/60699397@N08/5915082556/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Illustration : the Web Workers in action" align="right" src="http://farm6.static.flickr.com/5319/5915082556_655647d1f7.jpg" width="410" height="309" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;&lt;a href="#beforeworkers"&gt;Before the workers…&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#webworkers"&gt;Web Workers or how to be executed out of the UI Thread&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="#firstwebworker"&gt;My 1st Web Worker&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;&lt;a href="#json"&gt;Posting messages using JSON&lt;/a&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#browserssupport"&gt;Browsers support&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#elements"&gt;Non accessible elements from a worker&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#debugging"&gt;Errors handling &amp;amp; debugging&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="#f12"&gt;The F12 development bar for a better debugging experience&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;&lt;a href="#consolelog"&gt;An interesting solution to mimic console.log()&lt;/a&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#scenarios"&gt;Use cases and how to identify potential candidates&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="#usages"&gt;Web Workers for which scenarios?&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;&lt;a href="#profiling"&gt;How to identity hot spots in your code&lt;/a&gt;           &lt;ul&gt;           &lt;li&gt;&lt;a href="#case1"&gt;Case 1: canvas animation with the Speed Reading demo&lt;/a&gt; &lt;/li&gt;            &lt;li&gt;&lt;a href="#case2"&gt;Case 2: Raytracers inside canvas&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;em&gt;Pour ceux qui pratiquent la langue de Molière, vous trouverez une version française ici : &lt;/em&gt;&lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx"&gt;&lt;em&gt;Introduction aux Web Workers d’HTML5 : le multithreading version JavaScript&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Before the workers…&lt;/h2&gt;  &lt;p&gt;This JavaScript limitation implies that a long running processing will freeze the main window. We often say in our developers’ words that we’re blocking the “&lt;strong&gt;UI Thread&lt;/strong&gt;”. This is the main thread in charge of handling all the visual elements and associated tasks: drawing, refreshing, animating, user inputs events, etc. We all know the bad consequences of overloading this thread: the page freezes and the user can’t interact anymore with your application. The user experience is then of course very bad and the user will probably decide to kill the tab or the browser instance. This is probably not something you’d like to see while using your application!&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;To avoid that, the browsers have implemented a protection mechanism which alerts the user when a long-running suspect script occurs. Unfortunately, this protection mechanism can’t make the difference between a script not written correctly and a script which really needs more time to accomplish its work. Still, as it blocks the UI thread, it’s better to tell you that something wrong is maybe currently occurring. Here are some messages examples (from Firefox 5 &amp;amp; IE9): &lt;/p&gt;  &lt;p&gt;&lt;a title="ProtectionJSFF5 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5939882671/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="ProtectionJSFF5" src="http://farm7.static.flickr.com/6030/5939882671_3bf264fd60.jpg" width="500" height="147" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="20110419-hrii-image5 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5905126041/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="20110419-hrii-image5" src="http://farm7.static.flickr.com/6041/5905126041_117c858cd6.jpg" width="500" height="38" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hopefully, up to now, those problems were rarely occuring for 2 main reasons:&lt;/p&gt;  &lt;p&gt;1 – HTML and JavaScript weren’t used in the same way and for the same goals as other technologies able to achieve multithreaded tasks. The Websites were offering richless experiences to the users than native applications.    &lt;br /&gt;2 – There were some other ways to more or less solve this concurrency problem.&lt;/p&gt;  &lt;p&gt;Those ways are well known from all web developers. We were indeed trying to simulate parallel tasks thanks to the &lt;strong&gt;setTimeout()&lt;/strong&gt; and &lt;strong&gt;setInterval()&lt;/strong&gt; methods for instance. HTTP requests can also be done in asynchronous manner thanks to the &lt;strong&gt;XMLHttpRequest&lt;/strong&gt; object which avoids freezing the UI while loading some resources from some remote servers. At last, the &lt;strong&gt;DOM Events&lt;/strong&gt; allow us to write application making the illusion that several things occurs at the same time. Illusion, really? Yes! &lt;/p&gt;  &lt;p&gt;To better understand why, let’s have a look to a fake piece of code and let’s then see what happens inside the browser:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
    function &lt;/span&gt;init(){
        { piece of code taking &lt;strong&gt;5ms&lt;/strong&gt; to be executed } 
        A mouseClickEvent is raised
        { piece of code taking &lt;strong&gt;5ms&lt;/strong&gt; to be executed }
        setInterval(timerTask,&lt;span style="color: maroon"&gt;&amp;quot;10&amp;quot;&lt;/span&gt;);
        { piece of code taking &lt;strong&gt;5ms&lt;/strong&gt; to be executed }
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;handleMouseClick(){
          piece of code taking &lt;strong&gt;8ms&lt;/strong&gt; to be executed 
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;timerTask(){
          piece of code taking &lt;strong&gt;2ms&lt;/strong&gt; to be executed 
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Let’s take this code to project it on a model. This diagram then shows us what’s happening in the browser on a time scale:&lt;/p&gt;

&lt;p&gt;&lt;img id="imgSingleThread" alt="Diagram illustrating single-threaded JavaScript" src="" /&gt;&lt;/p&gt;

&lt;p&gt;This diagram well illustrates the non-parallel nature of our tasks. Indeed, the browser is only enqueuing the various execution requests:&lt;/p&gt;

&lt;p&gt;- from &lt;strong&gt;0&lt;/strong&gt; to &lt;strong&gt;5&lt;/strong&gt;ms: the&lt;em&gt; init()&lt;/em&gt; function starts by a 5ms task. After 5ms, the user raises a mouse click event. However, this event can’t be handled right now as we’re still executing the &lt;em&gt;init()&lt;/em&gt; function which currently monopolize the main thread. The click event is saved and will be handled later on. &lt;/p&gt;

&lt;p&gt;- from &lt;strong&gt;5&lt;/strong&gt; to &lt;strong&gt;10&lt;/strong&gt;ms: the &lt;em&gt;init()&lt;/em&gt; function continues its processing during 5ms and then asks to schedule the call to the &lt;em&gt;timerTask()&lt;/em&gt; in 10ms. This function should then logically be executed at the 20ms timeframe. &lt;/p&gt;

&lt;p&gt;- from &lt;strong&gt;10&lt;/strong&gt; to &lt;strong&gt;15&lt;/strong&gt;ms: 5 new milliseconds are needed to finish the complete run of the &lt;em&gt;init()&lt;/em&gt; function. This is then corresponding to the 15ms yellow block. As we’re freeing the main thread, it can now start to dequeue the saved requests.&lt;/p&gt;

&lt;p&gt;- from &lt;strong&gt;15&lt;/strong&gt; to &lt;strong&gt;23&lt;/strong&gt;ms: the browser starts by running the &lt;em&gt;handleMouseClock()&lt;/em&gt; event which runs during 8ms (the blue block).&lt;/p&gt;

&lt;p&gt;- from &lt;strong&gt;23&lt;/strong&gt; to &lt;strong&gt;25&lt;/strong&gt; ms: as a side effect, the &lt;em&gt;timerTask()&lt;/em&gt; function which was scheduled to be run on the 20ms timeframe is slightly shifted of 3ms. The other scheduled frames (30ms, 40ms, etc.) are respected as there is no more code taking some CPU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; this sample and the above diagram (in SVG or PNG via a feature detection mechanism) were inspired by the following article: &lt;a title="http://www.javascriptbank.com/html5-web-workers-multithreading-in-javascript.html" href="http://xebee.xebia.in/2010/11/02/multithreading-in-javascript-with-web-workers/"&gt;HTML5 Web Workers Multithreading in JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, all these tips don’t really solve our initial problem: everything keeps being executed inside the main UI thread.&lt;/p&gt;

&lt;p&gt;Moreover, even if JavaScript weren’t used in the past for the same kind of applications like the so-called “high level languages”, it starts to change lastly thanks to the new possibilities offered by HTML5 and its friends. It was then more than important to provide to JavaScript some new powers to make it ready building a new generation of applications being able to leverage parallel tasks. This is exactly what the Web Workers were made for.&lt;/p&gt;

&lt;h2 id="webworkers"&gt;Web Workers or how to be executed out of the UI Thread&lt;/h2&gt;

&lt;p&gt;The &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/complete/workers.html"&gt;Web Workers APIs&lt;/a&gt; define a way to run script in the background. We will then be able to execute some tasks in threads living outside the main page and thus non-impacting the drawing performance. However, in the same way that we know that not all algorithms can be parallelized, not all JavaScript code can take advantage of workers. Ok, enough blah blah, let’s have a look to those famous workers.&lt;/p&gt;

&lt;h3 id="firstwebworker"&gt;My 1st Web Worker&lt;/h3&gt;

&lt;p&gt;As Web Workers will be executed on separated threads, you need to host their code into separated files from the main page. Once done, you need to instantiate a Worker object to call them:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;myHelloWorker = &lt;span style="color: blue"&gt;new &lt;/span&gt;Worker(&lt;span style="color: maroon"&gt;'helloworkers.js'&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;You’ll then start the worker (and thus a thread under Windows) by sending it a first message:&lt;/p&gt;

&lt;pre class="code"&gt;myHelloWorker.postMessage();&lt;/pre&gt;

&lt;p&gt;Indeed, the Web Workers and the main page are communicating via messages. Those messages can be formed with normal strings or JSON objects. To illustrate simple messages posting, we're going to start by reviewing a very basic sample. It will post a string to a worker that will simply concatenate it with something else. To do that, add the following code into the “&lt;em&gt;helloworker.js&lt;/em&gt;” file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;messageHandler(event) {
    &lt;span style="color: #006400"&gt;// Accessing to the message data sent by the main page
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageSent = event.data;
    &lt;span style="color: #006400"&gt;// Preparing the message that we will send back
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageReturned = &lt;span style="color: maroon"&gt;&amp;quot;Hello &amp;quot; &lt;/span&gt;+ messageSent + &lt;span style="color: maroon"&gt;&amp;quot; from a separate thread!&amp;quot;&lt;/span&gt;;
    &lt;span style="color: #006400"&gt;// Posting back the message to the main page
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.postMessage(messageReturned);
}

&lt;span style="color: #006400"&gt;// Defining the callback function raised when the main page will call us
&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.addEventListener(&lt;span style="color: maroon"&gt;'message'&lt;/span&gt;, messageHandler, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;We’ve just defined inside “&lt;em&gt;helloworkers.js&lt;/em&gt;” a piece of code that will be executed on another thread. It can receive messages from your main page, do some tasks on it and send a message back to your page in return. We then need to write the receiver in the main page. Here is the page that will handle that:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Hello Web Workers&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;output&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color: #006400"&gt;// Instantiating the Worker
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;myHelloWorker = &lt;span style="color: blue"&gt;new &lt;/span&gt;Worker(&lt;span style="color: maroon"&gt;'helloworkers.js'&lt;/span&gt;);
        &lt;span style="color: #006400"&gt;// Getting ready to handle the message sent back
        // by the worker
        &lt;/span&gt;myHelloWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;message&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
            document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;output&amp;quot;&lt;/span&gt;).textContent = event.data;
        }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

        &lt;span style="color: #006400"&gt;// Starting the worker by sending a first message
        &lt;/span&gt;myHelloWorker.postMessage(&lt;span style="color: maroon"&gt;&amp;quot;David&amp;quot;&lt;/span&gt;);

        &lt;span style="color: #006400"&gt;// Stopping the worker via the terminate() command
        &lt;/span&gt;myHelloWorker.terminate();
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;span style="color: blue"&gt;&lt;/span&gt;

&lt;p&gt;The result will the be: “&lt;em&gt;Hello David from a separate thread!&lt;/em&gt;”. You’re now impressed, aren’t you? &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/5140.wlEmoticon_2D00_winkingsmile_5F00_6C9071D3.png" /&gt;&lt;/p&gt;

&lt;p&gt;The worker will live until you kill it. Beware of that. As they are not automatically garbage collected, it’s up to you to control their states. Moreover, keep in mind that instantiating a worker will have some memory cost and don’t negligate the cold start time neither. To stop a worker, there are 2 possible solutions: &lt;/p&gt;

&lt;p&gt;1 – from the main calling page by calling the &lt;em&gt;&lt;strong&gt;terminate()&lt;/strong&gt;&lt;/em&gt; command. 

  &lt;br /&gt;2 – from the worker itself via the &lt;em&gt;&lt;strong&gt;close()&lt;/strong&gt;&lt;/em&gt; command.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#800080"&gt;DEMO&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;: You can test this slightly enhanced sample in your browser here -&amp;gt; &lt;a title="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm" href="http://david.blob.core.windows.net/html5/HelloWebWorkers_EN.htm"&gt;http://david.blob.core.windows.net/html5/HelloWebWorkers_EN.htm&lt;/a&gt; &amp;lt;-&lt;/p&gt;

&lt;h3 id="json"&gt;Posting messages using JSON&lt;/h3&gt;

&lt;p&gt;Of course, most of the time we will send some more structurated data to the workers. By the way, Web Workers can also communicate between each others using &lt;a href="http://www.w3.org/TR/webmessaging/#messagechannel"&gt;Message channels&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;But the only way to send some structurated messages to a worker is to use the JSON format. Hopefully, browsers that currently support Web Workers are nice enough to also natively support JSON. How kind they are!&lt;/p&gt;

&lt;p&gt;Let’s then take our previous code sample. We’re going to add an object of type &lt;em&gt;WorkerMessage. &lt;/em&gt;This type will be used to send some commands with parameters to our Web Workers. &lt;/p&gt;

&lt;p&gt;Let’s use now the following simplified &lt;em&gt;HelloWebWorkersJSON_EN.htm&lt;/em&gt; web page:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Hello Web Workers JSON&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=inputForWorker /&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=btnSubmit&amp;gt;&lt;/span&gt;Send to the worker&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=killWorker&amp;gt;&lt;/span&gt;Stop the worker&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;output&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;HelloWebWorkersJSON.js&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We’re using here the &lt;a title="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript" href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;Unobtrusive JavaScript&lt;/a&gt; approach which helps us dissociating the view from the attached logic. The attached logic is then living inside this &lt;em&gt;HelloWebWorkersJSON_EN.js &lt;/em&gt;file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// HelloWebWorkersJSON_EN.js associated to HelloWebWorkersJSON_EN.htm

// Our WorkerMessage object will be automatically
// serialized and de-serialized by the native JSON parser
&lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;WorkerMessage(cmd, parameter) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.cmd = cmd;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.parameter = parameter;
}

&lt;span style="color: #006400"&gt;// Output div where the messages sent back by the worker will be displayed
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;_output = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;output&amp;quot;&lt;/span&gt;);

&lt;span style="color: #006400"&gt;/* Checking if Web Workers are supported by the browser */
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(window.Worker) {
    &lt;span style="color: #006400"&gt;// Getting references to the 3 other HTML elements
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;_btnSubmit = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;btnSubmit&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;_inputForWorker = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;inputForWorker&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;_killWorker = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;killWorker&amp;quot;&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// Instantiating the Worker
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;myHelloWorker = &lt;span style="color: blue"&gt;new &lt;/span&gt;Worker(&lt;span style="color: maroon"&gt;'helloworkersJSON_EN.js'&lt;/span&gt;);
    &lt;span style="color: #006400"&gt;// Getting ready to handle the message sent back
    // by the worker
    &lt;/span&gt;myHelloWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;message&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
        _output.textContent = event.data;
    }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// Starting the worker by sending it the 'init' command
    &lt;/span&gt;myHelloWorker.postMessage(&lt;span style="color: blue"&gt;new &lt;/span&gt;WorkerMessage(&lt;span style="color: maroon"&gt;'init'&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;));

    &lt;span style="color: #006400"&gt;// Adding the OnClick event to the Submit button
    // which will send some messages to the worker
    &lt;/span&gt;_btnSubmit.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
        &lt;span style="color: #006400"&gt;// We're now sending messages via the 'hello' command 
        &lt;/span&gt;myHelloWorker.postMessage(&lt;span style="color: blue"&gt;new &lt;/span&gt;WorkerMessage(&lt;span style="color: maroon"&gt;'hello'&lt;/span&gt;, _inputForWorker.value));
    }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// Adding the OnClick event to the Kill button
    // which will stop the worker. It won't be usable anymore after that.
    &lt;/span&gt;_killWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
        &lt;span style="color: #006400"&gt;// Stopping the worker via the terminate() command
        &lt;/span&gt;myHelloWorker.terminate();
        _output.textContent = &lt;span style="color: maroon"&gt;&amp;quot;The worker has been stopped.&amp;quot;&lt;/span&gt;;
    }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);
}
&lt;span style="color: blue"&gt;else &lt;/span&gt;{
    _output.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Web Workers are not supported by your browser. Try with IE10: &amp;lt;a href=\&amp;quot;http://ie.microsoft.com/testdrive\&amp;quot;&amp;gt;download the latest IE10 Platform Preview&amp;lt;/a&amp;gt;&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;At last, here is the code for the web worker contained in &lt;em&gt;helloworkerJSON_EN.js &lt;/em&gt;the file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;messageHandler(event) {
    &lt;span style="color: #006400"&gt;// Accessing to the message data sent by the main page
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageSent = event.data;

    &lt;span style="color: #006400"&gt;// Testing the command sent by the main page
    &lt;/span&gt;&lt;span style="color: blue"&gt;switch &lt;/span&gt;(messageSent.cmd) {
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: maroon"&gt;'init'&lt;/span&gt;:
            &lt;span style="color: #006400"&gt;// You can initialize here some of your models/objects
            // that will be used later on in the worker (but pay attention to the scope!)
            &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: maroon"&gt;'hello'&lt;/span&gt;:
            &lt;span style="color: #006400"&gt;// Preparing the message that we will send back
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageReturned = &lt;span style="color: maroon"&gt;&amp;quot;Hello &amp;quot; &lt;/span&gt;+ messageSent.parameter + &lt;span style="color: maroon"&gt;&amp;quot; from a separate thread!&amp;quot;&lt;/span&gt;;
            &lt;span style="color: #006400"&gt;// Posting back the message to the main page
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.postMessage(messageReturned);
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;
    }
}

&lt;span style="color: #006400"&gt;// Defining the callback function raised when the main page will call us
&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.addEventListener(&lt;span style="color: maroon"&gt;'message'&lt;/span&gt;, messageHandler, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Once again, this sample is very basic. Still, it should help you to understand the underlying logic. For instance, nothing prevents you to use the same approach to send to a worker some gaming elements that will be handled by an AI or physics engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#800080"&gt;DEMO&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;: You can test this JSON sample here: -&amp;gt; &lt;a title="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm" href="http://david.blob.core.windows.net/html5/HelloWebWorkersJSON_EN.htm"&gt;http://david.blob.core.windows.net/html5/HelloWebWorkersJSON_EN.htm&lt;/a&gt; &amp;lt;-&lt;/p&gt;

&lt;h2 id="browserssupport"&gt;Browsers support &lt;a title="browserslogos by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5910079454/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="browserslogos" src="http://farm6.static.flickr.com/5075/5910079454_91a45b5f12_t.jpg" width="100" height="19" /&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Web Workers have just arrived in the &lt;a href="http://ie.microsoft.com/testdrive/"&gt;IE10 PP2 (Platform Preview)&lt;/a&gt;. This is also supported by Firefox (since 3.6), Safari (since 4.0), Chrome &amp;amp; Opera 11. However, this is not supported by the mobile versions of these browsers. If you’d like to have a more detailed support matrix, have a look here: &lt;a href="http://caniuse.com/#search=worker"&gt;http://caniuse.com/#search=worker&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In order to dynamically know in your code that this feature is supported, please use the a &lt;strong&gt;feature detection&lt;/strong&gt; mechanism. You shouldn’t use anymore some user-agent sniffing!&lt;/p&gt;

&lt;p&gt;To help you, there are 2 available solutions. The first one is to simply test the feature yourself using this very simple piece of code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;/* Checking if Web Workers are supported by the browser */
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(window.Worker) {
    &lt;span style="color: #006400"&gt;// Code using the Web Workers
&lt;/span&gt;}&lt;/pre&gt;

&lt;p&gt;The second one is to use the famous &lt;a href="http://www.modernizr.com"&gt;Modernizr&lt;/a&gt; library (now natively shipped with the ASP.NET MVC3 project templates). Then, simply use a code like that:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
    var &lt;/span&gt;divWebWorker = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;webWorkers&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Modernizr.webworkers) {
        divWebWorker.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Web Workers ARE supported&amp;quot;&lt;/span&gt;;
    }
    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
        divWebWorker.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Web Workers ARE NOT supported&amp;quot;&lt;/span&gt;;
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Here is for instance the current support in your browser: &lt;span id="leDivWebWorker"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This will allow you to expose 2 versions of your application. If Web Workers &lt;strong&gt;are&lt;/strong&gt; &lt;strong&gt;not&lt;/strong&gt; supported, you will simply execute your JavaScript code as usual. If Web Workers &lt;strong&gt;are&lt;/strong&gt; supported, you will be able to push some of the JavaScript code to the workers to enhance the performance of your applications for the most recent browsers. You won’t then break anything or build a specific version only for the very latest browsers. It will work for all browsers with some performance differences. &lt;/p&gt;

&lt;h2 id="elements"&gt;Non accessible elements from a worker&lt;/h2&gt;

&lt;p&gt;Rather than looking to what you don’t have access from workers, let’s rather take a look to what you’ve &lt;strong&gt;only&lt;/strong&gt; have access to. For that, please have check the table from our MSDN Documentation: &lt;a title="http://msdn.microsoft.com/fr-fr/ie/hh272905.aspx#_HTML5WebWorker" href="http://msdn.microsoft.com/fr-fr/ie/hh272905.aspx#_HTML5WebWorker"&gt;HTML5 Web Worker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the short version is: you &lt;strong&gt;&lt;font color="#d90000"&gt;don’t have access to the DOM&lt;/font&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The &lt;a title="http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx" href="http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx"&gt;Web Workers in IE10: Background JavaScript Makes Web Apps Faster&lt;/a&gt; article from our IE Blog has a very good diagram summarizing that:&lt;/p&gt;

&lt;p&gt;&lt;a title="20110701-wwiibjmwaf-image2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5905343545/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="20110701-wwiibjmwaf-image2" src="http://farm7.static.flickr.com/6059/5905343545_14ef21238e.jpg" width="500" height="326" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, as you don’t have access to the &lt;em&gt;window &lt;/em&gt;object from a worker, you won’t be able to access to the Local Storage (which any way doesn’t seem to be thread-safe). Those limitations may look too constraint for developers used to multithreaded operations in other environments. However, the big advantage is not to fall into the same problems we usually encounter: lock, races conditions, etc. We won’t have to think about that with web workers. This then makes the web workers something very accessible while allowing some interesting performance boosts in specific scenarios. &lt;/p&gt;

&lt;h2 id="debugging"&gt;Errors handling &amp;amp; debugging&lt;/h2&gt;

&lt;p&gt;It is very easy to handle errors raised from your Web Workers.&amp;#160; You simply have to subscribe to the &lt;em&gt;OnError&lt;/em&gt; event in the same way we’ve done it with the &lt;em&gt;OnMessage&lt;/em&gt; event:&lt;/p&gt;

&lt;pre class="code"&gt;myWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;error&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
    _output.textContent = event.data;
}, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;This is the best Web Workers can give you natively to help you debugging their code… This is very limited, isn’t it?&lt;/p&gt;

&lt;h3 id="f12"&gt;The F12 development bar for a better debugging experience&lt;/h3&gt;

&lt;p&gt;To go beyond that, &lt;strong&gt;IE10 offers you to directly debug the code of your Web Workers inside its script debugger&lt;/strong&gt; like any other script. &lt;/p&gt;

&lt;p&gt;For that, you need to launch the development bar via the F12 key and navigate to the “&lt;em&gt;Script&lt;/em&gt;” tab. You shouldn’t see the JS file associated to your worker yet. But right after pressing the “&lt;em&gt;Start debugging&lt;/em&gt;” button, it should magically be displayed: &lt;/p&gt;

&lt;p&gt;&lt;a title="F12DebugWorker001 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5909471248/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="F12DebugWorker001" src="http://farm6.static.flickr.com/5116/5909471248_37ced53c67_b.jpg" width="1024" height="192" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next step is then to simply debug your worker like you’re used to debug your classic JavaScript code!&lt;/p&gt;

&lt;p&gt;&lt;a title="DebugWebWorkersF12 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5940436762/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="DebugWebWorkersF12" src="http://farm7.static.flickr.com/6131/5940436762_fb91159416_z.jpg" width="640" height="353" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IE10 is currently the only browser offering you that. If you want to know more about this feature, you can read this detailed article: &lt;a title="http://blogs.msdn.com/b/ie/archive/2011/07/12/debugging-web-workers-in-ie10.aspx" href="http://blogs.msdn.com/b/ie/archive/2011/07/12/debugging-web-workers-in-ie10.aspx"&gt;Debugging Web Workers in IE10&lt;/a&gt;&lt;/p&gt;

&lt;h3 id="consolelog"&gt;An interesting solution to mimic console.log() &lt;/h3&gt;

&lt;p&gt;At last, you need to know that the &lt;strong&gt;&lt;em&gt;console&lt;/em&gt; object is not available&lt;/strong&gt; within a worker. Thus, if you need to trace what’s going on inside the worker via the &lt;em&gt;.log()&lt;/em&gt; method, it won’t work as the &lt;em&gt;console&lt;/em&gt; object won’t be defined. Hopefully, I’ve found an interesting sample that &lt;strong&gt;mimic the console.log()&lt;/strong&gt; behavior by using the &lt;em&gt;MessageChannel&lt;/em&gt;: &lt;a title="http://www.davidflanagan.com/2011/01/consolelog-for.html" href="http://www.davidflanagan.com/2011/01/consolelog-for.html"&gt;console.log() for Web Workers&lt;/a&gt;. This works well inside IE10, Chrome &amp;amp; Opera but not in Firefox as it doesn’t support the &lt;em&gt;MessageChannel&lt;/em&gt; yet. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; in order to make the sample from this link working fine in IE10, you need to change this line of code:&lt;/p&gt;

&lt;pre class="code"&gt;console.log.apply(console, args); &lt;span style="color: #006400"&gt;// Pass the args to the real log
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;By this one:&lt;/p&gt;

&lt;pre class="code"&gt;console.log(args); &lt;span style="color: #006400"&gt;// Pass the args to the real log
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Then, you should be able to obtain such results:&lt;/p&gt;

&lt;p&gt;&lt;a title="DebugWebWorkersF12Console by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5939882031/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="DebugWebWorkersF12Console" src="http://farm7.static.flickr.com/6010/5939882031_0300ebe55b_z.jpg" width="640" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#800080"&gt;DEMO&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;: If you want to try this &lt;em&gt;console.log() &lt;/em&gt;simulation: -&amp;gt; &lt;a title="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm" href="http://david.blob.core.windows.net/html5/HelloWebWorkersJSONdebug_EN.htm"&gt;http://david.blob.core.windows.net/html5/HelloWebWorkersJSONdebug_EN.htm&lt;/a&gt; &amp;lt;-&lt;/p&gt;

&lt;h2 id="scenarios"&gt;Use cases and how to identify potential candidates&lt;/h2&gt;

&lt;h3 id="usages"&gt;Web Workers for which scenarios?&lt;/h3&gt;

&lt;p&gt;When you browse the web looking for sample usages of the Web Workers, you always find the same kind of demos: intensive mathematical/scientific computation. You’ll then find some JavaScript raytracers, fractals, prime numbers, and stuff like that. Nice demos to understand the way workers works but this gives us few concrete perspectives on how to use them in “real world” applications. &lt;/p&gt;

&lt;p&gt;It’s true that the limitations we’ve seen above on the resources available inside web workers narrow down the number of interesting scenarios. Still, if you just take some time to think about it, you’ll start to see new interesting usages:&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;image processing&lt;/strong&gt; by using the data extracted from the &amp;lt;canvas&amp;gt; or the &amp;lt;video&amp;gt; elements. You can divide the image into several zones and push them to the different workers that will work in parallel. You’ll then benefit from the new generation of multi-cores CPUs. The more you have, the fastest you’ll go. 

  &lt;br /&gt;- &lt;strong&gt;big amount of data &lt;/strong&gt;retrieved that you need to parse after an XMLHTTPRequest call. If the time needed to process this data is important, you’d better do it in background inside a web worker to avoid freezing the UI Thread. You’ll then keep a reactive application. 

  &lt;br /&gt;- &lt;strong&gt;background text analysis&lt;/strong&gt;: as we have potentially more CPU time available when using the web workers, we can now think about new scenarios in JavaScript. For instance, we could imagine parsing in real-time what the user is currently typing without impacting the UI experience. Think about an application like Word (of our Office Web Apps suite) leveraging such possibility: background search in dictionaries to help the user while typing, automatic correction, etc.&amp;#160; &lt;br /&gt;- &lt;strong&gt;concurrent requests against a local database&lt;/strong&gt;. IndexDB will allow what the Local Storage can’t offer us: a thread-safe storage environment for our Web Workers. &lt;/p&gt;

&lt;p&gt;Moreover, if you switch to the video game world, you can think about pushing the AI or physics engines to the Web Workers. For instance, I’ve found this experimentation: &lt;a title="http://extremelysatisfactorytotalitarianism.com/blog/?p=932" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=932"&gt;On Web Workers, GWT, and a New Physics Demo&lt;/a&gt; which use the &lt;a href="http://box2d-js.sourceforge.net/"&gt;Box2D physic engine&lt;/a&gt; with workers. For your Artificial Intelligence engine, this means also that you will be able in the same timeframe to process more data (anticipate more moves in a chess game for instance).&lt;/p&gt;

&lt;p&gt;Some of my colleagues may now argue that the only limit is your imagination! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smilewithtongueout" alt="Tire la langue" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/8182.wlEmoticon_2D00_smilewithtongueout_5F00_6FC259BB.png" /&gt;&lt;/p&gt;

&lt;p&gt;But in a general manner, as long as you don’t need the DOM, any time consuming JavaScript code that may impact the user experience is a good candidate for the web workers. However, you need to pay attention to 3 points while using the workers:&lt;/p&gt;

&lt;p&gt;1 – The initializing time and the communication time with the worker shouldn’t be superiors to the processing itself 
  &lt;br /&gt;2 – The memory cost of using several workers 

  &lt;br /&gt;3 – The dependency of the code blocks between them as you may then need some synchronization logic. Parallelization is not something easy my friends!&lt;/p&gt;

&lt;p&gt;On our side, we’ve recently published the demo named &lt;a href="http://ie.microsoft.com/testdrive/Graphics/WorkerFountains/Default.html"&gt;Web Workers Fountains&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a title="Web Workers Fountains by Internet Explorer 10" href="http://ie.microsoft.com/testdrive/Graphics/WorkerFountains/Default.html"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Web Workers Fountains" src="http://farm6.static.flickr.com/5078/5915109760_eb2d9a53d6.jpg" width="500" height="199" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This demo displays some particles effects (the fountains) and uses 1 web worker per fountain to try to compute the particles in the fastest way possible. Each worker result is then aggregated to be displayed inside the &amp;lt;canvas&amp;gt; element. Web Workers can also exchange messages between them via the &lt;a href="http://www.w3.org/TR/webmessaging/#messagechannel"&gt;Message Channels&lt;/a&gt;. In this demo, this is used to ask to each of the workers when to change the color of the fountains. We’re then looping through this array of colors: red, orange, yellow, green, blue, purple and pink thanks to the Message Channels. If you’re interesting into the details, jump into the &lt;em&gt;LightManager()&lt;/em&gt; function of the &lt;em&gt;Demo3.js&lt;/em&gt; file. &lt;/p&gt;

&lt;p&gt;Feel free also to launch this demo inside &lt;a href="http://ie.microsoft.com/testdrive/Info/Downloads/Default.html"&gt;Internet Explorer 10&lt;/a&gt;, it’s funny to play with! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1104.wlEmoticon_2D00_smile_5F00_78C3CF8D.png" /&gt;&lt;/p&gt;

&lt;h3 id="profiling"&gt;How to identity hot spots in your code&lt;/h3&gt;

&lt;p&gt;To track the bottlenecks and identity which parts of your code you could send to the web workers, you can use the script profiler available with the F12 bar of IE9/10. It will then help you to identify your hot spots. However, identifying a hot spot doesn’t mean you’ve identified a good candidate for web workers. To better understand that, let’s review together 2 different interesting cases.&lt;/p&gt;

&lt;h4 id="case1"&gt;Case 1: &amp;lt;canvas&amp;gt; animation with the Speed Reading demo &lt;/h4&gt;

&lt;p&gt;This demo comes from our &lt;a href="http://ie.microsoft.com/testdrive/"&gt;IE Test Drive&lt;/a&gt; center and can be browsed directly here: &lt;a title="http://ie.microsoft.com/testdrive/Performance/SpeedReading/Default.html" href="http://ie.microsoft.com/testdrive/Performance/SpeedReading/Default.html"&gt;Speed Reading&lt;/a&gt;. It tries to display as fast as possible some characters using the &amp;lt;canvas&amp;gt; element. The goal is to stress the quality of the implementation of the hardware acceleration layer of your browser. But going beyond that, would it be possible to obtain more performance by splitting some operations on threads? We need to achieve some analysis to check that.&lt;/p&gt;

&lt;p&gt;If you run this demo inside IE9/10, you can also start the profiler during a couple of seconds. Here is the kind of results you’ll obtain:&lt;/p&gt;

&lt;p&gt;&lt;a title="ProfilingF12SpeedReading by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5939882321/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="ProfilingF12SpeedReading" src="http://farm7.static.flickr.com/6020/5939882321_ca7f2f0585.jpg" width="417" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re sorting the time consuming functions in decreasing order, you’ll clearly see those functions coming first: &lt;em&gt;DrawLoop()&lt;/em&gt;, &lt;em&gt;Draw()&lt;/em&gt; and &lt;em&gt;drawImage()&lt;/em&gt;. If you’re double-clicking on the &lt;em&gt;Draw&lt;/em&gt; line, you’ll jump into the code of this method. You’ll then observe several calls of this type:&lt;/p&gt;

&lt;pre class="code"&gt;surface.drawImage(imgTile, 0, 0, 70, 100, this.left, this.top, this.width, this.height); &lt;/pre&gt;

&lt;p&gt;Where the &lt;em&gt;surface&lt;/em&gt; object is referencing a &amp;lt;canvas&amp;gt; element. &lt;/p&gt;

&lt;p&gt;A quick conclusion of this brief analysis is that this demo spends most of its time drawing inside the Canvas through the &lt;em&gt;drawImage()&lt;/em&gt; method. As the &amp;lt;canvas&amp;gt; element is not accessible from a web worker, we won’t be able to offload this time consuming task to different threads (we could have imagined some ways of handling the &amp;lt;canvas&amp;gt; element in a concurrency manner for instance). This demo is then not a good candidate for the parallelization possibilities offered by the web workers.&lt;/p&gt;

&lt;p&gt;But it’s well illustrating the process you need to put in place. If, after some profiling job, you’re discovering that the major part of the time consuming scripts are deeply linked to DOM objects, the web workers won’t be able to help you boosting the performance of your web app. &lt;/p&gt;

&lt;h4 id="case2"&gt;Case 2: Raytracers inside &amp;lt;canvas&amp;gt;&lt;/h4&gt;

&lt;p&gt;Let’s now take another easy example to understand. Let’s take a raytracer like this one: &lt;a title="http://labs.flog.co.nz/raytracer/" href="http://labs.flog.co.nz/raytracer/"&gt;Flog.RayTracer Canvas Demo&lt;/a&gt;. A raytracer uses some very CPU intensive mathematical computations in order to simulate the path of &lt;font color="#000000"&gt;light&lt;/font&gt;. The idea is to simulate some effects like reflection, refraction, materials, etc.&lt;/p&gt;

&lt;p&gt;Let’s render a scene while launching the script profiler, you should obtain something like that:&lt;/p&gt;

&lt;p&gt;&lt;a title="ProfilingF12RayTracer by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5939882569/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="ProfilingF12RayTracer" src="http://farm7.static.flickr.com/6133/5939882569_2b3a0c600a.jpg" width="357" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, if we sort the functions in a decreasing order, 2 functions clearly seem to take most of the time: &lt;em&gt;renderScene()&lt;/em&gt; and &lt;em&gt;getPixelColor().&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The goal of the &lt;em&gt;getPixelColor()&lt;/em&gt; method is to compute the current pixel. Indeed, ray-tracing is rendering a scene pixel per pixel. This &lt;em&gt;getPixelColor()&lt;/em&gt; method is then calling the &lt;em&gt;rayTrace()&lt;/em&gt; method in charge of rendering the shadows, ambient light, etc. This is the core of our application. And if you’re reviewing the code of the &lt;em&gt;rayTrace()&lt;/em&gt; function, you’ll see that it’s 100% pure JavaScript juice. This code has no DOM dependency. Well, I think you’ll get it: this sample is a very good candidate to parallelization. Moreover, we can easily split the image rendering on several threads (and thus potentially on several CPUs) as there’s no synchronization needed between each pixel computation. Each pixel operation is independent from its neighborhood as no anti-aliasing is used in this demo. &lt;/p&gt;

&lt;p&gt;This is not then a surprise if we can find some raytracers samples using some web workers like this one: &lt;a title="http://nerget.com/rayjs-mt/rayjs.html" href="http://nerget.com/rayjs-mt/rayjs.html"&gt;http://nerget.com/rayjs-mt/rayjs.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;After profiling this raytracer using IE10, we can see the important differences between using no worker and using 4 workers:&lt;/p&gt;

&lt;p&gt;&lt;a title="RayTracersWebWorkersIE10 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5912647611/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="RayTracersWebWorkersIE10" src="http://farm7.static.flickr.com/6034/5912647611_a6c2f2094a.jpg" width="500" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first screenshot, the &lt;em&gt;processRenderCommand()&lt;/em&gt; method is using almost all of the CPU available and the scene is rendered in &lt;strong&gt;2.854s&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With 4 web workers, the &lt;em&gt;processRenderCommand()&lt;/em&gt; method is executed in parallel on 4 different threads. We can even see their Worker Id on the right column. The scene is rendered this time in &lt;strong&gt;1.473s&lt;/strong&gt;. The benefits were real: the scene has been rendered 2 times faster. &lt;/p&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;There is no magical or new concepts linked to the web workers in the way to review/architect your JavaScript code for parallel execution. You need to isolate the intensive part of your code. It needs to be relatively independent of the rest of your page’s logic to avoid waiting for synchronization tasks. And the most important part: the code shouldn’t be linked to the DOM. If all these conditions are met, think about the web workers. They could definitely help you boosting the general performance of your web app!&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;

&lt;p&gt;PS : All the samples of this article are available in this ZIP file: &lt;a title="https://david.blob.core.windows.net/html5/WebWorkersSamples.zip" href="https://david.blob.core.windows.net/html5/WebWorkersSamples.zip"&gt;https://david.blob.core.windows.net/html5/WebWorkersSamples.zip&lt;/a&gt; . &lt;/p&gt;
&lt;script src="http://david.blob.core.windows.net/html5/modernizr-1.7.min.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;
    var imgSingle = document.getElementById("imgSingleThread");
    var divWebWorker = document.getElementById("leDivWebWorker");
    if (Modernizr.svg) {
        imgSingle.src = "http://david.blob.core.windows.net/html5/SVGSingleThreadJS_EN.svg";

    }
    else {
        imgSingle.src = "http://david.blob.core.windows.net/html5/SVGSingleThreadJS_EN.png";
    }
    if (Modernizr.webworkers) {
        divWebWorker.innerHTML = "Web Workers &lt;strong&gt;are&lt;/strong&gt; supported inside your browser.";
	divWebWorker.style.color = "green";
    }
    else {
        divWebWorker.innerHTML = "Web Workers &lt;strong&gt;are not&lt;/strong&gt; supported inside your browser.";
	divWebWorker.style.color = "red";
    }
&lt;/script&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10186905" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/WebWorkers/">WebWorkers</category></item><item><title>Introduction aux Web Workers d’HTML5 : le multithreading version JavaScript</title><link>http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx</link><pubDate>Fri, 08 Jul 2011 09:55:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10184529</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10184529</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction-aux-web-workers-d-html5-le-multithreading-version-javascript.aspx#comments</comments><description>&lt;p&gt;Une application HTML5 s’écrit bien entendu en JavaScript. Or, par rapport aux autres modèles de développements connus (clients lourds avec .NET/C++ ou même avec Silverlight), &lt;strong&gt;JavaScript&lt;/strong&gt; dispose historiquement d’une limitation importante : &lt;strong&gt;toute son exécution s’effectue dans un seul et même thread&lt;/strong&gt;. C’est plutôt ballot à l’heure des processeurs multi-cœurs comme les Core i5/i7 proposant jusqu’à 8 cœurs logiques voire même les derniers processeurs mobiles ARM double voire quadri-cœurs. Heureusement, nous allons voir qu’HTML5 nous propose une solution pour mieux exploiter ces nouvelles petites puces.&lt;/p&gt; &lt;a title="Web Workers" href="http://www.flickr.com/photos/60699397@N08/5915082556/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Illustration : the Web Workers in action" align="right" src="http://farm6.static.flickr.com/5319/5915082556_655647d1f7.jpg" width="410" height="309" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;&lt;a href="#exposeprobleme"&gt;Exposé du problème&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#webworkers"&gt;Web Workers ou comment sortir de l'UI Thread&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="#premierwebworker"&gt;Mon 1er Web Worker&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;&lt;a href="#json"&gt;Echanges à travers JSON&lt;/a&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#supportnavigateurs"&gt;Support dans les navigateurs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#elements"&gt;Les éléments non accessibles depuis un worker&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#debugging"&gt;Gérer les erreurs et le debugging&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="#f12"&gt;La barre de développement F12 pour le debug&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;&lt;a href="#consolelog"&gt;Une solution pour avoir console.log()&lt;/a&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#scenarios"&gt;Scénarios d’usages et comment identifier le code candidat&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="#usages"&gt;Web Workers pour quels usages ?&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;&lt;a href="#profiling"&gt;Comment identifier les points chauds dans son code&lt;/a&gt;           &lt;ul&gt;           &lt;li&gt;&lt;a href="#exemple1"&gt;Exemple 1 : animation dans canvas avec Speed Reading&lt;/a&gt; &lt;/li&gt;            &lt;li&gt;&lt;a href="#exemple2"&gt;Exemple 2 : Raytracer dans canvas&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="#ressources"&gt;Ressources complémentaires&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h2 id="exposeprobleme"&gt;Exposé du problème&lt;/h2&gt;  &lt;p&gt;Cette limitation historique de JavaScript implique qu’un traitement important va bloquer la fenêtre principale d’affichage (la page web en cours d’utilisation). On dit souvent dans le jargon des développeurs que l’on bloque ainsi le “&lt;strong&gt;UI Thread&lt;/strong&gt;”, le thread qui est dédié à l’affichage et au rafraichissement de celui-ci. Nous connaissons tous les conséquences d’une telle mauvaise pratique : la page se fige et l’utilisateur ne peut plus interagir avec l’application. Conséquence : l’expérience utilisateur est bien entendue très mauvaise et ce dernier finit naturellement par tuer l’onglet ou l’instance du navigateur en cours. Cela n’était surement pas le résultat que vous souhaitiez obtenir !&lt;/p&gt;  &lt;p&gt;Par ailleurs, les navigateurs disposent d'un système de protection pour avertir l’utilisateur qu’un script prends trop de temps à s’exécuter. Malheureusement, ce dernier ne différentie pas les cas où le script est effectivement mal écrit des cas où le script a réellement besoin de temps pour finir son traitement. Sauf que comme il bloque le thread d’affichage, on préfère vous prévenir avec ce genre de messages (issus de Firefox 5 et IE9) :&lt;/p&gt;  &lt;p&gt;&lt;a title="WarningJSBrowsers by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5904556249/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="WarningJSBrowsers" src="http://farm7.static.flickr.com/6057/5904556249_395aee143a.jpg" width="500" height="147" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a title="20110419-hrii-image5 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5905126041/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="20110419-hrii-image5" src="http://farm7.static.flickr.com/6041/5905126041_117c858cd6.jpg" width="500" height="38" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Cependant, jusqu’à présent, rares étaient les cas où cela nous posait vraiment problème pour 2 raisons :&lt;/p&gt;  &lt;p&gt;1 – HTML et JavaScript n’étaient pas utilisés de la même manière et dans le même but que les technologies capables d’effectuer des traitements multi-threadés. Les sites Web proposaient une expérience beaucoup moins riches que les applications de bureau.    &lt;br /&gt;2 – Il existait des techniques permettant plus ou moins de s’en sortir autrement.&lt;/p&gt;  &lt;p&gt;Ces techniques sont connues de tous les développeurs Web qui se débrouillent ainsi pour simuler des traitements parallèles grâce aux fonctions &lt;strong&gt;setTimeout&lt;/strong&gt;() ou &lt;strong&gt;setInterval&lt;/strong&gt;() par exemple. De la même manière, les appels HTTP se font de manières asynchrones via l’objet &lt;strong&gt;XMLHttpRequest&lt;/strong&gt;, ce qui évite ainsi de bloquer l’UI pendant le téléchargement de certaines ressources. Pour finir, l’utilisation des &lt;strong&gt;évènements du DOM&lt;/strong&gt; permet d’écrire des applications donnant l’illusion que plusieurs choses se passent en même temps. Illusion ? Oui, pour le comprendre regardons un exemple de code scolaire et tentons de comprendre ce qu’il se passe dans le navigateur :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
    function &lt;/span&gt;init(){
        { un code qui prends 5 ms à être exécuté } 
        un évènement de type mouseClickEvent est levé
        { un code qui prends 5 ms à être exécuté }
        setInterval(timerTask,&lt;span style="color: maroon"&gt;&amp;quot;10&amp;quot;&lt;/span&gt;);
        { un code qui prends 5 ms à être exécuté }
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;handleMouseClick(){
          un code qui prends 8 ms à être exécuté 
    }

    &lt;span style="color: blue"&gt;function &lt;/span&gt;timerTask(){
          un code qui prends 2 ms à être exécuté 
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Prenons ce code et projetons le sur un diagramme chargé de modéliser l’exécution dans le temps :&lt;/p&gt;

&lt;p&gt;&lt;img id="imgSingleThread" alt="Diagram illustrating single-threaded JavaScript" src="" /&gt;&lt;/p&gt;

&lt;p&gt;On voit bien sur ce diagramme la nature non-parallèle des traitements. En fait, le navigateur se contente d’enfiler dans une queue les différentes demandes d’exécution de code : &lt;/p&gt;

&lt;p&gt;- de &lt;strong&gt;0&lt;/strong&gt; à &lt;strong&gt;5&lt;/strong&gt; ms : la fonction &lt;em&gt;init()&lt;/em&gt; démarre en effet à 0 ms et commence par un traitement de 5 ms. Au bout de 5 ms, l’utilisateur déclenche un clic de souris. Cependant, la gestion de cet évènement ne peut être gérée car nous sommes toujours dans le bloc de la fonction &lt;em&gt;init()&lt;/em&gt; en train d’accaparer le thread principal. La demande de clic de souris est conservée mais sera gérée plus tard. &lt;/p&gt;

&lt;p&gt;- de &lt;strong&gt;5&lt;/strong&gt; à &lt;strong&gt;10&lt;/strong&gt; ms : la fonction&lt;em&gt; init() &lt;/em&gt;continue son traitement pendant 5 ms puis on demande à exécuter la fonction &lt;em&gt;timerTask()&lt;/em&gt; dans 10 ms. Cette fonction devrait donc logiquement être exécutée au à 20 ms sur l’échelle du temps. &lt;/p&gt;

&lt;p&gt;- de &lt;strong&gt;10&lt;/strong&gt; à &lt;strong&gt;15&lt;/strong&gt; ms : s’en suivent 5 nouvelles millisecondes de traitement pour terminer &lt;em&gt;init()&lt;/em&gt; ce qui constitue alors le 1er bloc jaune ininterrompu de 15 ms. Comme on libère le thread, ce dernier dépile alors les demandes. &lt;/p&gt;

&lt;p&gt;- de &lt;strong&gt;15&lt;/strong&gt; à &lt;strong&gt;23&lt;/strong&gt; ms : il commence par exécuter la fonction &lt;em&gt;handleMouseClick()&lt;/em&gt; qui dure 8 ms (le bloc bleu). &lt;/p&gt;

&lt;p&gt;- de &lt;strong&gt;23&lt;/strong&gt; à &lt;strong&gt;25&lt;/strong&gt; ms : du coup, la fonction&lt;em&gt; timerTask()&lt;/em&gt;, qui était programmée pour être exécutée sur la fenêtre des 20 ms sur l’échelle du temps, est légèrement décalée de 3 ms pour ensuite reprendre la programmation initiale (30 ms, 40 ms, etc.) puisqu’il n’y a pas de code qui reprend du CPU. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; cet exemple et le graphique ci-dessus (en SVG ou PNG par “feature detection”) a été inspiré de l’article suivant : &lt;a title="http://www.javascriptbank.com/html5-web-workers-multithreading-in-javascript.html" href="http://xebee.xebia.in/2010/11/02/multithreading-in-javascript-with-web-workers/"&gt;HTML5 Web Workers Multithreading in JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Donc au final, toutes ces techniques ne répondent pas réellement au problème initial : tout s’exécute malgré tout dans le thread principal. &lt;/p&gt;

&lt;p&gt;Par ailleurs, même si JavaScript n’était pas utilisé dans le même but que les technologies à base de langages dit de “haut niveau”, cela est entrain de changer ces derniers temps par les possibilités offertes par HTML5 et ses amis. Il a fallut donc doter JavaScript de nouvelles capacités pour le préparer à la réalisation d’applications plus riches et réellement parallèles. C’est justement le but des Web Workers.&lt;/p&gt;

&lt;h2 id="webworkers"&gt;Web Workers ou comment sortir de l’UI Thread&lt;/h2&gt;

&lt;p&gt;Les &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/complete/workers.html"&gt;APIs des Web Workers&lt;/a&gt; définissent justement un moyen d’exécuter des scripts en tâche de fond. Cela va donc vous permettre d’exécuter des traitements sur des threads séparés vivant donc à côté de la page principale et n’ayant pas d’impact sur ses performances d’affichage. Cependant, de la même manière que tous les algorithmes ne sont pas forcément parallèlisables, nous verrons que tout ne se prête pas à l’exécution via des workers. Allez, trêves de blabla. Regardons comment marche tout ça. &lt;/p&gt;

&lt;h3 id="premierwebworker"&gt;Mon 1er Web Worker&lt;/h3&gt;

&lt;p&gt;Comme les Web Workers vont être exécutés sur des threads séparés, il faut que leur code soit hébergé dans un fichier séparé de la page principale. Ensuite, pour les appeler, on instancie un objet de type Worker :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;monWorker = &lt;span style="color: blue"&gt;new &lt;/span&gt;Worker(&lt;span style="color: maroon"&gt;'lesuperworker.js'&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Puis, on démarre le worker (et donc un thread sous Windows), en lui envoyant un premier message :&lt;/p&gt;

&lt;pre class="code"&gt;monWorker.postMessage();&lt;/pre&gt;

&lt;p&gt;En effet, la manière de communiquer entre le Worker et la page principale se fait via l’utilisation de messages. Ces messages doivent être formés par des chaines de caractères classiques ou via des objets JSON. Pour illustrer le passage de messages, on va commencer par faire simple en envoyant une chaine au worker qui va simplement la concaténer avec autre chose. Pour cela, insérez ce code dans “helloworkers.js” :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;messageHandler(event) {
    &lt;span style="color: #006400"&gt;// On récupère le message envoyé par la page principale
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageSent = event.data;
    &lt;span style="color: #006400"&gt;// On prépare le message de retour
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageReturned = &lt;span style="color: maroon"&gt;&amp;quot;Bonjour &amp;quot; &lt;/span&gt;+ messageSent + &lt;span style="color: maroon"&gt;&amp;quot; depuis un thread séparé !&amp;quot;&lt;/span&gt;;
    &lt;span style="color: #006400"&gt;// On renvoit le tout à la page principale
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.postMessage(messageReturned);
}

&lt;span style="color: #006400"&gt;// On définit la fonction à appeler lorsque la page principale nous sollicite
// équivalent à this.onmessage = messageHandler;
&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.addEventListener(&lt;span style="color: maroon"&gt;'message'&lt;/span&gt;, messageHandler, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Nous avons donc défini dans “helloworkers.js” un code qui doit s’exécuter dans un autre thread. Il est capable de recevoir un message depuis notre page principale, de le traiter puis d’en renvoyer un autre en retour. Il faut maintenant écrire son pendant dans la page principale justement. Voici la page en question :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;font color="#000000"&gt;Hello Web Workers&lt;/font&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;output&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color: #006400"&gt;// On instantie le Worker
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;monWorker = &lt;span style="color: blue"&gt;new &lt;/span&gt;Worker(&lt;span style="color: maroon"&gt;'helloworkers.js'&lt;/span&gt;);
        &lt;span style="color: #006400"&gt;// On se prépare à traiter le message de retour qui sera
        // renvoyé par le worker
        &lt;/span&gt;monWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;message&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
            document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;output&amp;quot;&lt;/span&gt;).textContent = event.data;
        }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

        &lt;span style="color: #006400"&gt;// On démarre le worker en lui envoyant un 1er message
        &lt;/span&gt;monWorker.postMessage(&lt;span style="color: maroon"&gt;&amp;quot;David&amp;quot;&lt;/span&gt;);

        &lt;span style="color: #006400"&gt;// On stoppe le worker via la commande terminate()
        &lt;/span&gt;monWorker.terminate();
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;span style="color: blue"&gt;&lt;/span&gt;

&lt;p&gt;Le résultat sera bien : “&lt;em&gt;Bonjour David depuis un thread séparé !&lt;/em&gt;”. Ca vous épate hein ? &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3240.wlEmoticon_2D00_winkingsmile_5F00_3D1A2341.png" /&gt;&lt;/p&gt;

&lt;p&gt;Le worker va ensuite vivre sa vie tant que vous ne l’aurez pas tué. Par ailleurs, l’instanciation d’un worker a un cout non négligeable en temps de démarrage puis ensuite en consommation mémoire. Ils ne sont pas non plus automatiquement “garbage collectés”, c’est donc à vous de contrôler leurs états. Pour stopper le worker, il y a 2 façons de faire :&lt;/p&gt;

&lt;p&gt;1 – depuis la page principale en appelant la commande &lt;em&gt;terminate()&lt;/em&gt;. 

  &lt;br /&gt;2 – depuis le worker lui-même en appelant la commande &lt;em&gt;close()&lt;/em&gt;.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#800080"&gt;DEMO&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt; : Vous pouvez tester ce même exemple légèrement plus étoffé ici -&amp;gt; &lt;a title="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm" href="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm"&gt;http://david.blob.core.windows.net/html5/HelloWebWorkers.htm&lt;/a&gt; &amp;lt;-&lt;/p&gt;

&lt;h3 id="json"&gt;Echanges à travers JSON&lt;/h3&gt;

&lt;p&gt;Bien entendu, nous allons la plupart du temps envoyer des données à faire traiter par le worker. Les Web Workers peuvent également discuter entre eux à travers les &lt;a href="http://www.w3.org/TR/webmessaging/#messagechannel"&gt;Message channels&lt;/a&gt;. L’unique manière pour structurer les échanges consiste alors à utiliser le format JSON. Heureusement, les navigateurs supportant actuellement les Web Workers ont le bon gout également de supporter JSON de manière native.&lt;/p&gt;

&lt;p&gt;Reprenons ainsi notre exemple précédent. Nous allons construire un objet de type &lt;em&gt;WorkerMessage&lt;/em&gt; qui va nous servir à envoyer des commandes à notre Web Worker accompagnées d’un paramètre. Prenons ainsi la page web suivante simplifiée &lt;em&gt;HelloWebWorkersJSON.htm&lt;/em&gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Hello Web Workers JSON&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=inputForWorker /&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=btnSubmit&amp;gt;&lt;/span&gt;Envoyer au worker&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=killWorker&amp;gt;&lt;/span&gt;Stopper le worker&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;output&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;HelloWebWorkersJSON.js&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;On utilise ici la méthode dite d’&lt;a title="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript" href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;Unobtrusive JavaScript&lt;/a&gt; permettant de séparer notre vue de la logique associée derrière. Voici alors le script &lt;em&gt;HelloWebWorkersJSON.js &lt;/em&gt;:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;// HelloWebWorkerJSON.js associé à HelloWebWorkersJSON.htm
&lt;/span&gt;
&lt;span style="color: #006400"&gt;// Notre objet WorkerMessage sera automatiquement
// sérialisé puis désérialisé via le parseur JSON natif
&lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;WorkerMessage(cmd, parameter) {
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.cmd = cmd;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.parameter = parameter;
}

&lt;span style="color: #006400"&gt;// Le div où sera affiché les messages en retour du worker
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;_output = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;output&amp;quot;&lt;/span&gt;);

&lt;font color="#006400"&gt;/* Vérifie si les Web Workers sont supportés */&lt;br /&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(window.Worker) {
    &lt;span style="color: #006400"&gt;// On récupère les instances de nos 3 éléments HTML restant
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;_btnSubmit = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;btnSubmit&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;_inputForWorker = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;inputForWorker&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;_killWorker = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;killWorker&amp;quot;&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// On instantie le Worker
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;monWorker = &lt;span style="color: blue"&gt;new &lt;/span&gt;Worker(&lt;span style="color: maroon"&gt;'helloworkersJSON.js'&lt;/span&gt;);
    &lt;span style="color: #006400"&gt;// On se prépare à traiter le message de retour qui sera
    // renvoyé par le worker
    &lt;/span&gt;monWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;message&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
        _output.textContent = event.data;
    }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// On démarre le worker en lui envoyant la commande 'init'
    &lt;/span&gt;monWorker.postMessage(&lt;span style="color: blue"&gt;new &lt;/span&gt;WorkerMessage(&lt;span style="color: maroon"&gt;'init'&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;));

    &lt;span style="color: #006400"&gt;// On branche l'évènement click sur le bouton Submit
    // pour envoyer le contenu de l'input au worker
    &lt;/span&gt;_btnSubmit.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
        &lt;span style="color: #006400"&gt;// On envoit désormais les messages via la commande 'hello'
        &lt;/span&gt;monWorker.postMessage(&lt;span style="color: blue"&gt;new &lt;/span&gt;WorkerMessage(&lt;span style="color: maroon"&gt;'hello'&lt;/span&gt;, _inputForWorker.value));
    }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: #006400"&gt;// On branche l'évènement click sur le bouton Kill
    // pour stopper le worker. Il ne sera plus utilisable après
    &lt;/span&gt;_killWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
        &lt;span style="color: #006400"&gt;// On aurait pu créer une commande 'stop' qui aurait été traitée
        // au sein du worker qui se serait fait hara-kiri via .close()
        &lt;/span&gt;monWorker.terminate();
        _output.textContent = &lt;span style="color: maroon"&gt;&amp;quot;Le worker a été stoppé.&amp;quot;&lt;/span&gt;;
    }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);
}
&lt;span style="color: blue"&gt;else &lt;/span&gt;{
    _output.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Les Web Workers ne sont pas supportés par votre navigateur. &lt;br /&gt;    Réessayez avec IE10 : &amp;lt;a href=\&amp;quot;http://ie.microsoft.com/testdrive\&amp;quot;&amp;gt;téléchargez la dernière Platform Preview d'IE10 &amp;lt;/a&amp;gt;&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;Pour finir voici le nouveau code du worker contenu dans &lt;em&gt;helloworkerJSON.js&lt;/em&gt; :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;messageHandler(event) {
    &lt;span style="color: #006400"&gt;// On récupère le message envoyé par la page principale
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageSent = event.data;

    &lt;span style="color: #006400"&gt;// On teste la commande envoyée
    &lt;/span&gt;&lt;span style="color: blue"&gt;switch &lt;/span&gt;(messageSent.cmd) {
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: maroon"&gt;'init'&lt;/span&gt;:
            &lt;span style="color: #006400"&gt;// On peut initialiser certaines parties de nos objets qui serviront
            // dans ce worker (attention au scope cependant !)
            &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: maroon"&gt;'hello'&lt;/span&gt;:
            &lt;span style="color: #006400"&gt;// On prépare le message de retour
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;messageReturned = &lt;span style="color: maroon"&gt;&amp;quot;Bonjour &amp;quot; &lt;/span&gt;+ messageSent.parameter + &lt;span style="color: maroon"&gt;&amp;quot; depuis un thread séparé !&amp;quot;&lt;/span&gt;;
            &lt;span style="color: #006400"&gt;// On renvoit le tout à la page principale
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.postMessage(messageReturned);
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;
    }
}

&lt;span style="color: #006400"&gt;// On définit la fonction à appeler lorsque la page principale nous sollicite
&lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.addEventListener(&lt;span style="color: maroon"&gt;'message'&lt;/span&gt;, messageHandler, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;A nouveau cet exemple est extrêmement simple. Mais je pense que vous avez désormais compris le principe. Par exemple, rien ne vous empêche désormais d’envoyer à un worker des éléments d’un jeu qui devront être mis à jour par un moteur d’IA ou physique fonctionnant au sein d’un Web Worker. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#800080"&gt;DEMO&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt; : Vous pouvez tester ce même exemple ici -&amp;gt; &lt;a title="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm" href="http://david.blob.core.windows.net/html5/HelloWebWorkersJSON.htm"&gt;http://david.blob.core.windows.net/html5/HelloWebWorkersJSON.htm&lt;/a&gt; &amp;lt;-&lt;/p&gt;

&lt;h2 id="supportnavigateurs"&gt;Support dans les navigateurs &lt;a title="browserslogos by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5910079454/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="browserslogos" src="http://farm6.static.flickr.com/5075/5910079454_91a45b5f12_t.jpg" width="100" height="19" /&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Le support des Web Workers vient d’arriver dans la &lt;a href="http://ie.microsoft.com/testdrive/"&gt;PP2 (Platform Preview) d’IE10&lt;/a&gt; et cela fonctionne également sous Firefox (depuis la 3.6), Safari (depuis la 4.0), Chrome et Opera 11. Attention : cela n’est pas encore supporté par les versions mobiles de ces mêmes navigateurs. Si vous voulez un tableau plus précis, rendez-vous sur CanIUse : &lt;a href="http://caniuse.com/#search=worker"&gt;http://caniuse.com/#search=worker&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Pour savoir dynamiquement dans votre code si cette fonctionnalité est supportée par le navigateur, je vous rappelle que désormais la bonne pratique consiste à faire du “&lt;strong&gt;feature detection&lt;/strong&gt;”. Ne faites plus de tests sur le user-agent, c’est le mal !&lt;/p&gt;

&lt;p&gt;Pour cela, 2 techniques. Soit vous utilisez la très célèbre librairie &lt;a href="http://www.modernizr.com"&gt;Modernizr&lt;/a&gt; (que l’on trouve nativement dans les projets ASP.NET MVC3) via un code similaire à celui-ci :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
    var &lt;/span&gt;leDivWebWorker = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;webWorkers&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Modernizr.webworkers) {
        leDivWebWorker.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Les Web Workers sont supportés&amp;quot;&lt;/span&gt;;
    }
    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
        leDivWebWorker.innerHTML = &lt;span style="color: maroon"&gt;&amp;quot;Les Web Workers ne sont PAS supportés&amp;quot;&lt;/span&gt;;
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Et le résultat avec votre navigateur actuel est le suivant : &lt;span id="leDivWebWorker"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Soit vous testez vous-même la feature en utilisant en testant simplement ce booléen :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #006400"&gt;/* Vérifie si les Web Workers sont supportés */
&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;&lt;/span&gt;(window.Worker) {&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: "&gt;&lt;font color="#006400"&gt;  // Code utilisant les Web Workers&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;}&lt;/pre&gt;

&lt;p&gt;Cela vous permettra par détection d’offrir une version plus performante aux navigateurs les plus récents tout en conservant l’application fonctionnelle pour ceux ne supportant pas encore cette fonctionnalité. &lt;/p&gt;

&lt;h2 id="elements"&gt;Les éléments non accessibles depuis un worker&lt;/h2&gt;

&lt;p&gt;Plutôt de voir à quoi vous n’avez pas accès depuis un worker, regardons plutôt à quoi vous avez &lt;strong&gt;uniquement&lt;/strong&gt; accès :&lt;/p&gt;

&lt;table class="grid" width="800"&gt;&lt;tbody&gt;
    &lt;tr style="background-color: #7ca6cf; color: white"&gt;
      &lt;td valign="top" width="292"&gt;&lt;strong&gt;Méthode&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="508"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="292"&gt;&lt;strong&gt;void close();&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="508"&gt;Stop le worker thread.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="292"&gt;&lt;strong&gt;void importScripts(urls);&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="508"&gt;Une liste de fichiers JavaScript additionnels à importer séparés par des virgules.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="292"&gt;&lt;strong&gt;void postMessage(data);&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="508"&gt;Envoies un message depuis et vers un worker thread.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;table class="grid" width="800"&gt;&lt;tbody&gt;
    &lt;tr style="background-color: #7ca6cf; color: white"&gt;
      &lt;td valign="top" width="162"&gt;&lt;strong&gt;Attributs&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="125"&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="513"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="162"&gt;&lt;strong&gt;location&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="125"&gt;WorkerLocation&lt;/td&gt;

      &lt;td valign="top" width="513"&gt;Représente une URL absolue, incluant les composants &lt;strong&gt;protocol, host, port, hostname, pathname, search,&lt;/strong&gt; and &lt;strong&gt;hash&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="162"&gt;&lt;strong&gt;navigator&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="125"&gt;WorkerNavigator&lt;/td&gt;

      &lt;td valign="top" width="513"&gt;Représente l'identité et l'état &lt;strong&gt;onLine&lt;/strong&gt; du navigateur actuel.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="162"&gt;&lt;strong&gt;self&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="125"&gt;WorkerGlobalScope&lt;/td&gt;

      &lt;td valign="top" width="513"&gt;La portée totale du worker, ce qui inclus donc les objets &lt;strong&gt;WorkerLocation&lt;/strong&gt; et &lt;strong&gt;WorkerNavigator&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;table class="grid" width="800"&gt;&lt;tbody&gt;
    &lt;tr style="background-color: #7ca6cf; color: white"&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;Evènement&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;onerror&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;Une erreur s'est produite pendant l'exécution.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;onmessage&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;Un message contenant des données a été reçu.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;table class="grid" width="800"&gt;&lt;tbody&gt;
    &lt;tr style="background-color: #7ca6cf; color: white"&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;Méthode&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;void clearInterval(handle);&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;Annule un traitement programmé identifié par le handle fournit en paramètre.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;void clearTimeout(handle);&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;Annule un traitement programmé identifié par le handle fournit en paramètre.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;long setInterval(handler, valeur de timeout, arguments);&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;Programme un traitement devant être exécuté de manière &lt;em&gt;répétitive&lt;/em&gt; après le nombre indiqué de millisecondes. Retourne un handle. Vous pouvez alors l'annuler avec &lt;strong&gt;clearInterval&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="329"&gt;&lt;strong&gt;long setTimeout(handler, valeur de timeout, arguments);&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="571"&gt;Programme un traitement devant être exécuté après le nombre indiqué de millisecondes. Retourne un handle. Vous pouvez alors l'annuler avec &lt;strong&gt;clearInterval&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Vous n’avez ainsi &lt;strong&gt;&lt;font color="#d90000"&gt;pas du tout accès au DOM&lt;/font&gt;&lt;/strong&gt;. Cela est également résumé à travers ces 2 diagrammes :&lt;/p&gt;

&lt;p&gt;&lt;a title="20110701-wwiibjmwaf-image2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5905343545/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="20110701-wwiibjmwaf-image2" src="http://farm7.static.flickr.com/6059/5905343545_14ef21238e.jpg" width="500" height="326" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ainsi, si vous vous posiez la question, comme l’objet &lt;em&gt;window&lt;/em&gt; n’est pas accessible, vous n’avez pas accès au Local Storage depuis un worker. Ce fonctionnement limité peut paraitre parfois trop contraignant pour ceux qui ont l’habitude des opérations multithréadées dans d’autres environnements. Cependant, il a l’immense avantage du coup de ne pas récupérer tous les problèmes inhérents aux partages de ressources : lock, races conditions, etc. Cela rend ainsi les web workers particulièrement accessibles à tous tout en permettant une augmentation des performances dans certains scénarios plus ciblés. &lt;/p&gt;

&lt;h2 id="debugging"&gt;Gérer les erreurs et le debugging&lt;/h2&gt;

&lt;p&gt;Pour gérer les erreurs levées depuis votre Web Worker, rien de plus simple. Il suffit de s’abonner à l’évènement OnError de la même manière que nous l’avons fait avec OnMessage :&lt;/p&gt;

&lt;pre class="code"&gt;monWorker.addEventListener(&lt;span style="color: maroon"&gt;&amp;quot;error&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {
    _output.textContent = event.data;
}, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Ensuite, à vous de vous débrouiller… Bon, avouons le, cela n’est pas super comme pratique comme moyen de debug non? On est d’accord. &lt;/p&gt;

&lt;h3 id="f12"&gt;La barre de développement F12 pour le debug&lt;/h3&gt;

&lt;p&gt;Justement, &lt;strong&gt;IE10 vous propose la possibilité de débugger directement le code de vos Web Workers&lt;/strong&gt; comme avec n’importe lequel de vos scripts. &lt;/p&gt;

&lt;p&gt;Pour cela, lancez la barre de développement avec la touche F12 et rendez-vous sur l’onglet “&lt;em&gt;Script&lt;/em&gt;”. Au début, vous ne verrez pas votre fichier JS correspondant à votre worker apparaitre. Il suffit alors de presser le bouton “&lt;em&gt;Start debugging&lt;/em&gt;” pour le voir apparaitre :&lt;/p&gt;

&lt;p&gt;&lt;a title="F12DebugWorker001 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5909471248/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="F12DebugWorker001" src="http://farm6.static.flickr.com/5116/5909471248_37ced53c67_b.jpg" width="1024" height="192" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensuite, débuggez votre worker comme vous avez l’habitude de le faire !&lt;/p&gt;

&lt;p&gt;&lt;a title="F12DebugWorker002 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5909486048/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="F12DebugWorker002" src="http://farm7.static.flickr.com/6038/5909486048_573c897044_b.jpg" width="700" height="371" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id="consolelog"&gt;Une solution pour avoir console.log() &lt;/h3&gt;

&lt;p&gt;Pour finir, il faut savoir que &lt;strong&gt;l’objet console n’est pas disponible&lt;/strong&gt; au sein d’un worker. Ainsi, si vous souhaitez écrire ce qu’il se passe dans votre worker via la méthode .log() , cela ne va pas fonctionner car l’objet console ne sera pas définit. Pour palier à cela, j’ai trouvé cet excellent exemple qui se propose de &lt;strong&gt;simuler console.log()&lt;/strong&gt; en faisant appel aux &lt;em&gt;MessageChannel&lt;/em&gt; : &lt;a title="http://www.davidflanagan.com/2011/01/consolelog-for.html" href="http://www.davidflanagan.com/2011/01/consolelog-for.html"&gt;console.log() for Web Workers&lt;/a&gt; . Cela ne fonctionne donc que dans IE10, Chrome et Opera 11.50. Firefox ne supportant pas encore les &lt;em&gt;MessageChannel&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; pour que cela fonctionne bien dans IE10, il faut changer cette ligne de code :&lt;/p&gt;

&lt;pre class="code"&gt;console.log.apply(console, args); &lt;span style="color: #006400"&gt;// Pass the args to the real log
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Par celle-ci :&lt;/p&gt;

&lt;pre class="code"&gt;console.log(args); &lt;span style="color: #006400"&gt;// Pass the args to the real log
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Ensuite, voici un exemple de résultat en action :&lt;/p&gt;

&lt;p&gt;&lt;a title="F12DebugConsole by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5908793767/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="F12DebugConsole" src="http://farm7.static.flickr.com/6007/5908793767_f632260059.jpg" width="500" height="186" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#800080"&gt;DEMO&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt; : Vous pouvez tester ce même exemple ici -&amp;gt; &lt;a title="http://david.blob.core.windows.net/html5/HelloWebWorkers.htm" href="http://david.blob.core.windows.net/html5/HelloWebWorkersJSONdebug.htm"&gt;http://david.blob.core.windows.net/html5/HelloWebWorkersJSONdebug.htm&lt;/a&gt; &amp;lt;-&lt;/p&gt;

&lt;h2 id="scenarios"&gt;Scénarios d’usages et comment identifier le code candidat&lt;/h2&gt;

&lt;h3 id="usages"&gt;Web Workers pour quels usages ?&lt;/h3&gt;

&lt;p&gt;Lorsque l’on parcours la toile à la recherche d’exemples pertinents sur l’utilisation des Web Workers, on tombe toujours sur la même chose : des démonstrations de calculs mathématiques réellement intensifs gérés par les web workers. On retrouve ainsi des raytracers, des calculs de fractales, de nombres premiers, de l’âge de chacun des capitaines de chacune des étoiles de l’univers, etc. Bref, de belles démos technologiques mais peu de perspectives concrètes sur les applications dites du “monde réel”. &lt;/p&gt;

&lt;p&gt;Il est vrai que les limitations que fixent les Web Workers sur les ressources disponibles amenuisent potentiellement d’autant les scénarios. Cependant, il suffit juste de se creuser un peu la tête pour rapidement voir émerger des choses intéressantes :&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;traitement d’image&lt;/strong&gt; en utilisant les données issues de l’élément &amp;lt;canvas&amp;gt; ou &amp;lt;video&amp;gt; : on peut alors diviser les zones de traitement pour les fournir à différents workers qui bosseront en parallèle. On bénéficie ici des processeurs multi-cœurs. Plus nous aurons de cœurs, plus le traitement sera rapide. 

  &lt;br /&gt;- &lt;strong&gt;traitement de gros lot de données&lt;/strong&gt; ramenées par un appel via XMLHTTPRequest : cela alors évite tout simplement de le faire dans le thread principal et donc permet à l’application d’être réactive au près de l’utilisateur. 

  &lt;br /&gt;- &lt;strong&gt;analyse de texte en arrière-plan&lt;/strong&gt; : le fait d’avoir davantage de CPU disponible permet d’envisager de nouveaux scénarios comme le traitement temps réel de ce que tape l’utilisateur sans pénaliser à nouveau l’interface principale. Imaginez alors une version Word (comme celle issue des Office Web Apps) en ligne pouvant bénéficier de ce scénario : recherche dynamique dans un dictionnaire en arrière-plan pour une aide à la saisie, correction automatique, etc. 

  &lt;br /&gt;- &lt;strong&gt;requêtes multiples et concurrentes vers une base de données&lt;/strong&gt; locale : IndexDB permettra ce que le local storage ne peut nous fournir : un environnement thread-safe pour les web workers.&lt;/p&gt;

&lt;p&gt;Par ailleurs, dans le domaine du jeu vidéo, on peut envisager de basculer &lt;strong&gt;le moteur d’IA ou le moteur physique&lt;/strong&gt; vers des web workers. Il y a par exemple cette expérimentation qui a été faite : &lt;a title="http://extremelysatisfactorytotalitarianism.com/blog/?p=932" href="http://extremelysatisfactorytotalitarianism.com/blog/?p=932"&gt;On Web Workers, GWT, and a New Physics Demo&lt;/a&gt; qui propose un basculement du moteur Box2D vers les workers. Dans le cas de l’IA, cela veut aussi dire que le même laps de temps, on peut envisager d’anticiper davantage de choses (des coups dans le cas d’un jeu d’échecs par exemple).&lt;/p&gt;

&lt;p&gt;Ensuite certains diront que les seules limites se résument à votre propre imagination ! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3240.wlEmoticon_2D00_winkingsmile_5F00_3D1A2341.png" /&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Mais d’une manière générale, dès l’instant que le DOM n’est pas touché, tout traitement JavaScript relativement long et pouvant pénaliser la fluidité et l’expérience utilisateur méritera d’être un candidat aux web workers. Il faudra cependant être prudent à 3 choses :&lt;/p&gt;

&lt;p&gt;1 – A ce que le temps d’initialisation et de communication vers le worker ne soit pas supérieur au temps de traitement en lui-même 
  &lt;br /&gt;2 – A bien faire attention également à la mémoire prise supplémentaire 

  &lt;br /&gt;3 – A la dépendance des morceaux de code entre eux et donc des besoins de synchro. La parallelisation n’est pas une science simple mes amis !&lt;/p&gt;

&lt;p&gt;De notre côté, nous avons publié récemment la démo nommée &lt;a href="http://ie.microsoft.com/testdrive/Graphics/WorkerFountains/Default.html"&gt;Web Workers Fontains&lt;/a&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a title="Web Workers Fountains by Internet Explorer 10" href="http://ie.microsoft.com/testdrive/Graphics/WorkerFountains/Default.html"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Web Workers Fountains" src="http://farm6.static.flickr.com/5078/5915109760_eb2d9a53d6.jpg" width="500" height="199" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cette dernière calcule des effets de particules (les fontaines) et utilise 1 web worker par fontaine pour tenter de calculer le plus rapidement possible les effets de particules. Le résultat de chacun des workers est ensuite agrégé pour être affiché par le canvas. Les Web Workers peuvent ensuite éventuellement communiquer entre eux via les &lt;a href="http://www.w3.org/TR/webmessaging/#messagechannel"&gt;Message Channels&lt;/a&gt; pour se synchroniser sur la couleur actuellement retenue pour peintre chacune des fontaines. N’hésitez pas à aller jouer avec sous &lt;a href="http://ie.microsoft.com/testdrive/Info/Downloads/Default.html"&gt;Internet Explorer 10&lt;/a&gt;, c’est rigolo ! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/0755.wlEmoticon_2D00_smile_5F00_58CB9B2F.png" /&gt;&lt;/p&gt;

&lt;h3 id="profiling"&gt;Comment identifier les points chauds dans son code&lt;/h3&gt;

&lt;p&gt;Pour détecter les goulots d’étranglement et savoir éventuellement quelles parties de votre code envoyer aux web workers, vous pouvez utiliser le profileur de script intégré à IE9/10 avec la barre de développement accessible via la touche F12. Cela va vous permettre d’identifier les points chauds. Mais cela ne veut pas dire pour autant que les zones identifiées seront de bons candidats. Pour mieux le comprendre, faisons le test à travers 2 exemples.&lt;/p&gt;

&lt;h4 id="exemple1"&gt;Exemple 1 : animation dans &amp;lt;canvas&amp;gt; avec Speed Reading &lt;/h4&gt;

&lt;p&gt;Cette démo est issue de notre centre &lt;a href="http://ie.microsoft.com/testdrive/"&gt;IE Test Drive&lt;/a&gt; qui peut être vue ici :&amp;#160; &lt;a title="http://ie.microsoft.com/testdrive/Performance/SpeedReading/Default.html" href="http://ie.microsoft.com/testdrive/Performance/SpeedReading/Default.html"&gt;Speed Reading&lt;/a&gt;. Elle s’occupe d’essayer d’afficher le plus rapidement possible des lettres en utilisant &amp;lt;canvas&amp;gt;. Cette démo a pour but de mettre en valeur la qualité de l’accélération matérielle de votre navigateur. Mais est-il possible de gratter encore un peu plus de performance en splittant certains traitements sur des threads? Cela mérite analyse.&lt;/p&gt;

&lt;p&gt;Justement, si on la lance dans IE9/10, on peut utiliser le profileur de script pendant quelques secondes. Voici ce que l’on obtient :&lt;/p&gt;

&lt;p&gt;&lt;a title="F12ProfilingSpeedReading by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5912808488/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="F12ProfilingSpeedReading" src="http://farm7.static.flickr.com/6021/5912808488_8cb335aee4.jpg" width="454" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si l’on trie les fonctions consommant le plus de temps de manière décroissante, on voit clairement ressortir les fonctions suivantes : &lt;em&gt;DrawLoop()&lt;/em&gt;, &lt;em&gt;Draw()&lt;/em&gt; et &lt;em&gt;drawImage()&lt;/em&gt;. Si on double-clique sur &lt;em&gt;Draw&lt;/em&gt;, on saute dans le code de la méthode et on observe alors de nombreux appels de ce type :&lt;/p&gt;

&lt;pre class="code"&gt;surface.drawImage(imgTile, 0, 0, 70, 100, this.left, this.top, this.width, this.height); &lt;/pre&gt;

&lt;p&gt;Sachant que l’objet &lt;em&gt;surface&lt;/em&gt; référence un élément de type &amp;lt;canvas&amp;gt;. &lt;/p&gt;

&lt;p&gt;Au final, la conclusion de cette analyse rapide est que cette démo passe son temps à faire du dessin via la méthode &lt;em&gt;drawImage()&lt;/em&gt; de l’élément Canvas. Or, cet élément n’est pas accessible depuis un web worker donc on ne va pas pouvoir sous-traiter ces opérations à différents threads. On aurait pu imaginer en effet gérer l’élément Canvas de manière concurrente. Cette démo n’apparait donc pas comme un bon candidat à la parrallélisation. &lt;/p&gt;

&lt;p&gt;Mais elle illustre bien la démarche à mettre en place. Si après un profiling, vous découvrez que la partie la plus consommatrice de temps CPU utilise des éléments du DOM, les web workers ne pourront pas vous aider à augmenter les performances.&lt;/p&gt;

&lt;h4 id="exemple2"&gt;Exemple 2 : Raytracer dans &amp;lt;canvas&amp;gt;&lt;/h4&gt;

&lt;p&gt;Prenons maintenant l’exemple typique facile à comprendre, un raytracer comme celui-ci : &lt;a title="http://labs.flog.co.nz/raytracer/" href="http://labs.flog.co.nz/raytracer/"&gt;Flog.RayTracer Canvas Demo&lt;/a&gt; . Un raytracer met en place des calculs mathématiques consommant énormément de CPU dans le but de simuler le trajet effectué par des rayons dont on simule le lancé. On calcule ainsi les effets de réflexions, diffraction, de matière, etc.&amp;#160; &lt;/p&gt;

&lt;p&gt;Lançons le calcul d’une scène tout en lançant en parallèle le profileur de script et observons le résultat :&lt;/p&gt;

&lt;p&gt;&lt;a title="F12ProfilingRayTracer by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5913093416/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="F12ProfilingRayTracer" src="http://farm6.static.flickr.com/5040/5913093416_7824a71406.jpg" width="470" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A nouveau si l’on trie les fonctions appelées de manière décroissante, on voit clairement 2 choses ressortir : &lt;em&gt;renderScene()&lt;/em&gt; et &lt;em&gt;getPixelColor().&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;getPixelColor()&lt;/em&gt; a pour but de calculer la couleur du pixel courant. En effet, par ray-tracing , une scène est dessinée pixel par pixel. Cette méthode appelle ensuite la méthode &lt;em&gt;rayTrace()&lt;/em&gt; chargée de calculer les ombres, la lumière ambiante, etc. C’est le cœur même de notre application. Et justement en analysant le code de cette méthode &lt;em&gt;rayTrace()&lt;/em&gt;, on s’aperçoit que c’est du JavaScript 100% pur jus. Aucune dépendance vers le DOM n’y est présente. Bref, vous l’aurez compris, c’est un excellent candidat à la parallélisation. D’autant plus que l’on peut facilement répartir le calcul de l’image sur différents threads (et donc potentiellement différents processeurs) car il n’y pas de phénomène de synchronisation entre le calcul de chacun des pixels. Chaque opération est indépendante du résultat du voisin (il n’y pas d’anti-aliasing dans cette démo). &lt;/p&gt;

&lt;p&gt;D’ailleurs, ce n’est ainsi pas un hasard si l’on retrouve des exemples de ray-tracers mettant en œuvre les web workers comme ici par exemple : &lt;a title="http://nerget.com/rayjs-mt/rayjs.html" href="http://nerget.com/rayjs-mt/rayjs.html"&gt;http://nerget.com/rayjs-mt/rayjs.html&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Si on analyse ce dernier exemple au sein d’IE10 avec le profileur, on observe très bien la différence entre l’utilisation d’aucun web worker et de 4 web workers :&lt;/p&gt;

&lt;p&gt;&lt;a title="RayTracersWebWorkersIE10 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5912647611/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="RayTracersWebWorkersIE10" src="http://farm7.static.flickr.com/6034/5912647611_a6c2f2094a.jpg" width="500" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On voit ainsi sur le résultat du profiling que dans le 1er cas, la méthode &lt;em&gt;processRenderCommand()&lt;/em&gt; sature à elle seul l’ensemble du CPU et l’on obtient alors le résultat en &lt;strong&gt;2,854s&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Avec 4 web workers, on voit très bien la méthode &lt;em&gt;processRenderCommand()&lt;/em&gt; s’exécuter en parallèle sur 4 différents threads (dont on peut même voir les Worker Id dans la colonne de droite). On obtient alors le même résultat en&lt;strong&gt; 1,473s&lt;/strong&gt;. Le bénéfice a donc été réel : un traitement 2 fois plus rapide. &lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;Il n’y a pas de magie ou de nouveautés supplémentaires introduites par les web workers dans la démarche à entreprendre pour tenter de paralléliser un code. Il faut isoler un traitement long, indépendant du reste de la vie de notre page pour éviter d’avoir à attendre le résultat pour continuer et surtout n’ayant aucun besoin d’accès au DOM. Si vous tombez dans ce cas, pensez aux web workers, ils pourraient vous aider à augmenter les performances générales de votre application ! &lt;/p&gt;

&lt;h2 id="ressources"&gt;Ressources complémentaires&lt;/h2&gt;

&lt;p&gt;Si vous lisez l’anglais, voici des liens qui m’ont paru intéressants à lire et que je vous conseille donc :&lt;/p&gt;

&lt;p&gt;- La spécification officielle du W3C : &lt;a title="http://www.w3.org/TR/workers/" href="http://www.w3.org/TR/workers/"&gt;http://www.w3.org/TR/workers/&lt;/a&gt; 

  &lt;br /&gt;- Web Workers in IE10: Background JavaScript Makes Web Apps Faster : &lt;a title="http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx" href="http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx"&gt;http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx&lt;/a&gt; 

  &lt;br /&gt;- The Basics of Web Workers : &lt;a title="http://www.html5rocks.com/en/tutorials/workers/basics/" href="http://www.html5rocks.com/en/tutorials/workers/basics/"&gt;http://www.html5rocks.com/en/tutorials/workers/basics/&lt;/a&gt; 

  &lt;br /&gt;- La documentation issue du MDN : &lt;a title="https://developer.mozilla.org/En/Using_web_workers" href="https://developer.mozilla.org/En/Using_web_workers"&gt;https://developer.mozilla.org/En/Using_web_workers&lt;/a&gt; 

  &lt;br /&gt;- An Introduction to HTML 5 Web Workers : &lt;a title="http://cggallant.blogspot.com/2010/08/introduction-to-html-5-web-workers.html" href="http://cggallant.blogspot.com/2010/08/introduction-to-html-5-web-workers.html"&gt;http://cggallant.blogspot.com/2010/08/introduction-to-html-5-web-workers.html&lt;/a&gt; 

  &lt;br /&gt;- A Deeper Look at HTML 5 Web Workers : &lt;a title="http://cggallant.blogspot.com/2010/08/deeper-look-at-html-5-web-workers.html" href="http://cggallant.blogspot.com/2010/08/deeper-look-at-html-5-web-workers.html"&gt;http://cggallant.blogspot.com/2010/08/deeper-look-at-html-5-web-workers.html&lt;/a&gt; 

  &lt;br /&gt;- Une très belle illustration des Web Workers : &lt;a title="http://wearehugh.com/public/2010/08/html5-web-workers/" href="http://wearehugh.com/public/2010/08/html5-web-workers/"&gt;http://wearehugh.com/public/2010/08/html5-web-workers/&lt;/a&gt; (j’adore le concept !)&lt;/p&gt;

&lt;p&gt;Au boulot travailleurs du web !&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;
&lt;script src="http://david.blob.core.windows.net/html5/modernizr-1.7.min.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;
    var imgSingle = document.getElementById("imgSingleThread");
    var divWebWorker = document.getElementById("leDivWebWorker");
    if (Modernizr.svg) {
        imgSingle.src = "http://david.blob.core.windows.net/html5/SVGSingleThreadJS.svg";

    }
    else {
        imgSingle.src = "http://david.blob.core.windows.net/html5/SVGSingleThread.png";
    }
    if (Modernizr.webworkers) {
        divWebWorker.innerHTML = "les Web Workers &lt;strong&gt;sont&lt;/strong&gt; supportés par votre navigateur.";
	divWebWorker.style.color = "green";
    }
    else {
        divWebWorker.innerHTML = "les Web Workers &lt;strong&gt;ne sont pas&lt;/strong&gt; supportés par votre navigateur.";
	divWebWorker.style.color = "red";
    }
&lt;/script&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10184529" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/WebWorkers/">WebWorkers</category></item><item><title>Une application HTML5 pour afficher les vidéos 5 minutes pour comprendre IE9</title><link>http://blogs.msdn.com/b/davrous/archive/2011/06/16/une-application-html5-pour-afficher-les-vid-233-os-5-minutes-pour-comprendre-ie9.aspx</link><pubDate>Thu, 16 Jun 2011 16:25:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10175347</guid><dc:creator>David Rousset</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10175347</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/06/16/une-application-html5-pour-afficher-les-vid-233-os-5-minutes-pour-comprendre-ie9.aspx#comments</comments><description>&lt;p&gt;Avec Stanislas Quastana, nous avons créé une série de vidéos appelée “5 min pour comprendre” permettant d’illustrer assez rapidement quelques nouveautés autour d’Internet Explorer 9. Nous les avons publiées ici sur le blog IE France : &lt;a title="http://blogs.msdn.com/b/iefrance/archive/2011/04/29/la-s-233-rie-5-minutes-pour-comprendre-ie9-la-liste-compl-232-te.aspx" href="http://blogs.msdn.com/b/iefrance/archive/2011/04/29/la-s-233-rie-5-minutes-pour-comprendre-ie9-la-liste-compl-232-te.aspx"&gt;La série 5 minutes pour comprendre IE9: la liste complète&lt;/a&gt; . Ces vidéos sont visibles au format Silverlight Smooth Streaming et/ou avec la balise vidéo HTML5 au format h264.&lt;/p&gt;  &lt;p&gt;Certains d’entre vous m’ont indiqué qu’ils auraient aimé avoir également une version WebM. Je me suis donc amusé à ré-encoder les vidéos au format WebM en utilisant l’utilitaire gratuit &lt;a href="http://www.mirovideoconverter.com/"&gt;Miro Video Converter&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Ensuite, je voulais afficher l’ensemble de manière plus sympathique donc je suis reparti de la démo &lt;a href="http://ie.microsoft.com/testdrive/Graphics/VideoPanorama/Default.html"&gt;IMDb Video Panorama&lt;/a&gt; de notre site &lt;a href="http://ie.microsoft.com/testdrive/"&gt;IE Test Drive&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Cette démo met en avant les capacités de votre navigateur à afficher de manière fluide les animations et à afficher une vidéo en utilisant la balise HTML5 &amp;lt;video&amp;gt;. Par contre, comme la démo n’utilisait et ne testait que le support du codec h264, j’ai légèrement modifié le code pour également supporter le format WebM. En effet, pour rappel, h264 est supporté via HTML5 par IE9, Safari et Chrome même si Google a annoncé l’abandon de son support à terme dans son navigateur. WebM de son côté est supporté nativement par Chrome, Firefox, Opera et par IE9 via l’installation du codec par Google. Vous pouvez d’ailleurs le voir en démonstration dans IE9 ici : &lt;a title="http://ie.microsoft.com/testdrive/Graphics/VideoFormatSupport/Default.html" href="http://ie.microsoft.com/testdrive/Graphics/VideoFormatSupport/Default.html"&gt;Video Format Support&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En résumé donc, si vous souhaitez pouvoir afficher de la vidéo nativement via HTML5 sur l’ensemble des navigateurs actuels, il faut au moins faire du double encodage en h264 et en WebM. &lt;/p&gt;  &lt;p&gt;Au final, cela donne le résultat suivant : &lt;/p&gt;  &lt;p&gt;&lt;iframe height="800" src="http://david.blob.core.windows.net/5minie9/5minIE9Player.html" width="925"&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;p&gt;Vous pouvez également afficher l’ensemble en plein écran à part depuis ce lien : &lt;a title="http://david.blob.core.windows.net/5minie9/5minIE9Player.html" href="http://david.blob.core.windows.net/5minie9/5minIE9Player.html"&gt;5min IE9 Video Panorama&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10175347" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category></item><item><title>How to add the 3D animated HTML5 logo into your webpages thanks to &lt;canvas&gt;</title><link>http://blogs.msdn.com/b/davrous/archive/2011/05/27/how-to-add-the-3d-animated-html5-logo-into-your-webpages-thanks-to-lt-canvas-gt.aspx</link><pubDate>Fri, 27 May 2011 20:49:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10169196</guid><dc:creator>David Rousset</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10169196</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/05/27/how-to-add-the-3d-animated-html5-logo-into-your-webpages-thanks-to-lt-canvas-gt.aspx#comments</comments><description>&lt;p&gt;To change my mind tonight, I was looking into a way to use the &amp;lt;canvas&amp;gt; element to do something you’ll find probably useless: displaying the HTML5 logo in 3D on the top left of my blog. It’s sometimes so much fun to play with code just for your own pleasure. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/2330.wlEmoticon_2D00_winkingsmile_5F00_495B056C.png" /&gt;&lt;/p&gt;  &lt;p&gt;Well, it was very straightforward and simple to put in place. Luckily, I’ve found the excellent &lt;a href="http://www.kevs3d.co.uk/index.html"&gt;Kevin Roast&lt;/a&gt; website who has written a simple 3D engine based on the HTML5 &amp;lt;canvas&amp;gt; element. He has also built an animated 3D version of the HTML5 logo here: &lt;a title="http://www.kevs3d.co.uk/dev/html5logo/" href="http://www.kevs3d.co.uk/dev/html5logo/"&gt;http://www.kevs3d.co.uk/dev/html5logo/&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;After doing some little modifications and merging some of his sample code, I’ve obtained what you’re currently seeing on this page. If your browser doesn’t support &amp;lt;canvas&amp;gt;, here is a screenshot of the output under IE9:&lt;/p&gt;  &lt;p&gt;&lt;a title="HTML5Logo3Dfun by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5766035460/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Logo3Dfun" src="http://farm4.static.flickr.com/3415/5766035460_44aa336d84.jpg" width="500" height="268" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’ve also inserted it inside my 2 first articles on SVG &amp;amp; Canvas (in French):&lt;/p&gt;  &lt;p&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx"&gt;Introduction aux APIs graphiques d’HTML5: SVG &amp;amp; Canvas (1/4)&lt;/a&gt;     &lt;br /&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx"&gt;Introduction aux APIs graphiques d’HTML5: SVG &amp;amp; Canvas (2/4)&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you’re navigating into the page, you’ll see also that the little logo is following the vertical scrolling.&lt;/p&gt;  &lt;p&gt;If you’d like also to disturb your readers by displaying this little 3D useless thing, you simply have to copy/paste these 3 lines at the end of your page to import the needed scripts:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://david.blob.core.windows.net/html5/mathlib-min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://david.blob.core.windows.net/html5/k3d-min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://david.blob.core.windows.net/html5/html5logo.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;And you’re done!&lt;/p&gt;

&lt;p&gt;If you’re curious and if you’d like to quickly analyze how these scripts work, you just have to press the F12 key which will display the integrated IE9 development bar. In the Script section, select the &lt;strong&gt;k3d-min.js &lt;/strong&gt;file in which you’ll find the main logic that handle the 3D engine with Canvas. You’ll notice by the way that the file is completely unreadable as it has been minified. IE9 offers you an interesting option to reformat the code:&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Logo3Dfun4 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5765692097/"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; border-top: 0px; border-right: 0px; padding-top: 0px" border="0" alt="HTML5Logo3Dfun4" src="http://farm6.static.flickr.com/5069/5765692097_bc821cbd85.jpg" width="500" height="305" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second interesting script is included inside the &lt;strong&gt;html5logo.js&lt;/strong&gt; file which executes some code at the end of the loading of your page. It creates the &amp;lt;canvas&amp;gt; element by code, add it at the end of the document tree and display it at the top left corner using in-line CSS. The code then instantiates the k3d engine and asks it to display the 3D HTML5 logo thanks to 5 faces.&lt;/p&gt;

&lt;p&gt;For instance, here is the code for the first face:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;obj1 = &lt;span style="color: blue"&gt;new &lt;/span&gt;K3D.K3DObject();
&lt;span style="color: blue"&gt;with &lt;/span&gt;(obj1)
{
   drawmode = &lt;span style="color: maroon"&gt;&amp;quot;solid&amp;quot;&lt;/span&gt;;
   shademode = &lt;span style="color: maroon"&gt;&amp;quot;lightsource&amp;quot;&lt;/span&gt;;
   sortmode = &lt;span style="color: maroon"&gt;&amp;quot;unsorted&amp;quot;&lt;/span&gt;;
   addphi = -0.5;
   abouty = OBJMOVEY;
   scale = OBJSCALE;
   perslevel = 1000;
   init(
      [{x:-80,y:180,z:0},{x:0,y:180,z:-80},{x:0,y:0,z:-80},{x:-80,y:20,z:0},{x:-50,y:150,z:-30},&lt;br /&gt;       {x:0,y:150,z:-80},{x:0,y:130,z:-80},{x:-30,y:130,z:-50},{x:-28,y:110,z:-52},{x:0,y:110,z:-80},&lt;br /&gt;       {x:0,y:90,z:-80},{x:-45,y:90,z:-35},{x:-44,y:80,z:-36},{x:-25,y:80,z:-55},{x:-22,y:66,z:-58},&lt;br /&gt;       {x:0,y:60,z:-80},{x:0,y:40,z:-80},{x:-40,y:50,z:-40}],
      [],
      [{color:[227,76,38],vertices:[0,1,2,3,0]},{color:[235,235,235],vertices:[4,5,6,7,8,9,10,11,4]},&lt;br /&gt;       {color:[235,235,235],vertices:[12,13,14,15,16,17,12]}]
   );
}
k3dmain.addK3DObject(obj1);&lt;/pre&gt;

&lt;p&gt;This will output this face:&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Logo3Dfun3 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5766091166/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Logo3Dfun3" src="http://farm4.static.flickr.com/3554/5766091166_90ba560825_t.jpg" width="54" height="82" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And voilà! Have fun and have a nice HTML5 week-end!&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;
&lt;script src="http://david.blob.core.windows.net/html5/mathlib-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/k3d-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/html5logo.js"&gt;&lt;/script&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10169196" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Canvas/">Canvas</category></item><item><title>Comment ajouter le logo HTML5 animé en 3D à vos pages web grâce à &lt;canvas&gt;</title><link>http://blogs.msdn.com/b/davrous/archive/2011/05/27/comment-ajouter-le-logo-html5-anim-233-en-3d-224-vos-pages-web-gr-226-ce-224-lt-canvas-gt.aspx</link><pubDate>Fri, 27 May 2011 19:47:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10169184</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10169184</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/05/27/comment-ajouter-le-logo-html5-anim-233-en-3d-224-vos-pages-web-gr-226-ce-224-lt-canvas-gt.aspx#comments</comments><description>&lt;p&gt;Ce soir, j’avais envie de jouer avec la balise &amp;lt;canvas&amp;gt; pour faire un truc qui ne sert à rien : afficher le logo 3D animé d’HTML5 en haut à gauche d’une page de mon blog. C’est vrai quoi. Pourquoi n’aurais-je pas le droit de me changer un peu les idées en codant des trucs qui ne servent à rien ?!? &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/1033.wlEmoticon_2D00_winkingsmile_5F00_24D92314.png" /&gt;&lt;/p&gt;  &lt;p&gt;Figurez-vous que ce fut extrêmement simple. Je suis en effet tombé sur le site de &lt;a href="http://www.kevs3d.co.uk/index.html"&gt;Kevin Roast&lt;/a&gt; qui s’est amusé à faire un petit moteur 3D basé sur HTML5 &amp;lt;canvas&amp;gt;. Il s’est également amusé à générer et animer le logo HTML5 ici : &lt;a title="http://www.kevs3d.co.uk/dev/html5logo/" href="http://www.kevs3d.co.uk/dev/html5logo/"&gt;http://www.kevs3d.co.uk/dev/html5logo/&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Il ne m’a donc plus que fallu bidouiller tout ça pour obtenir le résultat que vous voyez sur cette page. Si vous navigateur ne supporte pas &amp;lt;canvas&amp;gt; voici ce que cela donne :&lt;/p&gt;  &lt;p&gt;&lt;a title="HTML5Logo3Dfun by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5766035460/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Logo3Dfun" src="http://farm4.static.flickr.com/3415/5766035460_44aa336d84.jpg" width="500" height="268" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Je l’ai également inséré sur mes 2 premiers articles consacrés à SVG et Canvas :&lt;/p&gt;  &lt;p&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx"&gt;Introduction aux APIs graphiques d’HTML5: SVG &amp;amp; Canvas (1/4)&lt;/a&gt;     &lt;br /&gt;- &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx"&gt;Introduction aux APIs graphiques d’HTML5: SVG &amp;amp; Canvas (2/4)&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Si vous naviguez dans la page, vous verrez que le petit logo suit votre niveau de scrolling vertical. &lt;/p&gt;  &lt;p&gt;Si vous aussi vous voulez perturber le lecteur en affichant un machin qui tourne en 3D et qui ne sert à rien, copiez simplement ces 3 lignes de déclaration d’import de scripts à la fin de votre page :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://david.blob.core.windows.net/html5/mathlib-min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://david.blob.core.windows.net/html5/k3d-min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://david.blob.core.windows.net/html5/html5logo.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Et le tour est joué !&lt;/p&gt;

&lt;p&gt;Si vous souhaitez analyser un peu comment tout cela fonctionne, il vous suffit de presser la touche F12 pour faire apparaitre la barre de développement d’IE9. Ensuite, sélectionnez le fichier &lt;strong&gt;k3d-min.js&lt;/strong&gt; dans lequel se trouve toute la logique principale pour gérer le moteur 3D avec Canvas. Vous constaterez que ce fichier est difficilement lisible car il a été réduit ou “minimisé”. IE9 propose une option pour reformater le code :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Logo3Dfun2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5765506807/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Logo3Dfun2" src="http://farm6.static.flickr.com/5228/5765506807_b6fa474c1d.jpg" width="500" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensuite, le fichier &lt;strong&gt;html5logo.js&lt;/strong&gt; permet de brancher du code à la fin du chargement de votre page. Il créé un élément canvas par code qu’il ajoute à la fin du document et qu’il positionne ensuite via CSS in-line en haut à gauche de la page. Le code instancie ensuite le moteur k3d puis constitue le logo 3D d’HTML5 à l’aide 5 différentes faces.&lt;/p&gt;

&lt;p&gt;Par exemple, le code de cette 1ère face :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;obj1 = &lt;span style="color: blue"&gt;new &lt;/span&gt;K3D.K3DObject();
&lt;span style="color: blue"&gt;with &lt;/span&gt;(obj1)
{
   drawmode = &lt;span style="color: maroon"&gt;&amp;quot;solid&amp;quot;&lt;/span&gt;;
   shademode = &lt;span style="color: maroon"&gt;&amp;quot;lightsource&amp;quot;&lt;/span&gt;;
   sortmode = &lt;span style="color: maroon"&gt;&amp;quot;unsorted&amp;quot;&lt;/span&gt;;
   addphi = -0.5;
   abouty = OBJMOVEY;
   scale = OBJSCALE;
   perslevel = 1000;
   init(
      [{x:-80,y:180,z:0},{x:0,y:180,z:-80},{x:0,y:0,z:-80},{x:-80,y:20,z:0},{x:-50,y:150,z:-30},&lt;br /&gt;       {x:0,y:150,z:-80},{x:0,y:130,z:-80},{x:-30,y:130,z:-50},{x:-28,y:110,z:-52},{x:0,y:110,z:-80},&lt;br /&gt;       {x:0,y:90,z:-80},{x:-45,y:90,z:-35},{x:-44,y:80,z:-36},{x:-25,y:80,z:-55},{x:-22,y:66,z:-58},&lt;br /&gt;       {x:0,y:60,z:-80},{x:0,y:40,z:-80},{x:-40,y:50,z:-40}],
      [],
      [{color:[227,76,38],vertices:[0,1,2,3,0]},{color:[235,235,235],vertices:[4,5,6,7,8,9,10,11,4]},&lt;br /&gt;       {color:[235,235,235],vertices:[12,13,14,15,16,17,12]}]
   );
}
k3dmain.addK3DObject(obj1);&lt;/pre&gt;

&lt;p&gt;Donne le résultat suivant :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Logo3Dfun3 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5766091166/"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; border-top: 0px; border-right: 0px; padding-top: 0px" border="0" alt="HTML5Logo3Dfun3" src="http://farm4.static.flickr.com/3554/5766091166_90ba560825_t.jpg" width="54" height="82" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voilà, vous savez tout maintenant. Allez, bon week-end !&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;
&lt;script src="http://david.blob.core.windows.net/html5/mathlib-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/k3d-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/html5logo.js"&gt;&lt;/script&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10169184" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Canvas/">Canvas</category></item><item><title>Hands-On Lab: Making Silverlight Applications Accessible</title><link>http://blogs.msdn.com/b/davrous/archive/2011/05/26/hands-on-lab-making-silverlight-applications-accessible.aspx</link><pubDate>Thu, 26 May 2011 12:31:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10168627</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10168627</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/05/26/hands-on-lab-making-silverlight-applications-accessible.aspx#comments</comments><description>&lt;p&gt;We have delivered a 2 days training in France around Accessibility. One slot of these 2 days was dedicated to Silverlight. As accessibility is something really important in building RIA applications, here is the complete lab to follow if you’d like to better understand how to build accessible Silverlight applications.&lt;/p&gt;  &lt;p&gt;You can download the very same instructions in a Word Document format as well as the Visual Studio solutions to work with during this lab here :&lt;/p&gt;  &lt;p&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-0ee4bd0f5ea745c6.office.live.com/embedicon.aspx/.Public/HOL%20-%20Making%20Silverlight%20Applications%20Accessible.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;h4&gt;&lt;a name="_Toc291763268"&gt;Estimated time to complete this lab&lt;/a&gt; : &lt;b&gt;60 minutes      &lt;br /&gt;&lt;/b&gt;&lt;/h4&gt;  &lt;h3&gt;&lt;a name="_Toc291763269"&gt;Objectives&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;The objective of this lab is to learn about how you can build accessible UI with Silverlight.&lt;/p&gt;  &lt;p&gt;After completing this lab, you will be able to:    &lt;br /&gt;· Understand how Silverlight offer ready to use accessible controls.     &lt;br /&gt;· Take care of basic accessibility principles like high contrast or zooming with Silverlight applications&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Important Note&lt;/strong&gt;: The exercises in this lab are intended to provide an overview of the technology presented. They are not intended to, and may not follow, Microsoft best practices or guidance on the technologies presented.&lt;/p&gt;  &lt;h4&gt;&lt;a name="_Toc291763270"&gt;Prerequisites&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;You’ll need Visual Studio 2010 or Visual Web Developer Express 2010 with the Silverlight Tools installed to follow this lab. You can use Web Platform Installer to setup your machine: &lt;a href="http://www.microsoft.com/web/downloads/platform.aspx"&gt;http://www.microsoft.com/web/downloads/platform.aspx&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;&lt;a name="_Toc291763271"&gt;Getting Started&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;The Hands-On Lab files available in the above ZIP archive to download contains a number of additional resources. &lt;/p&gt;  &lt;p&gt;This lab includes the following additional resources: &lt;/p&gt;  &lt;p&gt;   &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="201"&gt;           &lt;p&gt;The Lab Manual&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="244"&gt;           &lt;p&gt;&lt;i&gt;HOL – Making Silverlight Applications Accessible.docx&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="276"&gt;           &lt;p&gt;Equivalent of this blog post&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="201"&gt;           &lt;p&gt;Source CodeDC01&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="244"&gt;           &lt;p&gt;&lt;i&gt;Before\&lt;/i&gt; &lt;i&gt;Exercice1.Task1               &lt;br /&gt;&lt;/i&gt;&lt;i&gt;After\&lt;/i&gt; &lt;i&gt;Exercice1.Task1DC01&lt;/i&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="276"&gt;           &lt;p&gt;Lab exercise 1 source code             &lt;br /&gt;Completed lab exercise 1 source code&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;p&gt;This lab is mainly based on this excellent article: &lt;a href="http://www.silverlight.net/learn/quickstarts/accessibility/"&gt;http://www.silverlight.net/learn/quickstarts/accessibility/&lt;/a&gt; . &lt;/p&gt;  &lt;h3&gt;&lt;a name="_Toc291763274"&gt;Exercise 1 – Keyboard Support&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;Estimated time to complete this exercise: &lt;b&gt;30 minutes&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;To provide good keyboard support, you must ensure that every part of your application can be used with a keyboard. If your application makes heavy use of the standard controls, you are most of the way there already. The Silverlight control library provides built-in keyboard support including tab navigation, text input, and control-specific support such as arrow key navigation among &lt;b&gt;ListBox&lt;/b&gt; items and &lt;b&gt;DataGrid&lt;/b&gt; cells.&lt;/p&gt;  &lt;p&gt;In this exercise, you will: &lt;/p&gt;  &lt;p&gt;1. Add Tab Navigation    &lt;br /&gt;2. Add Keyboard Alternatives to Mouse Events     &lt;br /&gt;3. Handle Shortcut Keys and set the focus to the Silverlight Plug-in&lt;/p&gt;  &lt;h4&gt;&lt;a name="_Toc291763275"&gt;Task 1 – Adding Tab Navigation support&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;To use the keyboard with a control, it must have input focus, and to receive input focus (without using the mouse), it must be accessible via tab navigation. By default, the tab order of controls is the same as the order in which they are added to a design surface, listed in XAML, or programmatically added to a container.&lt;/p&gt;  &lt;p&gt;In most cases, the default order is the best order, especially because that is the order in which the controls are read by screen readers. However, the default order does not necessarily correspond to the visual order. The actual display position depends on the containing &lt;b&gt;Panel&lt;/b&gt; and the values of properties such as &lt;b&gt;Margin&lt;/b&gt;, &lt;b&gt;Canvas.Top&lt;/b&gt; and &lt;b&gt;Canvas.Left&lt;/b&gt;, or &lt;b&gt;Grid.Row&lt;/b&gt; and &lt;b&gt;Grid.Column&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;You can ensure that the tab order matches the visual order by adjusting the XAML, or you can override the default tab order by setting the &lt;b&gt;TabIndex&lt;/b&gt; property, as shown in the following example of a &lt;b&gt;Grid&lt;/b&gt; layout that uses column-first tab navigation.&lt;/p&gt;  &lt;p&gt;&lt;font color="#008000"&gt;&lt;strong&gt;Perform the following tasks:&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#008000"&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/font&gt;. Open the initial VS2010 project named “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Exercice1.Task1&lt;/font&gt;&lt;/strong&gt;” available in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Before&lt;/font&gt;&lt;/strong&gt;” folder. Launch it and see how you can navigate into the controls using the Tab key.&lt;/p&gt;  &lt;p&gt;&lt;font color="#008000"&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/font&gt;. Using the TabIndex property on each TextBox control, change the default way to navigate to match this order :&lt;/p&gt;  &lt;p&gt;&lt;a title="sllabacc_image1 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5761741852/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="sllabacc_image1" src="http://farm6.static.flickr.com/5261/5761741852_c7b0f51b66.jpg" width="454" height="94" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Tab navigation cycles through all controls in both the browser host and the application, and then repeats the cycle from the beginning. Users can navigate backward through the tab order by pressing SHIFT+TAB.&lt;/p&gt;  &lt;p&gt;If you want to exclude a control from the tab order, you can set the &lt;b&gt;IsTabStop&lt;/b&gt; property to &lt;b&gt;false&lt;/b&gt;. However, you will typically do this only if you make a control non-interactive, for example by setting its &lt;b&gt;IsEnabled&lt;/b&gt; property to &lt;b&gt;false&lt;/b&gt;, which automatically excludes it from the tab order. &lt;/p&gt;  &lt;p&gt;&lt;font color="#008000"&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/font&gt;. Solution is available in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;After&lt;/font&gt;&lt;/strong&gt;” folder&lt;/p&gt;  &lt;h4&gt;&lt;a name="_Toc291763276"&gt;Task 2 – Adding Keyboard alternatives to mouse events&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;If you implement any mouse-specific interactions, you should implement keyboard equivalents. However, in order to use the keyboard with a UI element, the element must have input focus. Only classes that derive from &lt;b&gt;Control&lt;/b&gt; support input focus and tab navigation. &lt;/p&gt;  &lt;p&gt;You could create your own custom control, in which case you must set the &lt;b&gt;IsTabStop&lt;/b&gt; property to &lt;b&gt;true&lt;/b&gt; to enable input focus and provide a visual indication of the focused state using the &lt;b&gt;VisualStateManager&lt;/b&gt; class. However, it is often easier to make use of Silverlight control composition.&lt;/p&gt;  &lt;p&gt;&lt;font color="#008000"&gt;&lt;strong&gt;Perform the following tasks:&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;1&lt;/font&gt;&lt;/strong&gt;. Open the initial VS2010 project named “&lt;font color="#9b00d3"&gt;&lt;strong&gt;Exercice1.Task2&lt;/strong&gt;&lt;/font&gt;” available in the “&lt;font color="#9b00d3"&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/font&gt;” folder. Launch it and see that you can only throw the click event with the mouse. Moreover, you can’t navigate via the Tab key through the controls.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;2&lt;/font&gt;&lt;/strong&gt;. Instead of handling a mouse event on an &lt;b&gt;Image&lt;/b&gt;, you could wrap it in a &lt;b&gt;Button&lt;/b&gt; to get mouse, keyboard, and focus support automatically. Modify the 2 elements to do so. For instance, modify the following piece of XAML:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btn1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Images/datagrid.png&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;29&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;32&amp;quot;  /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;MenuLabel&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Table&amp;quot;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTipService.ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;16&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Insert table&amp;quot;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTipService.ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btn1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.RowSpan&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;20,10,10,10&amp;quot; &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: red"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Left&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Click&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;TableClick&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image  &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Images/datagrid.png&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;29&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;32&amp;quot; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;MenuLabel&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Table&amp;quot;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTipService.ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;16&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Insert table&amp;quot;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTipService.ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;3&lt;/font&gt;&lt;/strong&gt;. Do the same modification on the second StackPanel to embed it inside another button. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;4&lt;/font&gt;&lt;/strong&gt;. Launch the project. You should now be able to navigate on the controls using the Tab key and call the click event using the Space key :&lt;/p&gt;

&lt;p&gt;&lt;a title="sllabacc_image2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5761741922/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="sllabacc_image2" src="http://farm4.static.flickr.com/3284/5761741922_9af64f1d67.jpg" width="462" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your Silverlight application is now accessible with the keyboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;5&lt;/font&gt;&lt;/strong&gt;. To go a step further, you can emphasis where the user has clicked by adding specific contrast to the element. For instance, add to the following style to both buttons :&lt;/p&gt;

&lt;p&gt;&lt;span style="color: red"&gt;Style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;ToolBarButtons&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;6&lt;/font&gt;&lt;/strong&gt;. Relaunch your Silverlight application and notice the difference when you’re clicking on one of the buttons :&lt;/p&gt;

&lt;p&gt;&lt;a title="sllabacc_image3 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5761197595/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="sllabacc_image3" src="http://farm4.static.flickr.com/3522/5761197595_339908b918.jpg" width="500" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;7&lt;/font&gt;&lt;/strong&gt;. Have a look to the App.xaml file to find where this style is defined. The change states are handled by the VisualStateManager. This is very important to work with it while building Accessible Silverlight applications. That’s why you should always try to start from core Silverlight controls already providing the default states to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;8&lt;/font&gt;&lt;/strong&gt;. Try changing the red rectangle by a green rectangle when the button is pressed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;9&lt;/font&gt;&lt;/strong&gt;. You’ll find the final solution on the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;After&lt;/font&gt;&lt;/strong&gt;” folder.&lt;/p&gt;

&lt;h4&gt;&lt;a name="_Toc291763277"&gt;Task 3 – Adding Shortcut Keys&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Tab navigation provides a good, basic level of keyboard support, but with complex forms, you might want to add support for shortcut keys as well. This can make your application more efficient to use, even for people who use both a keyboard and a mouse. &lt;/p&gt;

&lt;p&gt;Silverlight does not provide the kind of built-in shortcut key support that you find in Windows Presentation Foundation (WPF) or Windows Forms. One issue with shortcut keys in Silverlight is that many key combinations are intercepted by the browser host or operating system. Additionally, browser updates can add new shortcut keys at any time, creating unanticipated future conflicts.&lt;/p&gt;

&lt;p&gt;It is possible to implement your own shortcut key support, but you should test shortcut keys in all supported browsers. To avoid conflicts, you should not use modifier keys such as CTRL, SHIFT, and ALT. However, in some cases, such as data-entry applications, this is not practical.&lt;/p&gt;

&lt;p&gt;If you require modifier keys, one option is to require out-of-browser installation, although even in this case, you cannot use the ALT key. Another option is to use keystrokes that are less likely to cause conflict, such as number keys in combination with CTRL+SHIFT. Using number keys is also beneficial to avoid potential issues with language-dependent letter keys in localized applications. &lt;/p&gt;

&lt;p&gt;It is important to document the shortcut keys in your application so that users are aware of them. For example, you can provide a ToolTip on a button that has a shortcut key. You can also use the convention of underlining a letter in a control label. This kind of shortcut key is called an access key or mnemonic. Of course, ToolTips are not useful without a mouse, and neither ToolTips nor underlined letters are reported by screen readers.&lt;/p&gt;

&lt;p&gt;You can document access keys through screen readers by setting the &lt;b&gt;AutomationProperties.AccessKey&lt;/b&gt; attached property to a string that describes the shortcut key. There is also an &lt;b&gt;AutomationProperties.AcceleratorKey&lt;/b&gt; attached property for documenting non-mnemonic shortcut keys, although screen readers generally treat both properties the same way. In general, you should document shortcut keys in multiple ways, using ToolTips, automation properties, and written help documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;Perform the following tasks:&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;1&lt;/font&gt;&lt;/strong&gt;. Open the initial VS2010 project named “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Exercice1.Task3&lt;/font&gt;&lt;/strong&gt;” available in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Before&lt;/font&gt;&lt;/strong&gt;” folder or continue on your project built during the Task2. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;2&lt;/font&gt;&lt;/strong&gt;. We’re going to map to T key to the insert table action and the O key to the open file action. For that, set the following property :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: red"&gt;AutomationProperties.AccessKey
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;On both buttons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;3&lt;/font&gt;&lt;/strong&gt;. You need to tell to the user also which key is used for each action. There are 2 good things to do for that: adding an underline on the appropriate character and document it inside the tooltip. Use this piece of XAML to reflect these changes in your application :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;MenuLabel&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Underline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;T&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Underline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;able&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTipService.ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;16&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Insert table - Shortcut Key: T&amp;quot;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTipService.ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;4&lt;/font&gt;&lt;/strong&gt;. Do the same for the second button and launch your application. You will then be able to simulate the click by pressing the ‘T’ and ‘O’ keys. However, you have maybe seen that you need to provide the focus to the Silverlight application first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;5&lt;/font&gt;&lt;/strong&gt;. Indeed, another issue with shortcut keys in Silverlight is that Silverlight cannot receive any keystrokes unless the Silverlight plug-in itself has input focus. If the Silverlight plug-in is only part of a web page that has other content, users will need to tab to or click the plug-in before they can use the keyboard with it. If the plug-in occupies the entire page, however, you can add the following code to ensure that the plug-in receives focus as soon as the page finishes loading :&lt;/p&gt;

&lt;pre class="code"&gt;LayoutRoot.Loaded += (sender, e) =&amp;gt; System.Windows.Browser.&lt;span style="color: #2b91af"&gt;HtmlPage&lt;/span&gt;.Plugin.Focus();&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;6&lt;/font&gt;&lt;/strong&gt;. If you launch your application after adding this code, you’ll see that you will be able to immediately use the shortcut keys as now the Silverlight application get the focus by default. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;7&lt;/font&gt;&lt;/strong&gt;. You’ll find the solution in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;After&lt;/font&gt;&lt;/strong&gt;” folder as usual.&lt;/p&gt;

&lt;h3&gt;&lt;a name="_Toc291763278"&gt;Exercise 2 – &lt;/a&gt;Screen Reader Support&lt;/h3&gt;

&lt;p&gt;Estimated time to complete this exercise: &lt;b&gt;10 minutes&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Screen readers provide access to the text in an application by rendering it some other format, such as spoken language or Braille output. The exact behavior of a screen reader depends on the software and on the user configuration of the software.&lt;/p&gt;

&lt;p&gt;For example, some screen readers read the entire application UI when the user launches or switches to the application, enabling the user to receive all of the available informational content before using tab navigation. Some screen readers also read the text associated with an individual control when it receives input focus during tab navigation. This enables users to orient themselves as they navigate among the input controls of an application. Narrator is an example of a screen reader that uses both behaviors.&lt;/p&gt;

&lt;p&gt;On the other hand, some screen readers read the text of an application only during tab navigation. For this reason, you should ensure that all important information in your UI is part of a focusable control. For example, instead of using a &lt;b&gt;TextBlock&lt;/b&gt; to convey application instructions in your UI, you might use a &lt;b&gt;TextBox&lt;/b&gt; or &lt;b&gt;RichTextBox&lt;/b&gt; with an &lt;b&gt;IsReadOnly&lt;/b&gt; property value of &lt;b&gt;true&lt;/b&gt;. This enables the control to receive focus while preventing user input.&lt;/p&gt;

&lt;p&gt;In this exercise, you will: &lt;/p&gt;

&lt;p&gt;1. Add support for screen reader &lt;/p&gt;

&lt;h4&gt;&lt;a name="_Toc291763279"&gt;Task 1 – Adding support for screen reader&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;To support screen readers, you must provide text alternatives to non-textual information in the UI, such as images and charts, excluding any purely decorative or structural elements. You can do this by setting the &lt;b&gt;AutomationProperties.Name&lt;/b&gt; attached property&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;Perform the following tasks:&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;1&lt;/font&gt;&lt;/strong&gt;. Open the initial VS2010 project named “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Exercice2.Task1&lt;/font&gt;&lt;/strong&gt;” available in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Before&lt;/font&gt;&lt;/strong&gt;” folder. Launch it the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;2&lt;/font&gt;&lt;/strong&gt;. Launch the narrator by clicking on the Start button of Windows 7 and search for the “Narrator” application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;3&lt;/font&gt;&lt;/strong&gt;. Set the focus on the buttons and listen to what the narrator says. It will say “Tabulation, Button under Silverlight control”. The user has no way to know what the purpose of the button is. He just knows this is a Silverlight button.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;4&lt;/font&gt;&lt;/strong&gt;. Switch back to the code and set the value of &lt;b&gt;AutomationProperties.Name &lt;/b&gt;attached property to each button with “Insert Table” and “Open File”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;5&lt;/font&gt;&lt;/strong&gt;. Launch the application and use the narrator again. Now, it should say “Insert Table Button” and “Open File Button” when you navigate on the 2 buttons using the keyboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;6&lt;/font&gt;&lt;/strong&gt;. You’ll find the solution in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;After&lt;/font&gt;&lt;/strong&gt;” folder as usual.&lt;/p&gt;

&lt;h3&gt;&lt;a name="_Toc291763280"&gt;Exercise 3 – &lt;/a&gt;User Display Settings&lt;/h3&gt;

&lt;p&gt;Estimated time to complete this exercise: &lt;b&gt;20 minutes&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Users can adjust some display settings at the operating system level or in the host browser. Some of these settings automatically affect Silverlight, while others require some additional work or separate implementation.&lt;/p&gt;

&lt;p&gt;Users prefer to configure their display settings at a global level rather than figuring out how to adjust each individual application, so it is a good idea to take advantage of global settings whenever possible. In some cases, however, you will want to provide additional support, and Silverlight enables you to implement arbitrary display customizability that has no relationship to operating system or browser settings. &lt;/p&gt;

&lt;p&gt;In this exercise, you will: &lt;/p&gt;

&lt;p&gt;1. Know how to dynamically change the size of elements and of the fonts
  &lt;br /&gt;2. Know how to handle the high contrast mode&lt;/p&gt;

&lt;h4&gt;&lt;a name="_Toc291763281"&gt;Task 1 – &lt;/a&gt;Size Settings&lt;/h4&gt;

&lt;p&gt;Adjusting display sizes at the operating system level affects everything displayed on the monitor, including all Silverlight-based applications both inside and outside the browser.&lt;/p&gt;

&lt;p&gt;Outside the browser, increased size settings result in fuzziness and pixelization. Inside the browser, display size settings affect the browser zoom setting (for browsers that support zoom settings), which results a smooth, vector-based scaling of browser-hosted Silverlight applications. The following illustration shows the difference between browser zoom and out-of-browser zoom.&lt;/p&gt;

&lt;p&gt;&lt;a title="sllabacc_image4 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5761784000/"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; border-top: 0px; border-right: 0px; padding-top: 0px" border="0" alt="sllabacc_image4" src="http://farm6.static.flickr.com/5187/5761784000_70b8b1ec46.jpg" width="483" height="333" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In browsers that support zoom settings, users can set the browser zoom level independently of the operating system display settings. In this case, however, out-of-browser applications are not affected.&lt;/p&gt;

&lt;p&gt;For Silverlight-based applications hosted in the browser, you can customize the effect of the browser zoom setting by using the &lt;b&gt;Settings.EnableAutoZoom&lt;/b&gt; and &lt;b&gt;Content.ZoomFactor&lt;/b&gt; properties and the &lt;b&gt;Content.Zoomed&lt;/b&gt; event. This is useful for making dynamic layout adjustments. &lt;/p&gt;

&lt;p&gt;You can also implement your own display size settings that works regardless of operating system and browser settings. Browser text size settings have no effect on Silverlight, so implementing your own approach is necessary if you want to scale text independently of other UI elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;Perform the following tasks:&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;1&lt;/font&gt;&lt;/strong&gt;. Open the initial VS2010 project named “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Exercice3.Task1&lt;/font&gt;&lt;/strong&gt;” available in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Before&lt;/font&gt;&lt;/strong&gt;” folder. Launch the application to see what it does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;2&lt;/font&gt;&lt;/strong&gt;. The aim of this exercise is to change dynamically the size of the user control and the size of the font by using the 2 sliders available. Let’s start by changing the size of the font using the 2&lt;sup&gt;nd&lt;/sup&gt; slider. We’re going to use the element to element binding of Silverlight to do that. Add this property on the UserControl :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Value&lt;/span&gt;&lt;span style="color: blue"&gt;, &lt;/span&gt;&lt;span style="color: red"&gt;ElementName&lt;/span&gt;&lt;span style="color: blue"&gt;=FontZoomSlider}&amp;quot;
&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;3&lt;/font&gt;&lt;/strong&gt;. Thanks to this code, the FontSize property will be automatically updated based on the value of the FontZoomSlider element. This shows you how to let the user choosing the proper size for him.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;4&lt;/font&gt;&lt;/strong&gt;. We’re now going to see how to zoom the complete user control by using a simple transform operation. For that, add this XAML part inside the UserControl:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.RenderTransform&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ScaleTransform &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;transform&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;CenterX&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;200&amp;quot; 
        &lt;/span&gt;&lt;span style="color: red"&gt;ScaleX&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Value&lt;/span&gt;&lt;span style="color: blue"&gt;, &lt;/span&gt;&lt;span style="color: red"&gt;ElementName&lt;/span&gt;&lt;span style="color: blue"&gt;=UIZoomSlider}&amp;quot; 
        &lt;/span&gt;&lt;span style="color: red"&gt;ScaleY&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Value&lt;/span&gt;&lt;span style="color: blue"&gt;, &lt;/span&gt;&lt;span style="color: red"&gt;ElementName&lt;/span&gt;&lt;span style="color: blue"&gt;=UIZoomSlider}&amp;quot;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.RenderTransform&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;




&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;5&lt;/font&gt;&lt;/strong&gt;. We’re simply scaling the element using a RenderTransform, playing with the ScaleX &amp;amp; ScaleY properties binded to the UIZoomSlider value. &lt;/p&gt;

&lt;h4&gt;&lt;a name="_Toc291763282"&gt;Task 2 – Color and High Contrast Settings&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Many users have difficulty distinguishing certain colors or experience discomfort when viewing UIs with bright colors or insufficient contrast. It is therefore useful to provide the option to change the default colors, or at least to switch to a high contrast mode.&lt;/p&gt;

&lt;p&gt;If users select a high contrast setting at the operating system level, your application should respond to it and switch to high contrast mode automatically. You can do this by checking the &lt;b&gt;SystemParameters.HighContrast&lt;/b&gt; property when your UI loads. Note, however, that your application cannot automatically detect changes to this property, so it is helpful to provide your own UI in addition to checking the operating system setting.&lt;/p&gt;

&lt;p&gt;Another option is to use the System Colors theme provided by the Silverlight Toolkit. This theme automatically applies the current system colors (including high contrast colors) to all of the controls provided by Silverlight and the toolkit. For more information, see the &lt;a href="http://silverlight.codeplex.com/"&gt;Silverlight Toolkit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following example demonstrates how to use the &lt;b&gt;Style&lt;/b&gt; class and the &lt;b&gt;SystemParameters.HighContrast&lt;/b&gt; property to implement a high contrast mode. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;Perform the following tasks:&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;1&lt;/font&gt;&lt;/strong&gt;. Open the initial VS2010 project named “Exercice3.Task2” available in the “Before” folder. Launch the application to see what it does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;2&lt;/font&gt;&lt;/strong&gt;. The idea here is to change the color and contrast of the controls if the user has set the high contrast mode of Windows or if he’s enabling the checkbox. You’ll notice by looking at the XAML that there are 2 styles currently available. We then need a method that will apply these styles based on the current mode chosen by the user. &lt;/p&gt;

&lt;p&gt;Here is the based method for that:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;SetHighContrast(&lt;span style="color: #2b91af"&gt;Boolean &lt;/span&gt;highContrast)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(highContrast)
    {
        ContentBlock.Style =
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Resources[&lt;span style="color: #a31515"&gt;&amp;quot;ContentBlockHighContrastStyle&amp;quot;&lt;/span&gt;] &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Style&lt;/span&gt;;
        ContentBorder.Style =
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Resources[&lt;span style="color: #a31515"&gt;&amp;quot;ContentBorderHighContrastStyle&amp;quot;&lt;/span&gt;] &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Style&lt;/span&gt;;
    }
    &lt;span style="color: blue"&gt;else
    &lt;/span&gt;{
        ContentBlock.Style =
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Resources[&lt;span style="color: #a31515"&gt;&amp;quot;ContentBlockDefaultStyle&amp;quot;&lt;/span&gt;] &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Style&lt;/span&gt;;
        ContentBorder.Style =
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Resources[&lt;span style="color: #a31515"&gt;&amp;quot;ContentBorderDefaultStyle&amp;quot;&lt;/span&gt;] &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Style&lt;/span&gt;;
    }
}&lt;/pre&gt;




&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;3&lt;/font&gt;&lt;/strong&gt;. We now need to call this method during the initialization process of the Silverlight application checking the current contrast mode of Windows. Add this code into the constructor of the MainPage:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SystemParameters&lt;/span&gt;.HighContrast)
{
    SetHighContrast(&lt;span style="color: blue"&gt;true&lt;/span&gt;);
    HighContrastCheckBox.IsChecked = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
}&lt;/pre&gt;




&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;4&lt;/font&gt;&lt;/strong&gt;. Enable the high contrast mode of Windows (Left Alt + Left Shift + Print Screen) and launch your Silverlight application. The checkbox should be checked and the High Contrast Style should be applied. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;5&lt;/font&gt;&lt;/strong&gt;. Last step is to change the style by checking/unchecking the checkbox. You can use this piece of code for that:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;HighContrastCheckBox_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
    SetHighContrast(HighContrastCheckBox.IsChecked.Value);
}&lt;/pre&gt;




&lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;6&lt;/font&gt;&lt;/strong&gt;. If you want to see how far you can go on this topic, open the solution in the “&lt;strong&gt;&lt;font color="#9b00d3"&gt;After&lt;/font&gt;&lt;/strong&gt;” folder named “&lt;strong&gt;&lt;font color="#9b00d3"&gt;Exercice3.Task2.SLToolkit&lt;/font&gt;&lt;/strong&gt;” and check out the available “&lt;strong&gt;Basic Theme&lt;/strong&gt;” that works well with the high contrast mode of Windows.&lt;/p&gt;

&lt;h3&gt;&lt;a name="_Toc291763276"&gt;&lt;font color="#000000"&gt;Others&lt;/font&gt;&lt;/a&gt;&lt;font color="#000000"&gt; ressources&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;- MIX09 &amp;amp; MIX10 Sessions : 
  &lt;br /&gt;&amp;#160;&amp;#160; - &lt;a href="http://videos.visitmix.com/MIX09/T65M"&gt;Building Accessible RIAs in Microsoft Silverlight&lt;/a&gt;

  &lt;br /&gt;&amp;#160;&amp;#160; - &lt;a href="http://ecn.channel9.msdn.com/o9/mix/10/wmv/CL51.wmv"&gt;CL51- Building an Accessible Microsoft Silverlight Experience&lt;/a&gt; and you can download the presentation &lt;a href="http://live.visitmix.com/Archive"&gt;here&lt;/a&gt;. 

  &lt;br /&gt;- Silverlight Accessibility Issues and Proposed Guidelines by Hitachi : &lt;a href="http://www.hitachi.co.jp/universaldesign/silverlight/en/guideline.html"&gt;http://www.hitachi.co.jp/universaldesign/silverlight/en/guideline.html&lt;/a&gt;

  &lt;br /&gt;- Making Silverlight Applications Accessible : &lt;a href="http://www.silverlight.net/learn/quickstarts/accessibility/"&gt;http://www.silverlight.net/learn/quickstarts/accessibility/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10168627" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Silverlight+Toolkit/">Silverlight Toolkit</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Mix09/">Mix09</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Mix10/">Mix10</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Accessibilit_E900_/">Accessibilité</category></item><item><title>Slides, vidéo et exemples de ma présentation des Microsoft Days et du ReMix11 sur HTML5</title><link>http://blogs.msdn.com/b/davrous/archive/2011/05/20/slides-et-exemples-de-ma-pr-233-sentation-des-microsoft-days-et-du-remix11-sur-html5.aspx</link><pubDate>Fri, 20 May 2011 14:31:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10166700</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10166700</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/05/20/slides-et-exemples-de-ma-pr-233-sentation-des-microsoft-days-et-du-remix11-sur-html5.aspx#comments</comments><description>&lt;p&gt;Vous êtes nombreux à m’avoir réclamé la présentation que j’ai initialement jouée lors du ReMix11 et intitulée : “&lt;strong&gt;HTML5: Etat des lieux et projection vers l’avenir&lt;/strong&gt;”. J’ai ensuite joué la même présentation au cours de certaines dates de l’évènement &lt;a href="www.microsoftdays.fr"&gt;Microsoft Days&lt;/a&gt; comme à Rennes par exemple. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Mise à jour le 01/07/2011 &lt;/strong&gt;: ajout de la vidéo enregistrée en mai à Microsoft France au format Silverlight Smooth Streaming et HTML5 (h264/WebM). &lt;/p&gt;  &lt;h2&gt;Présentation&lt;/h2&gt;  &lt;p&gt;&lt;iframe height="327" src="http://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SDEE4BD0F5EA745C6!731&amp;amp;p4=" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;p&gt;A noter que j’ai fait une petite boulette (qui malheureusement a été reprise en boucle sur Twitter après le ReMix11) sur les parts de marché des “navigateurs HTML5”. J’avais oublié d’ajouter la part de marché du navigateur Safari 5… (hum, hum). Cela fait donc passer le chiffre de 33% à environ 38% au niveau mondial. Mea Culpa ! Mon approche a été d’ajouter les parts cumulées d’IE9 + FF 4.0 + FF 3.6 + Chrome 8/9/10/11/12 + Opera 10/11 depuis le site &lt;a title="http://www.netmarketshare.com/browser-market-share.aspx?qprid=2" href="http://www.netmarketshare.com/browser-market-share.aspx?qprid=2"&gt;Netmarketshare.com&lt;/a&gt;. Sachant que chacun de ces navigateurs dispose de support disparate de “HTML5”. Mais cela donne déjà une idée. &lt;/p&gt;  &lt;h2&gt;Vidéo&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;object type="application/x-silverlight-2" data="data:application/x-silverlight-2," width="768" height="432"&gt; 	 &lt;param name="minRuntimeVersion" value="4.0.50401.0" /&gt;&lt;param name="source" value="http://channel9.msdn.com/scripts/Channel9.xap?v=1.5" /&gt; 	 &lt;param name="initParams" value="mediaurl=http://smooth.ch9.ms/ch9/0426/d1ca1a74-73af-4d93-9d29-9f1200d60426/ReMix2011HTML5.ism/manifest,thumbnail=http://media.ch9.ms/ch9/0426/d1ca1a74-73af-4d93-9d29-9f1200d60426/ReMix2011HTML5_512_ch9.jpg,deliverymethod=adaptivestreaming,autoplay=false,entryid=d1ca1a7473af4d939d299f1200d60426" /&gt; 	  &lt;video poster="http://media.ch9.ms/ch9/0426/d1ca1a74-73af-4d93-9d29-9f1200d60426/ReMix2011HTML5_512_ch9.jpg" controls preload width="768" height="432"&gt; 		  &lt;source src="http://media.ch9.ms/ch9/0426/d1ca1a74-73af-4d93-9d29-9f1200d60426/ReMix2011HTML5_low_ch9.mp4" /&gt; 	  &lt;source src="http://az30446.vo.msecnd.net/videos/ReMix2011HTML5.webm" /&gt; &lt;/video&gt; &lt;/object&gt;&lt;/p&gt;  &lt;h2&gt;Exemples&lt;/h2&gt;  &lt;p&gt;Par ailleurs, voici l’ensemble des démonstrations que j’ai jouées pendant cette petite heure :&lt;/p&gt;  &lt;h3&gt;Bonnes pratiques&lt;/h3&gt;  &lt;p&gt;- Exemple de l’utilisation de &lt;a href="http://www.modernizr.com/"&gt;Modernizr&lt;/a&gt; pour les éléments sémantiques d’HTML5 pour IE &amp;lt; 9 via &lt;a href="http://weblogs.asp.net/scottgu/archive/2011/05/09/html5-improvements-with-the-asp-net-mvc-3-tools-update.aspx"&gt;ASP.NET MVC 3&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Internet Explorer 9&lt;/h3&gt;  &lt;p&gt;- &lt;a title="1 - SVG Theme Park" href="http://david.blob.core.windows.net/html5graphics/002_SVGBasics_RichScene.htm"&gt;SVG Theme Park&lt;/a&gt; : démonstration d’une scène SVG sur laquelle vous pouvez faire CTRL-F pour chercher le texte par exemple     &lt;br /&gt;- &lt;a title="2 - Canvas Pad" href="http://ie.microsoft.com/testdrive/Graphics/CanvasPad/Default.html"&gt;Canvas Pad&lt;/a&gt; : petite application sympathique pour apprendre les bases de canvas     &lt;br /&gt;- &lt;a title="3 - Microsoft OneNote 2010 - Microsoft Office" href="http://www.microsoft.com/office/onenote/"&gt;Site Microsoft Office OneNote 2010&lt;/a&gt; : la dernière version du site officiel de OneNote 2010 est entièrement réalisée en HTML5 à base de canvas. Preuve s’il en est que HTML5 est déjà en parti prêt pour la production.     &lt;br /&gt;- &lt;a title="4 - World&amp;#39;s Biggest PAC-MAN" href="http://worldsbiggestpacman.com/"&gt;World's Biggest PAC-MAN&lt;/a&gt; : utilisation de canvas pour créer le plus grand PacMan de tous les temps ! L’application destinée à tuer la productivité en entreprise.     &lt;br /&gt;- &lt;a title="5 - Your Director&amp;#39;s Cut † Bon Jovi" href="http://director.bonjovi.com/"&gt;Your Director's Cut † Bon Jovi&lt;/a&gt; : une application permettant de faire son propre montage vidéo à partir de clips issus de concerts de Bon Jovi (le rêve non ?). Au programme : &amp;lt;canvas&amp;gt;, &amp;lt;video&amp;gt; et &amp;lt;svg&amp;gt;.     &lt;br /&gt;&lt;a title="6 - Simple CSS3 Media Queries" href="http://david.blob.core.windows.net/html5graphics/SimpleMediaQueries.htm"&gt;- Un exemple ultrasimple de CSS3 Media Queries&lt;/a&gt; : redimensionnez la fenêtre et cela affichera plus ou moins de doigts dans l’image de fond grâce à CSS.     &lt;br /&gt;- &lt;a title="7 - More complex CSS3 Media Queries" href="http://ie.microsoft.com/testdrive/HTML5/CSS3MediaQueries/Default.html"&gt;Un exemple plus complet de CSS3 Media Queries&lt;/a&gt; : à nouveau jouez avec les dimensions de votre fenêtre sur cet exemple plus réaliste.&lt;/p&gt;  &lt;h3&gt;Intérêts de l’accélération matérielle&lt;/h3&gt;  &lt;p&gt;&lt;a title="8 - Dailymotion Stream" href="http://www.dailymotion.com/stream"&gt;- Dailymotion Stream&lt;/a&gt; : affichage de vidéos h264 en plein écran sans plug-ins grâce à l’accélération matérielle via GPU d’IE9. J’en ai déjà parlé ici : &lt;a title="http://blogs.msdn.com/b/iefrance/archive/2011/03/24/vivez-de-belles-exp-233-riences-avec-ie9-gr-226-ce-224-l-acc-233-l-233-ration-mat-233-rielle-et-l-int-233-gration-224-windows-7.aspx" href="http://blogs.msdn.com/b/iefrance/archive/2011/03/24/vivez-de-belles-exp-233-riences-avec-ie9-gr-226-ce-224-l-acc-233-l-233-ration-mat-233-rielle-et-l-int-233-gration-224-windows-7.aspx"&gt;Vivez de belles expériences avec IE9 grâce à l’accélération matérielle et l’intégration à Windows 7&lt;/a&gt; où vous pouvez notamment voir la différence de consommation GPU entre Chrome et IE9 sur ce site.     &lt;br /&gt;- &lt;a title="8 - Lancome" href="http://www.lancome.fr/_fr/_fr/index.aspx#/home"&gt;Lancome&lt;/a&gt; : qui a entièrement refait son site web à l’identique en HTML5 par rapport à Flash. Cela leur a couté 2 fois plus cher à rendu identique. Vous pouvez lire le communiqué de presse ici : &lt;a title="http://www.microsoft.com/france/espace-presse/communiques-de-presse/fiche-communique.aspx?EID=dbb26a53-b170-420a-88d9-92398b954f50" href="http://www.microsoft.com/france/espace-presse/communiques-de-presse/fiche-communique.aspx?EID=dbb26a53-b170-420a-88d9-92398b954f50"&gt;Lancôme et Internet Explorer 9 explorent ensemble la beauté du Web&lt;/a&gt;     &lt;br /&gt;- &lt;a title="9 - SVG Girl" href="http://jsdo.it/event/svggirl"&gt;SVG Girl&lt;/a&gt; : un manga expérimental spécialement conçu pour mettre en avant IE9 et qui montre surtout ce que SVG a dans le ventre lorsqu’on le pousse un peu.     &lt;br /&gt;- &lt;a title="10 - Galactic" href="http://ie.microsoft.com/testdrive/Performance/Galactic/Default.html"&gt;Galactic&lt;/a&gt; : une démonstration utilisant la balise &amp;lt;canvas&amp;gt; pour afficher une animation de la terre qui tourne autour du soleil grâce à un moteur 3D en JavaScript. A tester sous IE9 et sous Firefox 4.0 par exemple pour se rendre compte des différences de performances potentielles entre les navigateurs sur ce sujet.     &lt;br /&gt;- &lt;a title="11 - Paintball" href="http://ie.microsoft.com/testdrive/Performance/Paintball/Default.html"&gt;Paintball&lt;/a&gt; : utilisation à nouveau du Canvas mais via l’opération de &lt;a href="http://www.w3.org/TR/2dcontext/#dom-context-2d-globalcompositeoperation"&gt;globalCompositeOperation&lt;/a&gt;. Outre à nouveau les différences importantes de performances entre IE9 et ses concurrents, on voit également un problème/bug de rendu de Chrome sur cette opération &amp;lt;canvas&amp;gt;.&lt;/p&gt;  &lt;p&gt;A ce sujet, vous pouvez trouver la suite des tests unitaires officiels du W3C sur &amp;lt;canvas&amp;gt; ici : &lt;a title="http://w3c-test.org/html/tests/approved/canvas/" href="http://w3c-test.org/html/tests/approved/canvas/"&gt;W3C approved canvas tests&lt;/a&gt; . Je vous ai par exemple montré celui-ci : &lt;a title="http://w3c-test.org/html/tests/approved/canvas/2d.drawImage.image.incomplete.omitted.html" href="http://w3c-test.org/html/tests/approved/canvas/2d.drawImage.image.incomplete.omitted.html"&gt;2d.drawImage.image.incomplete.omitted&lt;/a&gt; aujourd’hui mal rendu par Chrome mais apparemment bien géré par IE9 et Firefox 4.0. &lt;/p&gt;  &lt;p&gt;Pour la performance de l’accélération matériele, j’avais travaillé à faire des comparaisons détaillées et complètes entre les différents navigateurs le proposant par défaut ou non ici : &lt;a title="http://blogs.msdn.com/b/iefrance/archive/2011/03/04/navigateurs-web-modernes-tous-vers-l-acc-233-l-233-ration-mat-233-rielle-mais-pas-224-la-m-234-me-vitesse.aspx" href="http://blogs.msdn.com/b/iefrance/archive/2011/03/04/navigateurs-web-modernes-tous-vers-l-acc-233-l-233-ration-mat-233-rielle-mais-pas-224-la-m-234-me-vitesse.aspx"&gt;Navigateurs web modernes : tous vers l’accélération matérielle ! Mais pas à la même vitesse…&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Internet Explorer 10&lt;/h3&gt;  &lt;p&gt;Ces exemples ont pour but de montrer les orientations sur lesquelles Microsoft travaille pour l’avenir. A tester donc avec IE10 PP1 téléchargeable &lt;a href="http://ie.microsoft.com/testdrive/Info/Downloads/Default.html"&gt;ici&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;- &lt;a href="http://ie.microsoft.com/testdrive/Graphics/CSSGradientBackgroundMaker/Default.html"&gt;CSS Gradient Background Maker&lt;/a&gt; : permettant de montrer les gradients CSS3. On peut voir ici qu’il est important d’utiliser les préfixes des éditeurs pour les fonctionnalités non encore figées. Sur cet exemple, pas moins de 5 versions différentes en plus de la future version standard !     &lt;br /&gt;- &lt;a href="http://david.blob.core.windows.net/html5graphics/SimpleCSS3GridDemo.html"&gt;Un exemple ultrasimple de CSS3 Grid&lt;/a&gt; : montrant un positionnement des éléments via &lt;a href="http://dev.w3.org/csswg/css3-grid-align/"&gt;CSS3 Grid&lt;/a&gt; couplé à la puissance de CSS3 Media Queries. A ma connaissance, cette démonstration ne fonctionne que sous IE10 aujourd’hui.     &lt;br /&gt;- &lt;a href="http://david.blob.core.windows.net/html5graphics/SimpleCSS3MultiColumn.html"&gt;Un exemple simple de CSS3 Multicolumns&lt;/a&gt; : montrant l’usage du formatage du texte par CSS en plusieurs colonnes. Si vous redimensionnez la fenêtre, vous verrez le nombre de colonnes s’adapter automatiquement à la largeur. Bien que CSS3 Multi-column soit supporté par Chrome et Firefox, cette démo ne fonctionne que sous IE10 et Opera 11 car le recalcul de la largeur se fait via l’opération suivante &lt;a href="http://www.w3.org/TR/css3-values/#calc"&gt;disponible en CSS3&lt;/a&gt;: “calc(100% - 20px);” non supportée par les 2 navigateurs de chez Google et Mozilla pour l’instant.     &lt;br /&gt;- &lt;a href="http://ie.microsoft.com/testdrive/HTML5/Griddle/Default.html#popular"&gt;Griddle&lt;/a&gt; : si vous mélangez les différentes démonstrations précédentes (MediaQueries, Grid, Flexbox, Multicolumns), vous obtenez cette démo. Testez là sous IE10 et amusez vous à nouveau à redimensionner la fenêtre plus simuler les différents périphériques : PC, Tablette et téléphone. &lt;/p&gt;  &lt;h3&gt;HTML5Labs.com&lt;/h3&gt;  &lt;p&gt;- &lt;a title="http://html5labs.cloudapp.net/WebSockets/JigsawDemo/DemoGame.htm" href="http://html5labs.cloudapp.net/WebSockets/JigsawDemo/DemoGame.htm"&gt;Jigsaw Game demo&lt;/a&gt; : disponible sur notre laboratoire d’expérimentations &lt;a href="http://html5labs.com/"&gt;HTML5Labs&lt;/a&gt; et montrant un jeu entre 2 joueurs connectés utilisant canvas mais surtout WebSockets.&lt;/p&gt;  &lt;p&gt;Voilà, c’est tout ! A bientôt pour d’autres aventures.&lt;/p&gt;  &lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10166700" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Microsoft+Days/">Microsoft Days</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/GPU/">GPU</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/CSS3/">CSS3</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/SVG/">SVG</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/ReMix11/">ReMix11</category></item><item><title>Introduction aux APIs graphiques d’HTML5: SVG &amp; Canvas (2/2)</title><link>http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx</link><pubDate>Fri, 20 May 2011 07:25:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10166581</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10166581</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx#comments</comments><description>&lt;p&gt;Nous allons voir ici les scénarios clés d’utilisation de canvas ou SVG après avoir vu les bases dans l’article précédent. &lt;/p&gt;  &lt;p&gt;Cet article fait donc parti de cette série :&lt;/p&gt;  &lt;p&gt;1 – &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx"&gt;les bases de SVG et de Canvas&lt;/a&gt;     &lt;br /&gt;2 – les scénarios clés d’utilisation de ces 2 jeux d’APIs &lt;/p&gt;  &lt;p&gt;Le but du jeu étant de vous donner quelques éléments de réponse et des orientations d’usage pour vous aider à choisir le mode potentiellement le plus adapté à vos besoins. &lt;/p&gt;  &lt;h2&gt;Tableau récapitulatif des grandes différences&lt;/h2&gt;  &lt;p&gt;Commençons tout d’abord par rappeler les grandes différences entre &amp;lt;canvas&amp;gt; et SVG :&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="0" width="900"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="181" align="center"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="366" align="center"&gt;         &lt;p&gt;&lt;b&gt;&lt;font color="#000080"&gt;&amp;lt;canvas&amp;gt;&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="351" align="center"&gt;         &lt;p&gt;&lt;b&gt;&lt;font color="#000080"&gt;SVG&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="181" align="center"&gt;&lt;font color="#800080"&gt;&lt;strong&gt;Niveau d’abstraction&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td width="366" align="center"&gt;         &lt;p&gt;Basé sur les &lt;strong&gt;pixels&lt;/strong&gt; (PNG dynamique)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="351" align="center"&gt;         &lt;p&gt;Basé sur des formes &amp;amp; &lt;strong&gt;vecteurs&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="181" align="center"&gt;&lt;font color="#800080"&gt;&lt;strong&gt;Eléments&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td width="366" align="center"&gt;         &lt;p&gt;Un &lt;strong&gt;unique élément HTML &lt;/strong&gt;similaire à &amp;lt;img&amp;gt; dans son comportement&lt;/p&gt;       &lt;/td&gt;        &lt;td width="351" align="center"&gt;         &lt;p&gt;De &lt;strong&gt;nombreux éléments&lt;/strong&gt; graphiques qui font alors partis du Document Object Model (DOM)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="181" align="center"&gt;&lt;font color="#800080"&gt;&lt;strong&gt;Interaction&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td width="366" align="center"&gt;         &lt;p&gt;Modifiable uniquement par &lt;strong&gt;Script&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="351" align="center"&gt;         &lt;p&gt;Modifiable par &lt;strong&gt;Script et CSS&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="181" align="center"&gt;&lt;font color="#800080"&gt;&lt;strong&gt;Modèle évènementiel&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td width="366" align="center"&gt;         &lt;p&gt;Interaction utilisateur très &lt;strong&gt;granulaire&lt;/strong&gt; (x,y de la souris)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="351" align="center"&gt;         &lt;p&gt;Interaction utilisateur &lt;strong&gt;abstraite et gérée par le DOM&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="181" align="center"&gt;&lt;font color="#800080"&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td width="366" align="center"&gt;         &lt;p&gt;Les performances sont meilleures avec des petites surfaces et/ou un &lt;strong&gt;nombre important d’objets à l’écran (&amp;gt;10k)&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="370" align="center"&gt;         &lt;p&gt;Les performances sont meilleures avec un nombre inférieur d’objets (&amp;lt;10k) et/ou &lt;strong&gt;sur de plus larges surface de dessin&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;   &lt;br /&gt;Pour ceux qui connaissent la programmation sur Windows Phone 7, vous savez que vous avez 2 choix possibles pour vos interfaces: XNA ou Silverlight (avant l’arrivée de Mango qui peut les mélanger). Le parallèle pour moi est assez évident, XNA de part son mode “fire &amp;amp; forget” ressemble à Canvas et Silverlight par son côté vectoriel basé sur XAML à SVG. Les 2 ont donc bien évidement des avantages et des inconvénients. &lt;/p&gt;  &lt;h2&gt;Quand utiliser &amp;lt;canvas&amp;gt; et quand utiliser SVG: les scénarios évidents&lt;/h2&gt;  &lt;p&gt;Nous allons maintenant voir les bénéfices et les limitations techniques de chacune des technologies en tentant d’y inclure une forme de bon sens lorsque l’une est plus appropriée que l’autre. Tout d’abord, vous devez comprendre que &amp;lt;canvas&amp;gt; ou SVG peuvent réaliser des choses très similaires la plupart du temps. Nous allons donc tenter de mettre en exergue les scénarios ou &amp;lt;canvas&amp;gt; est particulièrement meilleur que SVG et vice-versa. Pour d’autres cas, nous verrons que le recouvrement rend difficile la prise d’un choix tranché. Alors, qu’allez-vous prendre, la pilule bleue ou la pilule verte ? (Ou les 2 ! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3583.wlEmoticon_2D00_smile_5F00_5BFB6339.png" /&gt;)&lt;/p&gt;  &lt;p&gt;&lt;a title="HTML5Graphics_008_Canvas_ou_SVG by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5713120277/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_008_Canvas_ou_SVG" src="http://farm4.static.flickr.com/3256/5713120277_e68e7a7c9c_z.jpg" width="640" height="46" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Les documents vectoriels de haute qualité&lt;/h3&gt;  &lt;p&gt;Les documents nécessitant une très haute qualité graphique ont toujours été l’un des points fort de SVG qu’ils soient très détaillés pour une visualisation ou impression, seul ou embarqué au sein d’une page Web. Par ailleurs, la nature déclarative de SVG se prête bien à sa génération depuis des outils disposant d’interface riche ou depuis des données provenant d’une base de données. La génération du XML pouvant alors se faire soit coté serveur soit côté client via JavaScript.&lt;/p&gt;  &lt;p&gt;Le type de documents que l’on voit souvent produits ensuit au format SVG peuvent être:&lt;/p&gt;  &lt;p&gt;- Des plans de construction de bâtiments    &lt;br /&gt;- Des schémas électriques ou aéronautiques     &lt;br /&gt;- Des diagrammes d’organisations hiérarchiques     &lt;br /&gt;- De la cartographie     &lt;br /&gt;- Des diagrammes biologiques     &lt;br /&gt;    &lt;br /&gt;Bref, vous voyez l’idée. Le fait de pouvoir zoomer dans ce type de document sans perte de définition rend naturellement SVG attractif. Etudions ensemble 2 exemples d’applications de cette liste.&lt;/p&gt;  &lt;p&gt;Si vous lancez dans un navigateur récent la démo &lt;a title="Real-world Diagrams" href="http://ie.microsoft.com/testdrive/Graphics/RealWorldDataAndDiagrams/Default.xhtml"&gt;Real-world Diagrams&lt;/a&gt; issue de notre site &lt;a title="Internet Explorer Test Drive" href="http://ie.microsoft.com/testdrive/Default.html"&gt;Internet Explorer Test Drive&lt;/a&gt;, vous tomberez sur une page combinant &lt;strong&gt;3 diagrammes SVG&lt;/strong&gt;. Si l’on zoom sur l’équivalent du rectangle noir ci-dessous :&lt;/p&gt;  &lt;p&gt;&lt;a title="20110422-towtucas-image2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5716652292/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="20110422-towtucas-image2" src="http://farm3.static.flickr.com/2278/5716652292_c2ac89f31b.jpg" width="302" height="123" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On obtient le résultat suivant :&lt;/p&gt;  &lt;p&gt;&lt;a title="20110422-towtucas-image3 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5716088969/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="20110422-towtucas-image3" src="http://farm4.static.flickr.com/3165/5716088969_ef2dffeaa5.jpg" width="500" height="146" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Cela nous permet tout simplement d’extraire davantage d’informations grâce au côté vectoriel de SVG. Par ailleurs, le S de SVG veut dire Scalable. Dans un contexte d’impression, on pourrait tenter de le traduire en français par “pouvant s’étirer”. Du coup, les scénarios d’impression prennent vraiment tout leur sens et vous pouvez imaginer sortir de très grands formats de tirage tout en conservant une parfaite qualité. J’en veux pour exemple ce magnifique diagramme : &lt;a title="http://ie.microsoft.com/testdrive/Graphics/MBSCustomerModel/Default.html" href="http://ie.microsoft.com/testdrive/Graphics/MBSCustomerModel/Default.html"&gt;Microsoft Dynamics Customer Model&lt;/a&gt; qui combine SVG et les fonts WOFF sur lequel vous pouvez vous amuser à zoomer et avec lequel vous pouvez imaginer de très belles impressions. &lt;/p&gt;  &lt;p&gt;&lt;a title="DiagrammeSVGCRM by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5726521925/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="DiagrammeSVGCRM" src="http://farm6.static.flickr.com/5165/5726521925_ab6e6389ef_z.jpg" width="640" height="252" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; &lt;em&gt;cet exemple semble faire planter Firefox 4.0 pour une raison que j’ignore. A tester de préférence sous IE9, Chrome, Safari ou Opera donc.&lt;/em&gt; &lt;/p&gt;  &lt;p&gt;Le 2ème exemple est sur la cartographie. Vous ne le savez peut-être pas mais&lt;strong&gt; Bing Maps et Google Maps utilisent déjà SVG&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;Lancez dans votre navigateur cette recherche dans &lt;strong&gt;Bing Maps&lt;/strong&gt; : &lt;a title="http://www.bing.com/maps/#Y3A9NDguODQ2MjgzNjA3MTc5MzV+Mi4yNzk3OTgwMTU2MTg4MDgmbHZsPTEzJnN0eT1yJnJ0cD1wb3MuNDguODM0MzEyXzIuMjY1MTAxXzM5JTIwUXVhaSUyMGR1JTIwUHIlQzMlQTlzaWRlbnQlMjBSb29zZXZlbHQlMkMlMjA5MjEzMCUyMElzc3ktbGVzLU1vdWxpbmVhdXhfX19hX35wb3MuNDguODU4MjUwMzc5NTYyMzhfMi4yOTQ0OTUwMzEyMzc2MDIyX1RvdXIlMjBFaWZmZWwlMkMlMjBWaWxsZSUyMGRlJTIwUGFyaXMlMkMlMjBGcmFuY2VfX19lXyZtb2RlPUQmcnRvcD0wfjB+MH4=" href="http://www.bing.com/maps/#Y3A9NDguODQ2MjgzNjA3MTc5MzV+Mi4yNzk3OTgwMTU2MTg4MDgmbHZsPTEzJnN0eT1yJnJ0cD1wb3MuNDguODM0MzEyXzIuMjY1MTAxXzM5JTIwUXVhaSUyMGR1JTIwUHIlQzMlQTlzaWRlbnQlMjBSb29zZXZlbHQlMkMlMjA5MjEzMCUyMElzc3ktbGVzLU1vdWxpbmVhdXhfX19hX35wb3MuNDguODU4MjUwMzc5NTYyMzhfMi4yOTQ0OTUwMzEyMzc2MDIyX1RvdXIlMjBFaWZmZWwlMkMlMjBWaWxsZSUyMGRlJTIwUGFyaXMlMkMlMjBGcmFuY2VfX19lXyZtb2RlPUQmcnRvcD0wfjB+MH4="&gt;Itinéraire de Microsoft France à la tour Eiffel&lt;/a&gt; . Vous remarquez que lorsque vous zoomez sur la carte pour suivre le tracé, il n’y a pas de perte de définition du tracé en lui-même.&lt;/p&gt;  &lt;p&gt;Si vous lancez la barre de développement d’IE9 avec la touche F12 et que vous visez le rectangle contenant le tracé, vous obtiendrez le résultat suivant :&lt;/p&gt;  &lt;p&gt;&lt;a title="HTML5Graphics_009_BingMaps by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5716703606/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_009_BingMaps" src="http://farm4.static.flickr.com/3364/5716703606_b81417ae10.jpg" width="500" height="313" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Et surprise! On découvre la présence du tag SVG déclarant le path qui va bien pour suivre l’itinéraire qui vous intéresse :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.w3.org/2000/svg&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;path &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;none&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill-opacity&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#ffffff&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-dasharray&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;solid&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-linecap&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;butt&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-opacity&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;30&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;M 291 303 L 306 286 L 316 263 L 324 252 L 331 250 L 354 209 L 360 207 L 360 202 L 363 196 L 433 117 L 449 116 L 465 95&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;path &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;none&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill-opacity&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#3333ff&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-dasharray&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;solid&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-linecap&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;butt&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-opacity&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0.713726&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;stroke-width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;4&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;M 291 303 L 306 286 L 316 263 L 324 252 L 331 250 L 354 209 L 360 207 L 360 202 L 363 196 L 433 117 L 449 116 L 465 95&amp;quot; /&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Bref, pour toutes ces raisons, on peut sereinement placer ces usages à droite de notre cadran :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_008_Canvas_ou_SVG_2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5716726090/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_008_Canvas_ou_SVG_2" src="http://farm3.static.flickr.com/2263/5716726090_169854bd7e_z.jpg" width="640" height="104" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;SVG comme format d’image&lt;/h3&gt;

&lt;p&gt;Un autre scénario d’utilisation classique du format SVG est pour le rendu d’image simple que ce soit au sein d’application ou de pages web. Cependant, comme SVG est chargé en mémoire dans le DOM et son XML analysé avant d’en créer une image, les performances peuvent être légèrement dégradées par rapport à une image classique PNG ou JPG. Malgré tout, cela reste infinitésimal comparé au cout total du rendu complet d’une page Web. Par ailleurs, l’intérêt du côté vectoriel et de la qualité du rendu associé compense plus que largement cette légère perte de performance. &lt;/p&gt;

&lt;p&gt;Prenons l’exemple ci-dessous. Ces 2 images représentent potentiellement des pastilles associées via CSS à des éléments de type &amp;lt;li&amp;gt;. Ces 2 images sont identiques en rendu et ne diffèrent que de 1 Ko (SVG étant légèrement inférieur en taille bien que non compressé) :&lt;/p&gt;

&lt;p&gt;&lt;a title="BulletsPoints1 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5725475043/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="BulletsPoints1" src="http://farm3.static.flickr.com/2121/5725475043_d65a298623_m.jpg" width="113" height="53" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le SVG est à gauche et le format PNG à droite. Visuellement, on note donc que peu de différences. Par contre, imaginons que l’on décide de réutiliser le même élément sur des écrans plus larges ou disposant d’un DPI plus élevé (ou PPP pour points par pouce en français), cela va potentiellement poser problème côté PNG. En effet, lorsque l’on va zoomer sur une image PNG, on va rapidement obtenir un résultat pixélisé : &lt;/p&gt;

&lt;p&gt;&lt;a title="BulletsPoints2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5726030994/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="BulletsPoints2" src="http://farm4.static.flickr.com/3546/5726030994_faa2a87079.jpg" width="338" height="150" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C’est toujours le même élément SVG de dessiné à gauche, le fait de zoomer ne change en rien sa taille ou sa consommation mémoire. Par contre, il va falloir envisager de générer une image PNG à une plus haute résolution si l’on veut désormais obtenir un résultat comparable à droite. Cela va donc augmenter la taille de l’élément PNG à télécharger. SVG apparait alors dans ce scénario comme un bon candidat au remplacement des éléments de type image même pour des éléments extrêmement simplistes comme cette puce de liste. &lt;/p&gt;

&lt;p&gt;&lt;a title="Cadran2 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5726068354/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Cadran2" src="http://farm6.static.flickr.com/5090/5726068354_f03b56022b_z.jpg" width="640" height="133" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Canvas pour la manipulation de pixels&lt;/h3&gt;

&lt;p&gt;Allons maintenant voir de l’autre côté du cadran avec Canvas. Comme Canvas nous permet de dessiner et manipuler une surface basée sur des pixels, plusieurs expérimentations mettant en œuvre des algorithmes plus ou moins complexes ont vu le jour sur le web. Vous pouvez par exemple trouver des exemples impressionnants de Ray tracers ou de génération de fractales. Cela me rappelle donc ma jeunesse où je passais des heures (des nuits que dis-je !) à calculer des scènes sous &lt;a href="http://www.povray.org/"&gt;POV-Ray&lt;/a&gt; ou avec &lt;a href="http://www.fractint.org/"&gt;Fractint&lt;/a&gt;. On peut également imaginer traiter des pixels existant pour effectuer des filtres dessus. &lt;/p&gt;

&lt;h4&gt;Générer des pixels depuis 0&lt;/h4&gt;

&lt;p&gt;La première approche consiste à générer une image complètement depuis 0 par code au sein du canvas. C’est ce que l’on peut faire par exemple avec un lanceur de rayons. &lt;a href="http://labs.flog.co.nz/raytracer/"&gt;L’exemple ci-dessous&lt;/a&gt; a été écrit par Adam Burmister. Le but du jeu étant donc de simuler le trajet effectué par la lumière par pixel pour obtenir de jolis effets de réfraction, réflexion, etc.&lt;/p&gt;

&lt;p&gt;&lt;a title="raytracingcanvasJS by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5725727507/"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="raytracingcanvasJS" align="left" src="http://farm6.static.flickr.com/5173/5725727507_c2e34a404b_m.jpg" width="128" height="128" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’auteur lui-même vous averti cependant avec la phrase suivante : “&lt;em&gt;This is very CPU intensive. Your browser may appear to stop responding&lt;/em&gt;” qui pourrait être traduite par “&lt;em&gt;Cela consomme beaucoup de ressource CPU. Votre navigateur pourrait sembler ne plus répondre&lt;/em&gt;”. &lt;a title="HTML5Fractal by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5726807692/"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Fractal" align="right" src="http://farm3.static.flickr.com/2615/5726807692_c044772cc4_m.jpg" width="138" height="138" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ainsi, alors que les APIs de Canvas permettent effectivement de générer de telles images, cela n’apparait pas pour autant être une très bonne idée. L’auteur &lt;a href="http://www.flog.co.nz/journal/javascript-raytracer/"&gt;résume d’ailleurs ses expérimentations&lt;/a&gt; par la phrase suivante : “&lt;em&gt;Ray-Tracing [is] The Worst Application of JavaScript Ever&lt;/em&gt;” ou “&lt;em&gt;le lancer de rayons [est] la pire des applications JavaScript imaginable&lt;/em&gt;”. &lt;/p&gt;

&lt;p&gt;Dans le même genre d’idées, on retrouve la génération des fameuses fractales de Mandelbrot en Canvas/JS comme cet exemple : &lt;a href="http://www.atopon.org/mandel/"&gt;Mandelbrot Set in HTML 5 Canvas&lt;/a&gt; et comme vous pouvez le voir sur la copie d’écran de droite. Vous pouvez jouer à zoomer dans les zones en traçant de nouveaux rectangles à la souris au sein du canvas. &lt;/p&gt;

&lt;p&gt;Cependant, aussi bons soient devenus les moteurs JavaScript des derniers navigateurs, il n’y a vraiment aucun intérêt à faire de la génération d’images artificielles en ray-tracing en JavaScript/canvas plutôt qu’en C++/C#. Mieux vaut en effet être le plus bas possible et le plus rapide possible lorsqu’il s’agit de générer des séquences d’images virtuelles. C’est pour cela que je me pose souvent l’intérêt de la présence de mini ray-tracers dans les benchmarks JavaScript. L’application concrète de ces expérimentations dans un projet réel est proche de 0. Malgré tout, je trouve l’exemple particulièrement parlant sur les possibilités de canvas versus SVG. Il en est peut-être autrement des fractales où il peut y avoir un intérêt dans le milieu scientifique ou de l’éduction de pouvoir générer des fractales et de jouer avec dynamiquement au sein d’un navigateur ou d’une plateforme supportant HTML5.&amp;#160; &lt;/p&gt;

&lt;h4&gt;Retoucher des pixels existants&lt;/h4&gt;

&lt;p&gt;Autre intérêt de pouvoir manipuler les pixels, outre de pouvoir les créer depuis 0, c’est de pouvoir retoucher ou jouer avec des pixels existants. 2 scénarios me viennent en tête : un amusant ne servant à rien et un autre pouvant servir concrètement aux applications de demain. &lt;/p&gt;

&lt;p&gt;Le 1er amusant consiste à simuler les effets d’écran bleus/verts inaugurées par le film à qui nous devons tout aujourd’hui. Je veux bien entendu parler de Star Wars ! L’idée est donc d’identifier une couleur d’arrière-plan (un fond vert ou bleu habituellement) et de remplacer cette couleur par un pixel venant d’autre part. Cela permet ainsi assez simplement d’afficher un fond fictif derrière un personnage.&lt;/p&gt;

&lt;p&gt;Or, comme on peut peintre le canvas avec des images venant d’une vidéo HTML5, on peut imaginer combiner 2 vidéos en temps réel en utilisant cette technique de remplacement de pixels. Le code suivant permet ainsi de remplacer les pixels vert d’un des canvas avec les pixels de l’autre canvas faisant exactement la même taille :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;GreenScreenAtoB(a, b) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;aImageData = a.getImageData(0, 0, a.canvas.width, a.canvas.height);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;bImageData = b.getImageData(0, 0, b.canvas.width, b.canvas.height);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;aPixels = aImageData.data;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;bPixels = bImageData.data;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(aPixels.length != bPixels.length) {
        window.alert(&lt;span style="color: maroon"&gt;&amp;quot;Vos Canvas n'ont pas exactement le même nombre de pixels!&amp;quot;&lt;/span&gt;);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;bImageData;
    }

    &lt;span style="color: blue"&gt;var &lt;/span&gt;pixelCount = bPixels.length;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;pixelIndex = 0; pixelIndex &amp;lt; pixelcount; pixelIndex += 4) {
        &lt;span style="color: #006400"&gt;// On récupère les composantes RGBA de chacun des pixels de b
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;r = bPixels[pixelIndex + 0];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;g = bPixels[pixelIndex + 1];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;b = bPixels[pixelIndex + 2];
        &lt;span style="color: blue"&gt;var &lt;/span&gt;a = bPixels[pixelIndex + 3];

        &lt;span style="color: #006400"&gt;// Et si le pixel de b est vert, on le remplace avec le pixel venant de a
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(r == 0 &amp;amp;&amp;amp; g == 255 &amp;amp;&amp;amp; b == 0 &amp;amp;&amp;amp; a == 255) {
            bPixels[pixelIndex + 0] = aPixels[pixelIndex + 0];
            bPixels[pixelIndex + 1] = aPixels[pixelIndex + 1];
            bPixels[pixelIndex + 2] = aPixels[pixelIndex + 2];
            bPixels[pixelIndex + 3] = aPixels[pixelIndex + 3];
        }
    }

    &lt;span style="color: blue"&gt;return &lt;/span&gt;bImageData;
}&lt;/pre&gt;

&lt;p&gt;Vous pouvez jouer avec un exemple utilisant 2 vidéos h264 ici : &lt;a title="http://david.blob.core.windows.net/html5graphics/canvasgreenscreen.htm" href="http://david.blob.core.windows.net/html5graphics/canvasgreenscreen.htm"&gt;Star Wars Green Effect&lt;/a&gt; . Il vous faudra donc un navigateur comme IE9 ou Safari pour le jouer et cela vous donnera ce genre de résultat :&lt;/p&gt;

&lt;p&gt;&lt;a title="StarWarsGreenEffect by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5726477777/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="StarWarsGreenEffect" src="http://farm6.static.flickr.com/5067/5726477777_c238625617_b.jpg" width="782" height="156" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cependant, comme pour les ray-tracers, la limitation que nous avons aujourd’hui avec les performances de JavaScript font qu’il n’est pas envisageable de partir en production sur cette technologie. Les outils “client lourd” de post-production vivant sur nos PC ou nos Mac ont encore de beaux jours devant eux. &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/3583.wlEmoticon_2D00_smile_5F00_5BFB6339.png" /&gt;&lt;/p&gt;

&lt;p&gt;Le 2ème scénario qui me vient en tête est bien plus intéressant dans ses applications : c’est la retouche d’image. On peut ainsi imaginer faire un effet anti-yeux rouges par exemple. Vous pouvez tester cette démonstration écrite par Daniel Glazman ici : &lt;a title="http://disruptive-innovations.com/zoo/demos/eyes.html" href="http://disruptive-innovations.com/zoo/demos/eyes.html"&gt;Exemple anti-yeux rouges&lt;/a&gt; qui met en œuvre ce principe.&lt;/p&gt;

&lt;p&gt;Mais on peut aller encore plus loin sur la manipulation d’images comme le montre &lt;a href="http://david.blob.core.windows.net/html5graphics/ManipulationCanvas.htm"&gt;l’exemple ci-dessous&lt;/a&gt; :&lt;/p&gt;

&lt;p&gt;&lt;iframe height="425" src="http://david.blob.core.windows.net/html5graphics/ManipulationCanvas.htm" width="900"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; &lt;em&gt;cet exemple semble ne bien entièrement fonctionner que sous IE9, Chrome, Opera et Safari. Apparemment, le code pose problème avec Firefox 4.0 sur l’affichage de la position de la souris au survol. Mais le reste fonctionne bien.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ce dernier est adapté de l’article suivant : &lt;a title="http://windowsteamblog.com/windows/b/developers/archive/2011/02/15/canvas-direct-pixel-manipulation.aspx" href="http://windowsteamblog.com/windows/b/developers/archive/2011/02/15/canvas-direct-pixel-manipulation.aspx"&gt;Canvas Direct Pixel Manipulation&lt;/a&gt; et ouvre de belles perspectives je pense. On peut imaginer récupérer l’histogramme d’une image, faire des effets de reflet dynamiquement sur un élément… voir même créer un éditeur en ligne d’images comme celui de &lt;a href="http://muro.deviantart.com/"&gt;DeviantArt Muro&lt;/a&gt;. A vous maintenant de laisser libre court à votre imagination ! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-10-46-metablogapi/7701.wlEmoticon_2D00_winkingsmile_5F00_2A060E1F.png" /&gt;&lt;/p&gt;

&lt;p&gt;Bref, vous aurez compris que la grande force de &amp;lt;canvas&amp;gt; sur SVG est sa capacité à manipuler les pixels. Lorsque cela fait sens et que les performances ne sont pas trop bridées par le moteur JavaScript, &amp;lt;canvas&amp;gt; est clairement la solution qu’il vous faut :&lt;/p&gt;

&lt;p&gt;&lt;a title="Cadran3 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5726651985/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Cadran3" src="http://farm6.static.flickr.com/5166/5726651985_51b6f62345_z.jpg" width="640" height="174" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Les scénarios qui se recoupent et les scénarios hybrides&lt;/h2&gt;

&lt;p&gt;La plupart des scénarios intéressants ne montrent pas souvent un gagnant évident entre canvas et SVG. J’ai par exemple en tête 2 scénario qui pourraient vous intéresser en HTML5 : la génération de cartes/graphiques interactifs ou les jeux en 2D. &lt;/p&gt;

&lt;h3&gt;Cartes et diagrammes interactifs : plutôt SVG&amp;#160; &lt;/h3&gt;

&lt;p&gt;Comme nous l’avons déjà dit plus haut, SVG se montre particulièrement intéressant pour l’affichage d’organigrammes, de cartes ou de courbes en haute résolution. D’autant plus qu’il existe, comme nous le verrons dans l’article suivant, de nombreux outils permettant sa génération. &lt;/p&gt;

&lt;p&gt;Par ailleurs, par rapport à Canvas, SVG est plus adapté à une interaction utilisateur grâce à l’usage du DOM et de CSS derrière comme nous l’avons vu dans &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx"&gt;l’article précédent&lt;/a&gt;. SVG est également plus adapté &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/02/21/slides-et-ressources-de-la-session-accessibilit-233-d-html5-et-silverlight-des-techdays-2011.aspx"&gt;aux scénarios d’accessibilité&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Comme nous l’avons déjà fait précédemment, le mieux pour comprendre est d’illustrer les différences à travers un exemple concret. Prenons ainsi &lt;a href="http://commons.wikimedia.org/wiki/File:Gray_alaska.svg"&gt;une carte détaillée de l’Alaska&lt;/a&gt; disponible dans le domaine publique grâce à &lt;a href="http://commons.wikimedia.org/wiki/Main_Page"&gt;Wikimedia Commons&lt;/a&gt; : &lt;/p&gt;

&lt;p&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Gray_alaska.svg/200px-Gray_alaska.svg.png" /&gt;&lt;/p&gt;

&lt;p&gt;En SVG, l’état d’Alaska est représenté par un élément de type &amp;lt;path&amp;gt; constitué d’environ 162 500 caractères de données géométriques :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;path &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;AK&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#cdc3cc&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;M 777.5514,1536.1543 C 776.4904,1535.0933 776.7795,1530.0041 777.9416,&lt;br /&gt;1529.2859 C 781.3258,1527.1943 787.2657,1532.4522 784.8317,1535.3849 …&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Pour Canvas, la même forme pourrait être dessinée à travers la suite d’instructions JavaScript suivante :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;drawAlaska() {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;myCanvas&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;ctx = canvas.getContext(&lt;span style="color: maroon"&gt;&amp;quot;2d&amp;quot;&lt;/span&gt;);
    ctx.beginPath();
    ctx.moveTo(777.5514, 1536.1543);
    ctx.bezierCurveTo(776.4904, 1535.0933, 776.7795, 1530.0041, 777.9416, 1529.2859);
    ctx.bezierCurveTo(781.3258, 1527.1943, 787.2657, 1532.4522, 784.8317, 1535.3849);
    &lt;span style="color: #006400"&gt;//
    // Imaginez ici 2 875 directives supplémentaires...
    //
    &lt;/span&gt;ctx.bezierCurveTo(1689.8261, 12.13753, 1689.1395, 12.17333, 1685.8848, 10.52683);
    ctx.closePath();
    ctx.fillStyle = &lt;span style="color: maroon"&gt;&amp;quot;#cdc3cc&amp;quot;&lt;/span&gt;;
    ctx.fill();
}&lt;/pre&gt;

&lt;p&gt;Cela représente en fait 2 878 directives de dessins (&lt;em&gt;moveTo&lt;/em&gt;, &lt;em&gt;lineTo&lt;/em&gt; et &lt;em&gt;bezierCurveTo&lt;/em&gt;) pour fabriquer cette carte détaillée de l’Alaska à une résolution fixe. Il y a donc de fortes chances que la version Canvas soit plus lourdes en poids. Bien sûr, si l’on dessine la carte dans une résolution inférieure, il faudrait moins de lignes de code et donc un fichier plus petit. &lt;/p&gt;

&lt;p&gt;Les applications de cartes basées sur SVG proposent en général des expériences interactives comme des changements levés sur le survol de la souris, la sélection d’un élément, le passage d’un élément à l’autre et la mise à l’échelle. Ces opérations sont très simples à mettre en œuvre comme nous l’avions déjà vu. Par exemple, pour réagir sur un click de souris, voici l’unique chose à faire :&lt;/p&gt;

&lt;pre class="code"&gt; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;path &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;AK&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#cdc3cc&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onmousedown&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;window.alert('Alaska');&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;M 777.5514,1536.1543 …&amp;quot; /&amp;gt; 
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Ou pour réagir au survol :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;path#AK:hover &lt;/span&gt;{ &lt;span style="color: red"&gt;fill&lt;/span&gt;: &lt;span style="color: blue"&gt;yellow&lt;/span&gt;; } &lt;/pre&gt;

&lt;p&gt;Allez pour définitivement comprendre la différence sur les 2 modes, n’hésitez pas à jouer avec &lt;a href="http://david.blob.core.windows.net/html5graphics/USMapSVGvsCanvas.htm"&gt;l’exemple ci-dessous&lt;/a&gt; qui montre, à travers cette carte des Etats-Unis, la différence entre la taille du code JavaScript à produire pour Canvas et la taille du path SVG pour chacun des états. Je me suis amusé à prendre une partie des &lt;a href="http://www.w3.org/TR/SVG/paths.html"&gt;spécifications des paths SVG du W3C&lt;/a&gt; pour analyser dynamiquement le contenu SVG et le transformer dans l’équivalent Canvas :&lt;/p&gt;

&lt;p&gt;&lt;iframe height="360" src="http://david.blob.core.windows.net/html5graphics/USMapSVGvsCanvas.htm" width="900"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note :&lt;/u&gt;&lt;/strong&gt; &lt;em&gt;vous noterez que si vous testez cet exemple sous IE9 et ensuite sous Chrome/Firefox que le contenu des données affichées ici sous Path Data n’est pas le même (faites le test avec le même état sélectionné entre 2 navigateurs). Le code JS de parsing n’est donc pas tout à fait le même pour IE et FF pour générer le pseudo-code Canvas&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Un exemple plus intéressant de ce type d’interaction avec une carte peut être vu sur notre site Test Drive ici : &lt;a title="http://ie.microsoft.com/testdrive/Graphics/AtlaszurEuropawahl/Default.xhtml" href="http://ie.microsoft.com/testdrive/Graphics/AtlaszurEuropawahl/Default.xhtml"&gt;Atlas zur Europawahl 2004 in Deutschland&lt;/a&gt; . C’est une visualisation des résultats des élections Européenne de 2004 en Allemagne. &lt;/p&gt;

&lt;p&gt;Faire la même chose en Canvas vous obligerait à coder vous-même le “hit detection” en utilisant les coordonnées de position de la souris au moment du click ou du survol. En effet, vous n’avez alors plus le contexte lié à la forme que vous avez dessiné. Il existe bien sûr des librairies permettant de vous fournir de ce genre de services mais elles existent aussi pour SVG et disposent en général de bien meilleures performances.&lt;/p&gt;

&lt;p&gt;&lt;a title="Cadran4 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5727457574/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Cadran4" src="http://farm4.static.flickr.com/3517/5727457574_f84d497db6_z.jpg" width="640" height="183" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Affichage de données en temps réel : plutôt Canvas&lt;/h3&gt;

&lt;p&gt;Nous avons déjà vu qu’il était plus complexes de gérer les interactions avec les éléments dessinés au sein du &amp;lt;canvas&amp;gt; versus SVG. Mais si aucune interaction n’est nécessaire, Canvas apparait souvent comme un meilleur candidat pour l’affichage de données en temps réel.&lt;/p&gt;

&lt;p&gt;&lt;a title="CanvasMeteo by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5735930865/"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="CanvasMeteo" align="left" src="http://farm6.static.flickr.com/5181/5735930865_6640c0379e_m.jpg" width="240" height="167" /&gt;&lt;/a&gt;Prenons par exemple le cas d’affichage de données météo. Les techniques que l’on connait aujourd’hui consistent souvent à générer des images depuis le serveur sur un intervalle particulier puis de pousser l’image vers le client ou alors générer aussi rapidement que possible l’image côté client via l’utilisation de plug-ins. Bien que SVG pourrait permettre une alternative intéressante à la génération d’image rasterisée côté serveur pour économiser de la bande passante, &amp;lt;canvas&amp;gt; apparait malgré tout comme une option évidente pour ce scénario (tout comme pour les autres scénarios nécessitant l’affichage de données temps réel). En effet, comme vous pouvez le voir sur la copie d’écran de gauche affichant une carte météo, il n’y a pas forcément une très grande surface sur laquelle nous allons dessiner et le nombre d’objets (ou points) à dessiner peut être particulièrement élevé. Avec les APIs de &amp;lt;canvas&amp;gt;, cela peut être affiché (puis rafraichit) à une très grande vitesse sans aucune incidence sur le DOM. On pourrait de l’autre côté imaginer le même rendu en SVG en utilisant de nombreuses ellipses. Mais le cout de chargement de toutes ces formes dans le DOM ainsi que leurs modifications pour les animations serait particulièrement élevé en comparaison du &amp;lt;canvas&amp;gt;.&lt;/p&gt;

&lt;p&gt;&lt;a title="CanvasDonneesDynamiques by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5736481456/"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="CanvasDonneesDynamiques" align="right" src="http://farm4.static.flickr.com/3437/5736481456_a1a73f950f_m.jpg" width="189" height="100" /&gt;&lt;/a&gt; Ainsi s’il vous faut dessiner un nombre important de formes, spécialement des formes très différentes et non géométriques, afin de générer des images destinées à une analyse de données, cela devraient vous faire pencher la balance du côté de l’utilisation de Canvas. Outre la météo, on peut ainsi imaginer des scénarios autour de &lt;a href="http://www.skybeautiful.com"&gt;l’astronomie&lt;/a&gt;, la &lt;a href="http://alteredqualia.com/canvasmol/"&gt;biologie moléculaire&lt;/a&gt; ou l’affichage des modulations de fréquences d’un son comme on a pu le voir récemment avec l’application basée sur des sons de Daft Punk &lt;a href="http://daftpunk.themaninblue.com/"&gt;Anatomy of a Mashup&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a title="Cadran5 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5736525038/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Cadran5" src="http://farm3.static.flickr.com/2470/5736525038_606a4caa8d_z.jpg" width="640" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Les jeux vidéo 2D : léger avantage à canvas&lt;/h3&gt;

&lt;p&gt;HTML5 se prête bien également à ce que l’on appelle communément le “casual gaming”. Des petits jeux vidéo souvent relativement “simples” techniquement mais diablement efficaces et visant un public le plus large possible. Dernier exemple en date étant la publication par Google d’&lt;a href="http://chrome.angrybirds.com/"&gt;Angry Birds&lt;/a&gt; basé entre autre sur &amp;lt;canvas&amp;gt;. Vous pouvez d’ailleurs le tester dans IE9, il marche parfaitement bien grâce à son moteur d’accélération matérielle efficace.&lt;/p&gt;

&lt;p&gt;Mais alors, comment faire son choix entre canvas et SVG lors de la conception d’un jeu vidéo ?&lt;/p&gt;

&lt;p&gt;Tout d’abord, historiquement, les librairies de jeux ont souvent été basées sur des APIs graphiques de bas niveau. Les développeurs de jeux vidéo vont donc être tentés par &amp;lt;canvas&amp;gt; pour y adapter leur savoir faire. Cependant, d’autres composants désormais également très importants comme les moteurs physiques travaillent à des niveaux d’abstraction plus élevés et n’ont finalement que faire des détails d’implémentations techniques du mode de dessin.&amp;#160; De leur côté, ils attendent ainsi certaines informations sur les géométries comme leurs bords, vitesses, tailles et positions et renvoient en échange des informations permettant d’adapter la vitesse (gestion de la gravité par exemple), de gérer les collisions et de mettre à jour les positions. Cela vous donne alors l’impression de “réalisme” sur les mouvements des objets et leurs interactions.&lt;/p&gt;

&lt;p&gt;Si vous souhaitez jeter un œil sur des logiques de jeux démontrant qu’il est parfois difficile de choisir entre SVG et canvas, vous pouvez tester les 2 exemples suivant : &lt;a href="http://ie.microsoft.com/testdrive/Graphics/SVGoids/Default.html"&gt;SVG-oids&lt;/a&gt; et &lt;a href="http://ie.microsoft.com/testdrive/Graphics/CanvasPinball/Default.html"&gt;canvas-pinball&lt;/a&gt;. Ces 2 petits jeux ont été écrits par le même auteur. Il avait commencé par écrire le 1er jeu d’astéroïdes en SVG et il était parfaitement content du résultat. Lorsqu’il s’est ensuite attaqué au petit jeu de jeu de flipper, il avait également commencé par utiliser SVG du coup. Puis, finalement, il a changé son fusil d’épaule pour partir sur du &amp;lt;canvas&amp;gt; (pour des raisons que j’ignore). Cela veut simplement dire que pour ce genre de jeu, l’un ou l’autre fera parfaitement l’affaire.&lt;/p&gt;

&lt;p&gt;Un exemple peut-être plus parlant est l’analyse de 2 jeux utilisant le même moteur physique (Box2D) mais utilisant 2 modes différents de dessin. Ce sont &lt;a href="http://ie.microsoft.com/testdrive/Graphics/CanvasPinball/Default.html"&gt;canvas-pinball&lt;/a&gt; et &lt;a href="http://ie.microsoft.com/testdrive/Performance/SVGDice/Default.xhtml"&gt;SVG-Dice&lt;/a&gt;. Bien que ces deux jeux n’ont strictement rien à voir sur leur logique, ils utilisent le même moteur pour gérer les positions, collisions, vitesses et autre aspects physiques liés à nos composants de jeu.&lt;/p&gt;

&lt;p&gt;Pour le jeu de flipper, le gestionnaire d’animation de haut niveau redessine la scène en utilisant les APIs JavaScript du Canvas :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(animationsInProgress) {
     ctx.save();
     ctx.lineWidth = 2.0;
     ctx.beginPath();
     ctx.moveTo(89, 322);
     ctx.lineTo(101, 295);
     ….
     ctx.stroke();
     ctx.restore();
     ctx.moveTo(tVp.x, tVp.y);
}&lt;/pre&gt;

&lt;p&gt;Pour le jeu de dés en SVG, le gestionnaire d’animation utilise des transformations sur des groupes pour repositionner des éléments graphiques existant à travers le DOM :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(animationsInProgress) {
     &lt;span style="color: blue"&gt;this&lt;/span&gt;.rotation += (&lt;span style="color: blue"&gt;this&lt;/span&gt;.circleBody.m_linearVelocity.x/20);
     &lt;span style="color: blue"&gt;var &lt;/span&gt;transFormString = &lt;span style="color: maroon"&gt;&amp;quot;translate(&amp;quot; &lt;/span&gt;+ 
        Math.round(&lt;span style="color: blue"&gt;this&lt;/span&gt;.circleBody.m_position.x) + &lt;span style="color: maroon"&gt;&amp;quot;,&amp;quot; &lt;/span&gt;+ 
        Math.round(&lt;span style="color: blue"&gt;this&lt;/span&gt;.circleBody.m_position.y) + &lt;span style="color: maroon"&gt;&amp;quot;) scale (&amp;quot; &lt;/span&gt;+ 
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.scale.toString() + &lt;span style="color: maroon"&gt;&amp;quot;) rotate(&amp;quot; &lt;/span&gt;+
        Math.round(&lt;span style="color: blue"&gt;this&lt;/span&gt;.rotation).toString() + &lt;span style="color: maroon"&gt;&amp;quot;,&amp;quot; &lt;/span&gt;+
        Math.round(&lt;span style="color: blue"&gt;this&lt;/span&gt;.xTrans).toString() + &lt;span style="color: maroon"&gt;&amp;quot;,&amp;quot; &lt;/span&gt;+
        Math.round(&lt;span style="color: blue"&gt;this&lt;/span&gt;.yTrans).toString() + &lt;span style="color: maroon"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.die2.setAttribute(&lt;span style="color: maroon"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;, transFormString);
}&lt;/pre&gt;

&lt;p&gt;Ainsi, alors que le 1er redessine en permanence et repositionne les différentes géométries, l’autre se contente uniquement de les repositionner mais les maintient pour cela en mémoire. Cela a forcément un coup. Ce coup est néanmoins relativement faible pour des jeux de type “casual gaming”. Malgré tout, l’idée du mode immédiat fournit par &amp;lt;canvas&amp;gt; avec son jeu d’APIs bas niveau est souvent trop tentant pour les développeurs habitués à créer des jeux vidéos.&lt;/p&gt;

&lt;p&gt;Par contre, je tiens à noter un avantage intéressant pour SVG : son côté vectoriel à nouveau et donc sa possibilité de s’adapter dynamiquement à une résolution précise. Prenez par exemple ce petit jeu Pacman écrit en SVG : &lt;a href="http://ie.microsoft.com/testdrive/Performance/BrowserHunt/Default.xhtml"&gt;Browser Hunt&lt;/a&gt;. Si vous vous amusez à redimensionner la fenêtre de jeu, vous verrez que le contenu s’adapte automatiquement grâce à utilisation du &lt;a href="http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute"&gt;viewbox&lt;/a&gt;. Ceux d’entre vous qui sont développeurs WPF ou Silverlight connaissent ce mécanisme de viewbox. Et bah, c’est tout simplement la même logique appliquée ici à notre scène SVG. &lt;/p&gt;

&lt;h3&gt;Autre facteur : les compétences existantes et le niveau de performance intrinsèque&lt;/h3&gt;

&lt;p&gt;Pour continuer autour du jeu, il y existe aussi des éléments extérieurs qui vont influencer le choix de la technologie qui sont souvent indépendants des fonctionnalités. Entre SVG et Canvas, il y a 2 de ces éléments que je vois ressortir : vos connaissances actuelles et vos attentes sur la performance. &lt;/p&gt;

&lt;p&gt;En effet, les connaissances et jeux de compétences des développeurs jouent un rôle important dans le choix d’une nouvelle technologie. Comme nous l’avons déjà dit, pour la création d’un jeu, si vos développeurs ont une connaissance profonde des APIs graphiques de bas niveau (DirectX, OpenGL ou XNA) et disposent d’une connaissance limitée des technologies Web, Canvas va certainement s’imposer de lui-même. &lt;/p&gt;

&lt;p&gt;La performance dispose d’un rôle clé également. Nous en reparlerons ainsi dans le dernier article car l’arrivée de technologies permettant “l’accélération matérielle” via le GPU changent également la donne. Il faut alors prendre le temps de comparer les caractéristiques des 2 technologies en matière de performance pure. Regardons par exemple ce graphique basée sur quelques études internes à Microsoft :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_009_Performance by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5713832394/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_009_Performance" src="http://farm4.static.flickr.com/3472/5713832394_76b1de9e7f.jpg" width="500" height="262" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En général, plus la taille/résolution d’écran augmente, plus les performances de Canvas vont se dégrader puisque la quantité de pixels à rafraichir augmente. De son côté, SVG a tendance à dégrader les performances au fur et à mesure que l’on augmente le nombre d’objets à l’écran car cela a une incidence directe sur le DOM qui prend le relais derrière. Alors bien sûr, ces mesures sont relativement grossières et non représentatives de tous les scénarios. Par ailleurs, il y a des variations énormes en fonction des plateformes (PC, Tablet, Téléphone), de la qualité de l’accélération matérielle (et du GPU) ainsi que de la vitesse du moteur JavaScript. Bref, le choix d’une des 2 technologies pour sa performance devra forcément passer par une étape de prototypage pour pouvoir évaluer la techno en fonction du scénario que vous avez en tête. Malgré tout, je trouve que ce graphique donne déjà une bonne idée des performances inhérentes au fonctionnement même de chacune des 2 technologies. Par ailleurs, ces informations sont valides pour toute application devant animer des informations graphiques en dehors de l’écriture de jeux vidéo.&lt;/p&gt;

&lt;p&gt;&lt;a title="Cadran6 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5737425506/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="Cadran6" src="http://farm6.static.flickr.com/5105/5737425506_dc580e64d8_z.jpg" width="640" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Au fait : rien ne vous empêche d’utiliser les 2 !&lt;/h2&gt;

&lt;p&gt;Nous avons vu tout le long de cet article comment positionner l’une ou l’autre des technologies en fonction de nos besoins. Cependant, rien n’empêche de combiner ces 2 approches ! L’usage hybride dispose en effet de nombreux bénéfices puisque nous allons profiter des avantages de chacun. Ainsi, pour bénéficier d’un “hit detection” et d’une interaction utilisateur simplifiés, vous pouvez mettre en place un calque constitué de géométries SVG avec en dessous un élément &amp;lt;canvas&amp;gt; permettant de fournir des animations temps réel plus adaptées. &lt;/p&gt;

&lt;p&gt;Il y a ainsi un nombre grandissant d’expériences voyant le jour où cette combinaison est efficace. Quand vous vous retrouvez dans un scénario nécessitant à la fois des animations graphiques dynamiques (Canvas) et une interaction utilisateur riche (SVG), chacune des 2 technologies peut être utilisée et doit être utilisée.&lt;/p&gt;

&lt;p&gt;Cela est illustré par le site &lt;a href="http://www.sabrainpowerhtml5.com/"&gt;Brain Power&lt;/a&gt; réalisé par l’un de nos partenaires et présent sur notre galerie &lt;a href="http://www.beautyoftheweb.com/"&gt;The Beauty of the Web&lt;/a&gt;. Ce site particulier, ainsi que d’autres présents dans la galerie, ont réussi à mettre en œuvre cette délicate balance.&lt;/p&gt;

&lt;p&gt;Ainsi pour l’interaction utilisateur et l’affichage des portions du cerveau, le site utilise des géométries SVG :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;polygon &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;SensoryCortex&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;points&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;253,80,266,93,…&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;: rgba(0,0,0,0)&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Et pour réaliser les animations temps réel et les “effets spéciaux”, canvas est utilisé pour ce qu’il sait bien faire :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;canvas &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;cnvDisplay&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1920&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1099&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;position&lt;/span&gt;&lt;span style="color: blue"&gt;:absolute;&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Par contre, petit regret pour part, on ne peut pas afficher une forme SVG au sein d’un canvas sans en perdre sa nature intrinsèque : interaction via CSS ou remontée des events via le DOM. On peut utiliser un élément de type &lt;a href="http://samples.msdn.microsoft.com/ietestcenter/html5/canvas_harness.htm?url=canvas-images-drawImage-001"&gt;&amp;lt;img&amp;gt; alimenté par du SVG comme source de la méthode drawImage()&lt;/a&gt; de &amp;lt;canvas&amp;gt; mais cela a pour unique but de “rasteriser” le contenu SVG. Dommage, cela aurait offert de beaux scénarios également !&lt;/p&gt;

&lt;p&gt;Cela conclue notre tour d’horizon des possibilités offertes par SVG et &amp;lt;canvas&amp;gt;. Vous noterez que je n’ai pas abordé dans mes différents scénarios l’idée d’utiliser SVG pour produire entièrement une interface utilisateur. En effet, vu que j’ai fait un parallèle avec Silverlight et XAML en début d’article, il serait légitime de se demander si on ne pourrait pas réaliser une interface purement basée sur SVG comme on le fait en XAML. En tout cas, je me suis moi-même posé cette question. Il y a quelques années d’ailleurs, certains annonçaient que SVG était LA technologie à retenir pour nos UIs. Par exemple, il me semble qu’il existe au moins un frontal pour une version de Linux entièrement basé sur SVG. Des contrôles tels que les sliders, checkbox, bouton avec coins arrondis et toute autre forme de contrôles non rectangulaires sont possibles grâce à la nature vectorielle de SVG. &lt;/p&gt;

&lt;p&gt;Bah alors ? Pourquoi ne pas y aller ? Tout simplement parce qu’entre temps, HTML et CSS ont très bien évolués et offrent une palette riche de possibilités : coins arrondis, gradients, transitions, formulaires, etc. Ainsi une grande majorité des nouveaux contrôles peuvent être réalisés avec le modèle de boite standard HTML ce qui, à mon sens, est préférable à l’alternative SVG. Par ailleurs, le positionnement de nos éléments s’est vu grandement améliorés dans CSS3 comme le modèle &lt;a href="http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/"&gt;Flexbox&lt;/a&gt; ou notre proposition récente de positionnement par grille avec &lt;a href="http://dev.w3.org/csswg/css3-grid-align/"&gt;CSS3 Grid&lt;/a&gt; inauguré dans &lt;a href="http://ie.microsoft.com/testdrive/HTML5/Griddle/Default.html"&gt;Internet Explorer 10&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Voilà. Je pense avoir fait un tour assez vaste des scénarios d’usage des 2 technologies. J’espère que tout cela vous aidera à mieux les positionner et à mieux vous guider dans votre choix. Si vous avez une expérience différente sur l’utilisation de ces modes graphiques, n’hésitez pas à venir la partager en commentaire de cet article. Je suis bien entendu preneur de vos retours. &lt;/p&gt;

&lt;p&gt;Pour ma part, je tenais à remercier Patrick Dengler de Microsoft Corp, membre du &lt;a href="http://www.w3.org/2000/09/dbwg/details?group=19480&amp;amp;public=1&amp;amp;gs=1&amp;amp;"&gt;groupe de travail SVG&lt;/a&gt; au W3C, qui m’a bien aidé dans l’écriture de cet article.&lt;/p&gt;

&lt;p&gt;David&lt;/p&gt;
&lt;script src="http://david.blob.core.windows.net/html5/mathlib-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/k3d-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/html5logo_noscroll.js"&gt;&lt;/script&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10166581" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Canvas/">Canvas</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/SVG/">SVG</category></item><item><title>Introduction aux APIs graphiques d’HTML5: SVG &amp; Canvas (1/2)</title><link>http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx</link><pubDate>Mon, 09 May 2011 15:09:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10162502</guid><dc:creator>David Rousset</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10162502</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/05/09/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-1-4.aspx#comments</comments><description>&lt;link rel="stylesheet" type="text/css" href="http://david.blob.core.windows.net/html5graphics/articlesvg.css" media="screen" /&gt;  &lt;p&gt;&lt;a title="OverviewHTML5GraphicswithCanvasandSVG by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5661486462/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="OverviewHTML5GraphicswithCanvasandSVG" src="http://farm6.static.flickr.com/5270/5661486462_8dfe958cc0.jpg" width="500" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Au programme de cette série d’articles, nous allons découvrir :&lt;/p&gt;  &lt;p&gt;1 – les bases de SVG et de Canvas    &lt;br /&gt;2 – &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx"&gt;les scénarios clés d’utilisation de ces 2 jeux d’APIs&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ce premier article traitera donc des bases de SVG et de Canvas.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note&lt;/u&gt;&lt;/strong&gt; : vous pouvez tester la plupart des exemples directement au sein de cet article si vous utilisez IE9, Firefox 4.0 ou Chrome. Opera 11 ne supportant pas apparemment le SVG “in-line”, la plupart de mes exemples SVG ne fonctionnent pas. Par ailleurs, j’ai corrigé l’exemple de jeu en SVG à la fin de l’article fourni par le tutorial MSDN pour le faire fonctionner sous Firefox. &lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Les bases de SVG&lt;/h2&gt;  &lt;h3&gt;Les scènes statiques&lt;/h3&gt;  &lt;p&gt;Commençons donc par la base de la base de SVG. SVG (pour Scalable Vector Graphics) permet comme son nom l’indique d’afficher des objets graphiques vectoriels. Les objets sont décrits dans un langage XML qui vont enrichir le DOM comme les autres éléments HTML. Ainsi, l’interaction avec les éléments créés dans le DOM par SVG se fait de la même façon qu’avec les autres éléments HTML: évènements, application de CSS, accessibilité via ARIA, etc. Par ailleurs, le fait d’avoir cette persistance en mémoire des objets fait que l’on considère cette technologie comme “retained mode”. &lt;/p&gt;  &lt;p&gt;Vous avez un ensemble de primitives pour dessiner (rectangle, cercle, ellipse, etc.) ou alors via des &lt;a href="http://www.w3.org/TR/SVG/paths.html"&gt;Paths&lt;/a&gt;. Vous pouvez également effectuer des transformations, translations, afficher du texte. Bref, il y a de quoi faire vous allez voir.&lt;/p&gt;  &lt;p&gt;Si vous êtes développeur Silverlight, SVG vous rappellera furieusement XAML si nous devions faire un parallèle. Le moteur XAML de Silverlight étant quand même bien plus riche et plus orienté contrôle utilisateur/scénario data (moteur de binding, templating, visual state manager, etc.).&lt;/p&gt;  &lt;p&gt;Regardons un des exemples les plus simples qui soit utilisant la méthode de fragments SVG intégrés dans le code HTML5 (ou SVG in-line). Ce markup :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;style &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/css&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;media&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;screen&amp;quot;&amp;gt;

        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;          
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;110px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;110px&amp;quot;&amp;gt;    
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;rect &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myRect&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;blue&amp;quot;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Nous donne le résultat suivant (si votre navigateur supporte SVG) :&lt;/p&gt;

&lt;p&gt;&lt;svg width="110px" height="110px"&gt;Votre navigateur ne supporte pas le SVG in-line&lt;rect id="myRect" fill="blue" width="100px" height="100px" /&gt;&lt;/svg&gt;&lt;/p&gt;

&lt;p&gt;Ou vous pouvez tester cet exemple avec cette page : &lt;a href="http://david.blob.core.windows.net/html5graphics/001_SVGBasics_bluerect.htm"&gt;Exemple 1 SVG&lt;/a&gt;. La 1ère ligne de markup SVG demande à réserver une zone de dessin de 110 pixels par 110 pixels et de dessiner un rectangle bleu de 100x100. Bon, pour l’instant, vous me suivez toujours j’imagine. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-10-46-metablogapi/2100.wlEmoticon_2D00_winkingsmile_5F00_505A0144.png" /&gt;&lt;/p&gt;

&lt;p&gt;Il y a différentes façon d’intégrer du SVG dans sa page Web :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Les fragments SVG intégrés dans le code HTML5, sans utiliser d'objet étranger (c'est-à-dire, intégrer une balise &amp;lt;&lt;strong&gt;svg&lt;/strong&gt;&amp;gt; dans votre code HTML). C’est l’exemple que nous venons de voir ensemble juste au-dessus. &lt;/li&gt;

  &lt;li&gt;Le format SVG en tant que type de document complet (avec une extension de fichier &lt;strong&gt;.svg&lt;/strong&gt;) &lt;/li&gt;

  &lt;li&gt;Le format SVG dans le code XML ou XHTML (similaire à la méthode HTML5, uniquement avec les fichiers XML ou XHTML) &lt;/li&gt;

  &lt;li&gt;Le format SVG en tant qu'image CSS. Vous pouvez par exemple utiliser cet exemple : &lt;a title="http://ie.microsoft.com/testdrive/Graphics/SVGGradientBackgroundMaker/Default.html" href="http://ie.microsoft.com/testdrive/Graphics/SVGGradientBackgroundMaker/Default.html"&gt;SVG Gradient Background Maker&lt;/a&gt; si vous souhaitez ajouter un gradient SVG en tant qu’image de fond à un élément par CSS. &lt;/li&gt;

  &lt;li&gt;Le format SVG utilisant l'élément &lt;strong&gt;object&lt;/strong&gt;, comme dans l'exemple suivant (remarquez les attributs &lt;em&gt;type&lt;/em&gt;, &lt;em&gt;height&lt;/em&gt; et &lt;em&gt;width&lt;/em&gt;) : &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;object &lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;rect2.svg&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;400px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;image/svg+xml&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;object&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;Le format SVG utilisant les éléments &lt;strong&gt;img&lt;/strong&gt;, &lt;strong&gt;embed&lt;/strong&gt;, &lt;strong&gt;iframe&lt;/strong&gt;, ou &lt;strong&gt;frame&lt;/strong&gt;, comme dans l'exemple suivant : &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;embed &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Smiley&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;smiley.svg&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;image/svg+xml&amp;quot;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Internet Explorer 9 prend en charge l’ensemble de ces méthodes.&lt;/p&gt;

&lt;p&gt;Alors bien sûr on peut aller bien plus loin que l’exemple que nous venons de voir comme le montre cette page: &lt;a href="http://david.blob.core.windows.net/html5graphics/002_SVGBasics_RichScene.htm"&gt;Exemple 2 SVG&lt;/a&gt;. Dans IE9, cela donne ce résultat:&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_002_ComplexSVGScene by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5661648294/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_002_ComplexSVGScene" src="http://farm6.static.flickr.com/5189/5661648294_5fb48a144d.jpg" width="500" height="313" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1ère chose intéressante à noter sur cette copie d’écran, si vous faites “CTRL+F” pour chercher dans la page sur “tex”, vous voyez bien le texte dessiné sur un path (le rail du train) correctement sélectionné. Cela veut également dire qu’un moteur de recherche est susceptible de pouvoir indexer votre contenu malgré son côté vectoriel (chose plus difficile avec du Flash ou Silverlight). Par exemple, si vous tapez ces mots clé dans &lt;a href="http://www.google.fr/#hl=fr&amp;amp;xhr=t&amp;amp;q=The+Past%2C+Present%2Cand+Future+of+Vector+Graphics+for+the+Web+ARCADE+Funhouse&amp;amp;cp=75&amp;amp;pf=p&amp;amp;sclient=psy&amp;amp;site=&amp;amp;source=hp&amp;amp;aq=f&amp;amp;aqi=&amp;amp;aql=&amp;amp;oq=The+Past,+Present,and+Future+of+Vector+Graphics+for+the+Web+ARCADE+Funhouse&amp;amp;pbx=1&amp;amp;fp=1&amp;amp;cad=b"&gt;Google&lt;/a&gt; : “&lt;em&gt;The Past, Present,and Future of Vector Graphics for the Web ARCADE Funhouse&lt;/em&gt;”, vous allez tomber sur cette page: &lt;a title="SVG Theme Park" href="http://www.google.fr/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;sqi=2&amp;amp;ved=0CBwQFjAA&amp;amp;url=http%3A%2F%2Fwww.w3.org%2F2010%2FTalks%2F11-schepers-webdirectionseast%2Fthemepark.svg&amp;amp;ei=Rzm4TYyIFMPB8QPm9txL&amp;amp;usg=AFQjCNGOgNi9sSXwLDAS2Ojr1ZJ6E9DplQ"&gt;SVG Theme Park&lt;/a&gt; qui est la source de mon exemple 2. &lt;/p&gt;

&lt;p&gt;Ensuite, si vous lancez la barre de développement d’IE9 avec la touche F12 (ou si vous utilisez un outil équivalent comme FireBug), vous pourrez bien vérifier que chacun des éléments actuellement dessiné à l’écran est bien présent dans le DOM. Voici un exemple avec IE9 :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_003_ComplexSVGSceneF12 by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5661113945/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_003_ComplexSVGSceneF12" src="http://farm6.static.flickr.com/5143/5661113945_6450c09fb3.jpg" width="500" height="313" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sur cette copie d’écran, on voit que j’ai ciblé l’élément qui correspond à une sorte de piscine et que je suis tombé sur le path correspondant avec l’ID “&lt;em&gt;pool_water_1_&lt;/em&gt;”. Amusez vous à balader la souris en mode ciblage et vous verrez alors des petits rectangles bleus au dessus de chacune des zones du dessin.&lt;/p&gt;

&lt;p&gt;Par ailleurs, si vous zoomez dans la scène, vous observerez que vous n’avez aucune perte de définition grâce au côté vectoriel de SVG. Par exemple, si je reprends l’exemple précédent, je peux zoomer sur la piscine en conservant une excellente qualité graphique :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_005_SVGZoom by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5689361131/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_005_SVGZoom" src="http://farm6.static.flickr.com/5106/5689361131_90479029ce.jpg" width="500" height="269" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A ce stade, vous allez surement vous dire aussi: “&lt;em&gt;mais comment on fait pour générer une telle scène? On se tape quand même pas tout le SVG à la main ?&lt;/em&gt;”. Non, rassurez-vous ! Il existe des outils pour vous aider, on en parlera plus tard.&lt;/p&gt;

&lt;h3&gt;Ajout de l’interactivité&lt;/h3&gt;

&lt;p&gt;Il y a plusieurs façons d’ajouter de l’interactivité à des éléments SVG. Commençons par la plus simple: le branchement de code sur des évènements du DOM. Regardez le code de la page suivante (que vous pouvez tester ici : &lt;a href="https://david.blob.core.windows.net/html5graphics/003_SVGBasics_OnClick.htm"&gt;Exemple 3 SVG&lt;/a&gt;) :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color: #006400"&gt;// This function is called when the circle is clicked.
        &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;clickMe() {
            &lt;span style="color: #006400"&gt;// Display the alert.
            &lt;/span&gt;alert(&lt;span style="color: maroon"&gt;&amp;quot;You clicked the SVG UI element.&amp;quot;&lt;/span&gt;);
        }
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &lt;/span&gt;SVG User Interface
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!-- Create the SVG pane. --&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;200&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;200&amp;quot;&amp;gt;
      &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!-- Create the circle. --&amp;gt;
      &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;circle &lt;/span&gt;&lt;span style="color: red"&gt;cx&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;cy&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;r&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;50&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;gold&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;uIElement&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;clickMe();&amp;quot;
      /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &lt;/span&gt;Click on the gold circular user interface element.
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Cela donne le résultat suivant (si votre navigateur supporte SVG). Cliquez sur le cercle jaune pour lever l’évènement de click :&lt;/p&gt;

&lt;p&gt;&lt;!-- Create the SVG pane. --&gt;&lt;svg width="200" height="200"&gt;Votre navigateur ne supporte pas le SVG in-line &lt;!-- Create the circle. --&gt;&lt;circle id="uIElement" onclick="clickMe();" fill="gold" r="50" cy="100" cx="100" /&gt;&lt;/svg&gt;&lt;/p&gt;

&lt;p&gt;On dessine simplement un cercle jaune d’un rayon de 50 dont le centre est décalé de 100 pixels à gauche et 100 pixels vers le bas par rapport au coin supérieur gauche de la zone de dessin. Ensuite, on s’abonne à l’évènement onclick() sur lequel on branche la fonction “&lt;em&gt;clickMe()&lt;/em&gt;”. Le “hit testing” sera fait pour vous par le navigateur et ne sera déclenché uniquement lorsque vous cliquerez bien sur le cercle et pas à côté dans le reste de la surface de dessin SVG. Nous verrons que le fonctionnement de &amp;lt;canvas&amp;gt; est bien différent de ce côté. &lt;/p&gt;

&lt;p&gt;Il y a un truc chouette avec SVG, on peut le coupler avec CSS. Observons par exemple le code source suivant (que vous pouvez tester ici : &lt;a href="http://david.blob.core.windows.net/html5graphics/004_SVGBasics_svgstyling.htm"&gt;Exemple 4 SVG&lt;/a&gt;) :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;meta &lt;/span&gt;&lt;span style="color: red"&gt;http-equiv&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;X-UA-Compatible&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;IE=9&amp;quot;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;style &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/css&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;media&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;screen&amp;quot;&amp;gt;
            &lt;/span&gt;&lt;span style="color: maroon"&gt;rect.greenrect &lt;/span&gt;{&lt;span style="color: red"&gt;fill&lt;/span&gt;:&lt;span style="color: blue"&gt;green&lt;/span&gt;;}
            &lt;span style="color: maroon"&gt;rect:hover &lt;/span&gt;{&lt;span style="color: red"&gt;fill&lt;/span&gt;:&lt;span style="color: blue"&gt;yellow&lt;/span&gt;;} 
        &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot;&amp;gt;    
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--No fill (defaults the color to #000000)--&amp;gt;
            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;rect &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myRect1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot;&amp;gt;    
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--using the class=&amp;quot;greenrect&amp;quot;--&amp;gt;
            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;rect &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myRect2&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;greenrect&amp;quot;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot;&amp;gt;
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--using the style=&amp;quot;fill:pink&amp;quot;--&amp;gt;    
            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;rect &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myRect3&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;:pink&amp;quot;/&amp;gt; 
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;svg &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;75px&amp;quot;&amp;gt;
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--using the attribute fill=&amp;quot;red&amp;quot;--&amp;gt;    
            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;rect &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myRect4&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;fill&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;red&amp;quot;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;svg&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;On dessine 4 rectangles les uns derrière les autres. Le 1er est noir car nous ne précisons par la couleur donc il prend celle par défaut. Le 2ème est régit par la classe “greenrect” qui va, via CSS, le peindre en vert. Le 3ème est rose à travers le style in-line qui lui est fixé et enfin le dernier est simplement rouge. On observe alors une autre chose intéressante dans le style définit en haut de page. L’utilisation de la pseudo classe “hover” nous permet de dynamiquement changer la couleur en jaune au survol de la souris sur un des rectangles (sauf le 3ème qui écrase la règle avec son style in-line).&lt;/p&gt;

&lt;p&gt;Si votre navigateur le supporte, vous pouvez jouer avec directement an sein de cet article :&lt;/p&gt;

&lt;p&gt;&lt;svg width="75px" height="75px"&gt;Votre navigateur ne supporte pas le SVG in-line&lt;!--No fill (defaults the color to #000000)--&gt;&lt;rect id="myRect1" width="100%" height="100%"&gt;&lt;/svg&gt;&lt;svg width="75px" height="75px"&gt;&lt;!--using the class="greenrect"--&gt;&lt;rect id="myRect2" class="greenrect" width="100%" height="100%" /&gt;&lt;/svg&gt;&lt;svg width="75px" height="75px"&gt;&lt;!--using the style="fill:pink"--&gt;&lt;rect style="fill: pink" id="myRect3" width="100%" height="100%" /&gt;&lt;/svg&gt;&lt;svg width="75px" height="75px"&gt;&lt;!--using the attribute fill="red"--&gt;&lt;rect id="myRect4" fill="red" width="100%" height="100%" /&gt;&lt;/svg&gt;&lt;/p&gt;

&lt;p&gt;Avouez que c’est sympa non? &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-10-46-metablogapi/7563.wlEmoticon_2D00_smile_5F00_779CF6B5.png" /&gt; J’ai creusé un peu plus loin. Je me suis dit qu’il serait alors sympa de combiner les nouveaux jouets arrivant avec CSS3 avec SVG. Cela est possible uniquement avec l’élément racine de votre description SVG (le tag &amp;lt;svg&amp;gt; donc) et pas au niveau des sous-éléments. J’y reviendrais plus tard dans le 4ème billet dans les expérimentations que j’ai faites avec les différents navigateurs. &lt;/p&gt;

&lt;p&gt;Pour finir, rien ne vous empêche bien évidemment de mélanger les 2 comme le montre cet exemple-ci : &lt;a href="http://david.blob.core.windows.net/html5graphics/005_SVGBasics_svginteractivity.htm"&gt;Exemple 5 SVG&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_004_SVGInteractivity by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5661828416/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_004_SVGInteractivity" src="http://farm6.static.flickr.com/5142/5661828416_acb3464c3a.jpg" width="500" height="242" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Niveau de support dans IE9&lt;/h3&gt;

&lt;p&gt;On retrouve la spécification SVG aujourd’hui sous 2 formes : la version complète &lt;a href="http://www.w3.org/TR/SVG/"&gt;SVG 1.1 2nd Edition&lt;/a&gt; aujourd’hui en “&lt;em&gt;Working Draft&lt;/em&gt;” depuis le 22 juin 2010 implémentée par IE9 et les autres navigateurs modernes et la version &lt;a href="http://www.w3.org/TR/SVGTiny12/"&gt;SVG Tiny 1.2&lt;/a&gt; logiquement prévue pour les périphériques mobiles et elle en version “&lt;em&gt;Recommendation&lt;/em&gt;” depuis le 22 décembre 2008. &lt;/p&gt;

&lt;p&gt;Dans IE9, voici les éléments que nous avons choisis de supporter dans SVG 1.1 2nd Edition :&lt;/p&gt;

&lt;p&gt;&lt;a title="IE9SVGSupport by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5661844384/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="IE9SVGSupport" src="http://farm6.static.flickr.com/5269/5661844384_e0ede231af.jpg" width="500" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous aurez davantage de détails sur notre support de SVG dans IE9 dans le &lt;a title="http://msdn.microsoft.com/fr-fr/ie/ff468705.aspx#_Scaling_Vector_Graphics" href="http://msdn.microsoft.com/fr-fr/ie/ff468705.aspx#_Scaling_Vector_Graphics"&gt;Guide du développeur Internet Explorer 9&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;L’absence du support des “Declarative Animation” (basée sur les &lt;a href="http://www.w3.org/TR/1998/REC-smil-19980615/"&gt;animations SMIL&lt;/a&gt;) et des fonts SVG nous coute des points dans le très médiatique test ACID3 ce qui explique que nous sommes à 95 au lieu du score maximum de 100. Nous avons déjà parlé du manque de pertinence selon nous de ce genre de tests dans ce billet : &lt;a title="http://blogs.msdn.com/b/iefrance/archive/2011/02/28/html5-respect-des-standards-tests-et-marketing.aspx" href="http://blogs.msdn.com/b/iefrance/archive/2011/02/28/html5-respect-des-standards-tests-et-marketing.aspx"&gt;HTML5 : respect des standards, tests et marketing&lt;/a&gt;&amp;#160; &lt;/p&gt;

&lt;p&gt;Mozilla de son côté avec Firefox 4.0 va également en partie dans notre sens : &lt;a href="http://limi.net/articles/firefox-acid3"&gt;Mythbusting: Why Firefox 4 won’t score 100 on Acid3...and why that’s a good thing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IE9 comme Firefox 4.0 ont en effet fait le choix d’implémenter le format WOFF pour les fonts plutôt que de partir sur les fonts SVG qui, de l’aveu même du working group SVG, dispose d’un avenir incertain. WOFF semble donc un choix plus judicieux et pragmatique plutôt que de partir sur un support disparate des fonts SVG juste pour augmenter artificiellement le score au test ACID3. &lt;/p&gt;

&lt;p&gt;Par ailleurs, &lt;u&gt;pour ma part&lt;/u&gt;, je considère que les animations SVG rentre en conflit avec les possibilités offertes par CSS3 Animations (non encore supportées par IE à l’heure actuelle). Il existe en effet souvent des collisions dans les possibilités offertes par chacun des modèles (HTML5, CSS3 ou SVG). D’après ce que j’en sais, les groupes de travail au W3C n’ont pas encore tranchés sur l’intérêt des animations SVG vs les animations CSS3 qui pourraient être appliquées aux éléments SVG. Cela explique peut-être pourquoi nous ne nous sommes pas pour l’instant intéressés à cette partie de SVG. J’ai l’impression que les équipes WebKit partent dans la même direction. Aujourd’hui, il semblerait que le navigateur qui supporte au mieux les animations SVG soit Opera, suivi ensuite par Firefox et pour finir les navigateurs WebKit semblent les moins bon (mais ce sont eux qui ont inventé CSS3 Animations). Pour notre part, nous ne supportons pas du tout les animations SVG.&lt;/p&gt;

&lt;h2&gt;Les bases de Canvas&lt;/h2&gt;

&lt;h3&gt;Les scènes statiques&lt;/h3&gt;

&lt;p&gt;Il faut voir &amp;lt;canvas&amp;gt; comme une image PNG dynamique. Vous disposez d’une surface de dessin (une bitmap) dans laquelle vous allez dessiner à l’aide de primitive accessibles via JavaScript. Ces primitives sont grosso-modo les mêmes qu’avec SVG : rectangles, lignes, remplissage de formes, courbes de Bézier, etc. &lt;/p&gt;

&lt;p&gt;Par contre, la balise canvas est radicalement différente de SVG sur plusieurs points. Tout d’abord, c’est un mode dit “Fire and Forget”. Il n’y a donc pas de maintien en mémoire de ce que vous avez déjà dessiné. C’est à vous de savoir ce que vous avez dessiné et où. Ainsi, au niveau du DOM, canvas est vu comme une boite noire et peut donc poser potentiellement des problèmes d’accessibilité. J’en ai déjà parlé ici: &lt;a title="http://blogs.msdn.com/b/davrous/archive/2011/02/21/slides-et-ressources-de-la-session-accessibilit-233-d-html5-et-silverlight-des-techdays-2011.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/02/21/slides-et-ressources-de-la-session-accessibilit-233-d-html5-et-silverlight-des-techdays-2011.aspx"&gt;Techdays 2011 - slides et ressources de la session Accessibilité d’HTML5 et Silverlight&lt;/a&gt; . Par ailleurs, contrairement à SVG, vous pouvez manipuler chacun des pixels de votre zone de dessin si vous le souhaitez. Si&amp;#160; vous êtes développeur Silverlight, on pourrait ainsi un peu comparer cet élément HTML5 à l’objet WriteableBitmap quelque part. Mais heureusement l’élément canvas est bien plus riche que cela. &lt;/p&gt;

&lt;p&gt;Reprenons un exemple simple pour commencer. On va dessiner la même chose qu’avec le 1er exemple SVG vu plus haut. Regardez le code de cette page :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;style &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/css&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;media&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;screen&amp;quot;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
            function &lt;/span&gt;init() {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;monCanvas&amp;quot;&lt;/span&gt;);
                &lt;span style="color: blue"&gt;var &lt;/span&gt;ctx = canvas.getContext(&lt;span style="color: maroon"&gt;&amp;quot;2d&amp;quot;&lt;/span&gt;);
                ctx.fillStyle = &lt;span style="color: maroon"&gt;&amp;quot;rgb(0,0,255)&amp;quot;&lt;/span&gt;;
                ctx.fillRect(10, 10, 100, 100);
            }
        &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body &lt;/span&gt;&lt;span style="color: red"&gt;onload&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;init();&amp;quot;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;canvas &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;monCanvas&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100px&amp;quot; /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Vous pouvez le tester ici : &lt;a href="http://david.blob.core.windows.net/html5graphics/006_CanvasBasic_bluerect.htm"&gt;Exemple 1 Canvas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’élément canvas est déclaré avec une taille de 100 pixels de large par 100 pixels de haut. C’est tout ce qu’il faut faire du côté du markup HTML. Tout le reste se fait ensuite par JavaScript. &lt;/p&gt;

&lt;p&gt;En JavaScript, on exécute la function init() au chargement du document. Cette fonction s’occupe alors de récupérer mon élément canvas à partir de son ID puis ensuite récupère le contexte 2D (la surface de dessin). Une fois que vous avez votre contexte en main, vous pouvez appeler dessus les primitives du canvas. &lt;/p&gt;

&lt;p&gt;Si votre navigateur supporte cet élément, vous devriez avoir un magnifique carré bleu de dessiné juste en-dessous de ce texte :&lt;/p&gt;

&lt;p&gt;&lt;canvas id="monCanvas" width="100px" height="100px"&gt;Votre navigateur ne supporte pas Canvas&lt;/canvas&gt;&lt;/p&gt;

&lt;h3&gt;Ajout de l’interactivité&lt;/h3&gt;

&lt;p&gt;L’interactivité avec les éléments dessinés au sein du Canvas va se faire uniquement via JavaScript. Vous n’avez en effet pas d’évènements qui seront propagés par le navigateur vu que le DOM n’est pas rempli par les éléments du Canvas. Pour bien comprendre la différence avec SVG, nous allons reprendre le même exemple que l’&lt;a href="https://david.blob.core.windows.net/html5graphics/003_SVGBasics_OnClick.htm"&gt;exemple 3 SVG&lt;/a&gt; (avec un cercle jaune) mais en canvas. Vous pouvez le tester sur cette page &lt;a href="http://david.blob.core.windows.net/html5graphics/007_CanvasBasic_OnClick.htm"&gt;Exemple 2 Canvas&lt;/a&gt;. Cela correspond à ce code :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color: #006400"&gt;// This function is called on page load.
        &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;drawOnCanvas() {
            &lt;span style="color: #006400"&gt;// Get the canvas element.
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;canvas = document.getElementById(&lt;span style="color: maroon"&gt;&amp;quot;uIElement&amp;quot;&lt;/span&gt;);

            &lt;span style="color: #006400"&gt;// Make sure you got it.
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(canvas.getContext)
            &lt;span style="color: #006400"&gt;// If you have it, create a canvas user inteface element.
            &lt;/span&gt;{
                &lt;span style="color: #006400"&gt;// Specify 2d canvas type.
                &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;ctx = canvas.getContext(&lt;span style="color: maroon"&gt;&amp;quot;2d&amp;quot;&lt;/span&gt;);
                &lt;span style="color: #006400"&gt;// Draw gold UI element.
                // Start the path.
                &lt;/span&gt;ctx.beginPath();
                &lt;span style="color: #006400"&gt;// Define the fill color in RGB for gold.
                &lt;/span&gt;ctx.fillStyle = &lt;span style="color: maroon"&gt;&amp;quot;rgb(255 ,215 ,0)&amp;quot;&lt;/span&gt;;
                &lt;span style="color: #006400"&gt;// Draw the circle using an arc.
                &lt;/span&gt;ctx.arc(100, 100, 50, 0, 2 * Math.PI, &lt;span style="color: blue"&gt;true&lt;/span&gt;);
                &lt;span style="color: #006400"&gt;// Fill the circle.
                &lt;/span&gt;ctx.fill();
            }
        }

        &lt;span style="color: #006400"&gt;// This function is called when you click the canvas.
        &lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;clickOnUI() {
            alert(&lt;span style="color: maroon"&gt;&amp;quot;You clicked the canvas UI element.&amp;quot;&lt;/span&gt;);
        }
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body &lt;/span&gt;&lt;span style="color: red"&gt;onload&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;drawOnCanvas()&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Canvas User Interface&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!-- Create the Canvas element. --&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;canvas &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;uIElement&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;200&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;200&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;clickOnUI()&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Click on the gold circular user interface element.&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Si votre navigateur le supporte, vous devriez voir juste en-dessous le même cercle jaune que précédemment :&lt;/p&gt;

&lt;p&gt;&lt;canvas id="canvasCercleJaune" onclick="clickOnUI()" width="200px" height="200px"&gt;Votre navigateur ne supporte pas Canvas&lt;/canvas&gt;&lt;/p&gt;

&lt;p&gt;Vous remarquerez ainsi que l’évènement de click est levé indifféremment du fait que vous ayez cliqué sur le cercle jaune ou pas. En effet, c’est logique, nous nous sommes abonnés à l’évènement onclick() de l’élément canvas lui-même. Il sera donc levé quelque soit l’endroit sur lequel nous cliquerons. Si l’on souhaitait obtenir le même comportement qu’avec l’exemple SVG où l’évènement était uniquement levé sur le click sur le cercle, il faudrait procéder autrement. Il faudrait tout d’abord repérer où se trouvait le curseur de la souris au moment où l’utilisateur a cliqué pour obtenir les coordonnées X et Y. Une fois les coordonnées récupérées, il faudrait ensuite vérifier ce que nous avions dessiné à cet endroit précis et si ce pixel particulier faisait alors parti du cercle jaune (il suffit de faire un peu de math &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-10-46-metablogapi/2100.wlEmoticon_2D00_winkingsmile_5F00_505A0144.png" /&gt;). C’est donc à vous de vous occuper de tout cela et je pense que vous devriez maintenant mieux comprendre la différence entre le mode “retained mode” de SVG et le mode “fire &amp;amp; forget” de Canvas. &lt;/p&gt;

&lt;h3&gt;CanvasPad : une application pour apprendre Canvas en tout simplicité&lt;/h3&gt;

&lt;p&gt;Si vous souhaitez vous familiariser avec les bases de canvas, je ne serais que trop vous recommander d’aller jouer avec notre application CanvasPad présente sur notre site IE Test Drive ici : &lt;a href="http://ie.microsoft.com/testdrive/Graphics/CanvasPad/Default.html"&gt;Canvas Pad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Il y a un petit éditeur de script intégré avec des exemples simples vous permettant de faire vos premières armes dessus. &lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_006_CanvasPad by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5690805088/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_006_CanvasPad" src="http://farm6.static.flickr.com/5025/5690805088_06d8173020.jpg" width="500" height="308" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On y retrouve les formes de bases, la possibilité de gérer des ombres portées, d’afficher du texte, des images et des vidéos au sein même du canvas, des transformations et des animations.&lt;/p&gt;

&lt;h2&gt;Revue du même jeu écrit en Canvas et SVG&lt;/h2&gt;

&lt;p&gt;Il m’a paru intéressant pour finir cette introduction aux bases de ces 2 jeux d’APIs de comparer exactement le même jeu écrit à base de Canvas puis à base de SVG. Le principe est simple : on a une barre (un paddle) en bas, une petite balle rouge qui rebondit sur les murs et l’on doit simplement éviter que la petite balle rouge touche le sol. Voilà les règles extrêmement complexes du jeu. &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-10-46-metablogapi/7563.wlEmoticon_2D00_smile_5F00_779CF6B5.png" /&gt;&lt;/p&gt;

&lt;p&gt;Visuellement, les 2 jeux sont identiques :&lt;/p&gt;

&lt;p&gt;&lt;a title="HTML5Graphics_007_GamePad by Internet Explorer 9, on Flickr" href="http://www.flickr.com/photos/60699397@N08/5690283403/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" alt="HTML5Graphics_007_GamePad" src="http://farm6.static.flickr.com/5068/5690283403_541ae559c4.jpg" width="500" height="282" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous pouvez tester la version canvas ici : &lt;a href="http://david.blob.core.windows.net/html5graphics/009_SimpleGame_CanvasVersion.htm"&gt;Canvas Racquetball&lt;/a&gt; et la version SVG ici : &lt;a href="http://david.blob.core.windows.net/html5graphics/010_SimpleGame_SVGVersion.htm"&gt;SVG Racketball&lt;/a&gt;. Ils sont issus de ces 2 tutoriaux MSDN : &lt;a title="http://msdn.microsoft.com/fr-fr/library/gg589521(v=VS.85).aspx" href="http://msdn.microsoft.com/fr-fr/library/gg589521(v=VS.85).aspx"&gt;Programmation de jeux simples avec Canvas ou SVG&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Je vous invite à lire ce tutorial qui explique bien les différences entre les 2 modes sur ce jeu particulier. Nous verrons dans &lt;a href="http://blogs.msdn.com/b/davrous/archive/2011/05/20/introduction-aux-apis-graphiques-d-html5-svg-amp-canvas-2-4.aspx"&gt;le prochain article&lt;/a&gt; une tentative de positionnement de chacun des 2 modes par scénario d’utilisation.&amp;#160; &lt;/p&gt;

&lt;p&gt;A bientôt pour la suite !&lt;/p&gt;
&lt;script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.4.4.min.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;
jQuery(document).ready(function ($) {
    // Tested OK with IE9, FF4, Chrome 9, Opera 11 &amp; Safari 5
    if (isCanvasSupported())
    {
	simpleCanvas();
	canvasCercleJaune();
    }
});

// using recommendations from :
// http://stackoverflow.com/questions/2745432/best-way-to-detect-that-html5-canvas-is-not-supported
function isCanvasSupported(){  
     var elem = document.createElement('canvas');  
     return !!(elem.getContext &amp;&amp; elem.getContext('2d'));
}
    
	function simpleCanvas() {
                var canvas = document.getElementById("monCanvas");
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgb(0,0,255)";
                ctx.fillRect(10, 10, 100, 100);
            }

	function canvasCercleJaune() {
            // Get the canvas element.
            var canvas = document.getElementById("canvasCercleJaune");

            // Make sure you got it.
            if (canvas.getContext)
            // If you have it, create a canvas user inteface element.
            {
                // Specify 2d canvas type.
                var ctx = canvas.getContext("2d");
                // Draw gold UI element.
                // Start the path.
                ctx.beginPath();
                // Define the fill color in RGB for gold.
                ctx.fillStyle = "rgb(255 ,215 ,0)";
                // Draw the circle using an arc.
                ctx.arc(100, 100, 50, 0, 2 * Math.PI, true);
                // Fill the circle.
                ctx.fill();
            }
            }

        // This function is called when the circle is clicked.
        function clickMe() {
            // Display the alert.
            alert("Vous avez cliqué sur l'élément SVG: cercle jaune.");
        }

        // This function is called when you click the canvas.
        function clickOnUI() {
            alert("Vous avez cliqué sur l'élément canvas.");
        }
        &lt;/script&gt;

&lt;p&gt;David&lt;/p&gt;
&lt;script src="http://david.blob.core.windows.net/html5/mathlib-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/k3d-min.js"&gt;&lt;/script&gt;&lt;script src="http://david.blob.core.windows.net/html5/html5logo_noscroll.js"&gt;&lt;/script&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10162502" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Internet+Explorer+9/">Internet Explorer 9</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Canvas/">Canvas</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/SVG/">SVG</category></item><item><title>Mix11: retour sur la partie HTML5 du 1er keynote avec IE9/10, HTML5Labs et ASP.NET MVC3</title><link>http://blogs.msdn.com/b/davrous/archive/2011/04/13/mix11-retour-sur-la-partie-html5-du-1er-keynote-avec-ie9-10-html5labs-et-asp-net-mvc3.aspx</link><pubDate>Wed, 13 Apr 2011 02:31:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10152988</guid><dc:creator>David Rousset</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/davrous/rsscomments.aspx?WeblogPostID=10152988</wfw:commentRss><comments>http://blogs.msdn.com/b/davrous/archive/2011/04/13/mix11-retour-sur-la-partie-html5-du-1er-keynote-avec-ie9-10-html5labs-et-asp-net-mvc3.aspx#comments</comments><description>&lt;p&gt;Nous sommes plusieurs à avoir à nouveau la chance d’être présents à Las Vegas pour couvrir le MIX annuel. Cette année sera orientée HTML5, IE9/10, Windows Phone 7.5 et Silverlight 5. Bref, plein de bonnes et belles choses à découvrir. Je vais me concentrer pour ma part dans ce billet à ce qui touche à HTML5.&lt;/p&gt;  &lt;p&gt;Commençons par découvrir cette première plénière présentée par Dean Hachamovitch &amp;amp; Scott Guthrie que vous pouvez revoir ici : &lt;a title="http://live.visitmix.com/Keynotes" href="http://live.visitmix.com/Keynotes"&gt;http://live.visitmix.com/Keynotes&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Internet Explorer&lt;/h2&gt;  &lt;p&gt;Tout d’abord, Dean est revenu sur notre stratégie de développement du navigateur et la manière que nous avons choisis d’implémenter de nouvelles fonctionnalités au travers des Platform Preview. IE9 comporte ainsi un certain nombre de fonctionnalités d’HTML5 et CSS3 que nous considérons comme “Site Ready” ou autrement dit, prêts à être utilisés en production. Vous n’êtes pas sans savoir en effet que de nombreuses spécifications de CSS3 par exemple sont encore à l’état de brouillon (Working Draft).&lt;/p&gt;  &lt;p&gt;Nous avons ensuite fait de belles démonstrations d’applications purement HTML5 dans IE9 grâce à notre excellent support de l’accélération matérielle :&lt;/p&gt;  &lt;p&gt;- une façon unique de découvrir Foursquare en 3D isométrique avec Foursquare Playground : &lt;a title="http://foursquareplayground.com/" href="http://foursquareplayground.com/"&gt;http://foursquareplayground.com/&lt;/a&gt;    &lt;br /&gt;- une très impressionnante démo d’un manga animé entièrement réalisée en SVG : &lt;a title="http://jsdo.it/event/svggirl" href="http://jsdo.it/event/svggirl"&gt;http://jsdo.it/event/svggirl&lt;/a&gt; (ceci n’est pas une vidéo !).    &lt;br /&gt;- la possibilité de faire un montage vidéo des clips de Bon Jovi : &lt;a title="http://director.bonjovi.com/" href="http://director.bonjovi.com/"&gt;http://director.bonjovi.com/&lt;/a&gt; avec l’utilisation de canvas, SVG et bien sûr la balise vidéo.    &lt;br /&gt;- le plus grand PacMan au monde : &lt;a title="http://worldsbiggestpacman.com/" href="http://worldsbiggestpacman.com/"&gt;http://worldsbiggestpacman.com/&lt;/a&gt; ! &lt;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="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-10-46-metablogapi/7853.wlEmoticon_2D00_smile_5F00_1EB896CE.png" /&gt; Merci à &amp;lt;canvas&amp;gt; à nouveau.&amp;#160; &lt;/p&gt;  &lt;p&gt;Nous avons ensuite annoncé la disponibilité de la 1ère Platform Preview d’IE10 ! Vous pouvez la télécharger ici : &lt;a href="http://ie.microsoft.com/testdrive"&gt;http://ie.microsoft.com/testdrive&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Au programme, des nouveautés très intéressantes :&lt;/p&gt;  &lt;p&gt;- CSS3 Flexbox   &lt;br /&gt;- CSS3 Grid Alignment    &lt;br /&gt;- CSS3 Multi-column    &lt;br /&gt;- CSS3 Gradients     &lt;br /&gt;- ECMAScript5 Strict Mode&lt;/p&gt;  &lt;p&gt;Vous trouverez toutes ces nouveautés détaillées ici : &lt;a title="http://msdn.microsoft.com/fr-fr/ie/gg192966.aspx" href="http://msdn.microsoft.com/fr-fr/ie/gg192966.aspx"&gt;Internet Explorer Platform Preview Guide for Developers&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pour les développeurs Silverlight, CSS3 Flexbox ressemble tout simplement au container &amp;lt;StackPanel&amp;gt; et CSS3 Grid au container &amp;lt;Grid&amp;gt;. Je peux vous dire que ces nouveautés, combinées à CSS3 Media Queries, vont permettre la réalisation de sites ou d’applications HTML5 pouvant facilement s’adapter à des téléphones, des tablettes ou des PC. Une session était d’ailleurs dédiée à ce thème : &lt;a title="http://channel9.msdn.com/events/MIX/MIX11/HTM11" href="http://channel9.msdn.com/events/MIX/MIX11/HTM11"&gt;IE 10 Platform Preview 1: The Future of Adaptive Web Design&lt;/a&gt;. Elle est particulièrement intéressante et donne un aperçu du futur je pense. A regarder !&lt;/p&gt;  &lt;p&gt;Pendant le keynote, il y a eu également de belles démonstrations de CSS3 Transitions et CSS3 3D Transform qui arriveront dans une PP suivante. Le rythme des Platform Preview sera de 8 à 12 semaines (alors qu’IE9 avait un rythme de 6 à 8 semaines).&lt;/p&gt;  &lt;p&gt;Pour finir sur IE, Steven Sinofsky himself est venu nous faire les démos d’IE10 le tout sur… une machine disposant d’un CPU 1 Ghz à architecture ARM (un Tegra 2 de nVidia) ! La grosse surprise du keynote sans aucun doute !&lt;/p&gt;  &lt;p&gt;Stanislas a fait également un très beau billet sur cette partie du keynote sur notre blog IE France : &lt;a title="http://blogs.msdn.com/b/iefrance/archive/2011/04/12/internet-explorer-10-platform-preview-1-pr-233-sent-233-224-mix-2011.aspx" href="http://blogs.msdn.com/b/iefrance/archive/2011/04/12/internet-explorer-10-platform-preview-1-pr-233-sent-233-224-mix-2011.aspx"&gt;Internet Explorer 10 Platform Preview 1 présenté à MIX 2011&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;HTML5Labs&lt;/h2&gt;  &lt;p&gt;Notre stratégie est différente de celle des concurrents sur le travail autour des spécifications expérimentales. Nous ne les mettons pas directement dans le navigateur comme le font par exemple Google ou Mozilla avec le risque de devoir mettre à jour le navigateur puis ensuite son code pour avoir par exemple la dernière version du protocole WebSockets. Notre travail s’effectue autour d’une méthode différente proposée par notre groupe d’interopérabilité et nommée HTML5Labs : &lt;a href="http://html5labs.com"&gt;http://html5labs.com&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Une nouvelle version du site a été annoncée au keynote. On trouve désormais 4 spécifications présentes sur le site :&lt;/p&gt;  &lt;p&gt;- WebSockets   &lt;br /&gt;- IndexDB    &lt;br /&gt;- FileAPI    &lt;br /&gt;- Media Capture API&lt;/p&gt;  &lt;p&gt;J’ai pu assister à une session très intéressante &lt;a title="http://channel9.msdn.com/events/MIX/MIX11/HTM10" href="http://channel9.msdn.com/events/MIX/MIX11/HTM10"&gt;Hot from the Labs: HTML5 WebSockets&lt;/a&gt; sur laquelle je reviendrais dans un billet séparé. &lt;/p&gt;  &lt;h2&gt;ASP.NET MVC3, WebMatrix et Entity Framework 4.1&lt;/h2&gt;  &lt;p&gt;Pour finir sur les annonces autour d’HTML5, ASP.NET MVC3 a été mis à jour : &lt;a href="http://asp.net/mvc"&gt;http://asp.net/mvc&lt;/a&gt; et supporte désormais des templates HTML5. Au programme : nouveaux tags sémantiques (comme header, section, footer) et utilisation de quelques parties de CSS3 comme les border-radius. Bonne nouvelle : ASP.NET MVC3 livre désormais par défaut la très célèbre librairie JS &lt;a href="http://www.modernizr.com/"&gt;Modernizr&lt;/a&gt;. Cela permet (entre autres) d’utiliser ces nouveaux tags sémantiques HTML5 sans perdre pour autant le fonctionnement du site avec IE8 et inférieurs. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt; a alors fait une superbe prestation de 8 min où il a utilisé ces nouveaux templates, Entity Framework 4.1 Code First, jQuery pour créer un back office puis ensuite un frontal en WebMatrix. Très belle démonstration de la maturité de ces produits et des cibles différentes de chacun d’entre eux. Scott est aussi un excellent speaker ! &lt;/p&gt;  &lt;p&gt;D’autres comptes rendus en Français :&lt;/p&gt;  &lt;p&gt;- Nicolas Clerc : &lt;a title="http://nicolasclerc.wordpress.com/2011/04/13/mix-2011-cest-parti-keynote-du-11-avril/" href="http://nicolasclerc.wordpress.com/2011/04/13/mix-2011-cest-parti-keynote-du-11-avril/"&gt;http://nicolasclerc.wordpress.com/2011/04/13/mix-2011-cest-parti-keynote-du-11-avril/&lt;/a&gt;    &lt;br /&gt;- David Catuhe : &lt;a title="http://www.catuhe.com/post/Mix2011–Keynote–Day-1.aspx" href="http://www.catuhe.com/post/Mix2011&amp;ndash;Keynote&amp;ndash;Day-1.aspx"&gt;http://www.catuhe.com/post/Mix2011–Keynote–Day-1.aspx&lt;/a&gt;    &lt;br /&gt;- Christophe Lauer : &lt;a title="http://blogs.msdn.com/b/sublimaction/archive/2011/04/13/mix11-las-vegas-les-choses-224-retenir-du-premier-keynote.aspx" href="http://blogs.msdn.com/b/sublimaction/archive/2011/04/13/mix11-las-vegas-les-choses-224-retenir-du-premier-keynote.aspx"&gt;Mix11 Las Vegas : Les choses à retenir du premier keynote&lt;/a&gt; . Un très beau billet de Christophe à lire ! (même s’il se moque un peu de moi quelque part… &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d&amp;#39;œil" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-10-46-metablogapi/0601.wlEmoticon_2D00_winkingsmile_5F00_6A37C485.png" /&gt;)&lt;/p&gt;  &lt;p&gt;A demain pour la suite !&lt;/p&gt;  &lt;p&gt;David&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10152988" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/davrous/archive/tags/HTML5/">HTML5</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/IE10/">IE10</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Mix11/">Mix11</category><category domain="http://blogs.msdn.com/b/davrous/archive/tags/Mix2011/">Mix2011</category></item></channel></rss>
