Search code examples
javascriptsvggetboundingclientrectsvgpanzoompanzoom

SVG Pan Zoom: On Click Center Group Inside SVG to the Viewport


I am using this SVG Pan Zoom Library: https://github.com/bumbu/svg-pan-zoom

I have prepared a CodePen for you: https://codepen.io/ItsBenedict/pen/vYMbjpK

If you click on a category, the group should be centered to the viewport. The relevant code I am using here is starting at line 36.

var button1 = document.getElementById("cat-1")
button1.addEventListener("click", function() {
    const { left, width, top, height } = button1.getBoundingClientRect();
    customPanBy({x: width/2 - left, y: height/2 - top});
});

At the moment the group is moving to the top left so I guess the calculations are wrong. It looks like I need to use the getSizes from this plugin but I don't know how to use it. Here is another question but I am not really experienced with JavaScript, so I can't get it to work by myself: svg-pan-zoom pan/zoom to any object

If anyone could help me, it would me much appreciated!


Solution

  • I think things got a little confused with the width and height values - this is the repaired JS calculation, using window innerHeight and innerWidth

    function customPanBy(amount){ // {x: 1, y: 2}
        var animationTime = 300 // ms
        , animationStepTime = 15 // one frame per 30 ms
        , animationSteps = animationTime / animationStepTime
        , animationStep = 0
        , intervalID = null
        , destX = (window.innerWidth/2) - amount.x
        , destY = (window.innerHeight/2) - amount.y
        , stepX = destX / animationSteps
        , stepY = destY / animationSteps
        
    
        intervalID = setInterval(function(){
        if (animationStep++ < animationSteps) {
            panZoom.panBy({x: stepX, y: stepY})
        } else {
            // Cancel interval
            clearInterval(intervalID)
        }
        }, animationStepTime)
    }
    

    And the update to the button code

    var button1 = document.getElementById("cat-1")
    button1.addEventListener("click", function() {
        const { left, width, top, height } = button1.getBoundingClientRect();
    customPanBy({x: left + width/2, y: top + height/2});
    });
    

    And here is the updated codepen: https://codepen.io/lexicalnoscope/pen/NWmoQVM