0

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();
        }
    }
  • You should not query the DOM in Svelte (`getElementById` and the like). You can use `bind:this` to get elements or use actions (`use:...`) to interact with them. – H.B. Aug 29 '22 at 06:55
  • @H.B. Does this not only apply for querying elements for e.g. changing their style or adding eventListeners but also for per se getting the reference? So does it make a difference if the reference was set via `bind:this` or if it's queried inside onMount? – Corrl Aug 29 '22 at 07:46
  • 1
    @Corrl: Not necessarily, it is a matter of ensuring that the correct elements are referenced and idiomatic style. With queries there can always be the issue that the wrong element is found or as is the case here, that component boundaries are not respected (`Toolbar` should not directly access elements of `App`). – H.B. Aug 29 '22 at 08:04
  • @H.B. Thanks! Ensuring the correct reference is of course an argument. And I must confess I've completely overseen the two components.... – Corrl Aug 29 '22 at 08:14

1 Answers1

3

.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>
Corrl
  • 6,206
  • 1
  • 10
  • 36