HTML5/Canvas 支持双缓冲吗?

91
我想做的是在缓冲区上绘制图形,然后将其原样复制到画布上,以便进行动画处理并避免闪烁问题。但是我没有找到这个选项。有人知道我该怎么做吗?

12
我发现浏览器会对画布绘制进行合并,因此动画效果会更加流畅。你能否分享一些代码,让它像你描述的那样闪烁? - eyelidlessness
2
我注意到在使用explorercanvas时,IE在某些情况下会闪烁,但这当然不是HTML5,而只是由VML模拟的canvas元素。我从未见过其他浏览器这样做。 - cryo
3
与https://dev59.com/gWgt5IYBdhLWcg3w2A77相关。 - julien
2
真的很蠢的初学者代码,不会闪烁。http://jsfiddle.net/linuxlizard/ksohjr4f/3/ 按理说,应该会闪烁。浏览器真是令人印象深刻。 - David Poole
1
只有在使用异步绘制函数时才需要双缓冲。只要不让浏览器停下来,即使是同步绘制,也不会出现问题。一旦添加了 Promise 或 setTimeout 等内容,就会将控制权交还给浏览器,并在完成之前绘制当前状态,从而导致闪烁。 - albertjan
13个回答

4
在大多数情况下,您不需要这样做,浏览器会自动实现。但这并不总是有用的!当您的绘图非常复杂时,仍然需要实现这一点。大多数屏幕更新率约为60Hz,这意味着屏幕每16ms更新一次。浏览器的更新速度可能接近这个数字。如果您的形状需要100ms才能完成,您将看到一个未完成的形状。因此,在这种情况下,您可以实现双缓冲。我进行了测试:清除矩形,等待一段时间,然后填充某些颜色。如果我将时间设置为10ms,我不会看到闪烁。但如果我将其设置为20ms,闪烁就会发生。

3

Opera 9.10非常缓慢,显示绘图过程。如果你想看到一个没有使用双缓冲的浏览器,请试用Opera 9.10。

有些人认为浏览器在某种程度上确定了绘图过程何时结束,但你能解释一下它是如何工作的吗?即使绘图很慢,我在Firefox、Chrome或IE9中也没有注意到任何明显的闪烁,因此似乎它们正在这样做,但如何实现这一点对我来说仍然是个谜。浏览器怎么会知道在执行更多绘图指令之前刷新显示?你认为它们只是计时,如果超过5毫秒或更长时间间隔没有执行画布绘制指令,就会安全地交换缓冲区吗?


1

这是使用图像数据的双缓冲示例。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML5 Canvas Demo of PixelBuffer</title>
    <style>
        html,
        body {
            height: 100%;
            width: 100%;
        }
    </style>
</head>

<body>
    <canvas id="buffer1"></canvas>
    <script>
        const canvas = document.getElementById('buffer1');
        const ctx = canvas.getContext('2d');
        const imageData = ctx.createImageData(100, 100);
        const pixelBuffer = new Uint32Array(imageData.data.buffer);
        for (let i = 0; i < pixelBuffer.length; i++) {
            pixelBuffer[i] = 0xFF0000FF;
        }
        ctx.putImageData(imageData, 0, 0);
    </script>
</body>

</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接