Zooming SVG with Hammer.js

前端 未结 3 1885
有刺的猬
有刺的猬 2021-02-06 15:22

I am writing a cross platform web application that displays information using SVG. I need to have a multi-touch interface to pan and zoom the SVG graphic. From my research, it a

3条回答
  •  太阳男子
    2021-02-06 15:40

    I'm glad that some one else has been looking to solve these problems. It seems that SVG hasn't so far had enough attention.

    I have been looking and working on solutions for several months. Firstly, you have three options for moving an SVG.

    1. Using the viewBox as you said. This is I think the best solution if you want to treat the image as a single item.
    2. You can use css transforms of the SVG element. the downside is this causes pixelation but means that you can use solutions that exist for other kinds of elements
    3. You can use svg transforms on elements or groups of elements within the SVG.

    To answer the question of code a centered pinch can be described as follows. First you need to translate the pinch event center point from screen coordinate to SVG coordinates using the screenCTM (coordinate transform matrix). if point has coordinates (x,y) then the origin of you viewbox needs to undergo a transformation equivalent to

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

    I have made this work 'mostly' in a library I have called hammerhead which runs on top of hammerjs. Here is an example of it in action.I won't give you code to exactly solve your problem as there is too much code to go where you have put '...' I ended up writing a viewBox object to manipulate. Just for reference here is the code I use to manipulate that.

    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. Change the viewBox is very computationally intensive I will not make for a pleasant scrolling experience on a phone except for an image with very few elements. It will work nicely if you change the view once in response to an action. for example left right up down keys. I have explored some of other options I mentioned above in these repos

    1. svg maneuver
    2. svg agile
    3. svgViewer

    As I mentioned trying for quite sometime. These all use one of the approaches individually. To get both smooth scrolling and no pixilation I think will require a combination of both. For which I am working on yet another library.

提交回复
热议问题