How to get multiple canvas tags to render reliably

2019-08-01 20:00发布

问题:

Has anyone had problems with Google Chrome not rendering canvas tags when more than one canvas is used on a page?

I've been having this happen. It occurs in some of my pages, but not others; I'm having a hard time isolating the critical element. When the problem does occur, the behavior is consistent: a particular set of canvas tags (sometimes all canvases on the page) don't render -- they appear as whitespace. It occurs reliably in Chrome / Mac, but does not occur in Firefox / Mac. Interestingly, if I right-click on one of the blank canvases and choose Inspect Element, then suddenly all of the canvases appear. So it really looks like a Chrome bug, as opposed to some error in my code.

The problem can be observed by clicking "Run" in this jsfiddle file:

http://jsfiddle.net/9HbWV/

This page contains two canvas tags, and a script block that draws a rectangle in one of them. In Chrome, the rectangle does not appear. If you un-comment out the last line and re-run, the rectangle does appear. That last line simply invokes getContext() on the other canvas.

I have other, more complex examples where some canvases don't render even if getContext() is called for each canvas. So the problem is not as simple as "getContext must be called at least once for each canvas".

回答1:

EDIT: the discussion of the Chrome bug report (linked below) reveals a workaround: attach a unique CSS class to each canvas. I.e.

<canvas id="A" width=400 height=400 class=canvasA></canvas>
<canvas id='B' width=400 height=400 class=canvasB></canvas>​


Turns out this is in fact a bug in Chrome: http://code.google.com/p/chromium/issues/detail?id=144686. A couple of details emerge from the bug comments:

  1. You can work around the bug by going to about:flags and activating the "Disable accelerated 2D canvas" option.

  2. Small canvases (e.g. 200 x 200) do not appear to exhibit the problem, because the problem seems to be GPU-related and Chrome does not attempt to use the GPU for small canvases.