From 78ad5d3bc044fa68c1fa1baa127a4e4b3d7c1b0f Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Mon, 13 Oct 2025 22:41:20 +0200 Subject: [PATCH] Animates drag cancellation Improves user experience by animating the dragged element back to its original position when the drag operation is cancelled due to the mouse leaving the grid container. --- src/managers/DragDropManager.ts | 46 +++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/managers/DragDropManager.ts b/src/managers/DragDropManager.ts index 8a8a7a6..2a53d34 100644 --- a/src/managers/DragDropManager.ts +++ b/src/managers/DragDropManager.ts @@ -391,24 +391,44 @@ export class DragDropManager { /** * Cancel drag operation when mouse leaves grid container + * Animates clone back to original position before cleanup */ private cancelDrag(): void { - if (!this.originalElement) return; + if (!this.originalElement || !this.draggedClone) return; console.log('🚫 DragDropManager: Cancelling drag - mouse left grid container'); - this.cleanupAllClones(); - - this.originalElement.style.opacity = ''; - this.originalElement.style.cursor = ''; - - this.eventBus.emit('drag:cancelled', { - originalElement: this.originalElement, - reason: 'mouse-left-grid' - }); - - this.cleanupDragState(); - this.stopDragAnimation(); + // Get current clone position + const cloneRect = this.draggedClone.getBoundingClientRect(); + + // Get original element position + const originalRect = this.originalElement.getBoundingClientRect(); + + // Calculate distance to animate + const deltaX = originalRect.left - cloneRect.left; + const deltaY = originalRect.top - cloneRect.top; + + // Add transition for smooth animation + this.draggedClone.style.transition = 'transform 300ms ease-out'; + this.draggedClone.style.transform = `translate(${deltaX}px, ${deltaY}px)`; + + // Wait for animation to complete, then cleanup + setTimeout(() => { + this.cleanupAllClones(); + + if (this.originalElement) { + this.originalElement.style.opacity = ''; + this.originalElement.style.cursor = ''; + } + + this.eventBus.emit('drag:cancelled', { + originalElement: this.originalElement, + reason: 'mouse-left-grid' + }); + + this.cleanupDragState(); + this.stopDragAnimation(); + }, 300); } /**