Improves drag-and-drop scroll compensation.
Enhances drag-and-drop functionality by accurately compensating for scroll during drag operations. This ensures the dragged element remains correctly positioned relative to the mouse, even when the user scrolls the content during the drag. It achieves this by: - Tracking whether scrolling has occurred during a drag operation. - Factoring scroll delta into target position calculation. - Updating targetY/currentY instead of directly manipulating the clone's style.
This commit is contained in:
parent
dbbd19de13
commit
9a7a90c124
1 changed files with 41 additions and 21 deletions
|
|
@ -47,6 +47,7 @@ export class DragDropManager {
|
|||
private initialScrollTop = 0;
|
||||
private initialCloneTop = 0;
|
||||
private isScrollCompensating = false; // Track if scroll compensation is active
|
||||
private hasScrolledDuringDrag = false; // Track if we have scrolled during this drag operation
|
||||
private scrollListener: ((e: Event) => void) | null = null;
|
||||
|
||||
// Smooth drag animation
|
||||
|
|
@ -127,6 +128,7 @@ export class DragDropManager {
|
|||
// Listen to edge-scroll events to control scroll compensation
|
||||
this.eventBus.on('edgescroll:started', () => {
|
||||
this.isScrollCompensating = true;
|
||||
this.hasScrolledDuringDrag = true;
|
||||
console.log('🎬 DragDropManager: Edge-scroll started - disabling continueDrag()');
|
||||
});
|
||||
|
||||
|
|
@ -194,21 +196,20 @@ export class DragDropManager {
|
|||
}
|
||||
|
||||
if (event.buttons === 1) {
|
||||
const currentPosition: MousePosition = { x: event.clientX, y: event.clientY };
|
||||
this.currentMousePosition = currentPosition; // Track current mouse position
|
||||
// Always update mouse position from event
|
||||
this.currentMousePosition = { x: event.clientX, y: event.clientY };
|
||||
|
||||
// Try to initialize drag if not started
|
||||
if (!this.isDragStarted && this.originalElement) {
|
||||
if (!this.initializeDrag(currentPosition)) {
|
||||
if (!this.initializeDrag(this.currentMousePosition)) {
|
||||
return; // Not enough movement yet
|
||||
}
|
||||
}
|
||||
|
||||
// Continue drag if started //TODO: This has to be fixed... it fires way too many events, we can do better
|
||||
// Continue drag if started
|
||||
if (this.isDragStarted && this.originalElement && this.draggedClone) {
|
||||
//console.log("Continue drag if started", this.draggedClone);
|
||||
this.continueDrag(currentPosition);
|
||||
this.detectColumnChange(currentPosition);
|
||||
this.continueDrag(this.currentMousePosition);
|
||||
this.detectColumnChange(this.currentMousePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +266,14 @@ export class DragDropManager {
|
|||
if (column) {
|
||||
// Calculate raw Y position relative to column (accounting for mouse offset)
|
||||
const columnRect = column.boundingClientRect;
|
||||
const eventTopY = currentPosition.y - columnRect.top - this.mouseOffset.y;
|
||||
let eventTopY = currentPosition.y - columnRect.top - this.mouseOffset.y;
|
||||
|
||||
// Kompenser for scroll bevægelse hvis vi har scrollet
|
||||
if (this.scrollableContent && this.initialScrollTop > 0) {
|
||||
const totalScrollDelta = this.scrollableContent.scrollTop - this.initialScrollTop;
|
||||
eventTopY += totalScrollDelta;
|
||||
}
|
||||
|
||||
this.targetY = Math.max(0, eventTopY);
|
||||
this.targetColumn = column;
|
||||
|
||||
|
|
@ -453,38 +461,47 @@ export class DragDropManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handle scroll during drag - compensate clone position
|
||||
* Handle scroll during drag - compensate clone position via targetY/currentY
|
||||
*/
|
||||
private handleScroll(): void {
|
||||
if (!this.isDragStarted || !this.draggedClone || !this.scrollableContent || !this.isScrollCompensating) return;
|
||||
|
||||
// First time scrolling - save initial positions NOW!
|
||||
|
||||
if(this.initialScrollTop == 0)
|
||||
if(this.initialScrollTop == 0) {
|
||||
this.initialScrollTop = this.scrollableContent.scrollTop;
|
||||
if(this.initialCloneTop == 0)
|
||||
}
|
||||
if(this.initialCloneTop == 0) {
|
||||
this.initialCloneTop = parseFloat(this.draggedClone.style.top || '0');
|
||||
|
||||
|
||||
console.log('💾 DragDropManager: Scroll compensation started', {
|
||||
initialScrollTop: this.initialScrollTop,
|
||||
initialCloneTop: this.initialCloneTop
|
||||
});
|
||||
|
||||
console.log('💾 DragDropManager: Scroll compensation started', {
|
||||
initialScrollTop: this.initialScrollTop,
|
||||
initialCloneTop: this.initialCloneTop
|
||||
});
|
||||
}
|
||||
|
||||
const currentScrollTop = this.scrollableContent.scrollTop;
|
||||
const totalScrollDelta = currentScrollTop - this.initialScrollTop;
|
||||
|
||||
// Beregn ny position baseret på initial position + total scroll delta
|
||||
const newTop = this.initialCloneTop + totalScrollDelta;
|
||||
this.draggedClone.style.top = `${newTop}px`;
|
||||
|
||||
// Opdater targetY og currentY i stedet for direkte clone opdatering
|
||||
this.targetY = newTop;
|
||||
this.currentY = newTop;
|
||||
|
||||
// Kald animateDrag() hvis ikke allerede kører
|
||||
if (this.dragAnimationId === null) {
|
||||
this.animateDrag();
|
||||
}
|
||||
|
||||
console.log('📜 DragDropManager: Scroll compensation', {
|
||||
initialScrollTop: this.initialScrollTop,
|
||||
currentScrollTop,
|
||||
totalScrollDelta,
|
||||
initialCloneTop: this.initialCloneTop,
|
||||
newTop
|
||||
newTop,
|
||||
targetY: this.targetY,
|
||||
currentY: this.currentY
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -507,6 +524,9 @@ export class DragDropManager {
|
|||
this.draggedClone = null;
|
||||
this.currentColumn = null;
|
||||
this.isDragStarted = false;
|
||||
this.hasScrolledDuringDrag = false;
|
||||
this.initialScrollTop = 0;
|
||||
this.initialCloneTop = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue