sveltepanzoom

Why panzoom not disabled in svelte?


I am trying both panzoom library in projects. The panzoom is working perfectly but when I try to pause or dispose panzoom, it is not working. I have tried multiple approach to solve this but didn't find any working solution.

I have created a canvas then added panzoom to parent element. The panzoom working but pause or destroy not working.

App.svelte

    <div id="editor">
        <canvas id="canvas" />
    </div>

Toolbar.svelte

    import panzoom from "panzoom";

    function setActive(toolId) {
        const instance = panzoom(document.getElementById("editor"));

        if (toolId === "choose-color") {
            instance.resume();
        } else {
            instance.dispose();
        }
    }

Solution

  • .pause(), .resume() or .dispose() are methods to be called on the one instance which is created by calling const instance = panzoom(element) Since you're doing this inside setActive() you're creating a new instance every time...

    Here's a version using an action to initialize panzoom and pass instance as a prop to the child component to make it available. To temporarily disable the panning, I'd switch between pause/resume

    REPL

    App.svelte

    <script>
        import panzoom from 'panzoom'
        import Toolbar from './Toolbar.svelte'
    
        let instance
    
        function initPanzoom(node) {
            instance = panzoom(node)
        }
    </script>
    
    <Toolbar {instance} />
    
    <svg id="svelte" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 519 139">
        <g use:initPanzoom>
            ...
        </g>
    </svg>
    
    <style>
        svg {
            width: 100%;
            height: 100%;
        }
    </style>
    

    Toolbar.svelte

    <script>
        export let instance
    </script>
    
    <div>
        <button on:click={() => instance.pause()}>pause</button>
        <button on:click={() => instance.resume()}>resume</button>
        <button on:click={() => instance.dispose()}>dispose</button>
    </div>