HTML5+JavaScript: Tiled background cache


Not much of informative demonstration, but is cross-platform and shows performance.

If you've noticed, multiple systems are better at drawing single large images than lots of small ones.
Same applies to HTML5, meaning that filling a 640x480 canvas with 40x40 images using two for() loops is not exactly a good thing to do each frame.

Common solution to this problem is to create a 'cache' image that would hold a tiled version of image to be drawn easily.
That means drawing image W*H times only once in a while.

However, actually you can do even better than this.

HTML5 specification states that canvas should support drawing parts to itself, to allow moving content around in it.
Along with other obvious uses, this means that you can 'double' contents of canvas by drawing it into itself on a offset.
This in turn allows to reduce number of draws required to fill canvas from (W * H) to (log2W * log2H).
A 'full' function to utilize this in filling canvas with tiled image would look like this:

function fillTiledImage(canvas, context, image) {
	var iw = image.width, ih = image.height,
		cw = canvas.width, ch = canvas.height;
	context.clearRect(0, 0, cw, ch);
	context.drawImage(image, 0, 0);
	while (iw < cw) { context.drawImage(canvas, 0, 0, iw, ih, iw, 0, iw, ih); iw *= 2; }
	while (ih < ch) { context.drawImage(canvas, 0, 0, cw, ih, 0, ih, cw, ih); ih *= 2; }
}

(added 'rectangle' restriction to keep browser from possibly trying to draw empty parts of canvas).
As an additional note, if image is entirely opaque, one can keep this without clearRect method, saving time needed to reset all pixels in canvas.

Hopefully this was useful and\or informative enough.

Related posts:

Leave a Reply

Your email address will not be published. Required fields are marked *