2

我正在使用两个 html 画布,fronendCanvas 对用户可见,是 html DOM 树的一部分,设置为 100% 的窗口宽度和高度,backendCanvas 是在 javascript 代码上创建的,用于包含我需要绘制的巨大图表。

/** FrontendCanvas */
// HTML
<canvas id="canvas"></canvas> 

// JavaScript
frontCanvas.width = window.innerWidth;
frontCanvas.height = window.innerHeight;

// CSS
#canvas {
   display: block;
   background-color: #dddddd;
}

/** BackendCanvas */
// JavaScript
backCanvas = document.createElement('canvas');
backCanvas.width = diagram.maxX;
backCanvas.height = diagram.maxY;

基本上,为了实现平滑的可视化,frontendCanvas 只显示了使用 drawImage 函数在 backendCanvas 中绘制的巨大图像的一部分(用户可以使用鼠标在图表上拖动可视化区域,请参见示例Move HTML5 Canvas with a background image)。

frontCanvas.getContext('2d').drawImage(
    backCanvas,
    (-ix - offsetX),
    (-iy - offsetY),
    (frontCanvas.width),
    (frontCanvas.height),
    0,
    0,
    (frontCanvas.width),
    (frontCanvas.height)
);

当我将 backendCanvas 的宽度和高度设置为 15000 时,一切正常,但是当我将其设置为我实际需要的大小,宽度 62322 和高度 50946 时,drawImage 不知何故不再工作并引发大小错误:

IndexSizeError: Index or size is negative or greater than the allowed amount
(frontCanvas.height)

我的猜测是我达到了画布的最大尺寸并且它已被重置,但似乎并非如此,因为:

  1. 画布参考说画布宽度和高度限制是无符号长,因此比我提到的数字大得多;

  2. 我在调用 drawImage 函数之前检查了 backendCanvas 的大小,它是正确的。

任何帮助将不胜感激!

谢谢。

4

1 回答 1

2

Oo, those sizes (62322 x 50946) are way outside what you can use with canvas - even in 2013. ::-)

The max current supported size in the major browsers vary between some 6-15000 points depending on implementation (a few months back only 6-8000). It is related to actual need with most techniques as well as hardware acceleration, memory etc.

The raw size of the image you want to use is 11.83 GB (RGB + alpha as canvas uses RGBA only). In addition you will have to store the source image somewhere in memory before you can paint it to canvas which means you are up in 23+ GB memory usage even before the fun begin. This will force paging on most computers which will make everything very slow.

What you need to implement here is tiling/caching/buffering technique (think Google maps - this is why they tile their maps).

Describing this is perhaps a bit too broad for this Q&A site so I can also suggest you look at for example PanJS3 or Leaflet. Disclaimer: I don't know these libraries but you can at least study them to see how they deal with large images/maps.

于 2013-08-08T15:25:10.173 回答