javascript - HTML5 画布在 Google Chrome 中闪烁
问题描述
似乎谷歌浏览器的更新搞砸了我的画布渲染。我有一个非常简单的代码,可以在画布上呈现图像和文本:
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/ (只需将鼠标移到页面上)。
我发现只有两种方法可以防止这种行为:
- 调用
context.clearRect()
整个画布。但在这种情况下,我不能只重绘脏矩形。 - 为画布设置
image-rendering: pixelated
。在这种情况下,所有字体看起来都很糟糕。
这还能做什么?
解决方案
这是一个自 Chromium 版本 83 以来开始更频繁出现的错误,自 85 版本以来更频繁出现(因此除了 Chrome 之外,这也会影响 Opera 和新的 Edge)。几个月前我在 Chromium 提交了一个问题,他们目前正在修复: https ://bugs.chromium.org/p/chromium/issues/detail?id=1092080
发生的情况是在 drawImage() 调用之后的下一个监视器帧中将抗锯齿设置为“最近邻”。这会影响源元素和目标元素,并且会影响任何 CanvasImageSource(图像、视频、画布: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()})`
它的作用是在画布顶部覆盖一个 div。并且在每次 drawImage() 调用更改了变换样式中的 scaleX 以触发画布中抗锯齿设置的重置。
推荐阅读
- c# - 使用 interop excel 制作组织结构图
- php - 在 PHP 中获取远程服务器的 IP 地址
- javascript - 在javascript中无法将字符串转换为变量
- ios - iOS 在后台或应用程序处于活动状态时执行预定操作
- sql - SQL Server:声明临时表存在,但不在 INFORMATION_SCHEMA 中
- sql - 如果 A 列的值对于 B 列的最大值为空,则获取 B 列的第二大值
- java - 保存大字节数组的 Java 堆内存
- mysql - 如何在 SQL 中创建条件计算列?
- firebase - 为什么我可以使用 onRequest 从 firebase 函数调用 firestore,但在使用 onCall 时却不能
- sql - 解释窗口函数框架