Image zoom centered on mouse position

20,633

The key to solving this puzzle is to understand how the image gets enlarged. If we're using a zoom factor of 1.2, the image becomes 20% larger. We assign 1.2 to the variable factor and do the following:

image.setScaleX(image.getScaleX() * factor);
image.setScaleY(image.getScaleY() * factor);

The upper left corner of the image stays in the same place while the picture is enlarged. Now consider the point under the mouse cursor. Every pixel above and to the left of the cursor has become 20% larger. This displaces the point under the cursor by 20% downward and to the right. Meanwhile, the cursor is in the same position.

To compensate for the displacement of the point under the cursor, we move the image so that the point gets back under the cursor. The point moved down and right; we move the image up and left by the same distance.

Note that the image might have been moved in the canvas before the zooming operation, so the cursor's horizontal position in the image is currentMouseX - image.getLeft() before zooming, and likewise for the vertical position.

This is how we calculate the displacement after zooming:

var dx = (currentMouseX - image.getLeft()) * (factor - 1),
    dy = (currentMouseY - image.getTop()) * (factor - 1);

Finally, we compensate for the displacement by moving the point back under the cursor:

image.setLeft(image.getLeft() - dx);
image.setTop(image.getTop() - dy);

I integrated this calculation into your demo and made the following fiddle:

https://jsfiddle.net/fgLmyxw4/

I also implemented the zoom-out operation.

Share:
20,633
Gaurav_soni
Author by

Gaurav_soni

Frontend Developer , (Angularjs,Nodejs,HTML ,Less) Working at AllCAD , Jaipur My facebook ID - https://www.facebook.com/gauravsoni12345

Updated on July 09, 2022

Comments

  • Gaurav_soni
    Gaurav_soni almost 2 years

    I am writing a script with Fabric.js to zoom an image at the current mouse position. I have made some progress but there is an error somewhere.

    Case 1: Keep the mouse at one point and zoom with the mouse wheel.

    Result: Works perfectly, image zooms at that particular pixel.

    Case 2: Zoom in a little at one position (3-5 times with mouse wheel), then move the mouse to a new position and zoom in there.

    Result: Works fine for the first point, but after moving to another point and zooming, the image position is incorrect.

    My code is in this fiddle:

    https://jsfiddle.net/gauravsoni/y3w0yx2m/1/

    I suspect there is something wrong with the image positioning logic:

    imgInstance.set({top:imgInstance.getTop()-newMousY,left:imgInstance.getLeft()-newMousX});
    

    What is going wrong?

  • Gaurav_soni
    Gaurav_soni about 9 years
    Thanks a lot !! i have been stuck for 2 days on this. can award bounty after 8 hrs
  • Krunal Panchal
    Krunal Panchal almost 7 years
    Can anyone implement same using canvas only? without any library?
  • JokerMartini
    JokerMartini over 4 years
    How does one use this if the origin of the image is at the center not the top left corner?
  • Mattis
    Mattis over 2 years
    Oh god thank you @Michael Laszlo .