Zoom in/out at mouse position in canvas

南笙酒味 提交于 2019-12-06 07:54:04

In my mind, the way zoom works is that based on the position of the point of interest (in your case mouse), the zoom has a weighted impact on the (x, y) position of the canvas. If the mouse is at the top left, this weight should be (0,0), if it's at the bottom right, it should be (1,1). And the centre should be (0.5,0.5).

So, assuming we have the weights, whenever the zoom changes, the weights show us how far the top left corner of the canvas is from the point of interest, and we should move it away by the weight*dimension*(delta zoom).

Note that in order to calculate the weights, we need to consider the zoomed in/out value of the dimensions. So if width is 100 and zoom is 0.5, we should assume the width is 50. So all the values would be absolute (since the mouse (x,y) are absolute).

so, it's like:

function worldZoom(e) {
    const {x, y, deltaY} = e;
    const direction = deltaY > 0 ? -1 : 1;
    const factor = 0.01;
    const zoom = 1 * direction * factor;

    // compute the weights for x and y
    const wx = (x-controls.view.x)/(width*controls.view.zoom);
    const wy = (y-controls.view.y)/(height*controls.view.zoom);

    // apply the change in x,y and zoom.
    controls.view.x -= wx*width*zoom;
    controls.view.y -= wy*height*zoom;
    controls.view.zoom += zoom;
}

You can try it in this codepen.

Or a bit simpler, compute the weights inline:

controls.view.x -= (x-controls.view.x)/(controls.view.zoom)*zoom;
controls.view.y -= (y-controls.view.y)/(controls.view.zoom)*zoom;
controls.view.zoom += zoom;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!