HTML5 Canvas: Elements drawn with/cached for drawImage are smoothed when scaled and/or moved

I wrote the tutorial in your first link.

Just to clear the air:

shapeCanvas.style.width = w + 'px';
shapeCanvas.style.height = h + 'px';

is not really worth doing. No point setting the style if its just a in-memory canvas, and you shouldn't really ever want to set the width and height style of a canvas anyway, it just confounds things.

What ellisbben said in the comment is pretty much what's happening.

It's possible to get around it in a few hackish ways I bet. One way might be to make sure its never drawn on an integer pixel. Another might be to use ctx.scale(.99,.99) before drawing anything so it is always anti-aliased. It's tough to get a consistent solution here because different browswer's implementations of anti-aliasing are different.

Here are a few experiments from myself:

http://jsfiddle.net/KYZYT/29/

The first two are the shape drawn from a canvas and also drawn from a PNG

The second two are the same pair but scaled by .99,.99

The last one is the real thing. It still blurs a bit but looks a lot sharper than using the images.

None of my experiments lead to an end of your pulsating, at least not on a microscopic level. I think this is just something you're going to have to live with if you want to animate pixel-perfect images onto half-pixel spaces.

If you really feel you can't just draw on perfect pixels then your (second) best bet for consistency is probably to find a way to force anti-aliasing at all times. Making sure you are always translated to a non-integer or scaling it ever so slightly are decent candidates, but there may be others.

To be honest, you best bet is to not cache these animated paths until you absolutely need the performance from them. Cache the stylized buttons and other static things you make, but if you've got animated paths that need to move slowly and precisely and look very good, you might as well stick with the true thing over my caching optimization unless you really need it for those too.


Bit shameless plug but: I've implement smooth animation in HTML5 slot game with bit hacky way. The generated cached Image is drawn on small canvas once and then I used translate3d() with -moz-transform / -webkit-transform styles for the canvas to move, mirror and scale the image around.

Pregeneration

  1. Create Image
  2. Draw image content
  3. Create canvas object in DOM

Animation phase

  1. Clear canvas
  2. Draw the cached image to the canvas
  3. Use CSS3 transforms (scale3d and translate3d) to move canvas around.