UNPKG

@gdjiami/hooks

Version:

react hooks for mygzb.com

115 lines (114 loc) 5.31 kB
import { __assign, __read } from "tslib"; import { useRef, useEffect } from 'react'; import { TOUCH_SUPPROTED, extraPosition, isMouseEvent, } from './utils'; import useInstance from './useInstance'; import useRefState from './useRefState'; /** * 获取抽象化的mouse/touch事件 * TODO: pasive * @param options */ export default function useGesture(options) { var el = options.ref || useRef(); var _a = __read(useRefState(false), 3), interacting = _a[0], setInteracting = _a[1], refInteracting = _a[2]; var _b = __read(useInstance({}), 2), state = _b[0], updateState = _b[1]; useEffect(function () { var handleActionStart = function (event) { var pos = extraPosition(event); if (pos == null) { return; } var coord = __assign(__assign({}, pos), { timestamp: Date.now(), target: el.current, delta: 0, deltaX: 0, deltaY: 0, distance: 0, distanceX: 0, distanceY: 0, velocity: 0 }); if (options.onDown != null && options.onDown(coord) === false) { // prevented return; } event.stopPropagation(); event.preventDefault(); if (options.onAction) { options.onAction({ down: true, first: true, coordinate: coord }); } updateState({ start: coord, last: coord }); setInteracting(true); /** * 处理移动 */ var handleActionMove = function (event) { if (!isMouseEvent(event)) { event.preventDefault(); } var pos = extraPosition(event, state.start && state.start.id); if (pos == null) { return; } var start = state.start; var last = state.last; var deltaX = pos.pageX - last.pageX; var deltaY = pos.pageY - last.pageY; var delta = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); var distanceX = pos.pageX - start.pageX; var distanceY = pos.pageY - start.pageY; var distance = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2)); var timestamp = Date.now(); var coord = __assign(__assign({}, pos), { start: start, previous: last, timestamp: timestamp, deltaX: deltaX, deltaY: deltaY, delta: delta, distanceX: distanceX, distanceY: distanceY, distance: distance, velocity: delta / (timestamp - last.timestamp), target: el.current }); if (options.onMove) { options.onMove(coord); } if (options.onAction) { options.onAction({ down: true, first: false, coordinate: coord }); } updateState({ last: coord }); }; /** * 动作结束 */ var handleActionEnd = function (event) { if (!refInteracting.current) { return; } var pos = extraPosition(event, state.start && state.start.id); var coord = __assign(__assign(__assign({}, state.last), pos), { timestamp: Date.now(), target: el.current, start: state.start, last: state.last }); setInteracting(false); if (options.onUp) { options.onUp(coord); } if (options.onAction) { options.onAction({ down: false, first: false, coordinate: coord }); } }; if (isMouseEvent(event)) { var clean = function (event) { document.removeEventListener('mousemove', handleActionMove); handleActionEnd(event); }; document.addEventListener('mousemove', handleActionMove); document.addEventListener('mouseup', clean, { once: true }); document.addEventListener('mouseleave', clean, { once: true }); } else { var clean = function (event) { el.current.removeEventListener('touchmove', handleActionMove); handleActionEnd(event); }; el.current.addEventListener('touchmove', handleActionMove); el.current.addEventListener('touchend', clean, { once: true }); el.current.addEventListener('touchcancel', clean, { once: true }); } }; var useTouch = TOUCH_SUPPROTED; el.current.addEventListener('mousedown', handleActionStart); useTouch && el.current.addEventListener('touchstart', handleActionStart); return function () { el.current.removeEventListener('mousedown', handleActionStart); useTouch && el.current.removeEventListener('touchstart', handleActionStart); }; }, []); return { ref: el, interacting: interacting }; }