I do know about the case of float/integer values for drawImage
's x
and y
. But what I need is a smooth animation with an ability to cache my shapes.
drawImage
with float parametersFor example, I want to draw some complex shape (i.e. SVG-tiger, converted to canvas-commands) to canvas just once and then move it smoothly with ctx.translate
and ctx.drawImage
. I need the float values then, because instead I get a step-by-step moving:
Here's the examples at JSFiddle:
Math.floor
applied to translate
parameters (x
and y
are equal to time in seconds multiplied by 10
): Animation is weird (sequential, not smooth).Math.floor
applied to translate
parameters (x
and y
are equal to time in seconds): Animation is weird (sequential, not smooth).x
and y
are equal to time in seconds multiplied by 10
). Speed is fast, so animation looks good.x
and y
are equal to time in seconds). Speed is slow, so animation looks pulsating. Why?
The last case is the one that confuses me. Am I wrong in my tryings and there is a possibility to make this caching trick work nice?
In Firefox, there is a property of canvas named mozImageSmoothingEnabled
(see), but there is no help from that in other browsers. And it also removes paths smoothing.
Code extract:
var shapeCanvas = null;
var w = 320, h = 240;
var startTime = 0;
function start() {
startTime = Date.now();
var docCanvas = document.getElementById('canvas');
. . .
shapeCanvas = document.createElement('canvas');
. . .
drawShape(shapeCanvas.getContext('2d'));
drawNext(docCanvas.getContext('2d'));
}
function drawNext(ctx) {
var msec = (Date.now() - startTime);
var time = msec / 1000; // seconds passed from start
ctx.clearRect(0, 0, w, h);
ctx.save();
// the lines to change: time | (time * 10) | Math.floor(time * 10)
ctx.translate((time < 500) ? Math.floor(time * 10) : 500,
(time < 500) ? Math.floor(time * 10) : 500);
ctx.drawImage(shapeCanvas, 0, 0);
ctx.restore();
__nextFrame(function() {
drawNext(ctx);
});
}
function drawShape(ctx) {
. . .
}
Set your DPI to 300 or Higher. For accurate photo reproduction on canvas, ensure that you set your image to at least 300 DPI. If you set the DPI too low, it will result in fuzzed-out, poor-quality images. This can be straightforwardly easy when working with a porous-stock like canvas.
The Canvas tab loaded in one second and takes up 30MB. It also takes up 13% of CPU time all of the time, regardless of whether or not one is looking at it.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With