在调整HTML5画布大小时闪烁 [英] Flickering during resizing of HTML5 canvas

查看:136
本文介绍了在调整HTML5画布大小时闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调整动画画布控件的大小时会观察到一些闪烁。



你可以看到它在行动在此页面。左右拖动'width'滑块以自行尝试。我在Linux上运行的Chrome 26.0.1410.43中看到了这种闪烁。目前,只有支持HTML5的< input type =range> ,此页面才能在Firefox中使用。



<我试图在这个jsFiddle 中以较小的比例重现这个问题。它不是那么引人注目,但是当画布大约是可用宽度宽度的90%时,就会出现这种情况。



代码陷阱 requestAnimationFrame ,并调整大小擦除画布。我希望在绘制浏览器的框架之前调用渲染回调。情况似乎并非如此,因为在调整大小期间偶尔会显示白色背景。



有什么可以做的以避免这种情况吗?

解决方案

当你设置canvas.width或canvas.height时,它会清除画布,再加上重绘会导致你看到的闪烁。



您可以通过在调整大小之前将画布保存到临时画布然后再将其绘制回来来将此缓解到合理的范围。



这是我的调整大小函数:

 函数调整大小(宽度,高度){
//创建临时画布和context
var tempContext = Utils.Canvas.Create2DContext(context.canvas.width,context.canvas.height);

//将当前画布绘制到临时画布
tempContext.drawImage(context.canvas,0,0);

//调整当前画布的大小
context.canvas.height = height;
context.canvas.width = width;

//将临时画布绘制回当前画布
context.drawImage(tempContext.canvas,0,0);
}

如果调整到较小的尺寸,那么临时画布会透支,所以它会完全填满当前的画布。但是,如果您调整到更大的尺寸,那么临时画布将只填充当前画布的一部分。它没有填充的部分仍会在重新绘制时闪烁。



如果你想要更加想象一下,你可以尝试绘制正确的临时画布(最终)大小而不是简单地复制当前画布。这会慢一点,但可以消除所有闪烁。



在我的情况下,我正在调整大小以填充div,所以沿着底部和右边缘有一点闪烁是可以忍受,当然比整个闪烁的东西要好得多。



编辑:



这是你的jsFiddle的更新应用我的更改:



jsfiddle.net/Uz5Pt/13



它似乎比我在我的应用程序中使用它更好!在任何新创建的画布上都几乎看不到任何闪烁。


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?

解决方案

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.

这篇关于在调整HTML5画布大小时闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆