Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

How to drag a clone with Svelte5 and interact.js

$
0
0

I'm using interact.js and Svelte 5 (version 5.0.0-next.200) to drag an element which initially sits inside a scrollable div and must be dropped outside of that div. To make this work I need to clone the element and then drag the clone, I guess there's no way around.

Now, in a former Vanilla-js project I successfully adapted the code from this stackoverflow-answer and everything worked fine. However, I can't make it work in Svelte.

Below is my code. I assume the error is in interaction.start({ name: 'drag' }, ev.interactable, clone);, which fails to pass the drag-action on to the clone. Instead the original div is moved double the distance, which I cannot explain either.

Any help is warmly welcome. I'm struggling with this since days.

EDIT: solved the striked-through part above and commented one line of code.

<script>    import interact from 'interactjs';    const dragElement = (ev) => {        const el = ev.target;        let x = (parseFloat(el.getAttribute('data-x')) || 0) + ev.dx;        let y = (parseFloat(el.getAttribute('data-y')) || 0) + ev.dy;        el.style.webkitTransform = el.style.transform = `translate(${x}px,${y}px)`;        el.setAttribute('data-x', x);        el.setAttribute('data-y', y);    }    const makeDraggable = (DRAG) => {        const draggable = document.querySelector('.draggable');        interact(draggable)            .draggable({                allowFrom: '*',                inertia: false,                autoScroll: false,                modifiers: [                    interact.modifiers.restrict({                        restriction: '#outer',                        endOnly: true                    })                ],                onstart: (ev) => {                    console.log('DRAG START of ', ev.target);                },                onmove: (ev) => {                    console.log('DRAG MOVE of ', ev.target);                    dragElement(ev);                },                onend: (ev) => {                    console.log('DRAG END of ', ev.target);                    DRAG.node.orig.style.opacity = 100; // show original again after drag                }            })            .on('move', (ev) => {                const el = ev.currentTarget;                const interaction = ev.interaction;                console.log('ON.MOVE TRY of ', el);                if (                    interaction.pointerIsDown && // Only on active interaction                    interaction.interacting() // Prevent activation by swiping through element                ) {                    // If ORIG then make a clone                    if (                        DRAG.active == false && // Create only one clone                        el.getAttribute('isClone') == 'orig' // Prevent re-cloning clones                    ) {                        DRAG.active = true;                        console.log('CLONING START');                        // Clone node and set its position                        let clone = el.cloneNode(true);                        clone.style.left = el.offsetLeft +'px';                        clone.style.top = el.offsetTop +'px';                        clone.style.position = 'absolute';                        clone.setAttribute('isClone', 'clone');                        clone.style.backgroundColor = 'grey';                        // makeDraggable(DRAG); // EDIT: this line caused the double-distance dragging                        // Append Clone and start drag interaction                        document.querySelector('#outer').appendChild(clone);                        console.log('CLONE IS READY: ', clone);                        DRAG.node.orig = el;                        DRAG.node.clone = clone;                        DRAG.node.orig.style.opacity = 0; // hide original while dragging clone                        interaction.start({ name: 'drag' }, ev.interactable, clone);                        // if CLONE then drag                        // } else if (el.getAttribute('isClone') == 'clone') {                        //  // console.log('MOVING THE CLONE START');                        //  // dragElement(ev);                        // }                    }                }            });    };    ///////////////////////////////////////////////////////////////    // DRAG State    let DRAG = $state({        active: false,        node: {            orig: undefined,            clone: undefined        }    });    ///////////////////////////////////////////////////////////////    // Handle drag    const handleDrag = () => {        makeDraggable(DRAG);    };</script><div id="outer"><h1>outer</h1><div id="inner"><h1>inner (scrollable)</h1><div class="draggable" isClone="orig" use:handleDrag>Drag me</div></div></div><style>    #outer {        position: absolute;        background-color: yellow;        height: 95vh;        width: 90vw;    }    #inner {        position: absolute;        height: 400px;        width: 100%;        background: lightblue;        overflow-y: scroll;    }    .draggable {        position: absolute;        background-color: black;        color: white;        height: 500px;        width: 150px;    }</style>

Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>