Question

I’m using two html canvas, the fronendCanvas is visible to the users and is part of the html DOM tree and is set to have 100% of the window width and height, the backendCanvas is created on the javascript code and is used to contain the huge diagram that I need to draw.

/** 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;

Basically, to have a smooth visualisation the frontendCanvas only shows a part of the huge image drawn in the backendCanvas using the drawImage function (user can use the mouse to drag the visualisation area across the diagram, see the example 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)
);

When I set the backendCanvas width and height to 15000 everything works fine, but when I set it to the size that I actually need, width 62322 and height 50946, somehow the drawImage doesn’t work any more and throws the size error:

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

My guess would be that I’m reaching the maximum size of the canvas and it’s reseted, but it doesn’t seem the case because:

  1. the canvas reference says that the canvas width and height limit is an unsigned long, therefore much bigger than the numbers that I mentioned;

  2. I checked the size of the backendCanvas right before the drawImage function call and it is correct.

Any help would be very much appreciated!

Thanks.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top