@havue/use-gesture-2-mouse
Version:
Gesture recognition hook for Vue3
502 lines (501 loc) • 17.5 kB
JavaScript
import { ref, computed, toValue, isRef, watch, onBeforeUnmount } from "vue";
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
function isObject$3(value) {
var type = typeof value;
return value != null && (type == "object" || type == "function");
}
var isObject_1 = isObject$3;
var freeGlobal$1 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
var _freeGlobal = freeGlobal$1;
var freeGlobal = _freeGlobal;
var freeSelf = typeof self == "object" && self && self.Object === Object && self;
var root$2 = freeGlobal || freeSelf || Function("return this")();
var _root = root$2;
var root$1 = _root;
var now$1 = function() {
return root$1.Date.now();
};
var now_1 = now$1;
var reWhitespace = /\s/;
function trimmedEndIndex$1(string) {
var index = string.length;
while (index-- && reWhitespace.test(string.charAt(index))) {
}
return index;
}
var _trimmedEndIndex = trimmedEndIndex$1;
var trimmedEndIndex = _trimmedEndIndex;
var reTrimStart = /^\s+/;
function baseTrim$1(string) {
return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string;
}
var _baseTrim = baseTrim$1;
var root = _root;
var Symbol$3 = root.Symbol;
var _Symbol = Symbol$3;
var Symbol$2 = _Symbol;
var objectProto$1 = Object.prototype;
var hasOwnProperty = objectProto$1.hasOwnProperty;
var nativeObjectToString$1 = objectProto$1.toString;
var symToStringTag$1 = Symbol$2 ? Symbol$2.toStringTag : void 0;
function getRawTag$1(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag$1), tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = void 0;
var unmasked = true;
} catch (e) {
}
var result = nativeObjectToString$1.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
var _getRawTag = getRawTag$1;
var objectProto = Object.prototype;
var nativeObjectToString = objectProto.toString;
function objectToString$1(value) {
return nativeObjectToString.call(value);
}
var _objectToString = objectToString$1;
var Symbol$1 = _Symbol, getRawTag = _getRawTag, objectToString = _objectToString;
var nullTag = "[object Null]", undefinedTag = "[object Undefined]";
var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : void 0;
function baseGetTag$1(value) {
if (value == null) {
return value === void 0 ? undefinedTag : nullTag;
}
return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
}
var _baseGetTag = baseGetTag$1;
function isObjectLike$1(value) {
return value != null && typeof value == "object";
}
var isObjectLike_1 = isObjectLike$1;
var baseGetTag = _baseGetTag, isObjectLike = isObjectLike_1;
var symbolTag = "[object Symbol]";
function isSymbol$1(value) {
return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag;
}
var isSymbol_1 = isSymbol$1;
var baseTrim = _baseTrim, isObject$2 = isObject_1, isSymbol = isSymbol_1;
var NAN = 0 / 0;
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
var reIsBinary = /^0b[01]+$/i;
var reIsOctal = /^0o[0-7]+$/i;
var freeParseInt = parseInt;
function toNumber$1(value) {
if (typeof value == "number") {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject$2(value)) {
var other = typeof value.valueOf == "function" ? value.valueOf() : value;
value = isObject$2(other) ? other + "" : other;
}
if (typeof value != "string") {
return value === 0 ? value : +value;
}
value = baseTrim(value);
var isBinary = reIsBinary.test(value);
return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
}
var toNumber_1 = toNumber$1;
var isObject$1 = isObject_1, now = now_1, toNumber = toNumber_1;
var FUNC_ERROR_TEXT$1 = "Expected a function";
var nativeMax = Math.max, nativeMin = Math.min;
function debounce$1(func, wait, options) {
var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
if (typeof func != "function") {
throw new TypeError(FUNC_ERROR_TEXT$1);
}
wait = toNumber(wait) || 0;
if (isObject$1(options)) {
leading = !!options.leading;
maxing = "maxWait" in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = "trailing" in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs, thisArg = lastThis;
lastArgs = lastThis = void 0;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
lastInvokeTime = time;
timerId = setTimeout(timerExpired, wait);
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall;
return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
}
function timerExpired() {
var time = now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = void 0;
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = void 0;
return result;
}
function cancel() {
if (timerId !== void 0) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = void 0;
}
function flush() {
return timerId === void 0 ? result : trailingEdge(now());
}
function debounced() {
var time = now(), isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === void 0) {
return leadingEdge(lastCallTime);
}
if (maxing) {
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === void 0) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
var debounce_1 = debounce$1;
var debounce = debounce_1, isObject = isObject_1;
var FUNC_ERROR_TEXT = "Expected a function";
function throttle(func, wait, options) {
var leading = true, trailing = true;
if (typeof func != "function") {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (isObject(options)) {
leading = "leading" in options ? !!options.leading : leading;
trailing = "trailing" in options ? !!options.trailing : trailing;
}
return debounce(func, wait, {
"leading": leading,
"maxWait": wait,
"trailing": trailing
});
}
var throttle_1 = throttle;
const throttle$1 = /* @__PURE__ */ getDefaultExportFromCjs(throttle_1);
function useGestrue2Mouse(target, options) {
let operateBoxRef = ref();
if (target) {
operateBoxRef = computed(() => {
return isRef(target) ? toValue(target) : target;
});
}
const rect = computed(() => {
const sizeOptions = (options == null ? void 0 : options.TargetRealSize) || void 0;
return isRef(sizeOptions) ? toValue(sizeOptions) : sizeOptions;
});
const isThrottleMoveEvent = typeof (options == null ? void 0 : options.throttle) === "object";
const _throttleOptions = computed(() => {
const throttleOptions = (options == null ? void 0 : options.throttle) || {};
return Object.assign(
{
wait: 0,
leading: true,
trailing: false
},
throttleOptions
);
});
let touchType = void 0;
let touchMovingCount = 0;
let touchStartPos = void 0;
let lastTouchPos = void 0;
let resetLastTouchPosTimer = null;
function handleTouchStart(e) {
var _a, _b, _c, _d;
resetLastTouchPosTimer && clearTimeout(resetLastTouchPosTimer);
resetLastTouchPosTimer = null;
if (!operateBoxRef.value || touchMovingCount > 0) {
return;
}
e.preventDefault();
document.body.addEventListener("touchmove", handleTouchMove);
document.body.addEventListener("touchend", handleTouchEnd);
const touchCount = e.touches.length;
touchType = touchCount === 1 ? "single" : touchCount === 2 ? "double" : void 0;
switch (touchType) {
case "single": {
const { clientX, clientY } = e.touches[0];
const pos = transformMousePosToTargetPos(
clientX,
clientY,
operateBoxRef.value,
(_a = rect.value) == null ? void 0 : _a.width,
(_b = rect.value) == null ? void 0 : _b.height
);
if (lastTouchPos && Math.abs(lastTouchPos.x - pos.x) < 30 && Math.abs(lastTouchPos.y - pos.y) < 30) {
touchStartPos = lastTouchPos;
} else {
touchStartPos = pos;
lastTouchPos = pos;
}
break;
}
case "double": {
const [{ clientX: x1, clientY: y1 }, { clientX: x2, clientY: y2 }] = e.touches;
const x = (x1 + x2) / 2;
const y = (y1 + y2) / 2;
const pos = transformMousePosToTargetPos(x, y, operateBoxRef.value, (_c = rect.value) == null ? void 0 : _c.width, (_d = rect.value) == null ? void 0 : _d.height);
touchStartPos = pos;
lastTouchPos = pos;
break;
}
}
}
const touchMoveFn = (e) => {
var _a, _b, _c, _d;
if (!operateBoxRef.value) {
return;
}
switch (touchType) {
case "single": {
const { clientX, clientY } = e.touches[0];
const pos = transformMousePosToTargetPos(
clientX,
clientY,
operateBoxRef.value,
(_a = rect.value) == null ? void 0 : _a.width,
(_b = rect.value) == null ? void 0 : _b.height
);
lastTouchPos = pos;
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos, "left");
break;
}
case "double": {
const [{ clientX: x1, clientY: y1 }, { clientX: x2, clientY: y2 }] = e.touches;
const x = (x1 + x2) / 2;
const y = (y1 + y2) / 2;
const pos = transformMousePosToTargetPos(x, y, operateBoxRef.value, (_c = rect.value) == null ? void 0 : _c.width, (_d = rect.value) == null ? void 0 : _d.height);
let deltaY = 0;
if (lastTouchPos) {
deltaY = lastTouchPos.y - pos.y;
}
lastTouchPos = pos;
(options == null ? void 0 : options.onMouseWheel) && options.onMouseWheel(touchStartPos, deltaY);
break;
}
}
};
const onTouchMove = isThrottleMoveEvent ? throttle$1(touchMoveFn, _throttleOptions.value.wait || 0, {
leading: _throttleOptions.value.leading,
trailing: _throttleOptions.value.trailing
}) : touchMoveFn;
function handleTouchMove(e) {
e.preventDefault();
if (!touchType || !operateBoxRef.value) {
return;
}
touchMovingCount++;
onTouchMove(e);
}
function handleTouchEnd() {
document.body.removeEventListener("touchmove", handleTouchMove);
document.body.removeEventListener("touchend", handleTouchEnd);
if (!operateBoxRef.value) {
return;
}
if (lastTouchPos) {
const pos = lastTouchPos;
switch (touchType) {
case "single": {
if (touchMovingCount <= 2) {
Promise.resolve((options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos, "left")).then(
() => (options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos)
);
} else {
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos);
}
break;
}
case "double": {
if (touchMovingCount <= 2) {
Promise.resolve((options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos, "right")).then(
() => (options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos)
);
} else {
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos);
}
break;
}
}
}
touchMovingCount = 0;
touchType = void 0;
touchStartPos = void 0;
resetLastTouchPosTimer = setTimeout(() => {
lastTouchPos = void 0;
resetLastTouchPosTimer = null;
}, 300);
}
let isMouseDown = false;
function handleMouseDown(e) {
e.preventDefault();
if (!operateBoxRef.value) {
return;
}
document.body.addEventListener("mousemove", handleMouseMove);
document.body.addEventListener("mouseup", handleMouseUp);
isMouseDown = true;
handleMouseEvent(e);
}
const mouseMoveFn = handleMouseEvent;
const onMouseMove = isThrottleMoveEvent ? throttle$1(mouseMoveFn, _throttleOptions.value.wait, {
leading: _throttleOptions.value.leading,
trailing: _throttleOptions.value.trailing
}) : mouseMoveFn;
function handleMouseMove(e) {
if (!operateBoxRef.value || !isMouseDown) {
return;
}
onMouseMove(e);
}
function handleMouseUp(e) {
document.body.removeEventListener("mousemove", handleMouseMove);
document.body.removeEventListener("mouseup", handleMouseUp);
if (!operateBoxRef.value) {
return;
}
isMouseDown = false;
handleMouseEvent(e);
}
function handleMouseEvent(e) {
var _a, _b;
if (!operateBoxRef.value) {
return;
}
const { clientX, clientY } = e;
const pos = transformMousePosToTargetPos(
clientX,
clientY,
operateBoxRef.value,
(_a = rect.value) == null ? void 0 : _a.width,
(_b = rect.value) == null ? void 0 : _b.height
);
if ((e.buttons & 2) !== 0) {
e.preventDefault();
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos, "right");
} else if ((e.buttons & 1) !== 0) {
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos, "left");
} else if ((e.buttons & 4) !== 0) {
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos, "middle");
} else {
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos);
}
}
function handleWheel(e) {
var _a, _b;
e.preventDefault();
if (!operateBoxRef.value) {
return;
}
const { clientX, clientY } = e;
const pos = transformMousePosToTargetPos(
clientX,
clientY,
operateBoxRef.value,
(_a = rect.value) == null ? void 0 : _a.width,
(_b = rect.value) == null ? void 0 : _b.height
);
Promise.resolve((options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos)).then(() => (options == null ? void 0 : options.onMouseWheel) && options.onMouseWheel(pos, e.deltaY)).then(() => {
(options == null ? void 0 : options.onMouseEvent) && options.onMouseEvent(pos);
});
}
function preventDefaultEvent(event) {
event.preventDefault();
}
watch(
() => operateBoxRef.value,
() => {
if (!operateBoxRef.value) {
return;
}
operateBoxRef.value.addEventListener("touchstart", handleTouchStart);
operateBoxRef.value.addEventListener("mousedown", handleMouseDown);
operateBoxRef.value.addEventListener("wheel", handleWheel);
operateBoxRef.value.addEventListener("contextmenu", preventDefaultEvent);
}
);
onBeforeUnmount(() => {
if (!operateBoxRef.value) {
return;
}
operateBoxRef.value.removeEventListener("touchstart", handleTouchStart);
document.body.removeEventListener("touchmove", handleTouchMove);
document.body.removeEventListener("touchend", handleTouchEnd);
operateBoxRef.value.removeEventListener("mousedown", handleMouseDown);
document.body.removeEventListener("mousemove", handleMouseMove);
document.body.removeEventListener("mouseup", handleMouseUp);
operateBoxRef.value.removeEventListener("wheel", handleWheel);
operateBoxRef.value.removeEventListener("contextmenu", preventDefaultEvent);
});
return {
operateBoxRef
};
}
function transformMousePosToTargetPos(x, y, el, targetWidth, targetHeight) {
const rect = el == null ? void 0 : el.getBoundingClientRect();
if (!rect) {
return { elX: 0, elY: 0, x: 0, y: 0 };
}
const { top, left, width: elWidth, height: elHeight } = rect;
targetWidth = targetWidth || elWidth;
targetHeight = targetHeight || elHeight;
let elX = x;
let elY = y;
elX = x < left ? 0 : x > left + elWidth ? elWidth : x - left;
elY = y < top ? 0 : y > top + elHeight ? elHeight : y - top;
const scaleX = elWidth !== 0 ? targetWidth / elWidth : 0;
const scaleY = elHeight !== 0 ? targetHeight / elHeight : 0;
const targetX = elX * scaleX;
const targetY = elY * scaleY;
return {
elX,
elY,
x: Math.round(targetX),
y: Math.round(targetY)
};
}
export {
useGestrue2Mouse
};