svg-pan-zoom pan/zoom to any object

2019-08-15 09:18发布

I'm using the svg-pan-zoom code https://github.com/ariutta/svg-pan-zoom to make an svg map of some kind, now it is time to add a feature to pan & zoom to an art component of the svg on a click event. However, I'm not sure how to use the panBy() function to get to a desired svg art item: I tried to use the getBBox() on the group I'm looking to pan to and use that with the panZoomInstance.getPan() and getSizes() information, but my experiments are not working out. I'd like to accomplish the same king of animation as their example (http://ariutta.github.io/svg-pan-zoom/demo/simple-animation.html) but center the viewport to the item.

1条回答
在下西门庆
2楼-- · 2019-08-15 10:03

Against all odds I was able to figure out this part of it!

function customPanByZoomAtEnd(amount, endZoomLevel, animationTime){ // {x: 1, y: 2}
  if(typeof animationTime == "undefined"){
      animationTime =   300; // ms
  }
  var animationStepTime = 15 // one frame per 30 ms
    , animationSteps = animationTime / animationStepTime
    , animationStep = 0
    , intervalID = null
    , stepX = amount.x / animationSteps
    , stepY = amount.y / animationSteps;

  intervalID = setInterval(function(){
    if (animationStep++ < animationSteps) {
      panZoomInstance.panBy({x: stepX, y: stepY})
    } else {
      // Cancel interval
      if(typeof endZoomLevel != "undefined"){
        var viewPort = $(".svg-pan-zoom_viewport")[0];
        viewPort.style.transition = "all " + animationTime / 1000 + "s ease";
        panZoomInstance.zoom(endZoomLevel);
        setTimeout(function(){
            viewPort.style.transition = "none";
            $("svg")[0].style.pointerEvents = "all"; // re-enable the pointer events after auto-panning/zooming.
                    panZoomInstance.enablePan();
                    panZoomInstance.enableZoom();
                    panZoomInstance.enableControlIcons();
                    panZoomInstance.enableDblClickZoom();
                    panZoomInstance.enableMouseWheelZoom();
        }, animationTime + 50);
      }
      clearInterval(intervalID)
    }
  }, animationStepTime)
}

function panToElem(targetElem) {

    var initialSizes = panZoomInstance.getSizes();
    var initialLoc = panZoomInstance.getPan();
    var initialBounds = targetElem.getBoundingClientRect();
    var initialZoom = panZoomInstance.getZoom();
    var initialCX = initialBounds.x + (initialBounds.width / 2);
    var initialCY = initialBounds.y + (initialBounds.height / 2);

    var dX = (initialSizes.width / 2) - initialCX;
    var dY = (initialSizes.height / 2) - initialCY;

  customPanByZoomAtEnd({x: dX, y: dY}, 2, 700);
}

The key was in calculating the difference between the center of the viewport width & height from panZoomInstance.getSizes() and the center of the target element's client bounding rectangle.

Now the issue is trying to make an animated zoom. For now I've made it do a zoom to a specified location with a command at the end of the panning animation and set some css to make the zoom a smooth transition. The css gets removed after some time interval so normal zooming and panning isn't affected. In my attempts to make the zoom a step animation it always appeared to zoom past the intended max point.

查看更多
登录 后发表回答