51 lines
1.1 KiB
TypeScript
51 lines
1.1 KiB
TypeScript
export type TouchPoint = {
|
|
clientX: number;
|
|
clientY: number;
|
|
};
|
|
|
|
export type TouchDecisionState = {
|
|
x: number;
|
|
y: number;
|
|
decided: boolean;
|
|
};
|
|
|
|
type TouchLike = {
|
|
clientX: number;
|
|
clientY: number;
|
|
};
|
|
|
|
type TouchEventLike = {
|
|
touches: ArrayLike<TouchLike>;
|
|
changedTouches: ArrayLike<TouchLike>;
|
|
};
|
|
|
|
export function getTouchPoint(event: TouchEventLike): TouchPoint {
|
|
const touch = event.touches[0] ?? event.changedTouches[0];
|
|
return {
|
|
clientX: touch?.clientX ?? 0,
|
|
clientY: touch?.clientY ?? 0,
|
|
};
|
|
}
|
|
|
|
export function resolveTouchDragDecision(
|
|
state: TouchDecisionState,
|
|
point: TouchPoint,
|
|
thresholdPx = 8,
|
|
): { nextState: TouchDecisionState; shouldHandleDrag: boolean } {
|
|
if (state.decided) {
|
|
return { nextState: state, shouldHandleDrag: true };
|
|
}
|
|
|
|
const dx = Math.abs(point.clientX - state.x);
|
|
const dy = Math.abs(point.clientY - state.y);
|
|
if (dx <= thresholdPx && dy <= thresholdPx) {
|
|
return { nextState: state, shouldHandleDrag: false };
|
|
}
|
|
|
|
const nextState = { ...state, decided: true };
|
|
return {
|
|
nextState,
|
|
shouldHandleDrag: dx >= dy,
|
|
};
|
|
}
|