Fix drag offset calculation and scrolling behavior in FixedLayout component

This commit fixes several issues with the drag functionality in the FixedLayout
component to ensure smooth and accurate dragging behavior:

Changes:
- Initialize dragOffset to (0, 0) instead of scroll position when drag starts
- Fix drag offset calculation direction (changed from -= to +=)
- Add proper scroll position updates during drag operations
- Ensure dragOffset is reset to (0, 0) when drag completes

The previous implementation was incorrectly initializing dragOffset with the
current scroll position, which caused the drag offset to compound with scroll
position and led to incorrect rendering. The new approach starts drag offset
at zero and directly updates the scroll position during drag operations.

This ensures that:
1. Drag movements are accurately tracked relative to the drag start point
2. Scroll position is properly synchronized with drag movements
3. Drag state is cleanly reset when drag operations complete
This commit is contained in:
2026-04-17 11:02:26 -04:00
parent 3f9ab7528b
commit 5b822b682b
+12 -8
View File
@@ -308,8 +308,8 @@ export class FixedLayout extends HTMLElement {
if (this.#dragState.isPotentialDrag) { if (this.#dragState.isPotentialDrag) {
console.log("[FixedLayout Debug] ✋ DRAG MODE ACTIVATED (timeout)"); console.log("[FixedLayout Debug] ✋ DRAG MODE ACTIVATED (timeout)");
this.#dragState.isDragging = true; this.#dragState.isDragging = true;
this.dragOffset.x = this.scrollLeft; this.dragOffset.x = 0;
this.dragOffset.y = this.scrollTop; this.dragOffset.y = 0;
this.style.cursor = "grabbing"; this.style.cursor = "grabbing";
// Prevent text selection while dragging // Prevent text selection while dragging
@@ -340,8 +340,8 @@ export class FixedLayout extends HTMLElement {
clearTimeout(this.#dragState.dragTimeout); clearTimeout(this.#dragState.dragTimeout);
this.#dragState.isPotentialDrag = false; this.#dragState.isPotentialDrag = false;
this.#dragState.isDragging = true; this.#dragState.isDragging = true;
this.dragOffset.x = this.scrollLeft; this.dragOffset.x = 0;
this.dragOffset.y = this.scrollTop; this.dragOffset.y = 0;
this.style.cursor = "grabbing"; this.style.cursor = "grabbing";
} }
} }
@@ -361,11 +361,14 @@ export class FixedLayout extends HTMLElement {
}); });
// Update drag offset instead of scrolling // Update drag offset instead of scrolling
this.dragOffset.x -= dx; this.dragOffset.x += dx;
this.dragOffset.y -= dy; this.dragOffset.y += dy;
// Re-render with new drag offset // Re-render with new drag offset
this.#render(); const newScrollX = this.#dragState.scrollLeft - this.dragOffset.x;
const newScrollY = this.#dragState.scrollTop - this.dragOffset.y;
this.scrollLeft = newScrollX;
this.scrollTop = newScrollY;
} }
} }
@@ -386,7 +389,8 @@ export class FixedLayout extends HTMLElement {
this.#dragState.isDragging = false; this.#dragState.isDragging = false;
this.#dragState.isPotentialDrag = false; this.#dragState.isPotentialDrag = false;
this.style.cursor = ""; this.style.cursor = "";
this.dragOffset.x = 0;
this.dragOffset.y = 0;
// NEW: Reset drag offset when drag completes // NEW: Reset drag offset when drag completes
if (wasDragging) { if (wasDragging) {
console.log("[FixedLayout Debug] ✅ Drag completed"); console.log("[FixedLayout Debug] ✅ Drag completed");