HTML5 canvas 在 Google 中闪烁 Chrome
HTML5 canvas is flickering in Google Chrome
似乎 google chrome 的更新搞砸了我的 canvas 渲染。
我有一个非常简单的代码,可以在 canvas:
上呈现图像和文本
var onDraw = function() {
context.clearRect(0, 0, 256, 256);
context.drawImage(image, 0, 0, 256, 256);
context.fillText('TEST', 0, 20);
requestAnimationFrame(onDraw);
};
此代码在 Chrome 上闪烁得非常厉害:https://jsfiddle.net/gp9jxn6q/(只需将鼠标移到页面上)。
我发现只有两种方法可以防止这种行为:
- 为整个canvas调用
context.clearRect()
。但在这种情况下,我不能只重绘脏矩形。
- 为 canvas 设置
image-rendering: pixelated
。在这种情况下,所有字体看起来都很糟糕。
还能用这个做什么?
这是一个错误,自 Chromium 版本 83 开始出现得更加频繁,自 85 版以来出现得更多(因此除了 Chrome 这也会影响 Opera 和新的 Edge)。
几个月前我在 Chromium 提交了一个问题,他们目前正在修复:
https://bugs.chromium.org/p/chromium/issues/detail?id=1092080
发生的情况是在 drawImage() 调用后的下一个监视器帧中将抗锯齿设置为“最近的邻居”。这会影响源和目标元素,这会影响任何 CanvasImageSource(图像、视频、canvas:https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource)。
它是随机发生的,因为它可能与设备的性能和时序有关,因为某些图形设置可以修复错误,同时它们可以在另一台设备上创建错误。
但我也有一些好消息。我想我终于找到了一个解决方法,您可以在重置抗锯齿的 drawImage() 调用之后执行:http://jsfiddle.net/u7k5qz2p/
<div class="chromium-issue-1092080-workaround__wrapper">
<canvas id="canvas" width="300" height="300"></canvas>
<div class="chromium-issue-1092080-workaround__overlay"></div>
</div>
context.drawImage(image, 0, 0, 256, 256);
chromiumIssue1092080WorkaroundOverlay.style.transform = `scaleX(${Math.random()})`
它所做的是在 canvas 之上叠加一个 div。在每次 drawImage() 调用更改变换样式中的 scaleX 以触发重置 canvas.
中的抗锯齿设置后
似乎 google chrome 的更新搞砸了我的 canvas 渲染。 我有一个非常简单的代码,可以在 canvas:
上呈现图像和文本var onDraw = function() {
context.clearRect(0, 0, 256, 256);
context.drawImage(image, 0, 0, 256, 256);
context.fillText('TEST', 0, 20);
requestAnimationFrame(onDraw);
};
此代码在 Chrome 上闪烁得非常厉害:https://jsfiddle.net/gp9jxn6q/(只需将鼠标移到页面上)。
我发现只有两种方法可以防止这种行为:
- 为整个canvas调用
context.clearRect()
。但在这种情况下,我不能只重绘脏矩形。 - 为 canvas 设置
image-rendering: pixelated
。在这种情况下,所有字体看起来都很糟糕。
还能用这个做什么?
这是一个错误,自 Chromium 版本 83 开始出现得更加频繁,自 85 版以来出现得更多(因此除了 Chrome 这也会影响 Opera 和新的 Edge)。 几个月前我在 Chromium 提交了一个问题,他们目前正在修复: https://bugs.chromium.org/p/chromium/issues/detail?id=1092080
发生的情况是在 drawImage() 调用后的下一个监视器帧中将抗锯齿设置为“最近的邻居”。这会影响源和目标元素,这会影响任何 CanvasImageSource(图像、视频、canvas:https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource)。
它是随机发生的,因为它可能与设备的性能和时序有关,因为某些图形设置可以修复错误,同时它们可以在另一台设备上创建错误。
但我也有一些好消息。我想我终于找到了一个解决方法,您可以在重置抗锯齿的 drawImage() 调用之后执行:http://jsfiddle.net/u7k5qz2p/
<div class="chromium-issue-1092080-workaround__wrapper">
<canvas id="canvas" width="300" height="300"></canvas>
<div class="chromium-issue-1092080-workaround__overlay"></div>
</div>
context.drawImage(image, 0, 0, 256, 256);
chromiumIssue1092080WorkaroundOverlay.style.transform = `scaleX(${Math.random()})`
它所做的是在 canvas 之上叠加一个 div。在每次 drawImage() 调用更改变换样式中的 scaleX 以触发重置 canvas.
中的抗锯齿设置后