UNPKG

@gdjiami/hooks

Version:

react hooks for mygzb.com

187 lines (186 loc) 8.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = require("react"); var utils_1 = require("./utils"); var useInstance_1 = tslib_1.__importDefault(require("./useInstance")); var useRefState_1 = tslib_1.__importDefault(require("./useRefState")); /** * 获取抽象化的mouse/touch事件. 支持多点触摸 * TODO: 可配mouse * TODO: pasive * TODO: 过滤 * @param options */ function useMultiTouchGesture(options) { var el = options.ref || react_1.useRef(); var _a = tslib_1.__read(useRefState_1.default(false), 3), interacting = _a[0], setInteracting = _a[1], refInteracting = _a[2]; var _b = tslib_1.__read(useInstance_1.default({ touches: new Map(), }), 1), state = _b[0]; react_1.useEffect(function () { var getTouches = function () { return Array.from(state.touches.values()); }; var handleActionStart = function (event) { var coords = utils_1.extraPositions(event); if (coords.length === 0) { return; } var changedTouches = coords.map(function (i) { return (tslib_1.__assign(tslib_1.__assign({}, i), { 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({ touches: getTouches().concat(changedTouches), changedTouches: changedTouches, }) === false) { // prevented return; } event.stopPropagation(); event.preventDefault(); // save changedTouches.forEach(function (i) { state.touches.set(i.id, tslib_1.__assign(tslib_1.__assign({}, i), { start: i, previous: i })); }); if (options.onAction) { options.onAction(getTouches()); } if (refInteracting.current) { return; } setInteracting(true); /** * 处理移动 */ var handleActionMove = function (event) { if (!utils_1.isMouseEvent(event)) { event.preventDefault(); } var coords = utils_1.extraPositions(event); if (coords.length === 0) { return; } var changedTouches = coords .map(function (pos) { var savedTouch = state.touches.get(pos.id); if (savedTouch == null) { return null; } var start = savedTouch.start; var last = savedTouch; 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 velocity = delta / (timestamp - last.timestamp); return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, savedTouch), pos), { previous: savedTouch, timestamp: timestamp, deltaX: deltaX, deltaY: deltaY, delta: delta, distanceX: distanceX, distanceY: distanceY, distance: distance, velocity: velocity }); }) .filter(function (i) { return !!i; }); changedTouches.forEach(function (touch) { state.touches.set(touch.id, touch); }); if (options.onMove) { options.onMove({ changedTouches: changedTouches, touches: getTouches(), }); } if (options.onAction) { options.onAction(getTouches()); } }; if (utils_1.isMouseEvent(event)) { // mouse drive var clean = function (event) { // 鼠标事件只能有一个 document.removeEventListener('mousemove', handleActionMove); if (!refInteracting.current) { return; } var pos = utils_1.extraPositions(event); var savedTouch = state.touches.get(pos[0].id); var changedTouches = [ tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, savedTouch), pos[0]), { previous: savedTouch, timestamp: Date.now() }), ]; setInteracting(false); state.touches.clear(); state.touches.delete(pos[0].id); if (options.onUp) { options.onUp({ touches: [], changedTouches: changedTouches, }); } if (options.onAction) { options.onAction([]); } }; document.addEventListener('mousemove', handleActionMove); document.addEventListener('mouseup', clean, { once: true }); document.addEventListener('mouseleave', clean, { once: true }); } else { // touch drive var removeListener_1 = function () { el.current.removeEventListener('touchmove', handleActionMove); el.current.removeEventListener('touchend', clean_1); el.current.removeEventListener('touchcancel', clean_1); state.touches.clear(); }; var clean_1 = function (event) { if (!refInteracting.current) { removeListener_1(); return; } var coods = utils_1.extraPositions(event); if (coods.length === 0) { return; } var changedTouches = coods .map(function (pos) { var savedTouch = state.touches.get(pos.id); if (savedTouch === null) { return null; } return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, savedTouch), pos), { previous: savedTouch, timestamp: Date.now() }); }) .filter(function (i) { return !!i; }); changedTouches.forEach(function (i) { state.touches.delete(i.id); }); var currentTouches = getTouches(); if (options.onUp) { options.onUp({ touches: currentTouches, changedTouches: changedTouches }); } if (currentTouches.length === 0) { removeListener_1(); setInteracting(false); } }; el.current.addEventListener('touchmove', handleActionMove); el.current.addEventListener('touchend', clean_1); el.current.addEventListener('touchcancel', clean_1); } }; var useTouch = utils_1.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 }; } exports.default = useMultiTouchGesture;