Skip to content

Commit a7a4549

Browse files
MilanMilan
authored andcommitted
Add custom drag preview showing node shape
1 parent ca63f3f commit a7a4549

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

src/lib/components/panels/NodeLibrary.svelte

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
// Track drag state to prevent click after drag
2323
let isDragging = $state(false);
2424
25+
// Drag preview - rendered off-screen, used as drag image
26+
let dragPreviewNode = $state<NodeTypeDefinition | null>(null);
27+
let dragPreviewElement: HTMLDivElement;
28+
2529
// Collapsed categories
2630
let collapsedCategories = $state<Set<string>>(new Set());
2731
@@ -85,12 +89,27 @@
8589
return result;
8690
});
8791
92+
// Handle mouse enter to prepare drag preview
93+
function handleMouseEnter(node: NodeTypeDefinition) {
94+
dragPreviewNode = node;
95+
}
96+
8897
// Handle drag start
8998
function handleDragStart(event: DragEvent, nodeType: NodeTypeDefinition) {
9099
isDragging = true;
91100
if (event.dataTransfer) {
92101
event.dataTransfer.setData('application/pathview-node', nodeType.type);
93102
event.dataTransfer.effectAllowed = 'copy';
103+
104+
// Use the pre-rendered preview as drag image, centered on cursor
105+
if (dragPreviewElement) {
106+
const rect = dragPreviewElement.getBoundingClientRect();
107+
event.dataTransfer.setDragImage(
108+
dragPreviewElement,
109+
rect.width / 2,
110+
rect.height / 2
111+
);
112+
}
94113
}
95114
}
96115
@@ -99,6 +118,7 @@
99118
// Reset after a short delay to prevent click from firing
100119
setTimeout(() => {
101120
isDragging = false;
121+
dragPreviewNode = null;
102122
}, 100);
103123
}
104124
@@ -196,6 +216,7 @@
196216
class="node-tile"
197217
class:selected={isSelected(node)}
198218
draggable="true"
219+
onmouseenter={() => handleMouseEnter(node)}
199220
ondragstart={(e) => handleDragStart(e, node)}
200221
ondragend={handleDragEnd}
201222
onclick={() => handleNodeClick(node)}
@@ -219,6 +240,15 @@
219240
<span>Click or drag to add</span>
220241
<span>↑↓ Enter</span>
221242
</div>
243+
244+
<!-- Hidden drag preview container (rendered off-screen, used as drag image) -->
245+
<div class="drag-preview-container" aria-hidden="true">
246+
{#if dragPreviewNode}
247+
<div bind:this={dragPreviewElement} class="drag-preview-wrapper">
248+
<NodePreview node={dragPreviewNode} />
249+
</div>
250+
{/if}
251+
</div>
222252
</div>
223253

224254
<style>
@@ -380,4 +410,16 @@
380410
font-size: 10px;
381411
color: var(--text-disabled);
382412
}
413+
414+
/* Hidden container for drag preview image */
415+
.drag-preview-container {
416+
position: fixed;
417+
left: -9999px;
418+
top: -9999px;
419+
pointer-events: none;
420+
}
421+
422+
.drag-preview-wrapper {
423+
display: inline-block;
424+
}
383425
</style>

0 commit comments

Comments
 (0)