HTML canvas 在浏览器 window/tab 变为非活动状态后在 Chrome 中消失

HTML canvas disappears in Chrome after browser window/tab becomes inactive

我的 canvas 元素工作得很好,除了在 Chrome 上 Mac 运行 MacOS 12.2 上测试时,其中canvas 当我

时内容被完全清除

...即使 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>

我在这个问题上添加了评论,让他们知道恢复失败,以防他们回来。