UNPKG

@cn-ui/core

Version:

The @cn-ui/core is a collection of UI components and utilities for building modern web applications with SolidJS.

82 lines (71 loc) 2.03 kB
const TAP_OFFSET = 5; import { atom } from "@cn-ui/reactive"; type Direction = "" | "vertical" | "horizontal"; function getDirection(x: number, y: number) { if (x > y) { return "horizontal"; } if (y > x) { return "vertical"; } return ""; } export function useTouch() { const startX = atom(0); const startY = atom(0); const deltaX = atom(0); const deltaY = atom(0); const offsetX = atom(0); const offsetY = atom(0); const direction = atom<Direction>(""); const isTap = atom(true); const isVertical = () => direction() === "vertical"; const isHorizontal = () => direction() === "horizontal"; const reset = () => { deltaX(0); deltaY(0); offsetX(0); offsetY(0); direction(""); isTap(true); }; const start = ((event: TouchEvent) => { reset(); startX(event.touches[0].clientX); startY(event.touches[0].clientY); }) as EventListener; const move = ((event: TouchEvent) => { const touch = event.touches[0]; // safari back will set clientX to negative number deltaX((touch.clientX < 0 ? 0 : touch.clientX) - startX()); deltaY(touch.clientY - startY()); offsetX(Math.abs(deltaX())); offsetY(Math.abs(deltaY())); // lock direction when distance is greater than a certain value const LOCK_DIRECTION_DISTANCE = 10; if ( !direction() || (offsetX() < LOCK_DIRECTION_DISTANCE && offsetY() < LOCK_DIRECTION_DISTANCE) ) { direction(getDirection(offsetX(), offsetY())); } if (isTap() && (offsetX() > TAP_OFFSET || offsetY() > TAP_OFFSET)) { isTap(false); } }) as EventListener; return { move, start, reset, startX, startY, deltaX, deltaY, offsetX, offsetY, direction, isVertical, isHorizontal, isTap, }; }