feat(reader): swipe left/right to turn pages in single mode
Wire horizontal swipe into the mobile tap-zone overlay (single mode only, so continuous mode keeps native vertical scroll). A leftward swipe past the threshold turns to the next page, rightward to the previous; a mostly- vertical drag is ignored so panning a tall page never turns it. The gesture suppresses the synthesized zone tap so it doesn't double-fire. Swipe classification is a pure, unit-tested helper; e2e drives real touch pointer events for horizontal (both directions) and vertical cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
23
frontend/src/lib/swipe.ts
Normal file
23
frontend/src/lib/swipe.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// Pure gesture helper for the reader's single-page swipe navigation. Kept
|
||||
// UI-free so the "is this a page-turn swipe, and which way" decision is
|
||||
// unit-testable without dispatching pointer events.
|
||||
|
||||
export const SWIPE_THRESHOLD_PX = 45;
|
||||
|
||||
/**
|
||||
* Classifies a pointer displacement as a page-turn swipe. Returns `'next'`
|
||||
* for a leftward swipe, `'prev'` for a rightward one, or `null` when the
|
||||
* gesture is too short or too vertical to be a deliberate horizontal swipe
|
||||
* (so vertical panning never turns the page).
|
||||
*/
|
||||
export function swipeDirection(
|
||||
dx: number,
|
||||
dy: number,
|
||||
threshold: number = SWIPE_THRESHOLD_PX
|
||||
): 'next' | 'prev' | null {
|
||||
if (Math.abs(dx) < threshold) return null;
|
||||
// Must be predominantly horizontal — a diagonal or vertical drag is not
|
||||
// a page turn.
|
||||
if (Math.abs(dx) <= Math.abs(dy)) return null;
|
||||
return dx < 0 ? 'next' : 'prev';
|
||||
}
|
||||
Reference in New Issue
Block a user