{"id":74,"date":"2011-01-19T09:33:04","date_gmt":"2011-01-19T15:33:04","guid":{"rendered":"http:\/\/timothypoon.com\/blog\/?p=74"},"modified":"2016-02-19T09:04:43","modified_gmt":"2016-02-19T15:04:43","slug":"html5-canvas-particle-animation","status":"publish","type":"post","link":"https:\/\/timothypoon.com\/blog\/2011\/01\/19\/html5-canvas-particle-animation\/","title":{"rendered":"HTML5 Canvas Particle Animation"},"content":{"rendered":"<p><strong>UPDATE:<\/strong> yes, I know some people out there will see some flickering when viewing the <a href=\"\/blog\/demos\/canvas-particle-parallax\/\" title=\"HTML5 Canvas Particle Animation and Parallax Demo\">demo<\/a>. This is because a) I didn&#8217;t implement a double buffer, and b) there is no built-in canvas support for double buffering. There is a very <a href=\"http:\/\/stackoverflow.com\/questions\/2795269\/does-html5-canvas-support-double-buffering\" title=\"javascript - Does HTML5\/Canvas Support Double Buffering? - Stack Overflow\">simple solution<\/a>, but I&#8217;ll save that for another time.<\/p>\n<p>Having never really been a user of Apple products, I guess it&#8217;s not all that surprising that I&#8217;ve never been to the <a href=\"http:\/\/www.me.com\/\" title=\"MobileMe Signin\">MobileMe website<\/a>. However, after Googling something like the lines of &#8220;<a href=\"http:\/\/www.google.com\/search?q=most+popular+e-mail+providers\" title=\"most popular e-mail providers - Google Search\">most popular e-mail providers<\/a>,&#8221; I came across its login page and was blown away.<\/p>\n<p><a href=\"http:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-1.png\"><img decoding=\"async\" src=\"http:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-1.png\" alt=\"\" title=\"MobileMe Login\" width=\"100%\" class=\"aligncenter size-full wp-image-75\" srcset=\"https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-1.png 800w, https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-1-300x225.png 300w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>Holy moly, that looks amazing. Not only is the design great and the colors are just about perfect, but those little sparkles are crazy! They move in what appears to be 3D space, pulsing from behind the cloud to further into the background amongst and into (while highlighting) the iPads and iPhones, and follow your mouse movements for extra fun.<\/p>\n<p>After poking around <a href=\"https:\/\/auth.me.com\/my\/loginForm\/en-us\/2E11\/javascript-packed.js\" title=\"JavaScript source\">the source<\/a> and giving up on <a href=\"http:\/\/jsbeautifier.org\/\" title=\"Online javascript beautifier\">100% comprehension<\/a>, I decided it might be fun to take a whack at my own thoroughly underwhelming homage to the MobileMe page.<\/p>\n<h2>The Setup<\/h2>\n<p>For some reason or another, I decided to make a night scene of some mountains and grass for some stars to streak across (I also threw in some <a href=\"http:\/\/en.wikipedia.org\/wiki\/Parallax\" title=\"Parallax - Wikipedia, the free encyclopedia\">parallax<\/a>, but that&#8217;s for another post). Here&#8217;s what I&#8217;m starting out with prior to any <a href=\"http:\/\/en.wikipedia.org\/wiki\/Canvas_element\" title=\"Canvas element - Wikipedia, the free encyclopedia\">canvas magic<\/a>:<\/p>\n<p><a href=\"http:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-2.png\"><img decoding=\"async\" src=\"http:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-2-1024x576.png\" alt=\"\" title=\"Blank Night Sky\" width=\"100%\" class=\"aligncenter size-large wp-image-76\" srcset=\"https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-2-1024x576.png 1024w, https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-2-300x168.png 300w, https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-2.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>And here&#8217;s the accompanying code to make that happen (it&#8217;s pretty simple, but I&#8217;m including it anyways so as little is left out as possible):<\/p>\n<div class=\"codecolorer-container css railscasts\" style=\"overflow:auto;white-space:nowrap;width:100%;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/><\/div><\/td><td><div class=\"css codecolorer\"><span class=\"re0\">#container<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">overflow<\/span><span class=\"sy0\">:<\/span><span class=\"kw2\">hidden<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">position<\/span><span class=\"sy0\">:<\/span><span class=\"kw2\">relative<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"re0\">#pixie<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">z-index<\/span><span class=\"sy0\">:<\/span><span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">background<\/span><span class=\"sy0\">:<\/span>-moz-linear-gradient<span class=\"br0\">&#40;<\/span><span class=\"kw2\">top<\/span><span class=\"sy0\">,<\/span> <span class=\"re0\">#040429<\/span><span class=\"sy0\">,<\/span> <span class=\"re0\">#257eb7<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">background<\/span><span class=\"sy0\">:<\/span>-webkit-gradient<span class=\"br0\">&#40;<\/span>linear<span class=\"sy0\">,<\/span> <span class=\"kw2\">left<\/span> <span class=\"kw2\">top<\/span><span class=\"sy0\">,<\/span> <span class=\"kw2\">left<\/span> <span class=\"kw2\">bottom<\/span><span class=\"sy0\">,<\/span> color-stop<span class=\"br0\">&#40;<\/span><span class=\"re3\">0%<\/span><span class=\"sy0\">,<\/span><span class=\"re0\">#040429<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span> color-stop<span class=\"br0\">&#40;<\/span><span class=\"re3\">100%<\/span><span class=\"sy0\">,<\/span><span class=\"re0\">#257eb7<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"re0\">#mountains<\/span><span class=\"sy0\">,<\/span> <span class=\"re0\">#grass<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">width<\/span><span class=\"sy0\">:<\/span><span class=\"re3\">100%<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">position<\/span><span class=\"sy0\">:<\/span><span class=\"kw2\">absolute<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">bottom<\/span><span class=\"sy0\">:<\/span><span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"re0\">#mountains<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">height<\/span><span class=\"sy0\">:<\/span><span class=\"re3\">156px<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">z-index<\/span><span class=\"sy0\">:<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">background<\/span><span class=\"sy0\">:<\/span><span class=\"kw3\">url<\/span><span class=\"br0\">&#40;<\/span><span class=\"co2\">mountains.png<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw2\">repeat-x<\/span> <span class=\"nu0\">0<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"re0\">#grass<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">height<\/span><span class=\"sy0\">:<\/span><span class=\"re3\">62px<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">z-index<\/span><span class=\"sy0\">:<\/span><span class=\"nu0\">2<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">background<\/span><span class=\"sy0\">:<\/span><span class=\"kw3\">url<\/span><span class=\"br0\">&#40;<\/span><span class=\"co2\">grass.png<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw2\">repeat-x<\/span> <span class=\"kw2\">left<\/span> <span class=\"re3\">10px<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<div class=\"codecolorer-container html4strict railscasts\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/><\/div><\/td><td><div class=\"html4strict codecolorer\"><span class=\"sc2\">&lt;<a href=\"http:\/\/december.com\/html\/4\/element\/div.html\"><span class=\"kw2\">div<\/span><\/a> <span class=\"kw3\">id<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;container&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;canvas <span class=\"kw3\">id<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;pixie&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span>canvas&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<a href=\"http:\/\/december.com\/html\/4\/element\/div.html\"><span class=\"kw2\">div<\/span><\/a> <span class=\"kw3\">id<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;mountains&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><a href=\"http:\/\/december.com\/html\/4\/element\/div.html\"><span class=\"kw2\">div<\/span><\/a>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<a href=\"http:\/\/december.com\/html\/4\/element\/div.html\"><span class=\"kw2\">div<\/span><\/a> <span class=\"kw3\">id<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;grass&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><a href=\"http:\/\/december.com\/html\/4\/element\/div.html\"><span class=\"kw2\">div<\/span><\/a>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><a href=\"http:\/\/december.com\/html\/4\/element\/div.html\"><span class=\"kw2\">div<\/span><\/a>&gt;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>But that&#8217;s child&#8217;s play compared to what you really came here for: <a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/the-canvas-element.html\" title=\"4.8.11 The canvas element - HTML5 (including next generation additions still in development)\">HTML5 canvas<\/a>! (You should note, though, that the actual height and width attributes of the canvas element must be set in the HTML or dynamically through JavaScript and not just the CSS, otherwise you&#8217;ll get something&#8230;weird)<\/p>\n<h2>The JavaScript<\/h2>\n<p>What first needs to happen is setting up the drawing environment. This includes grabbing the appropriate elements and getting the drawing dimensions.<\/p>\n<div class=\"codecolorer-container javascript railscasts\" style=\"overflow:auto;white-space:nowrap;width:100%;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/><\/div><\/td><td><div class=\"javascript codecolorer\"><span class=\"kw1\">var<\/span> WIDTH <span class=\"sy0\">=<\/span> window.<span class=\"me1\">innerWidth<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; HEIGHT <span class=\"sy0\">=<\/span> window.<span class=\"me1\">innerHeight<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; MAX_PARTICLES <span class=\"sy0\">=<\/span> <span class=\"nu0\">100<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; DRAW_INTERVAL <span class=\"sy0\">=<\/span> <span class=\"nu0\">60<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; container <span class=\"sy0\">=<\/span> document.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'#container'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; canvas <span class=\"sy0\">=<\/span> document.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'#pixie'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; context <span class=\"sy0\">=<\/span> canvas.<span class=\"me1\">getContext<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'2d'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; gradient <span class=\"sy0\">=<\/span> <span class=\"kw2\">null<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; pixies <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Array<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">function<\/span> setDimensions<span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; WIDTH <span class=\"sy0\">=<\/span> window.<span class=\"me1\">innerWidth<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; HEIGHT <span class=\"sy0\">=<\/span> window.<span class=\"me1\">innerHeight<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; container.<span class=\"me1\">style<\/span>.<span class=\"me1\">width<\/span> <span class=\"sy0\">=<\/span> WIDTH<span class=\"sy0\">+<\/span><span class=\"st0\">'px'<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; container.<span class=\"me1\">style<\/span>.<span class=\"me1\">height<\/span> <span class=\"sy0\">=<\/span> HEIGHT<span class=\"sy0\">+<\/span><span class=\"st0\">'px'<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; canvas.<span class=\"me1\">width<\/span> <span class=\"sy0\">=<\/span> WIDTH<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; canvas.<span class=\"me1\">height<\/span> <span class=\"sy0\">=<\/span> HEIGHT<span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\nsetDimensions<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nwindow.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'resize'<\/span><span class=\"sy0\">,<\/span> setDimensions<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>This ensures that on window resizes, everything gets set again and updated to the new dimensions. You can also tinker with <code class=\"codecolorer text geshi\"><span class=\"text\">MAX_PARTICLES<\/span><\/code> and <code class=\"codecolorer text geshi\"><span class=\"text\">DRAW_INTERVAL<\/span><\/code> to your liking.<\/p>\n<p>Next up is the <code class=\"codecolorer text geshi\"><span class=\"text\">Circle<\/span><\/code> object. It contains the bulk of the logic of how the particles will behave.<\/p>\n<div class=\"codecolorer-container javascript railscasts\" style=\"overflow:auto;white-space:nowrap;width:100%;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/>52<br \/><\/div><\/td><td><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> Circle<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#123;<\/span>ttl<span class=\"sy0\">:<\/span><span class=\"nu0\">8000<\/span><span class=\"sy0\">,<\/span> xmax<span class=\"sy0\">:<\/span><span class=\"nu0\">5<\/span><span class=\"sy0\">,<\/span> ymax<span class=\"sy0\">:<\/span><span class=\"nu0\">2<\/span><span class=\"sy0\">,<\/span> rmax<span class=\"sy0\">:<\/span><span class=\"nu0\">10<\/span><span class=\"sy0\">,<\/span> rt<span class=\"sy0\">:<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">,<\/span> xdef<span class=\"sy0\">:<\/span><span class=\"nu0\">960<\/span><span class=\"sy0\">,<\/span> ydef<span class=\"sy0\">:<\/span><span class=\"nu0\">540<\/span><span class=\"sy0\">,<\/span> xdrift<span class=\"sy0\">:<\/span><span class=\"nu0\">4<\/span><span class=\"sy0\">,<\/span> ydrift<span class=\"sy0\">:<\/span> <span class=\"nu0\">4<\/span><span class=\"sy0\">,<\/span> random<span class=\"sy0\">:<\/span><span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span> blink<span class=\"sy0\">:<\/span><span class=\"kw2\">true<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">reset<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">random<\/span> <span class=\"sy0\">?<\/span> WIDTH<span class=\"sy0\">*<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">:<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">xdef<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">random<\/span> <span class=\"sy0\">?<\/span> HEIGHT<span class=\"sy0\">*<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">:<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">ydef<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">r<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">rmax<\/span><span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">+<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">dx<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">xmax<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&lt;<\/span> .5 <span class=\"sy0\">?<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span> <span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">dy<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">ymax<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&lt;<\/span> .5 <span class=\"sy0\">?<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span> <span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">ttl<\/span><span class=\"sy0\">\/<\/span>DRAW_INTERVAL<span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">r<\/span><span class=\"sy0\">\/<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">rmax<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">+<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">stop<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span>.2<span class=\"sy0\">+<\/span>.4<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">xdrift<\/span> <span class=\"sy0\">*=<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&lt;<\/span> .5 <span class=\"sy0\">?<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span> <span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">ydrift<\/span> <span class=\"sy0\">*=<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">*<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw4\">Math<\/span>.<span class=\"me1\">random<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&lt;<\/span> .5 <span class=\"sy0\">?<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span> <span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">fade<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">+=<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">rt<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">draw<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">blink<\/span> <span class=\"sy0\">&amp;&amp;<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">&lt;=<\/span> <span class=\"nu0\">0<\/span> <span class=\"sy0\">||<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">&gt;=<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">settings<\/span>.<span class=\"me1\">rt<\/span><span class=\"sy0\">*-<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <span class=\"kw1\">else<\/span> <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span> <span class=\"sy0\">&gt;=<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">reset<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> newo <span class=\"sy0\">=<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">-<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span><span class=\"sy0\">\/<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; context.<span class=\"me1\">beginPath<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; context.<span class=\"me1\">arc<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">r<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">PI<\/span><span class=\"sy0\">*<\/span><span class=\"nu0\">2<\/span><span class=\"sy0\">,<\/span> <span class=\"kw2\">true<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; context.<span class=\"me1\">closePath<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> cr <span class=\"sy0\">=<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">r<\/span><span class=\"sy0\">*<\/span>newo<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gradient <span class=\"sy0\">=<\/span> context.<span class=\"me1\">createRadialGradient<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#40;<\/span>cr <span class=\"sy0\">&lt;=<\/span> <span class=\"nu0\">0<\/span> <span class=\"sy0\">?<\/span> <span class=\"nu0\">1<\/span> <span class=\"sy0\">:<\/span> cr<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gradient.<span class=\"me1\">addColorStop<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">0.0<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'rgba(255,255,255,'<\/span><span class=\"sy0\">+<\/span>newo<span class=\"sy0\">+<\/span><span class=\"st0\">')'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gradient.<span class=\"me1\">addColorStop<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">stop<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'rgba(77,101,181,'<\/span><span class=\"sy0\">+<\/span><span class=\"br0\">&#40;<\/span>newo<span class=\"sy0\">*<\/span>.6<span class=\"br0\">&#41;<\/span><span class=\"sy0\">+<\/span><span class=\"st0\">')'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gradient.<span class=\"me1\">addColorStop<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">1.0<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'rgba(77,101,181,0)'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; context.<span class=\"me1\">fillStyle<\/span> <span class=\"sy0\">=<\/span> gradient<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; context.<span class=\"me1\">fill<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">move<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span> <span class=\"sy0\">+=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span><span class=\"sy0\">\/<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">dx<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span> <span class=\"sy0\">+=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">rt<\/span><span class=\"sy0\">\/<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">hl<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">*<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">dy<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span> <span class=\"sy0\">&gt;<\/span> WIDTH <span class=\"sy0\">||<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span> <span class=\"sy0\">&lt;<\/span> <span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">dx<\/span> <span class=\"sy0\">*=<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span> <span class=\"sy0\">&gt;<\/span> HEIGHT <span class=\"sy0\">||<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span> <span class=\"sy0\">&lt;<\/span> <span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">dy<\/span> <span class=\"sy0\">*=<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">getX<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">x<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">this<\/span>.<span class=\"me1\">getY<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">y<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>The first line is some settings for each particle, each of which is named in a pretty self-explanatory manner.<\/p>\n<ul>\n<li><strong>time_to_live<\/strong> &#8211; used to calculate <strong>hl<\/strong>&#8211;or the half-life&#8211;of each particle<\/li>\n<li><strong>x_maxspeed and y_maxspeed<\/strong> &#8211; defines the maximum number of pixels a particle can move each frame<\/li>\n<li><strong>radius_max<\/strong> &#8211; maximum radius a particle can achieve<\/li>\n<li><strong>rt<\/strong> &#8211; used in conjunction with <strong>hl<\/strong> to determine how the ratio of maximum speed and full opacity of each particle in each frame<\/li>\n<\/ul>\n<p>The <code class=\"codecolorer text geshi\"><span class=\"text\">reset()<\/span><\/code> function just sets up the particle in a new location if it&#8217;s the first iteration or if random is set to true and the <code class=\"codecolorer text geshi\"><span class=\"text\">move()<\/span><\/code> function just moves the particle according to the settings (you&#8217;ll notice I have them moving faster as they get smaller and more transparent). The good stuff comes in the <code class=\"codecolorer text geshi\"><span class=\"text\">draw()<\/span><\/code> function.<\/p>\n<p>Within <code class=\"codecolorer text geshi\"><span class=\"text\">draw()<\/span><\/code>, you see that a new path is started for each particle and drawn into a circle with the <em><a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/the-canvas-element.html#dom-context-2d-arc\" title=\"4.8.11 The canvas element - HTML5 (including next generation additions still in development)\">arc()<\/a><\/em> function. Normally you would use this just to draw an arc, but by supplying 2&#928;, or the radian equivalent to a full circle, as the fifth argument, you get a circle.<\/p>\n<p>Then you can call <em><a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/the-canvas-element.html#dom-context-2d-createradialgradient\" title=\"4.8.11 The canvas element - HTML5 (including next generation additions still in development)\">createRadialGradient()<\/a><\/em> to fill in the circles we just created with color, which I have set with three color stops at various opacities to really make the particles look like they&#8217;re glowing. You should note, though, that the con and g variables are set outside of the Circle object and treated as member variables.<\/p>\n<h2>Animating the Particles<\/h2>\n<p>Finally, you need to create all of the particles and iterate through each one to move and render:<\/p>\n<div class=\"codecolorer-container javascript railscasts\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/><\/div><\/td><td><div class=\"javascript codecolorer\"><span class=\"kw1\">for<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">var<\/span> i <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> MAX_PARTICLES<span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; pixies.<span class=\"me1\">push<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> Circle<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; pixies<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">reset<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">function<\/span> draw<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; context.<span class=\"me1\">clearRect<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> WIDTH<span class=\"sy0\">,<\/span> HEIGHT<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">var<\/span> i <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> pixies.<span class=\"me1\">length<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; pixies<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">fade<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; pixies<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">move<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; pixies<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">draw<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\nsetInterval<span class=\"br0\">&#40;<\/span>draw<span class=\"sy0\">,<\/span> DRAW_INTERVAL<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>The first part creates each new particle (or <code class=\"codecolorer text geshi\"><span class=\"text\">Circle()<\/span><\/code> in this case) and stores it in an array. We then set a function to run at a certain interval based on what frames per second we desire to run at.<\/p>\n<p>The <code class=\"codecolorer text geshi\"><span class=\"text\">draw()<\/span><\/code> function simply iterates over the array and calls each necessary function of each particle to animate its movement. It&#8217;s necessary, though, to point out the <code class=\"codecolorer text geshi\"><span class=\"text\">clearRect()<\/span><\/code> call. Without it, you wouldn&#8217;t get an animation of moving stars in the night sky but rather streaking purple circles.<\/p>\n<p>With any luck, you should get something like this:<\/p>\n<p><a href=\"http:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-3.png\"><img decoding=\"async\" src=\"http:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-3-1024x640.png\" alt=\"\" title=\"The finished product\" width=\"100%\" class=\"aligncenter size-large wp-image-77\" srcset=\"https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-3-1024x640.png 1024w, https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-3-300x187.png 300w, https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/canvas-particle-3.png 1680w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>This is a very base attempt at particle animation with HTML5&#8217;s canvas element. You can do a lot of <a href=\"https:\/\/gaming.mozillalabs.com\/\" title=\"Mozilla Labs - Game On 2010\">other<\/a>, <a href=\"http:\/\/sebleedelisle.com\/2010\/11\/javascript-2d-and-3d-particle-effects-at-full-frontal\/\" title=\"JavaScript 2D and 3D particle effects at Full Frontal | Seb Lee-Delisle\">crazier things<\/a> with canvas, but this is a good place to start understanding how it works and how to get animated things moving with JavaScript.<\/p>\n<p>You can also click and drag left and right on the screen to get some parallax going between the mountains and the grass. I&#8217;ll go into detail on how to achieve that effect later on in life at some point maybe perhaps.<\/p>\n<p><a href=\"\/blog\/demos\/canvas-particle-parallax\/\" title=\"HTML5 Canvas Particle Animation and Parallax Demo\">View the demo<\/a> (requires you to be running an <a href=\"http:\/\/dev.w3.org\/html5\/spec\/spec.html\" title=\"HTML5\">HTML5<\/a>-capable browser).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UPDATE: yes, I know some people out there will see some flickering when viewing the demo. This is because a) I didn&#8217;t implement a double buffer, and b) there is no built-in canvas support for double buffering. There is a very simple solution, but I&#8217;ll save that for another time. Having never really been a user of Apple products, I guess it&#8217;s not all that surprising that I&#8217;ve never been to the MobileMe website. However, after Googling something like the lines of &#8220;most popular e-mail providers,&#8221; I came across its&#8230;<a class=\"read-more\" href=\"https:\/\/timothypoon.com\/blog\/2011\/01\/19\/html5-canvas-particle-animation\/\">read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":279,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[17,16,18,19],"class_list":["post-74","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code","tag-canvas","tag-html5","tag-javascript","tag-particle-animation","et-bg-layout-dark","et-white-bg"],"jetpack_featured_media_url":"https:\/\/timothypoon.com\/blog\/wp-content\/uploads\/2011\/01\/html5-canvas-particle-animation.png","jetpack_shortlink":"https:\/\/wp.me\/p462yg-1c","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/posts\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":3,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"predecessor-version":[{"id":278,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/posts\/74\/revisions\/278"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/media\/279"}],"wp:attachment":[{"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/timothypoon.com\/blog\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}