【问题标题】:Flickering during resizing of HTML5 canvas在调整 HTML5 画布大小期间闪烁
【发布时间】:2013-03-25 20:09:44
【问题描述】:

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

您可以在at this page 中看到它。左右拖动 'width' 滑块,亲自尝试一下。我在 Linux 上运行的 Chrome 26.0.1410.43 中看到了这种闪烁。目前此页面在支持 HTML5 的 <input type="range"> 之前无法在 Firefox 中运行。

我已尝试在this jsFiddle 中以较小的规模重现该问题。它不那么明显,但是当画布大约是可用宽度的 90% 时会发生这种情况。

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

有什么办法可以避免这种情况吗?

【问题讨论】:

    标签: html canvas html5-canvas flicker


    【解决方案1】:

    当您设置 canvas.width 或 canvas.height 时,它会清除画布,结合重绘会导致您看到的闪烁。

    您可以通过在调整大小之前将画布保存到临时画布并在之后再次将其重新绘制来在合理程度上缓解这种情况。

    这是我的调整大小功能:

        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);
        }
    

    如果您将大小调整为较小的尺寸,则临时画布将“过度绘制”,因此它将完全填满当前画布。但是,如果您调整到更大的尺寸,那么您的临时画布将仅填充当前画布的一部分。未填充的部分在重绘时仍会闪烁。

    如果您想更花哨,可以尝试绘制正确(最终)大小的临时画布,而不是简单地复制当前画布。这会比较慢,但可以很好地消除所有闪烁。

    在我的情况下,我正在调整大小以填充 div,因此在底部和右侧边缘有一点闪烁是可以容忍的,而且肯定比整个闪烁要好得多。

    编辑:

    这是您的 jsFiddle 的更新,其中应用了我的更改:

    jsfiddle.net/Uz5Pt/13

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

    【讨论】:

    • 感谢您的回答。我不确定这与我正在做的事情有什么不同,因为我在调整大小后通过我的draw 函数重绘了整个事情。问题似乎是浏览器调整大小、清除、绘制,然后调用我的重绘,然后再次绘制。您是否尝试过增加我的 jsFiddle 中的滑块?
    • 嗨 Drew,我冒昧地将我的修复应用到您的 jsFiddle。 jsfiddle.net/Uz5Pt/13 希望它能满足你的需求!
    • 谢谢,看起来很棒。我会进一步尝试看看为什么它有效,但我的代码没有。你能告诉?如果您将滑块拖动到零,您的小提琴也会中断:)
    • 我猜它会坏掉,因为它不喜欢制作 0 宽度的画布或类似的东西......但这需要更多的调试并且超出了这个问题的范围;)
    【解决方案2】:

    您可以尝试使用双缓冲区。这是一篇不错的文章,介绍了您可以尝试的一些技术:

    http://www.html5rocks.com/en/tutorials/canvas/performance/

    【讨论】:

    • 你试过了吗?我没有,但我认为这不会有帮助。当高度/宽度发生变化时,浏览器会重置画布,并且似乎在画布有机会重新绘制之前发生了浏览器渲染。我看不出双缓冲有什么帮助。不过,这是一篇不错的文章,谢谢。
    • 特别没有,但是您的问题似乎是由于您必须强制重新绘制。画布规范的一部分指出“当画布元素被创建时,以及随后无论何时设置宽度和高度属性(无论是新值还是以前的值),位图和任何关联的上下文都必须被清除回它们的初始值状态并使用新指定的坐标空间尺寸重新初始化。“您可以尝试通过使用新属性制作第二个画布并销毁旧画布来伪造它,从而避免重绘问题。
    猜你喜欢
    • 2021-07-21
    • 2013-10-06
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    相关资源
    最近更新 更多