Move HTML5 canvas with background image

I want to render a huge diagram that is drawn in HTML5 canvas. As shown below, let's imagine a map of the world, it is impossible to visualize all this at the same time with a β€œdecent” detail. Therefore, on my canvas, I would like us to be able to wrap it around with the mouse to see other countries that are not visible.

Does anyone know how to implement such panning in HTML5 canvas? Another feature is zooming in and out.

canvas diagram I saw a few examples, but I could not get them to work, no seams, to answer my question.

Thanks in advance!

0
source share
2 answers

To achieve pan-functionality with peep-hole, it's just a matter of two drawing operations, one full and one cropped.

To get this result , you can do the following ( see full code here ):

Settings:

var ctx = canvas.getContext('2d'), ix = 0, iy = 0, /// image position offsetX = 0, offsetY = 0, /// current offsets deltaX, deltaY, /// deltas from mouse down mouseDown = false, /// in mouse drag img = null, /// background rect, /// rect position rectW = 200, rectH = 150; /// size of highlight area 

Configure the basic functions that you use to set the size according to the size of the window (including when resizing):

 /// calc canvas w/h in relation to window as well as /// setting rectangle in center with the pre-defined /// width and height function setSize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; rect = [canvas.width * 0.5 - rectW * 0.5, canvas.height * 0.5 - rectH * 0.5, rectW, rectH] update(); } /// window resize so recalc canvas and rect window.onresize = setSize; 

The main function in this is the draw function. Here we draw the image at the position calculated by the mouse movement (see the next section).

  • The first step to get this blurry look is to set the alpha to about 0.2 (you can also draw a transparent rectangle on top, but it's more efficient).
  • Then draw the full image.
  • Reset alpha
  • Draw a pip hole using clipping with corrected offsets for the source.

-

 /// main draw function update() { if (img === null) return; /// limit x/y as drawImage cannot draw with negative /// offsets for clipping if (ix + offsetX > rect[0]) ix = rect[0] - offsetX; if (iy + offsetY > rect[1]) iy = rect[1] - offsetY; /// clear background to clear off garbage ctx.clearRect(0, 0, canvas.width, canvas.height); /// make everything transparent ctx.globalAlpha = 0.2; /// draw complete background ctx.drawImage(img, ix + offsetX, iy + offsetY); /// reset alpha as we need opacity for next draw ctx.globalAlpha = 1; /// draw a clipped version of the background and /// adjust for offset and image position ctx.drawImage(img, -ix - offsetX + rect[0], /// sx -iy - offsetY + rect[1], /// sy rect[2], rect[3], /// sw/h /// destination rect[0], rect[1], rect[2], rect[3]); /// make a nice sharp border by offsetting it half pixel ctx.strokeRect(rect[0] + 0.5, rect[1] + 0.5, rect[2], rect[3]); } 

Now it's a matter of processing the mouse, moving and zooming in, and calculating the offsets -

At the bottom of the mouse, we save the current position of the mouse, which we will use to calculate the deltas on the mouse movement:

 canvas.onmousedown = function(e) { /// don't do anything until we have an image if (img === null) return; /// correct mouse pos var coords = getPos(e), x = coords[0], y = coords[1]; /// store current position to calc deltas deltaX = x; deltaY = y; /// here we go.. mouseDown = true; } 

Here we use the delta to avoid jumping the image by setting the angle to the position of the mouse. Deltas are transferred as offsets to the update function:

 canvas.onmousemove = function(e) { /// in a drag? if (mouseDown === true) { var coords = getPos(e), x = coords[0], y = coords[1]; /// offset = current - original position offsetX = x - deltaX; offsetY = y - deltaY; /// redraw what we have so far update(); } } 

And finally, with the mouse, we make the displacements a constant part of the image position:

 document.onmouseup = function(e) { /// was in a drag? if (mouseDown === true) { /// not any more!!! mouseDown = false; /// make image pos. permanent ix += offsetX; iy += offsetY; /// so we need to reset offsets as well offsetX = offsetY = 0; } } 

To scale the canvas, I believe that this question has already been answered: you should merge this with the answer given here:
Zoom Canvas to Mouse Cursor

+3
source

To do something like what you requested, this is just a case of having 2 bands, each with a different z-index. one canvas is smaller than the other, and the position set on the x and y axis of the mouse.

Then you simply show on the small canvas the correct image based on the x and y positions on the small canvas relative to the larger canvas.

However, your question requires a specific solution, which, if someone has not done this, and they are ready to simply reset their code, it will be difficult for you to get a complete answer. I hope all be fine.

+1
source

Source: https://habr.com/ru/post/1495958/


All Articles