使用Hammer.js缩放SVG

Zooming SVG with Hammer.js

本文关键字:SVG 缩放 js Hammer 使用      更新时间:2023-09-26

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

我可以使用SVG的viewBox属性平移和缩放图像。我遇到的问题是在缩放过程中使用中心点信息(相对于从左上角缩放)。这个中心点,无论它在我的图像中的哪个位置,都应该保持在夹点的中心。显然,解决方案是修改viewBox的前两个部分,但我在确定正确的值时遇到了问题。中心点(event.signature.center)似乎在浏览器页面坐标中,所以我需要弄清楚如何可靠地缩放它,然后计算viewBox的x和y坐标。我找过一些例子,但找不到任何相关的例子。

使用viewBox属性是缩放SVG图像的最佳方式吗?有更好的选择吗?有人有从夹点中心缩放SVG图像的示例代码吗?

此外,我注意到,尽管我将事件处理绑定到SVG元素,但捏手势似乎可以在页面上的任何位置工作。它不是默认的浏览器处理夹点,因为它只是使用我的代码缩放SVG图像。以下是我用于绑定pinck事件的代码:

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

感谢您在这两个问题上的帮助。

我很高兴其他人一直在寻求解决这些问题。到目前为止,SVG似乎还没有得到足够的关注。

几个月来,我一直在寻找并研究解决方案。首先,您有三个移动SVG的选项。

  1. 按照您所说的使用viewBox。如果您想将图像视为单个项目,我认为这是最好的解决方案
  2. 您可以使用SVG元素的css转换。缺点是这会导致像素化,但意味着您可以使用其他类型元素的解决方案
  3. 您可以对svg中的元素或元素组使用svg转换

为了回答代码的问题,可以如下描述一个居中的夹点。首先,您需要使用screenCTM(坐标变换矩阵)将捏夹事件中心点从屏幕坐标转换为SVG坐标。如果点有坐标(x,y),则视框的原点需要进行相当于的变换

  • 翻译(-x,-y)
  • 比例(比例因子)
  • 平移(x,y)

我"主要"在一个我称之为锤头的图书馆里完成了这项工作,这个图书馆位于锤头之上。下面是一个实际操作的例子。我不会给你代码来准确地解决你的问题,因为有太多的代码要放在你放"…"的地方我最终编写了一个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;
}

这种方法并非没有问题。更改viewBox的计算量非常大,除了元素很少的图像外,我不会在手机上获得愉快的滚动体验。如果您对一个操作进行一次更改视图,它会很好地工作。例如左右上下键。我已经探索了我在这些回购上面提到的一些其他选择

  1. svg机动
  2. svg敏捷
  3. svgViewer

正如我提到的尝试了很长一段时间。这些都单独使用其中一种方法。为了实现平滑滚动和无像素化,我认为需要两者的结合。为此,我正在另一个图书馆工作。

最好的方法是使用svg变换,通过平移和缩放的组合,您可以在捏集中执行缩放。你只需要算出公式。这个例子可以帮助你(它使用css转换,但你已经明白了):https://github.com/EightMedia/hammer.js/blob/1.0.x/examples/pinchzoom.html

还有另一个专门为该任务设计的库,名为PanZoom。不幸的是,哈默的表现并不好。我用它来放大/缩小SVG文件,非常成功。

https://github.com/timmywil/jquery.panzoom