Fix swipe conflicting with scroll (#1116)

This commit is contained in:
Alexander Zinchuk 2021-05-24 13:09:59 +03:00
parent 344590b58b
commit 800a23f731

View File

@ -29,12 +29,15 @@ export interface RealTouchEvent extends TouchEvent {
pageY?: number; pageY?: number;
} }
type TSwipeAxis = 'x' | 'y' | undefined;
const MOVED_THRESHOLD = 15; const MOVED_THRESHOLD = 15;
const SWIPE_THRESHOLD = 50; const SWIPE_THRESHOLD = 50;
export function captureEvents(element: HTMLElement, options: CaptureOptions) { export function captureEvents(element: HTMLElement, options: CaptureOptions) {
let captureEvent: MouseEvent | RealTouchEvent | undefined; let captureEvent: MouseEvent | RealTouchEvent | undefined;
let hasMoved = false; let hasMoved = false;
let currentSwipeAxis: TSwipeAxis;
function onCapture(e: MouseEvent | RealTouchEvent) { function onCapture(e: MouseEvent | RealTouchEvent) {
if (options.excludedClosestSelector && ( if (options.excludedClosestSelector && (
@ -100,6 +103,7 @@ export function captureEvents(element: HTMLElement, options: CaptureOptions) {
} }
hasMoved = false; hasMoved = false;
currentSwipeAxis = undefined;
} }
function onMove(e: MouseEvent | RealTouchEvent) { function onMove(e: MouseEvent | RealTouchEvent) {
@ -127,11 +131,34 @@ export function captureEvents(element: HTMLElement, options: CaptureOptions) {
} }
if (options.onSwipe) { if (options.onSwipe) {
processSwipe(e, dragOffsetX, dragOffsetY, options.onSwipe); onSwipe(e, dragOffsetX, dragOffsetY);
} }
} }
} }
function onSwipe(e: Event, dragOffsetX: number, dragOffsetY: number) {
if (!currentSwipeAxis) {
const xAbs = Math.abs(dragOffsetX);
const yAbs = Math.abs(dragOffsetY);
if (dragOffsetX && dragOffsetY) {
const ratio = Math.max(xAbs, yAbs) / Math.min(xAbs, yAbs);
// Diagonal swipe
if (ratio < 2) {
return;
}
}
if (xAbs >= SWIPE_THRESHOLD) {
currentSwipeAxis = 'x';
} else if (yAbs >= SWIPE_THRESHOLD) {
currentSwipeAxis = 'y';
}
}
processSwipe(e, currentSwipeAxis, dragOffsetX, dragOffsetY, options.onSwipe!);
}
element.addEventListener('mousedown', onCapture); element.addEventListener('mousedown', onCapture);
element.addEventListener('touchstart', onCapture, { passive: true }); element.addEventListener('touchstart', onCapture, { passive: true });
@ -142,26 +169,19 @@ export function captureEvents(element: HTMLElement, options: CaptureOptions) {
} }
function processSwipe( function processSwipe(
e: Event, dragOffsetX: number, dragOffsetY: number, onSwipe: (e: Event, direction: SwipeDirection) => void, e: Event,
currentSwipeAxis:TSwipeAxis,
dragOffsetX: number,
dragOffsetY: number,
onSwipe: (e: Event, direction: SwipeDirection) => void,
) { ) {
const xAbs = Math.abs(dragOffsetX); if (currentSwipeAxis === 'x') {
const yAbs = Math.abs(dragOffsetY);
if (dragOffsetX && dragOffsetY) {
const ratio = Math.max(xAbs, yAbs) / Math.min(xAbs, yAbs);
// Diagonal swipe
if (ratio < 2) {
return;
}
}
if (xAbs >= SWIPE_THRESHOLD) {
if (dragOffsetX < 0) { if (dragOffsetX < 0) {
onSwipe(e, SwipeDirection.Left); onSwipe(e, SwipeDirection.Left);
} else { } else {
onSwipe(e, SwipeDirection.Right); onSwipe(e, SwipeDirection.Right);
} }
} else if (yAbs >= SWIPE_THRESHOLD) { } else if (currentSwipeAxis === 'y') {
if (dragOffsetY < 0) { if (dragOffsetY < 0) {
onSwipe(e, SwipeDirection.Up); onSwipe(e, SwipeDirection.Up);
} else { } else {