From 0ef60c32f99ce581365faf4a8f2f36c44092a92a Mon Sep 17 00:00:00 2001 From: blakkd Date: Wed, 1 Jul 2026 09:56:55 +0200 Subject: [PATCH] fix: use maxDragDistance peak instead of release distance to prevent far-drag returning to origin entering sticky mode Before: handleMouseUp checked distance from press origin to release position, so releasing near origin after dragging far was treated as a click (sticky scroll continued). After: maxDragDistance tracks the furthest distance traveled from origin during the session. Release now stops scroll if the cursor ever moves beyond dragThreshold, regardless of where it is released. --- .gitignore | 1 + extensions/roller/src/Roller.ts | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index fa14230..fc1bc71 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ web-ext-artifacts *.crx .playwright-mcp package-lock.json +TODO \ No newline at end of file diff --git a/extensions/roller/src/Roller.ts b/extensions/roller/src/Roller.ts index 19f7ccf..8f80f2d 100644 --- a/extensions/roller/src/Roller.ts +++ b/extensions/roller/src/Roller.ts @@ -27,6 +27,7 @@ export default class Roller { timeout: number | null oldX: number | null oldY: number | null + maxDragDistance: number dirX: number dirY: number clicked: boolean @@ -53,6 +54,7 @@ export default class Roller { this.timeout = null this.oldX = null this.oldY = null + this.maxDragDistance = 0 this.dirX = 0 this.dirY = 0 this.clicked = false @@ -128,10 +130,10 @@ export default class Roller { loop() } - shouldSticky(x: number, y: number): boolean { + shouldSticky(): boolean { return ( this.options.stickyScroll && - utils.hypot(x, y) < this.options.dragThreshold + this.maxDragDistance < this.options.dragThreshold ) } @@ -149,7 +151,12 @@ export default class Roller { const x = event.clientX - this.oldX! const y = event.clientY - this.oldY! - if (utils.hypot(x, y) > this.options.moveThreshold) { + const distance = utils.hypot(x, y) + if (distance > this.maxDragDistance) { + this.maxDragDistance = distance + } + + if (distance > this.options.moveThreshold) { this.cursor = utils.getCursorStyleFromAngle(utils.angle(x, y)) let dx = x @@ -180,10 +187,7 @@ export default class Roller { handleMouseUp(event: MouseEvent): void { utils.stopEvent(event, true) - const x = event.clientX - this.oldX! - const y = event.clientY - this.oldY! - - if (this.clicked || !this.shouldSticky(x, y)) { + if (this.clicked || !this.shouldSticky()) { this.stop() } else { this.clicked = true @@ -204,6 +208,7 @@ export default class Roller { this.cursor = 'auto' this.oldX = null this.oldY = null + this.maxDragDistance = 0 this.dirX = 0 this.dirY = 0 this.clicked = false @@ -311,6 +316,11 @@ export default class Roller { const dx = x - this.iframeOldX! const dy = y - this.iframeOldY! + const dragDistance = utils.hypot(x - this.oldX!, y - this.oldY!) + if (dragDistance > this.maxDragDistance) { + this.maxDragDistance = dragDistance + } + if (utils.hypot(dx, dy) > this.options.moveThreshold) { this.cursor = utils.getCursorStyleFromAngle(utils.angle(dx, dy))