Refactors edge scroll start detection

Improves edge scroll detection by listening for actual scroll events instead of relying on mouse position.

This change ensures that the 'edgescroll:started' event is only emitted when scrolling has actually begun, preventing false positives and improving the accuracy of scroll compensation. It also removes the unnecessary scroll listener from the DragDropManager, consolidating scroll handling in the EdgeScrollManager.
This commit is contained in:
Janus C. H. Knudsen 2025-10-13 17:49:19 +02:00
parent faf8b50593
commit d259620371
2 changed files with 41 additions and 28 deletions

View file

@ -182,7 +182,7 @@ export class DragDropManager {
* Optimized mouse move handler with consolidated position calculations
*/
private handleMouseMove(event: MouseEvent): void {
console.log('handleMouseMove', event)
if (this.isScrollCompensating) return;
//this.currentMouseY = event.clientY;
// this.lastMousePosition = { x: event.clientX, y: event.clientY };
@ -305,7 +305,6 @@ export class DragDropManager {
*/
private handleMouseUp(event: MouseEvent): void {
this.stopDragAnimation();
this.removeScrollListener();
if (this.originalElement) {
@ -376,7 +375,6 @@ export class DragDropManager {
console.log('🚫 DragDropManager: Cancelling drag - mouse left grid container');
this.cleanupAllClones();
this.removeScrollListener();
this.originalElement.style.opacity = '';
this.originalElement.style.cursor = '';
@ -486,19 +484,6 @@ export class DragDropManager {
});
}
/**
* Remove scroll listener
*/
private removeScrollListener(): void {
if (this.scrollListener && this.scrollableContent) {
this.scrollableContent.removeEventListener('scroll', this.scrollListener);
this.scrollListener = null;
}
this.isScrollCompensating = false;
this.initialScrollTop = 0;
this.initialCloneTop = 0;
}
/**
* Stop drag animation
*/

View file

@ -14,6 +14,8 @@ export class EdgeScrollManager {
private isScrolling = false; // Track if edge-scroll is active
private lastTs = 0;
private rect: DOMRect | null = null;
private initialScrollTop = 0;
private scrollListener: ((e: Event) => void) | null = null;
// Constants - fixed values as per requirements
private readonly OUTER_ZONE = 100; // px from edge (slow zone)
@ -32,6 +34,10 @@ export class EdgeScrollManager {
if (this.scrollableContent) {
// Disable smooth scroll for instant auto-scroll
this.scrollableContent.style.scrollBehavior = 'auto';
// Add scroll listener to detect actual scrolling
this.scrollListener = this.handleScroll.bind(this);
this.scrollableContent.addEventListener('scroll', this.scrollListener, { passive: true });
}
}, 100);
@ -62,7 +68,10 @@ export class EdgeScrollManager {
this.isScrolling = false; // Reset scroll state
this.lastTs = performance.now();
// Don't save initial positions here - wait until scrolling actually starts!
// Save initial scroll position
if (this.scrollableContent) {
this.initialScrollTop = this.scrollableContent.scrollTop;
}
if (this.scrollRAF === null) {
this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts));
@ -71,13 +80,39 @@ export class EdgeScrollManager {
private stopDrag(): void {
this.isDragging = false;
this.isScrolling = false;
// Emit stopped event if we were scrolling
if (this.isScrolling) {
this.isScrolling = false;
console.log('🛑 EdgeScrollManager: Edge-scroll stopped (drag ended)');
this.eventBus.emit('edgescroll:stopped', {});
}
if (this.scrollRAF !== null) {
cancelAnimationFrame(this.scrollRAF);
this.scrollRAF = null;
}
this.rect = null;
this.lastTs = 0;
this.initialScrollTop = 0;
}
private handleScroll(): void {
if (!this.isDragging || !this.scrollableContent) return;
const currentScrollTop = this.scrollableContent.scrollTop;
const scrollDelta = Math.abs(currentScrollTop - this.initialScrollTop);
// Only emit started event if we've actually scrolled more than 1px
if (scrollDelta > 1 && !this.isScrolling) {
this.isScrolling = true;
console.log('💾 EdgeScrollManager: Edge-scroll started (actual scroll detected)', {
initialScrollTop: this.initialScrollTop,
currentScrollTop,
scrollDelta
});
this.eventBus.emit('edgescroll:started', {});
}
}
private scrollTick(ts: number): void {
@ -114,15 +149,8 @@ export class EdgeScrollManager {
}
if (vy !== 0 && this.isDragging) {
// Mark that scrolling is active
if (!this.isScrolling) {
this.isScrolling = true;
console.log('💾 EdgeScrollManager: Edge-scroll started');
// Notify DragDropManager that scroll compensation should start
this.eventBus.emit('edgescroll:started', {});
}
// Time-based scrolling for frame-rate independence
// The scroll listener will detect actual scrolling and emit edgescroll:started
this.scrollableContent.scrollTop += vy * dt;
this.rect = null; // Invalidate cache for next frame
this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts));
@ -130,8 +158,8 @@ export class EdgeScrollManager {
// Mouse moved away from edge - stop scrolling
if (this.isScrolling) {
this.isScrolling = false;
console.log('🛑 EdgeScrollManager: Edge-scroll stopped');
// Notify DragDropManager that scroll compensation should stop
this.initialScrollTop = this.scrollableContent.scrollTop; // Reset for next scroll
console.log('🛑 EdgeScrollManager: Edge-scroll stopped (mouse left edge)');
this.eventBus.emit('edgescroll:stopped', {});
}