8

我的应用程序的一部分包含类似于谷歌地图的功能,因为用户应该能够放大和缩小容器内的图像。

与谷歌地图一样,我希望用户能够使用鼠标滚轮滚动,并且图像上的像素始终保持在鼠标指针的正下方。因此,基本上用户将缩放到鼠标指针所在的任何位置。

对于缩放/翻译,我正在使用 css 转换,如下所示:

可见的

   $('#image').css({
            '-moz-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
            '-moz-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
              '-webkit-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
            '-webkit-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
              '-o-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
            '-o-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
              '-ms-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
            '-ms-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
              'transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
            'transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px'
            });

我已经设法找到了如何执行此操作的各种实现,但是我使用自滚动平滑滚动技术来插入鼠标事件并提供动力。

试图让两者正确地协同工作被证明是很麻烦的。

我没有在此处粘贴一大堆代码,而是创建了一个 jsFiddle,其中包括鼠标滚轮平滑滚动技术以及我目前拥有的缩放功能。

http://jsfiddle.net/gordyr/qGGwx/2/

这本质上是我的应用程序这一部分的功能齐全的演示。

如果滚动鼠标滚轮,您将看到 jqueryui 滑块插入并正确提供动量/减速度。然而,变焦没有正确反应。

如果您只滚动鼠标滚轮一点,则缩放效果很好,但任何进一步的滚动都不起作用。我认为这是因为图像的比例现在已经改变,导致计算不正确。我试图弥补这一点,但到目前为止还没有运气。

总而言之,我想修改我的 jsFiddle 中的代码,以便图像始终直接缩放到鼠标指针。

非常感谢任何愿意提供帮助的人。

4

1 回答 1

10

您可以使用 css3 转换更轻松地做到这一点。
示例:http : //jsfiddle.net/BaliBalo/xn75a/
主要的中心鼠标算法在这里:

//Center the image if it's smaller than the container
if(scale <= 1)
{
    currentLocation.x = im.width() / 2;
    currentLocation.y = im.height() / 2;
}
else
{
    currentLocation.x += moveSmooth * (mouseLocation.x - currentLocation.x) / currentScale;
    currentLocation.y += moveSmooth * (mouseLocation.y - currentLocation.y) / currentScale;
}

如果您想保留您已经存在的代码,我认为您可以大致相同地执行此操作:当图像本身通过 css 比例变换和使用 transform-origin 进行缩放时,获取缩放图像上的鼠标位置的技巧是将变换原点减去您的点,然后乘以因子,最后重新添加变换原点。

您还可以在此更新示例中使用翻译:http: //jsfiddle.net/BaliBalo/xn75a/15/ 正如您所看到的,它甚至简化了公式,但不要忘记将元素的中心分到鼠标点为{0, 0} 的平移将放大图像的中间。


编辑:

我今天偶然发现了我的这个答案,并认为这不是你想要的行为。我第一次没有正确理解您不想将鼠标放在鼠标下方的中心而是将其保持在同一个位置。正如我最近为一个个人项目所做的那样,我试图纠正自己。所以这是一个更准确的答案:http:
//jsfiddle.net/BaliBalo/7ozrc1cq/

现在的主要部分是(如果 currentLocation 是容器中图像的左上角):

var factor = 1 - newScale / currentScale;
currentLocation.x += (mouseLocation.x - currentLocation.x) * factor;
currentLocation.y += (mouseLocation.y - currentLocation.y) * factor;

我还删除了 CSS 过渡。我认为实现平滑滚动的最佳方法是使用requestAnimationFrame创建动画循环,而不是直接在zoom函数中更改值,而是存储值并在循环中对它们进行动画处理。

于 2013-01-21T00:55:06.227 回答