使用Hammer.js缩放SVG

4

我正在编写一个跨平台的Web应用程序,使用SVG显示信息。我需要具有多点触摸界面来平移和缩放SVG图形。根据我的研究,似乎Hammer.js是最好的方法,我正在使用jQuery库版本。

我能够使用SVG的viewBox属性平移和缩放图像。我遇到的问题是在捏合缩放过程中使用中心点信息(而不是从左上角缩放)。不管它在我的图片中的位置如何,在缩放时该中心点都应保持在捏合的中心位置。显然,解决方案是修改viewBox的前两个部分,但我无法确定正确的值。中心点(event.gesture.center)似乎是在浏览器页面坐标系中的,因此我需要找出如何可靠地缩放并计算viewBox的x和y坐标。我寻找了示例,但找不到与之相对应的。

使用viewBox属性是缩放SVG图像的最佳方法吗?是否有更好的替代方案?有人有关于从捏合中心缩放SVG图像的示例代码吗?

此外,我注意到即使我将事件处理绑定到SVG元素,捏合手势似乎也可以从页面的任何位置进行操作。这不是默认的浏览器处理捏合手势,因为它只使用我的代码缩放SVG图像。下面是我用于绑定捏合事件的代码:

$(window.demoData.svgElement).hammer().on("pinch", function (event) {
    event.preventDefault();
    ...
});

Thanks for any help on these two issues.


1
我知道这并不是你问题的答案,所以我把它作为评论留下来,但是我使用jQuery PanZoom做了很多类似于你所询问的事情,并且运气非常好。https://github.com/timmywil/jquery.panzoom。你可能想试试它。 - JasCav
非常感谢您的评论。我已经找到了我的问题的答案,并计划将其写下来并发布。现在我怀疑您提到的库在长期运行中可能对我更有效。他们的演示在我的手机上表现良好,但我需要将其与我的其他解决方案在平板电脑上进行比较,以确定哪个最适合我。正如您所说,它似乎可以完全满足我的需求(在约束元素内缩放和平移SVG)。 - JSwartzen
3个回答

3
我很高兴看到其他人也在寻找解决这些问题的方法。似乎SVG还没有得到足够的关注。
我已经研究并解决了几个月的问题。 首先,移动SVG有三个选项。
  1. 如您所说,使用viewBox。如果您想将图像视为单个项目,则我认为这是最佳解决方案。
  2. 您可以使用SVG元素的CSS变换。缺点是会导致像素化,但意味着您可以使用其他类型元素的现有解决方案。
  3. 您可以在SVG内的元素或元素组上使用SVG变换。
要回答代码居中捏合的问题,可以描述如下。 首先,您需要使用screenCTM(坐标转换矩阵)将捏合事件中心点从屏幕坐标转换为SVG坐标。如果点具有坐标(x,y),则您的viewbox原点需要进行等效于以下转换的变换:
  • 平移(-x, -y)
  • 比例(scalefactor)
  • 平移(x, y)
我已经在一个名为hammerhead的库中“基本上”完成了这项工作,它运行在hammerjs之上。 这里是其 示例 。由于存在太多的代码要放在你放置'...'的位置,所以我不会给你解决问题的确切代码。 我最终编写了一个viewBox对象来进行操作。 仅供参考,这是我用于操作它的代码。
scale: function(scale, center){
  var boxScale = 1.0/scale;
  center = center || this.center();
  var newMinimal = this.getMinimal().subtract(center).multiply(boxScale).add(center);
  var newMaximal = this.getMaximal().subtract(center).multiply(boxScale).add(center);
  var newViewBox = viewBox(newMinimal, newMaximal, this.getValidator());
  return newViewBox.valid()? newViewBox : null;
}

这种方法并非没有问题。更改视图框架需要大量计算,会导致在手机上进行愉快的滚动体验变得困难,除非是对于具有非常少元素的图片。如果您只在响应操作时更改视图,它将起到很好的作用。例如左右上下键。我已经在这些 repos 中探索了我提到的其他一些选项。
1. svg maneuver 2. svg agile 3. svgViewer 正如我之前提到的尝试了相当长时间。所有这些都单独使用其中一种方法。为了同时获得平滑滚动和无失真,我认为需要两种方法的结合。为此我正在开发另一个库。

2
不幸的是,它已经被搁置了。这是我在 https://github.com/CrowdHailer/Hammerhead2 上取得的最大进展。 - Peter Saxton

1

1

他们删除了示例文件夹,我修复了链接。 - madmed
很遗憾,链接已经失效了 :( - Eduardo

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