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

21

我正在使用Fabric.js编写脚本,以当前鼠标位置为中心缩放图像。我取得了一些进展,但是存在某些错误。

情况1: 将鼠标保持在一个点上,并使用鼠标滚轮进行缩放。

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

情况2: 在一个位置缩小一点(用鼠标滚轮缩小3-5次),然后将鼠标移动到新位置并在那里缩小。

结果:对于第一个点运行良好,但是移动到另一个点并缩放后,图像位置不正确。

我的代码在这个fiddle里:

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

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

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

出了什么问题?


1
为什么不使用画布缩放和平移功能?或者你只需要缩放图像对象而不是其他内容?请查看此链接:http://fabricjs.com/kitchensink/#zoom(使用滚动来缩放) 使用画布缩放将允许您在需要时缩放画布中的更多对象,而无需进行计算。 如果您想探索这种可能性,我可以创建一个fiddle。 - AndreaBogazzi
@AndreaBogazzi 我需要在鼠标所在的特定位置进行缩放,画布的缩放功能只会对图像进行整体缩放。 - Gaurav_soni
是的,我在谈论FABRICJS的pan to point和zoom to point功能。不是canvas的那个。我看到你正在使用fabricjs实现它。 - AndreaBogazzi
@AndreaBogazzi 噢,我明白了。错过了文档的这部分内容。让我试一试。 - Gaurav_soni
1个回答

58

解决这个难题的关键是理解图片如何被放大。如果我们使用 1.2 的缩放比例,那么图片就会变大 20%。我们将 1.2 赋值给变量 factor,并执行以下操作:

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

图片的左上角在放大时保持相对位置不变。现在考虑鼠标指针下的点。光标上方和左侧的每个像素都变大了20%。这将使光标下方的点向下和向右移动20%。同时,光标位置不变。
为了补偿光标下方的点的位移,我们移动图像,使该点回到光标下方。该点向下和向右移动;我们通过相同的距离向上和向左移动图像。
请注意,图片在缩放操作之前可能已经在画布内移动过,因此在缩放之前,光标在图片中的水平位置为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/

同时,我还实现了缩小操作。


1
非常感谢!我已经卡在这里两天了。8小时后可以授予奖励。 - Gaurav_soni
6
有人能否只使用画布实现相同的效果?不使用任何库? - Krunal Panchal
5
如果图像的原点不在左上角而是在中心,该怎么使用它? - JokerMartini
哦,天啊,感谢@Michael Laszlo。 - Mattis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接