May 6, 2010

Faster Background Rendering in HTML5 Canvas

One thing that is common in video games and other graphical applications is generating some sort of background image. Generating this may not be a very fast task, so rendering it every frame in this case is not a feasible option.

A common technique to use instead is to render to an off-screen surface that works as a kind of cache. If you're programming using Javascript and the HTML5 canvas element, an off-screen surface is just another canvas that is not being displayed.

To render to an off-screen canvas:
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;

var context = canvas.getContext("2d");

// rendering code
How do you go about getting this onto your main canvas? It's really simple. As it turns out, the drawImage() function of the canvas context object can take not only image objects, but other canvas objects. So you would just go:
var context = mainCanvas.getContext("2d");

context.drawImage(offscreenSurface, ...);
You can get more details on the different ways the surface can be rendered by looking at the specs for the canvas. A great thing about some of the options are that you can have the background of the entire world (if the world is not gigantic) rendered to an off-screen surface, and only render a certain portion of it to your main canvas. This makes it nice and easy for you to implement some kind of scrolling mechanism.

This is very applicable for games, since many 2D games use some kind of tiled background, and need to render it 30+ times per second. Unfortunately if you have say 400 or so tiles visible at a time, using a basic drawImage() for each tile is too slow. You'd need to use some sort of off-screen surface to do this.

1 comment:

Damon Oehlman said...

Nice one Rob - I was hoping there would be something like this that could be done. Ahhh... takes me back to coding custom windows controls :)