Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom scrolling on html5 canvas

What is the recommended way to provide scrolling and native scrollbars for very large data displayed in an hmtl5 canvas?

I need to display data that is 128000x128000 pixels. Using a canvas with width/height set to 128000 is not an option as that would use an enormous amount of RAM (around 61 GB according to my quick calculation).

So I need a way to provide custom scrollbars for an HTML5 canvas.

like image 463
JohanShogun Avatar asked Aug 11 '12 13:08

JohanShogun


2 Answers

After a quick test, I'm not sure Chrome or Firefox will even render a canvas that big. My bet would be to create a canvas element but never append it to the DOM. Just like this:

var hiddenCanvas = document.createElement('canvas');
hiddenCanvas.width = 128000;
hiddenCanvas.height = 128000;
var hiddenContext = hiddenCanvas.getContext('2d');

Then create a smaller canvas that will actually display a portion of your hidden canvas

<canvas width="something reasonable" height="something reasonable" id="viewCanvas"/>

And use the drawImage method to draw portions:

var viewCanvas = document.getElementById('viewCanvas');
var viewContext = viewCanvas.getContext('2d');
viewCanvasContext.drawImage(hiddenCanvas, 40, 50, viewCanvas.width, viewCanvas.height, 0, 0, viewCanvas.width, viewCanvas.height);

Then it would be up to you to either provide up/down/right/left buttons to navigate, or maybe fake scrollbars by using 20px wide DIVs that would only show scrollbars and which you would hook an onscroll even listener on. And each time the user changes position, do a call again to drawImage, updating the x/y positions (40 and 50 in my example).

Having said this, again, even when hidden I doubt that browsers will work with a canvas that big.

I happen to be looking for a solution to the same problem, so if in your research you get lucky, please share.

like image 74
Patrick Brosset Avatar answered Sep 19 '22 13:09

Patrick Brosset


Interesting question. I haven’t used <canvas> very much, but I believe the inside of the <canvas> is best thought of like an image, i.e. it’s a black box as far as the DOM is concerned.

As such, I don’t think you can really scroll it in the way that you’re imagining. If you had a 128000×128000 <canvas>, you could put it inside a <div> that’s e.g. 1280×1280 and set that <div> to overflow:hidden, but as you say, a 128000×128000 <canvas> is impractical.

I guess the kind of solution you’re looking for would provide a virtual 128000×128000 canvas interface, but then split it up into chunks, provide a scroll interface, and draw in each chunk as it was scrolled into view.

like image 21
Paul D. Waite Avatar answered Sep 19 '22 13:09

Paul D. Waite