以鼠标位置为中心的图像缩放
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/
我也实现了缩小操作
我正在用 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/
我也实现了缩小操作