SVG scaling with Hammer.js

I am writing a cross-platform web application that displays information using SVG. I need to have a multi-touch interface for panning and zooming SVG graphics. From my research, it seems that Hammer.js is my best approach and I am using the jQuery library version.

I can pan and zoom using the viewBox SVG property. The problem I am facing is using the center point information while scaling (compared to scaling in the upper left corner). This central point, wherever it is in my image, should remain in the center of the pinch. Obviously, the solution is to change the first two parts of the viewBox, but I am having trouble determining the correct values. The center point (event.gesture.center) seems to be in the coordinates of the browser page, so I need to figure out how to scale it reliably, and then calculate the x and y coordinates of the viewBox. I searched for examples, but could not find anything like it.

Does the viewBox attribute use the best way to scale SVG images? Are there any better alternatives? Does anyone have an example SVG image scaling code from the center of a pinch?

In addition, I notice that although I am attaching event processing to an SVG element, the pinch gesture seems to work from anywhere on the page. This is not the default browser setting, because it is just scaling an SVG image using my code. Here is the code I use to bind the pinch event:

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

Thanks for any help on these two questions.

+4
source share
3 answers

I am glad that someone else is looking for solutions to these problems. SVG doesn't seem to be paying enough attention yet.

I have been watching and working on solutions for several months. First, you have three options for moving SVGs.

  • Using viewBox, as you said. I think this is the best solution if you want to consider the image as a separate element.
  • You can use css transformations of an SVG element. the disadvantage is that it causes pixelation, but means that you can use the solutions that exist for other types of elements.
  • You can use svg conversions for elements or groups of elements in SVG.

To answer the question about the code, a centered pinch can be described as follows. First, you need to translate the pinch event center point from the screen coordinate to the SVG coordinates using the CTT screen matrix (coordinate transformation matrix). if the point has coordinates (x, y), then to start your viewing you need a transformation equivalent to

  • translation (-x, -y)
  • scalefactor
  • translation (x, y)

I did this work β€œmainly” in a library that I called hammerhead , which runs on top of hammerjs. Here is an example of this in action. I will not give you code to exactly solve your problem, because there is too much code to go where you put the '...' I ended up writing a viewBox to manipulate. For reference, the code I use to manage this is used here.

 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; } 

This method is not without problems. Changing the viewBox is very computationally intensive. I will not make a pleasant scroll on the phone, except for the image with a very small number of elements. This will work well if you change the view once in response to an action. for example, from left to right. I explored some of the other options mentioned above in these repositories.

As I said, I tried it for quite some time. All of them use one of the approaches individually. To get both smooth scrolling and the lack of pixelation, I think a combination of both is required. Why am I working on another library.

+2
source

The best way is to use svg conversions, with a combination of translation and scaling, you can scale with your pinch. You just need to figure out the formula. This example may help you (it uses css transforms, but you get the idea): https://github.com/EightMedia/hammer.js/blob/1.0.x/examples/pinchzoom.html

+1
source

There is another library specifically designed for this task called PanZoom. Unfortunately, it does not work very well with Hammer. I used it to increase / decrease SVG files with great success.

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

+1
source

Source: https://habr.com/ru/post/1497450/


All Articles