javascript - HTML canvas disappears in Chrome after browser windowtab becomes inactive - Stack Overflow

My canvas element works perfectly fine except when tested in Chrome on a Mac running MacOS 12.2, where

My canvas element works perfectly fine except when tested in Chrome on a Mac running MacOS 12.2, where the canvas content gets pletely wiped out when I

  • minimize Chrome
  • switch to a different tab
  • swipe to another screen
  • place a window on top of Chrome

... even though the canvas tag still remains in the DOM. I was able to reproduce this with some websites using canvas (e.g. ) but not others. Cannot reproduce it in other browsers.

Is there anything I can do to prevent this from happening or is this an issue with Chrome? There appears to be similar plaints from a few years ago.

React code snippet

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>
    ...
  </>
);

My canvas element works perfectly fine except when tested in Chrome on a Mac running MacOS 12.2, where the canvas content gets pletely wiped out when I

  • minimize Chrome
  • switch to a different tab
  • swipe to another screen
  • place a window on top of Chrome

... even though the canvas tag still remains in the DOM. I was able to reproduce this with some websites using canvas (e.g. https://minexmr./poolstats) but not others. Cannot reproduce it in other browsers.

Is there anything I can do to prevent this from happening or is this an issue with Chrome? There appears to be similar plaints from a few years ago.

React code snippet

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>
    ...
  </>
);

Share Improve this question asked Feb 21, 2022 at 5:00 kaikai 831 silver badge3 bronze badges 3
  • Do you have the chrome://flags#enable-experimental-web-platform-features flag switched on? I can reproduce with this but not otherwise. And it seems they fixed it in the latest Canary. – Kaiido Commented Feb 21, 2022 at 5:25
  • @Kaiido Yes I did. Turning it off fixed it for me. Thank you. – kai Commented Feb 21, 2022 at 6:02
  • I found a temporary solution from issues.chromium/issues/41042153. This is just for the understanding of the issue and below settings need to be applied to sort out the issue in the browser. Step 1 : Type "chrome://flags/" into chrome address bar (URL Area) Step 2 : Find "Disable accelerated 2D canvas" Step 3 : Click "Disable" Step 4 : Make Sure the option for "Disable accelerated 2D canvas" is set to "Disable" Step 5 : Restart Chrome. After applying this change, now the canvas is working properly in my browser. – Manish Nayak Commented May 24, 2024 at 9:58
Add a ment  | 

1 Answer 1

Reset to default 9

This is caused by https://crbug./1268146 where they are trying to free the resources held by canvases in background pages. Note that to reproduce this bug you must have the chrome://flags#enable-experimental-web-platform-features flag on.
The context is supposed to be restored back when the document gains focus again, but obviously this part was failing as the context is just wiped out entirely.
They now hide this feature even more and thus the new Canary doesn't expose this issue anymore.

Given that this is all behind dev flags, few of your users should face it, and it's probably not worth the effort to implement a workaround for it.
But if you really need one, you can create an ImageBitmap in the visibilitychange event and do the restore yourself:

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>

I added a ment on the issue to let them know that the restoring fails in case they e back to it.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742345840a4426525.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信