I recently worked on a project creating an animated music visualisation using HTML5 canvas elements to create interactive animations.
Since the canvas element is quite new, I thought it might be useful to compile a list of tips I’ve build up while working with it.
In-memory canvas caching
The biggest consideration with canvas animations in optimising the efficiency of the code so that on slower machines and devices the animation doesn’t appear laggy.
The browser will attempt to re-draw the entire canvas every time the context is modified. So if you have complex paths to draw, or several graphics to render for a single frame it can be useful to create an in-memory canvas which you draw your frame on to. Then use a single drawImage() call to draw the in-memory canvas on to the visible canvas.
Layering up canvas elements
If you have used Photoshop or Flash in the past you may be familiar with the idea of layering up graphics to compose a scene. Breaking up your scene into layers of content can help save processing time by only updating layers which have changed, or updating background layers less frequently than foreground layers.
This layering can be accomplished by absolutely positioning several canvas elements on top of each other, using their z-index property to make sure the layers sit in the right order.
CSS3 transitions
If you have a large graphic that you want to animate, like a background image, it may be worth using css3 transforms to move it rather than using a drawImage() command on a canvas element.
Browsers are able to animate CSS3 transforms using keyframe animations a lot more efficiently than canvas re-draws are able to.
requestAnimationFrame
When animating frame-by-frame animations, one option is to use a setTimeout() function to re-draw the canvas element at a set interval. This will work, but there is a more efficient way.
requestAnimationFrame tells the browser to draw the next frame but only if it’s not still busy drawing the previous frame. This ensures that if your animation starts running slowly your frame re-draws don’t get backed up.
It also has the added bonus that if the window isn’t visible, the script won’t bother rendering the frame – so you’ll save processing power (and battery life on mobile devices).
Know your limits
The scope of what is possible with Canvas is almost endless, however the current device capabilities certainly aren’t.
While you’re developing make sure you keep testing on a multitude of browsers and mobile devices to make sure your code isn’t overtaking the processing power available.
Don’t forget that 3d animations aren’t supported by many browsers – crucially iOS.
Android’s native browser is notoriously slow at processing canvas animation because it only uses software acceleration, and doesn’t make the processing power of the full device available to canvas.
Keep this to hand
It’s not cheating to use the HTML 5 Canvas Cheatsheet, so keep this handy.
Now, some cool examples
It wouldn’t be an HTML5 canvas starter post without a list of my favourite demos, so here goes:
- 9Elements audio reacting particle system
- Interactive blobs
- Fractal trees
- Arcade Fire – The Wilderness Downtown
- Nebula Cloud