以鼠标位置为中心的图像缩放

Image zoom centered on mouse position

我正在用 Fabric.js 编写脚本以在当前鼠标位置缩放图像。我取得了一些进展,但某处出错了。

案例一:鼠标停留在一点,滚轮缩放

结果:效果完美,图像在该特定像素处缩放。

案例2:在一个位置稍微放大一点(鼠标滚轮3-5倍),然后将鼠标移动到新的位置并放大。

结果:第一个点没问题,但移动到另一个点缩放后,图像位置不正确。

我的代码在这个fiddle:

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

我怀疑图片定位逻辑有问题:

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

出了什么问题?

解决这个难题的关键是了解图像是如何放大的。如果我们使用 1.2 的缩放系数,则图像会放大 20%。我们将 1.2 分配给变量 factor 并执行以下操作:

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

图片放大时,图片的左上角保持不变。现在考虑鼠标光标下的点。光标上方和左侧的每个像素都变大了 20%。这会将光标下的点向下和向右移动 20%。同时,光标在同一位置。

为了补偿光标下的点的位移,我们移动图像,使该点回到光标下。该点向右下方移动;我们将图像向上和向左移动相同的距离。

请注意,在缩放操作之前,图像可能已在 canvas 中移动,因此光标在图像中的水平位置在缩放之前为 currentMouseX - image.getLeft(),垂直位置也是如此。

缩放后的位移是这样计算的:

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

最后,我们通过将点移回光标下方来补偿位移:

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

我将这个计算整合到你的演示中并做了以下 fiddle:

https://jsfiddle.net/fgLmyxw4/

我也实现了缩小操作