fabian
fabian

Reputation: 158

JS canvas zoom and pan with large data (100k-1M objects)

I want to implement fast and high-res zooming and panning on my Canvas. As you may already read in the title, I have a lot of data, so using CanvasRenderingContext2D.scale() and CanvasRenderingContext2D.translate() with redrawing isn't an option, because it is way to laggy. I already tried using Images, but I want to see all the data-points while zooming and panning. Drawing only the data-points that are visible is a good start, but this makes the zooming and panning only possible on a very close zoom, but I actually want to be able to zoom out until I can see all the data points. The data points are drawn with circles and are very close together if that helps you in any way. I appreciate every suggestion on how to handle this.

Upvotes: 2

Views: 827

Answers (2)

Dawid Wekwejt
Dawid Wekwejt

Reputation: 543

I think You should try one of these:

  1. WebGL (it is something line OpenGL for web browesers)
    materials: khronos group web page repo: GitHub
  2. three.js materials: three.js web page repo: GitHub

I sugested them because they are able to work with 2D also (not only with 3D) and they have tools to work with big textures. You can create static camera which will just change the distance to the surface (with texture) - zoom.

With Three.js there is a way to load bitmaps progressively with mipmap chains or with "Prefiltered, Mipmapped Radiance Environment Map: PMREMGenerator.

Upvotes: 1

user16603402
user16603402

Reputation:

An alternative approach that worked for me was having a (hidden) canvas for drawing and a viewport canvas the user could see. Drawing on the hidden canvas allows you to draw a bigger image, and then simply update the viewport by redrawing the canvas to view only the middle part (you can use viewportContext.drawImage(sourceCanvas, -canvasWidth / 2, -canvasHeight / 2) to draw from one canvas to another).

To implement zooming and panning, I would simply store the image from the source canvas at the beginning (on mouseDown or scroll) and redraw it according to new mouse position/scroll (simply translating it or changing its dimensions will work) to the source canvas.

Upvotes: 0

Related Questions