UNPKG

@gdjiami/hooks

Version:

react hooks for mygzb.com

195 lines (166 loc) 5.04 kB
import _extends from "@babel/runtime/helpers/esm/extends"; 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 _useRefState = useRefState(false), interacting = _useRefState[0], setInteracting = _useRefState[1], refInteracting = _useRefState[2]; var _useInstance = useInstance({}), state = _useInstance[0], updateState = _useInstance[1]; useEffect(function () { var handleActionStart = function handleActionStart(event) { var pos = extraPosition(event); if (pos == null) { return; } var coord = _extends({}, 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 handleActionMove(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 = _extends({}, 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 handleActionEnd(event) { if (!refInteracting.current) { return; } var pos = extraPosition(event, state.start && state.start.id); var coord = _extends({}, 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 clean(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 _clean(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 }; }