Paul King chronic tinkererer

Scaling HTML5 Canvas For Cheap

Last night while trying boost the framerate of my canvas based Raycaster, I remembered a post I'd read on using CSS 3D transforms to optimize 2d canvas drawing on the iPhone 4.

While this approach seemed effective I soon discarded it due to limited browser support for CSS 3D transforms.

Some tinkering/caffeine later I found that the dimensions of a canvas element need not be the same as its CSS dimensions, to clarify: + canvas.width ≠ canvas.style.width + canvas.height ≠ canvas.style.height

This means that you can render to a smaller canvas, then scale it using the CSS width and height properties.

Moreover, the rendering cost of a frame is relative ONLY to the dimensions of the canvas!

Sample Code

canvas = document.getElementById("viewport");
canvas.width = 320;
canvas.height = 240;
canvas.style.width = "640px";
canvas.style.height = "480px";

Real-world Example

Below are three frames from my caster at various canvas sizes, all scaled to 640x480 using CSS.

Rendered 640x480, CSS: 640x480, ~20 FPS:

Rendered 320x240, CSS: 640x480, ~45 FPS

Rendered 160x120, CSS: 640x480, ~52 FPS

There's obviously a diminishing return here, but it's pretty good bang for buck!