@gdjiami/hooks
Version:
react hooks for mygzb.com
187 lines (186 loc) • 8.61 kB
JavaScript
;
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;