/** * 纯 Web 触摸事件 Hook(不依赖 @tarojs/components) * 参考 mobile-app/src/utils/touch.ts 的逻辑,适配标准 Web TouchEvent */ import { useCallback, useRef } from 'react'; const MIN_DISTANCE = 10; type Direction = 'horizontal' | 'vertical' | undefined; function getDirection(x: number, y: number): Direction { if (x > y && x > MIN_DISTANCE) return 'horizontal'; if (y > x && y > MIN_DISTANCE) return 'vertical'; return undefined; } export function useTouch() { const ref = useRef({ startX: 0, startY: 0, deltaX: 0, deltaY: 0, offsetX: 0, offsetY: 0, direction: undefined as Direction, }); const start = useCallback((e: React.TouchEvent | TouchEvent) => { const touch = e.touches[0]; ref.current.startX = touch.clientX; ref.current.startY = touch.clientY; ref.current.deltaX = 0; ref.current.deltaY = 0; ref.current.offsetX = 0; ref.current.offsetY = 0; ref.current.direction = undefined; }, []); const move = useCallback((e: React.TouchEvent | TouchEvent) => { const touch = e.touches[0]; const dx = touch.clientX < 0 ? 0 : touch.clientX - ref.current.startX; const dy = touch.clientY - ref.current.startY; ref.current.deltaX = dx; ref.current.deltaY = dy; ref.current.offsetX = Math.abs(dx); ref.current.offsetY = Math.abs(dy); if (!ref.current.direction) { ref.current.direction = getDirection(ref.current.offsetX, ref.current.offsetY); } }, []); const isVertical = () => ref.current.direction === 'vertical'; const isHorizontal = () => ref.current.direction === 'horizontal'; return { touch: ref.current, start, move, isVertical, isHorizontal }; }