画布上的节点 - 一些奇怪的行为

问题描述 投票:0回答:1

我使用优秀的“Neodrag”包制作了一个简单的 REPL,用于拖动组件。

但是,当我添加新节点或调整节点大小时,它们似乎会相互交互。例如,当调整“旧”节点的大小时,新节点彼此偏移,并且其他节点会移动。有没有人有这方面的经验并且能够提供帮助?

https://svelte.dev/playground/a35a7c16caa64842b694b5631d1d7a57?version=5.19.0

谢谢!

代码是:

// globalstate.svelte.js
export let thestate = $state({
  nodes:[
    {id:0, x:12, y:13, width:145, height:67, text:"The first one"},
    {id:1, x:16, y:20, width:145, height:67, text:"Another node"},
  ]
})
<!-- Node.svelte -->
<script>
    import {thestate} from "./globalstate.svelte.js"    
    import { draggable } from '@neodrag/svelte';
    
    let {id="", x=5, y=5, width=10, height=10, text=""} = $props()
    
    let isResizing = false;
    let initialMouseX, initialMouseY, initialWidth, initialHeight;
    
    // Resize logic
    const startResize = (event) => {
        isResizing = true;
        initialMouseX = event.clientX;
        initialMouseY = event.clientY;
        initialWidth = thestate.nodes[id].width;
        initialHeight = thestate.nodes[id].height;
        document.addEventListener('mousemove', doResize);
        document.addEventListener('mouseup', stopResize);
    };
    
    const doResize = (event) => {
        if (isResizing) {
            const deltaX = event.clientX - initialMouseX;
            const deltaY = event.clientY - initialMouseY;
            thestate.nodes[id].width = initialWidth + deltaX;
            thestate.nodes[id].height = initialHeight + deltaY;
        }
    };
    
    const stopResize = () => {
        isResizing = false;
        document.removeEventListener('mousemove', doResize);
        document.removeEventListener('mouseup', stopResize);
    };
</script>

<div
    use:draggable={{
        bounds: 'parent',
        handle: '.handle',
        position: {x:thestate.nodes[id].x, y:thestate.nodes[id].y},
        onDrag: ({ offsetX, offsetY }) => {
            thestate.nodes[id].x= offsetX; 
            thestate.nodes[id].y= offsetY ;
        }
    }}

    style="min-width:50px; min-height:50px; width:{width}px; height:{height}px; 
          background-color: white; position: relative; 
                 border-radius: 8px; padding:3px; margin:3px;
          transform:translate3d({thestate.nodes[id].x}px, {thestate.nodes[id].y}px, 0px);"
>
    <div
        class="dragContent cancel"
        style="z-index:100; position:absolute; 
            overflow:auto; width:100%; height:100%; color:black;"
    >
        <p>{text}</p>
    </div>

    <!-- Drag Handle -->
    <div
        class="handle"
        style="width: calc({thestate.nodes[id].width}px + 10px);
    height: calc({thestate.nodes[id].height}px + 30px);"
    ></div>

    <!-- Resize Handle -->
    <div class="resize-handle" on:mousedown={startResize}></div>
</div>

<style>
    .handle {
        position: absolute;
        bottom: -5px;
        left: -5px;
        border: 2px dotted #333;
        border-radius: 8px;
        cursor: grab;
        opacity: 0;
        transition: opacity 0.2s ease;
    }
    
    div:hover > .handle {
        opacity: 1;
        cursor: grab;
    }
    
    .resize-handle {
        position: absolute;
        bottom: -5px;
        right: -5px;
        width: 10px;
        height: 10px;
        background-color: blue;
        cursor: nwse-resize;
    }
</style>
<!-- App.svelte -->
<script>
    import {thestate} from "./globalstate.svelte.js"
    import Node from "./Node.svelte"
    
    function addnode(){
        thestate.nodes.push({id:thestate.nodes.length, x:10, y:11, width:120, height:130, text:thestate.nodes.length+"here"})
    }
</script>

<h2>Example nodes on canvas</h2>
<button onclick={addnode}>Add node</button>
<div style="width:500px; height:500px; background-color: lightgray; overflow:auto">
    {#each thestate.nodes as node}
        {#key node.id}
            <Node {...node}/>
        {/key}
    {/each}
</div>

<h2>Debugging</h2>
<a>{JSON.stringify(thestate)}</a>
user-interface resize svelte draggable
1个回答
0
投票

事实证明,所需的所有 div 都是“位置:绝对!重要;”风格。

© www.soinside.com 2019 - 2024. All rights reserved.