问题
I'm observing some flickering during the resizing of an animated canvas control.
You can see it in action at this page. Drag the 'width' slider left and right to try it for yourself. I see this flickering in Chrome 26.0.1410.43 running on Linux. Currently this page won't work in Firefox until it supports HTML5's <input type="range">
.
I've tried to reproduce the issue on a smaller scale in this jsFiddle. It's not as noticeable, but occurs for me when the canvas is around 90% of the available width wide.
The code traps requestAnimationFrame
, and resizing wipes the canvas. I would hope that the render callback would be called before the browser's frame was painted. This doesn't seem to be the case, as the white background shows through occasionally during resizing.
Is there anything that can be done to avoid this?
回答1:
When you set canvas.width or canvas.height it clears the canvas, combined with the redrawing this causes the flicker you see.
You can mitigate this to a reasonable extent by saving the canvas to a temporary canvas before resizing and then drawing it back again afterwards.
Here's my resize function:
function resize(width, height) {
//Create temp canvas and context
var tempContext = Utils.Canvas.Create2DContext(context.canvas.width, context.canvas.height);
//Draw current canvas to temp canvas
tempContext.drawImage(context.canvas, 0, 0);
//Resize current canvas
context.canvas.height = height;
context.canvas.width = width;
//Draw temp canvas back to the current canvas
context.drawImage(tempContext.canvas, 0, 0);
}
If you resize to a smaller size then the temp canvas is "overdrawn" so it'll completely fill the current canvas. However if you resize to a larger size then your temp canvas will only fill part of the current canvas. The part it doesn't fill will still flicker as it's redrawn.
If you wanted to get a bit more fancy you could try drawing a temp canvas of the correct (final) size rather than simply copying the current canvas. This would be slower but could well eliminate all flicker.
In my case I'm resizing to fill a div, so having a little flicker along the bottom and right edges is tolerable, and certainly much better than the whole thing flickering.
EDIT:
Here's an update of your jsFiddle with my changes applied:
jsfiddle.net/Uz5Pt/13
It seems to work better than where I'm using it in my app! You can hardly see any flashing on any newly created bits of canvas.
回答2:
You could try using a double buffer. Here's a nice article on some techniques you could try:
http://www.html5rocks.com/en/tutorials/canvas/performance/
来源:https://stackoverflow.com/questions/15799564/flickering-during-resizing-of-html5-canvas