HTML canvas 在浏览器 window/tab 变为非活动状态后在 Chrome 中消失
HTML canvas disappears in Chrome after browser window/tab becomes inactive
我的 canvas 元素工作得很好,除了在 Chrome 上 Mac 运行 MacOS 12.2 上测试时,其中canvas 当我
时内容被完全清除
- 最小化Chrome
- 切换到不同的标签页
- 滑动到另一个屏幕
- 在 Chrome
之上放置一个 window
...即使 canvas 标签仍然保留在 DOM 中。我能够使用 canvas(例如 https://minexmr.com/poolstats)在某些网站上重现此内容,但在其他网站上却无法重现。无法在其他浏览器中重现。
我能做些什么来防止这种情况发生吗?或者这是 Chrome 的问题?好像几年前就有类似的投诉了。
React 代码片段
const canvasRef = useRef(null);
useEffect(() => {
if (canvasRef && canvasRef.current && canvasRef.current.getContext) {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
}
}, [])
return (
<>
...
<canvas ref={canvasRef} width="1000" height="200">
Fallback text
</canvas>
...
</>
);
这是由于 https://crbug.com/1268146 他们试图释放背景页面中画布所占用的资源。
请注意,要重现此错误,您必须打开 chrome://flags#enable-experimental-web-platform-features 标志。
当文档再次获得焦点时,应该恢复上下文,但显然这部分失败了,因为上下文刚刚完全消失。
他们现在更加隐藏此功能,因此新的 Canary 不再暴露此问题。
鉴于这一切都在开发标志之后,您的用户中应该很少有人会面对它,并且可能不值得为它实施解决方法。
但是如果你真的需要一个,你可以在 visibilitychange
事件中创建一个 ImageBitmap 并自己进行恢复:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 40, 40);
let bmp;
document.onvisibilitychange = async(evt) => {
if (document.visibilityState === "hidden") {
bmp = await createImageBitmap(canvas);
} else {
ctx.globalCompositeOperation = "copy";
ctx.drawImage(bmp, 0, 0);
ctx.globalCompositeOperation = "source-over";
}
};
<canvas></canvas>
我在这个问题上添加了评论,让他们知道恢复失败,以防他们回来。
我的 canvas 元素工作得很好,除了在 Chrome 上 Mac 运行 MacOS 12.2 上测试时,其中canvas 当我
时内容被完全清除- 最小化Chrome
- 切换到不同的标签页
- 滑动到另一个屏幕
- 在 Chrome 之上放置一个 window
...即使 canvas 标签仍然保留在 DOM 中。我能够使用 canvas(例如 https://minexmr.com/poolstats)在某些网站上重现此内容,但在其他网站上却无法重现。无法在其他浏览器中重现。
我能做些什么来防止这种情况发生吗?或者这是 Chrome 的问题?好像几年前就有类似的投诉了。
React 代码片段
const canvasRef = useRef(null);
useEffect(() => {
if (canvasRef && canvasRef.current && canvasRef.current.getContext) {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
}
}, [])
return (
<>
...
<canvas ref={canvasRef} width="1000" height="200">
Fallback text
</canvas>
...
</>
);
这是由于 https://crbug.com/1268146 他们试图释放背景页面中画布所占用的资源。
请注意,要重现此错误,您必须打开 chrome://flags#enable-experimental-web-platform-features 标志。
当文档再次获得焦点时,应该恢复上下文,但显然这部分失败了,因为上下文刚刚完全消失。
他们现在更加隐藏此功能,因此新的 Canary 不再暴露此问题。
鉴于这一切都在开发标志之后,您的用户中应该很少有人会面对它,并且可能不值得为它实施解决方法。
但是如果你真的需要一个,你可以在 visibilitychange
事件中创建一个 ImageBitmap 并自己进行恢复:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 40, 40);
let bmp;
document.onvisibilitychange = async(evt) => {
if (document.visibilityState === "hidden") {
bmp = await createImageBitmap(canvas);
} else {
ctx.globalCompositeOperation = "copy";
ctx.drawImage(bmp, 0, 0);
ctx.globalCompositeOperation = "source-over";
}
};
<canvas></canvas>
我在这个问题上添加了评论,让他们知道恢复失败,以防他们回来。