1495 lines
46 KiB
JavaScript
1495 lines
46 KiB
JavaScript
'use strict';
|
|
|
|
var maths = require('./maths-267f0992.cjs.dev.js');
|
|
|
|
function _toPrimitive(input, hint) {
|
|
if (typeof input !== "object" || input === null) return input;
|
|
var prim = input[Symbol.toPrimitive];
|
|
if (prim !== undefined) {
|
|
var res = prim.call(input, hint || "default");
|
|
if (typeof res !== "object") return res;
|
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
}
|
|
return (hint === "string" ? String : Number)(input);
|
|
}
|
|
|
|
function _toPropertyKey(arg) {
|
|
var key = _toPrimitive(arg, "string");
|
|
return typeof key === "symbol" ? key : String(key);
|
|
}
|
|
|
|
function _defineProperty(obj, key, value) {
|
|
key = _toPropertyKey(key);
|
|
if (key in obj) {
|
|
Object.defineProperty(obj, key, {
|
|
value: value,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
} else {
|
|
obj[key] = value;
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
function ownKeys(e, r) {
|
|
var t = Object.keys(e);
|
|
if (Object.getOwnPropertySymbols) {
|
|
var o = Object.getOwnPropertySymbols(e);
|
|
r && (o = o.filter(function (r) {
|
|
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
})), t.push.apply(t, o);
|
|
}
|
|
return t;
|
|
}
|
|
function _objectSpread2(e) {
|
|
for (var r = 1; r < arguments.length; r++) {
|
|
var t = null != arguments[r] ? arguments[r] : {};
|
|
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
_defineProperty(e, r, t[r]);
|
|
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
});
|
|
}
|
|
return e;
|
|
}
|
|
|
|
const EVENT_TYPE_MAP = {
|
|
pointer: {
|
|
start: 'down',
|
|
change: 'move',
|
|
end: 'up'
|
|
},
|
|
mouse: {
|
|
start: 'down',
|
|
change: 'move',
|
|
end: 'up'
|
|
},
|
|
touch: {
|
|
start: 'start',
|
|
change: 'move',
|
|
end: 'end'
|
|
},
|
|
gesture: {
|
|
start: 'start',
|
|
change: 'change',
|
|
end: 'end'
|
|
}
|
|
};
|
|
function capitalize(string) {
|
|
if (!string) return '';
|
|
return string[0].toUpperCase() + string.slice(1);
|
|
}
|
|
const actionsWithoutCaptureSupported = ['enter', 'leave'];
|
|
function hasCapture(capture = false, actionKey) {
|
|
return capture && !actionsWithoutCaptureSupported.includes(actionKey);
|
|
}
|
|
function toHandlerProp(device, action = '', capture = false) {
|
|
const deviceProps = EVENT_TYPE_MAP[device];
|
|
const actionKey = deviceProps ? deviceProps[action] || action : action;
|
|
return 'on' + capitalize(device) + capitalize(actionKey) + (hasCapture(capture, actionKey) ? 'Capture' : '');
|
|
}
|
|
const pointerCaptureEvents = ['gotpointercapture', 'lostpointercapture'];
|
|
function parseProp(prop) {
|
|
let eventKey = prop.substring(2).toLowerCase();
|
|
const passive = !!~eventKey.indexOf('passive');
|
|
if (passive) eventKey = eventKey.replace('passive', '');
|
|
const captureKey = pointerCaptureEvents.includes(eventKey) ? 'capturecapture' : 'capture';
|
|
const capture = !!~eventKey.indexOf(captureKey);
|
|
if (capture) eventKey = eventKey.replace('capture', '');
|
|
return {
|
|
device: eventKey,
|
|
capture,
|
|
passive
|
|
};
|
|
}
|
|
function toDomEventType(device, action = '') {
|
|
const deviceProps = EVENT_TYPE_MAP[device];
|
|
const actionKey = deviceProps ? deviceProps[action] || action : action;
|
|
return device + actionKey;
|
|
}
|
|
function isTouch(event) {
|
|
return 'touches' in event;
|
|
}
|
|
function getPointerType(event) {
|
|
if (isTouch(event)) return 'touch';
|
|
if ('pointerType' in event) return event.pointerType;
|
|
return 'mouse';
|
|
}
|
|
function getCurrentTargetTouchList(event) {
|
|
return Array.from(event.touches).filter(e => {
|
|
var _event$currentTarget, _event$currentTarget$;
|
|
return e.target === event.currentTarget || ((_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 || (_event$currentTarget$ = _event$currentTarget.contains) === null || _event$currentTarget$ === void 0 ? void 0 : _event$currentTarget$.call(_event$currentTarget, e.target));
|
|
});
|
|
}
|
|
function getTouchList(event) {
|
|
return event.type === 'touchend' || event.type === 'touchcancel' ? event.changedTouches : event.targetTouches;
|
|
}
|
|
function getValueEvent(event) {
|
|
return isTouch(event) ? getTouchList(event)[0] : event;
|
|
}
|
|
function distanceAngle(P1, P2) {
|
|
try {
|
|
const dx = P2.clientX - P1.clientX;
|
|
const dy = P2.clientY - P1.clientY;
|
|
const cx = (P2.clientX + P1.clientX) / 2;
|
|
const cy = (P2.clientY + P1.clientY) / 2;
|
|
const distance = Math.hypot(dx, dy);
|
|
const angle = -(Math.atan2(dx, dy) * 180) / Math.PI;
|
|
const origin = [cx, cy];
|
|
return {
|
|
angle,
|
|
distance,
|
|
origin
|
|
};
|
|
} catch (_unused) {}
|
|
return null;
|
|
}
|
|
function touchIds(event) {
|
|
return getCurrentTargetTouchList(event).map(touch => touch.identifier);
|
|
}
|
|
function touchDistanceAngle(event, ids) {
|
|
const [P1, P2] = Array.from(event.touches).filter(touch => ids.includes(touch.identifier));
|
|
return distanceAngle(P1, P2);
|
|
}
|
|
function pointerId(event) {
|
|
const valueEvent = getValueEvent(event);
|
|
return isTouch(event) ? valueEvent.identifier : valueEvent.pointerId;
|
|
}
|
|
function pointerValues(event) {
|
|
const valueEvent = getValueEvent(event);
|
|
return [valueEvent.clientX, valueEvent.clientY];
|
|
}
|
|
const LINE_HEIGHT = 40;
|
|
const PAGE_HEIGHT = 800;
|
|
function wheelValues(event) {
|
|
let {
|
|
deltaX,
|
|
deltaY,
|
|
deltaMode
|
|
} = event;
|
|
if (deltaMode === 1) {
|
|
deltaX *= LINE_HEIGHT;
|
|
deltaY *= LINE_HEIGHT;
|
|
} else if (deltaMode === 2) {
|
|
deltaX *= PAGE_HEIGHT;
|
|
deltaY *= PAGE_HEIGHT;
|
|
}
|
|
return [deltaX, deltaY];
|
|
}
|
|
function scrollValues(event) {
|
|
var _ref, _ref2;
|
|
const {
|
|
scrollX,
|
|
scrollY,
|
|
scrollLeft,
|
|
scrollTop
|
|
} = event.currentTarget;
|
|
return [(_ref = scrollX !== null && scrollX !== void 0 ? scrollX : scrollLeft) !== null && _ref !== void 0 ? _ref : 0, (_ref2 = scrollY !== null && scrollY !== void 0 ? scrollY : scrollTop) !== null && _ref2 !== void 0 ? _ref2 : 0];
|
|
}
|
|
function getEventDetails(event) {
|
|
const payload = {};
|
|
if ('buttons' in event) payload.buttons = event.buttons;
|
|
if ('shiftKey' in event) {
|
|
const {
|
|
shiftKey,
|
|
altKey,
|
|
metaKey,
|
|
ctrlKey
|
|
} = event;
|
|
Object.assign(payload, {
|
|
shiftKey,
|
|
altKey,
|
|
metaKey,
|
|
ctrlKey
|
|
});
|
|
}
|
|
return payload;
|
|
}
|
|
|
|
function call(v, ...args) {
|
|
if (typeof v === 'function') {
|
|
return v(...args);
|
|
} else {
|
|
return v;
|
|
}
|
|
}
|
|
function noop() {}
|
|
function chain(...fns) {
|
|
if (fns.length === 0) return noop;
|
|
if (fns.length === 1) return fns[0];
|
|
return function () {
|
|
let result;
|
|
for (const fn of fns) {
|
|
result = fn.apply(this, arguments) || result;
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
function assignDefault(value, fallback) {
|
|
return Object.assign({}, fallback, value || {});
|
|
}
|
|
|
|
const BEFORE_LAST_KINEMATICS_DELAY = 32;
|
|
class Engine {
|
|
constructor(ctrl, args, key) {
|
|
this.ctrl = ctrl;
|
|
this.args = args;
|
|
this.key = key;
|
|
if (!this.state) {
|
|
this.state = {};
|
|
this.computeValues([0, 0]);
|
|
this.computeInitial();
|
|
if (this.init) this.init();
|
|
this.reset();
|
|
}
|
|
}
|
|
get state() {
|
|
return this.ctrl.state[this.key];
|
|
}
|
|
set state(state) {
|
|
this.ctrl.state[this.key] = state;
|
|
}
|
|
get shared() {
|
|
return this.ctrl.state.shared;
|
|
}
|
|
get eventStore() {
|
|
return this.ctrl.gestureEventStores[this.key];
|
|
}
|
|
get timeoutStore() {
|
|
return this.ctrl.gestureTimeoutStores[this.key];
|
|
}
|
|
get config() {
|
|
return this.ctrl.config[this.key];
|
|
}
|
|
get sharedConfig() {
|
|
return this.ctrl.config.shared;
|
|
}
|
|
get handler() {
|
|
return this.ctrl.handlers[this.key];
|
|
}
|
|
reset() {
|
|
const {
|
|
state,
|
|
shared,
|
|
ingKey,
|
|
args
|
|
} = this;
|
|
shared[ingKey] = state._active = state.active = state._blocked = state._force = false;
|
|
state._step = [false, false];
|
|
state.intentional = false;
|
|
state._movement = [0, 0];
|
|
state._distance = [0, 0];
|
|
state._direction = [0, 0];
|
|
state._delta = [0, 0];
|
|
state._bounds = [[-Infinity, Infinity], [-Infinity, Infinity]];
|
|
state.args = args;
|
|
state.axis = undefined;
|
|
state.memo = undefined;
|
|
state.elapsedTime = state.timeDelta = 0;
|
|
state.direction = [0, 0];
|
|
state.distance = [0, 0];
|
|
state.overflow = [0, 0];
|
|
state._movementBound = [false, false];
|
|
state.velocity = [0, 0];
|
|
state.movement = [0, 0];
|
|
state.delta = [0, 0];
|
|
state.timeStamp = 0;
|
|
}
|
|
start(event) {
|
|
const state = this.state;
|
|
const config = this.config;
|
|
if (!state._active) {
|
|
this.reset();
|
|
this.computeInitial();
|
|
state._active = true;
|
|
state.target = event.target;
|
|
state.currentTarget = event.currentTarget;
|
|
state.lastOffset = config.from ? call(config.from, state) : state.offset;
|
|
state.offset = state.lastOffset;
|
|
state.startTime = state.timeStamp = event.timeStamp;
|
|
}
|
|
}
|
|
computeValues(values) {
|
|
const state = this.state;
|
|
state._values = values;
|
|
state.values = this.config.transform(values);
|
|
}
|
|
computeInitial() {
|
|
const state = this.state;
|
|
state._initial = state._values;
|
|
state.initial = state.values;
|
|
}
|
|
compute(event) {
|
|
const {
|
|
state,
|
|
config,
|
|
shared
|
|
} = this;
|
|
state.args = this.args;
|
|
let dt = 0;
|
|
if (event) {
|
|
state.event = event;
|
|
if (config.preventDefault && event.cancelable) state.event.preventDefault();
|
|
state.type = event.type;
|
|
shared.touches = this.ctrl.pointerIds.size || this.ctrl.touchIds.size;
|
|
shared.locked = !!document.pointerLockElement;
|
|
Object.assign(shared, getEventDetails(event));
|
|
shared.down = shared.pressed = shared.buttons % 2 === 1 || shared.touches > 0;
|
|
dt = event.timeStamp - state.timeStamp;
|
|
state.timeStamp = event.timeStamp;
|
|
state.elapsedTime = state.timeStamp - state.startTime;
|
|
}
|
|
if (state._active) {
|
|
const _absoluteDelta = state._delta.map(Math.abs);
|
|
maths.V.addTo(state._distance, _absoluteDelta);
|
|
}
|
|
if (this.axisIntent) this.axisIntent(event);
|
|
const [_m0, _m1] = state._movement;
|
|
const [t0, t1] = config.threshold;
|
|
const {
|
|
_step,
|
|
values
|
|
} = state;
|
|
if (config.hasCustomTransform) {
|
|
if (_step[0] === false) _step[0] = Math.abs(_m0) >= t0 && values[0];
|
|
if (_step[1] === false) _step[1] = Math.abs(_m1) >= t1 && values[1];
|
|
} else {
|
|
if (_step[0] === false) _step[0] = Math.abs(_m0) >= t0 && Math.sign(_m0) * t0;
|
|
if (_step[1] === false) _step[1] = Math.abs(_m1) >= t1 && Math.sign(_m1) * t1;
|
|
}
|
|
state.intentional = _step[0] !== false || _step[1] !== false;
|
|
if (!state.intentional) return;
|
|
const movement = [0, 0];
|
|
if (config.hasCustomTransform) {
|
|
const [v0, v1] = values;
|
|
movement[0] = _step[0] !== false ? v0 - _step[0] : 0;
|
|
movement[1] = _step[1] !== false ? v1 - _step[1] : 0;
|
|
} else {
|
|
movement[0] = _step[0] !== false ? _m0 - _step[0] : 0;
|
|
movement[1] = _step[1] !== false ? _m1 - _step[1] : 0;
|
|
}
|
|
if (this.restrictToAxis && !state._blocked) this.restrictToAxis(movement);
|
|
const previousOffset = state.offset;
|
|
const gestureIsActive = state._active && !state._blocked || state.active;
|
|
if (gestureIsActive) {
|
|
state.first = state._active && !state.active;
|
|
state.last = !state._active && state.active;
|
|
state.active = shared[this.ingKey] = state._active;
|
|
if (event) {
|
|
if (state.first) {
|
|
if ('bounds' in config) state._bounds = call(config.bounds, state);
|
|
if (this.setup) this.setup();
|
|
}
|
|
state.movement = movement;
|
|
this.computeOffset();
|
|
}
|
|
}
|
|
const [ox, oy] = state.offset;
|
|
const [[x0, x1], [y0, y1]] = state._bounds;
|
|
state.overflow = [ox < x0 ? -1 : ox > x1 ? 1 : 0, oy < y0 ? -1 : oy > y1 ? 1 : 0];
|
|
state._movementBound[0] = state.overflow[0] ? state._movementBound[0] === false ? state._movement[0] : state._movementBound[0] : false;
|
|
state._movementBound[1] = state.overflow[1] ? state._movementBound[1] === false ? state._movement[1] : state._movementBound[1] : false;
|
|
const rubberband = state._active ? config.rubberband || [0, 0] : [0, 0];
|
|
state.offset = maths.computeRubberband(state._bounds, state.offset, rubberband);
|
|
state.delta = maths.V.sub(state.offset, previousOffset);
|
|
this.computeMovement();
|
|
if (gestureIsActive && (!state.last || dt > BEFORE_LAST_KINEMATICS_DELAY)) {
|
|
state.delta = maths.V.sub(state.offset, previousOffset);
|
|
const absoluteDelta = state.delta.map(Math.abs);
|
|
maths.V.addTo(state.distance, absoluteDelta);
|
|
state.direction = state.delta.map(Math.sign);
|
|
state._direction = state._delta.map(Math.sign);
|
|
if (!state.first && dt > 0) {
|
|
state.velocity = [absoluteDelta[0] / dt, absoluteDelta[1] / dt];
|
|
state.timeDelta = dt;
|
|
}
|
|
}
|
|
}
|
|
emit() {
|
|
const state = this.state;
|
|
const shared = this.shared;
|
|
const config = this.config;
|
|
if (!state._active) this.clean();
|
|
if ((state._blocked || !state.intentional) && !state._force && !config.triggerAllEvents) return;
|
|
const memo = this.handler(_objectSpread2(_objectSpread2(_objectSpread2({}, shared), state), {}, {
|
|
[this.aliasKey]: state.values
|
|
}));
|
|
if (memo !== undefined) state.memo = memo;
|
|
}
|
|
clean() {
|
|
this.eventStore.clean();
|
|
this.timeoutStore.clean();
|
|
}
|
|
}
|
|
|
|
function selectAxis([dx, dy], threshold) {
|
|
const absDx = Math.abs(dx);
|
|
const absDy = Math.abs(dy);
|
|
if (absDx > absDy && absDx > threshold) {
|
|
return 'x';
|
|
}
|
|
if (absDy > absDx && absDy > threshold) {
|
|
return 'y';
|
|
}
|
|
return undefined;
|
|
}
|
|
class CoordinatesEngine extends Engine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "aliasKey", 'xy');
|
|
}
|
|
reset() {
|
|
super.reset();
|
|
this.state.axis = undefined;
|
|
}
|
|
init() {
|
|
this.state.offset = [0, 0];
|
|
this.state.lastOffset = [0, 0];
|
|
}
|
|
computeOffset() {
|
|
this.state.offset = maths.V.add(this.state.lastOffset, this.state.movement);
|
|
}
|
|
computeMovement() {
|
|
this.state.movement = maths.V.sub(this.state.offset, this.state.lastOffset);
|
|
}
|
|
axisIntent(event) {
|
|
const state = this.state;
|
|
const config = this.config;
|
|
if (!state.axis && event) {
|
|
const threshold = typeof config.axisThreshold === 'object' ? config.axisThreshold[getPointerType(event)] : config.axisThreshold;
|
|
state.axis = selectAxis(state._movement, threshold);
|
|
}
|
|
state._blocked = (config.lockDirection || !!config.axis) && !state.axis || !!config.axis && config.axis !== state.axis;
|
|
}
|
|
restrictToAxis(v) {
|
|
if (this.config.axis || this.config.lockDirection) {
|
|
switch (this.state.axis) {
|
|
case 'x':
|
|
v[1] = 0;
|
|
break;
|
|
case 'y':
|
|
v[0] = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const identity = v => v;
|
|
const DEFAULT_RUBBERBAND = 0.15;
|
|
const commonConfigResolver = {
|
|
enabled(value = true) {
|
|
return value;
|
|
},
|
|
eventOptions(value, _k, config) {
|
|
return _objectSpread2(_objectSpread2({}, config.shared.eventOptions), value);
|
|
},
|
|
preventDefault(value = false) {
|
|
return value;
|
|
},
|
|
triggerAllEvents(value = false) {
|
|
return value;
|
|
},
|
|
rubberband(value = 0) {
|
|
switch (value) {
|
|
case true:
|
|
return [DEFAULT_RUBBERBAND, DEFAULT_RUBBERBAND];
|
|
case false:
|
|
return [0, 0];
|
|
default:
|
|
return maths.V.toVector(value);
|
|
}
|
|
},
|
|
from(value) {
|
|
if (typeof value === 'function') return value;
|
|
if (value != null) return maths.V.toVector(value);
|
|
},
|
|
transform(value, _k, config) {
|
|
const transform = value || config.shared.transform;
|
|
this.hasCustomTransform = !!transform;
|
|
if (process.env.NODE_ENV === 'development') {
|
|
const originalTransform = transform || identity;
|
|
return v => {
|
|
const r = originalTransform(v);
|
|
if (!isFinite(r[0]) || !isFinite(r[1])) {
|
|
console.warn(`[@use-gesture]: config.transform() must produce a valid result, but it was: [${r[0]},${[1]}]`);
|
|
}
|
|
return r;
|
|
};
|
|
}
|
|
return transform || identity;
|
|
},
|
|
threshold(value) {
|
|
return maths.V.toVector(value, 0);
|
|
}
|
|
};
|
|
if (process.env.NODE_ENV === 'development') {
|
|
Object.assign(commonConfigResolver, {
|
|
domTarget(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`);
|
|
}
|
|
return NaN;
|
|
},
|
|
lockDirection(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`lockDirection\` option has been merged with \`axis\`. Use it as in \`{ axis: 'lock' }\``);
|
|
}
|
|
return NaN;
|
|
},
|
|
initial(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`initial\` option has been renamed to \`from\`.`);
|
|
}
|
|
return NaN;
|
|
}
|
|
});
|
|
}
|
|
|
|
const DEFAULT_AXIS_THRESHOLD = 0;
|
|
const coordinatesConfigResolver = _objectSpread2(_objectSpread2({}, commonConfigResolver), {}, {
|
|
axis(_v, _k, {
|
|
axis
|
|
}) {
|
|
this.lockDirection = axis === 'lock';
|
|
if (!this.lockDirection) return axis;
|
|
},
|
|
axisThreshold(value = DEFAULT_AXIS_THRESHOLD) {
|
|
return value;
|
|
},
|
|
bounds(value = {}) {
|
|
if (typeof value === 'function') {
|
|
return state => coordinatesConfigResolver.bounds(value(state));
|
|
}
|
|
if ('current' in value) {
|
|
return () => value.current;
|
|
}
|
|
if (typeof HTMLElement === 'function' && value instanceof HTMLElement) {
|
|
return value;
|
|
}
|
|
const {
|
|
left = -Infinity,
|
|
right = Infinity,
|
|
top = -Infinity,
|
|
bottom = Infinity
|
|
} = value;
|
|
return [[left, right], [top, bottom]];
|
|
}
|
|
});
|
|
|
|
const KEYS_DELTA_MAP = {
|
|
ArrowRight: (displacement, factor = 1) => [displacement * factor, 0],
|
|
ArrowLeft: (displacement, factor = 1) => [-1 * displacement * factor, 0],
|
|
ArrowUp: (displacement, factor = 1) => [0, -1 * displacement * factor],
|
|
ArrowDown: (displacement, factor = 1) => [0, displacement * factor]
|
|
};
|
|
class DragEngine extends CoordinatesEngine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "ingKey", 'dragging');
|
|
}
|
|
reset() {
|
|
super.reset();
|
|
const state = this.state;
|
|
state._pointerId = undefined;
|
|
state._pointerActive = false;
|
|
state._keyboardActive = false;
|
|
state._preventScroll = false;
|
|
state._delayed = false;
|
|
state.swipe = [0, 0];
|
|
state.tap = false;
|
|
state.canceled = false;
|
|
state.cancel = this.cancel.bind(this);
|
|
}
|
|
setup() {
|
|
const state = this.state;
|
|
if (state._bounds instanceof HTMLElement) {
|
|
const boundRect = state._bounds.getBoundingClientRect();
|
|
const targetRect = state.currentTarget.getBoundingClientRect();
|
|
const _bounds = {
|
|
left: boundRect.left - targetRect.left + state.offset[0],
|
|
right: boundRect.right - targetRect.right + state.offset[0],
|
|
top: boundRect.top - targetRect.top + state.offset[1],
|
|
bottom: boundRect.bottom - targetRect.bottom + state.offset[1]
|
|
};
|
|
state._bounds = coordinatesConfigResolver.bounds(_bounds);
|
|
}
|
|
}
|
|
cancel() {
|
|
const state = this.state;
|
|
if (state.canceled) return;
|
|
state.canceled = true;
|
|
state._active = false;
|
|
setTimeout(() => {
|
|
this.compute();
|
|
this.emit();
|
|
}, 0);
|
|
}
|
|
setActive() {
|
|
this.state._active = this.state._pointerActive || this.state._keyboardActive;
|
|
}
|
|
clean() {
|
|
this.pointerClean();
|
|
this.state._pointerActive = false;
|
|
this.state._keyboardActive = false;
|
|
super.clean();
|
|
}
|
|
pointerDown(event) {
|
|
const config = this.config;
|
|
const state = this.state;
|
|
if (event.buttons != null && (Array.isArray(config.pointerButtons) ? !config.pointerButtons.includes(event.buttons) : config.pointerButtons !== -1 && config.pointerButtons !== event.buttons)) return;
|
|
const ctrlIds = this.ctrl.setEventIds(event);
|
|
if (config.pointerCapture) {
|
|
event.target.setPointerCapture(event.pointerId);
|
|
}
|
|
if (ctrlIds && ctrlIds.size > 1 && state._pointerActive) return;
|
|
this.start(event);
|
|
this.setupPointer(event);
|
|
state._pointerId = pointerId(event);
|
|
state._pointerActive = true;
|
|
this.computeValues(pointerValues(event));
|
|
this.computeInitial();
|
|
if (config.preventScrollAxis && getPointerType(event) !== 'mouse') {
|
|
state._active = false;
|
|
this.setupScrollPrevention(event);
|
|
} else if (config.delay > 0) {
|
|
this.setupDelayTrigger(event);
|
|
if (config.triggerAllEvents) {
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
} else {
|
|
this.startPointerDrag(event);
|
|
}
|
|
}
|
|
startPointerDrag(event) {
|
|
const state = this.state;
|
|
state._active = true;
|
|
state._preventScroll = true;
|
|
state._delayed = false;
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
pointerMove(event) {
|
|
const state = this.state;
|
|
const config = this.config;
|
|
if (!state._pointerActive) return;
|
|
const id = pointerId(event);
|
|
if (state._pointerId !== undefined && id !== state._pointerId) return;
|
|
const _values = pointerValues(event);
|
|
if (document.pointerLockElement === event.target) {
|
|
state._delta = [event.movementX, event.movementY];
|
|
} else {
|
|
state._delta = maths.V.sub(_values, state._values);
|
|
this.computeValues(_values);
|
|
}
|
|
maths.V.addTo(state._movement, state._delta);
|
|
this.compute(event);
|
|
if (state._delayed && state.intentional) {
|
|
this.timeoutStore.remove('dragDelay');
|
|
state.active = false;
|
|
this.startPointerDrag(event);
|
|
return;
|
|
}
|
|
if (config.preventScrollAxis && !state._preventScroll) {
|
|
if (state.axis) {
|
|
if (state.axis === config.preventScrollAxis || config.preventScrollAxis === 'xy') {
|
|
state._active = false;
|
|
this.clean();
|
|
return;
|
|
} else {
|
|
this.timeoutStore.remove('startPointerDrag');
|
|
this.startPointerDrag(event);
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
this.emit();
|
|
}
|
|
pointerUp(event) {
|
|
this.ctrl.setEventIds(event);
|
|
try {
|
|
if (this.config.pointerCapture && event.target.hasPointerCapture(event.pointerId)) {
|
|
;
|
|
event.target.releasePointerCapture(event.pointerId);
|
|
}
|
|
} catch (_unused) {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.warn(`[@use-gesture]: If you see this message, it's likely that you're using an outdated version of \`@react-three/fiber\`. \n\nPlease upgrade to the latest version.`);
|
|
}
|
|
}
|
|
const state = this.state;
|
|
const config = this.config;
|
|
if (!state._active || !state._pointerActive) return;
|
|
const id = pointerId(event);
|
|
if (state._pointerId !== undefined && id !== state._pointerId) return;
|
|
this.state._pointerActive = false;
|
|
this.setActive();
|
|
this.compute(event);
|
|
const [dx, dy] = state._distance;
|
|
state.tap = dx <= config.tapsThreshold && dy <= config.tapsThreshold;
|
|
if (state.tap && config.filterTaps) {
|
|
state._force = true;
|
|
} else {
|
|
const [_dx, _dy] = state._delta;
|
|
const [_mx, _my] = state._movement;
|
|
const [svx, svy] = config.swipe.velocity;
|
|
const [sx, sy] = config.swipe.distance;
|
|
const sdt = config.swipe.duration;
|
|
if (state.elapsedTime < sdt) {
|
|
const _vx = Math.abs(_dx / state.timeDelta);
|
|
const _vy = Math.abs(_dy / state.timeDelta);
|
|
if (_vx > svx && Math.abs(_mx) > sx) state.swipe[0] = Math.sign(_dx);
|
|
if (_vy > svy && Math.abs(_my) > sy) state.swipe[1] = Math.sign(_dy);
|
|
}
|
|
}
|
|
this.emit();
|
|
}
|
|
pointerClick(event) {
|
|
if (!this.state.tap && event.detail > 0) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
}
|
|
setupPointer(event) {
|
|
const config = this.config;
|
|
const device = config.device;
|
|
if (process.env.NODE_ENV === 'development') {
|
|
try {
|
|
if (device === 'pointer' && config.preventScrollDelay === undefined) {
|
|
const currentTarget = 'uv' in event ? event.sourceEvent.currentTarget : event.currentTarget;
|
|
const style = window.getComputedStyle(currentTarget);
|
|
if (style.touchAction === 'auto') {
|
|
console.warn(`[@use-gesture]: The drag target has its \`touch-action\` style property set to \`auto\`. It is recommended to add \`touch-action: 'none'\` so that the drag gesture behaves correctly on touch-enabled devices. For more information read this: https://use-gesture.netlify.app/docs/extras/#touch-action.\n\nThis message will only show in development mode. It won't appear in production. If this is intended, you can ignore it.`, currentTarget);
|
|
}
|
|
}
|
|
} catch (_unused2) {}
|
|
}
|
|
if (config.pointerLock) {
|
|
event.currentTarget.requestPointerLock();
|
|
}
|
|
if (!config.pointerCapture) {
|
|
this.eventStore.add(this.sharedConfig.window, device, 'change', this.pointerMove.bind(this));
|
|
this.eventStore.add(this.sharedConfig.window, device, 'end', this.pointerUp.bind(this));
|
|
this.eventStore.add(this.sharedConfig.window, device, 'cancel', this.pointerUp.bind(this));
|
|
}
|
|
}
|
|
pointerClean() {
|
|
if (this.config.pointerLock && document.pointerLockElement === this.state.currentTarget) {
|
|
document.exitPointerLock();
|
|
}
|
|
}
|
|
preventScroll(event) {
|
|
if (this.state._preventScroll && event.cancelable) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
setupScrollPrevention(event) {
|
|
this.state._preventScroll = false;
|
|
persistEvent(event);
|
|
const remove = this.eventStore.add(this.sharedConfig.window, 'touch', 'change', this.preventScroll.bind(this), {
|
|
passive: false
|
|
});
|
|
this.eventStore.add(this.sharedConfig.window, 'touch', 'end', remove);
|
|
this.eventStore.add(this.sharedConfig.window, 'touch', 'cancel', remove);
|
|
this.timeoutStore.add('startPointerDrag', this.startPointerDrag.bind(this), this.config.preventScrollDelay, event);
|
|
}
|
|
setupDelayTrigger(event) {
|
|
this.state._delayed = true;
|
|
this.timeoutStore.add('dragDelay', () => {
|
|
this.state._step = [0, 0];
|
|
this.startPointerDrag(event);
|
|
}, this.config.delay);
|
|
}
|
|
keyDown(event) {
|
|
const deltaFn = KEYS_DELTA_MAP[event.key];
|
|
if (deltaFn) {
|
|
const state = this.state;
|
|
const factor = event.shiftKey ? 10 : event.altKey ? 0.1 : 1;
|
|
this.start(event);
|
|
state._delta = deltaFn(this.config.keyboardDisplacement, factor);
|
|
state._keyboardActive = true;
|
|
maths.V.addTo(state._movement, state._delta);
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
}
|
|
keyUp(event) {
|
|
if (!(event.key in KEYS_DELTA_MAP)) return;
|
|
this.state._keyboardActive = false;
|
|
this.setActive();
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
bind(bindFunction) {
|
|
const device = this.config.device;
|
|
bindFunction(device, 'start', this.pointerDown.bind(this));
|
|
if (this.config.pointerCapture) {
|
|
bindFunction(device, 'change', this.pointerMove.bind(this));
|
|
bindFunction(device, 'end', this.pointerUp.bind(this));
|
|
bindFunction(device, 'cancel', this.pointerUp.bind(this));
|
|
bindFunction('lostPointerCapture', '', this.pointerUp.bind(this));
|
|
}
|
|
if (this.config.keys) {
|
|
bindFunction('key', 'down', this.keyDown.bind(this));
|
|
bindFunction('key', 'up', this.keyUp.bind(this));
|
|
}
|
|
if (this.config.filterTaps) {
|
|
bindFunction('click', '', this.pointerClick.bind(this), {
|
|
capture: true,
|
|
passive: false
|
|
});
|
|
}
|
|
}
|
|
}
|
|
function persistEvent(event) {
|
|
'persist' in event && typeof event.persist === 'function' && event.persist();
|
|
}
|
|
|
|
const isBrowser = typeof window !== 'undefined' && window.document && window.document.createElement;
|
|
function supportsTouchEvents() {
|
|
return isBrowser && 'ontouchstart' in window;
|
|
}
|
|
function isTouchScreen() {
|
|
return supportsTouchEvents() || isBrowser && window.navigator.maxTouchPoints > 1;
|
|
}
|
|
function supportsPointerEvents() {
|
|
return isBrowser && 'onpointerdown' in window;
|
|
}
|
|
function supportsPointerLock() {
|
|
return isBrowser && 'exitPointerLock' in window.document;
|
|
}
|
|
function supportsGestureEvents() {
|
|
try {
|
|
return 'constructor' in GestureEvent;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
const SUPPORT = {
|
|
isBrowser,
|
|
gesture: supportsGestureEvents(),
|
|
touch: supportsTouchEvents(),
|
|
touchscreen: isTouchScreen(),
|
|
pointer: supportsPointerEvents(),
|
|
pointerLock: supportsPointerLock()
|
|
};
|
|
|
|
const DEFAULT_PREVENT_SCROLL_DELAY = 250;
|
|
const DEFAULT_DRAG_DELAY = 180;
|
|
const DEFAULT_SWIPE_VELOCITY = 0.5;
|
|
const DEFAULT_SWIPE_DISTANCE = 50;
|
|
const DEFAULT_SWIPE_DURATION = 250;
|
|
const DEFAULT_KEYBOARD_DISPLACEMENT = 10;
|
|
const DEFAULT_DRAG_AXIS_THRESHOLD = {
|
|
mouse: 0,
|
|
touch: 0,
|
|
pen: 8
|
|
};
|
|
const dragConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
|
|
device(_v, _k, {
|
|
pointer: {
|
|
touch = false,
|
|
lock = false,
|
|
mouse = false
|
|
} = {}
|
|
}) {
|
|
this.pointerLock = lock && SUPPORT.pointerLock;
|
|
if (SUPPORT.touch && touch) return 'touch';
|
|
if (this.pointerLock) return 'mouse';
|
|
if (SUPPORT.pointer && !mouse) return 'pointer';
|
|
if (SUPPORT.touch) return 'touch';
|
|
return 'mouse';
|
|
},
|
|
preventScrollAxis(value, _k, {
|
|
preventScroll
|
|
}) {
|
|
this.preventScrollDelay = typeof preventScroll === 'number' ? preventScroll : preventScroll || preventScroll === undefined && value ? DEFAULT_PREVENT_SCROLL_DELAY : undefined;
|
|
if (!SUPPORT.touchscreen || preventScroll === false) return undefined;
|
|
return value ? value : preventScroll !== undefined ? 'y' : undefined;
|
|
},
|
|
pointerCapture(_v, _k, {
|
|
pointer: {
|
|
capture = true,
|
|
buttons = 1,
|
|
keys = true
|
|
} = {}
|
|
}) {
|
|
this.pointerButtons = buttons;
|
|
this.keys = keys;
|
|
return !this.pointerLock && this.device === 'pointer' && capture;
|
|
},
|
|
threshold(value, _k, {
|
|
filterTaps = false,
|
|
tapsThreshold = 3,
|
|
axis = undefined
|
|
}) {
|
|
const threshold = maths.V.toVector(value, filterTaps ? tapsThreshold : axis ? 1 : 0);
|
|
this.filterTaps = filterTaps;
|
|
this.tapsThreshold = tapsThreshold;
|
|
return threshold;
|
|
},
|
|
swipe({
|
|
velocity = DEFAULT_SWIPE_VELOCITY,
|
|
distance = DEFAULT_SWIPE_DISTANCE,
|
|
duration = DEFAULT_SWIPE_DURATION
|
|
} = {}) {
|
|
return {
|
|
velocity: this.transform(maths.V.toVector(velocity)),
|
|
distance: this.transform(maths.V.toVector(distance)),
|
|
duration
|
|
};
|
|
},
|
|
delay(value = 0) {
|
|
switch (value) {
|
|
case true:
|
|
return DEFAULT_DRAG_DELAY;
|
|
case false:
|
|
return 0;
|
|
default:
|
|
return value;
|
|
}
|
|
},
|
|
axisThreshold(value) {
|
|
if (!value) return DEFAULT_DRAG_AXIS_THRESHOLD;
|
|
return _objectSpread2(_objectSpread2({}, DEFAULT_DRAG_AXIS_THRESHOLD), value);
|
|
},
|
|
keyboardDisplacement(value = DEFAULT_KEYBOARD_DISPLACEMENT) {
|
|
return value;
|
|
}
|
|
});
|
|
if (process.env.NODE_ENV === 'development') {
|
|
Object.assign(dragConfigResolver, {
|
|
useTouch(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`useTouch\` option has been renamed to \`pointer.touch\`. Use it as in \`{ pointer: { touch: true } }\`.`);
|
|
}
|
|
return NaN;
|
|
},
|
|
experimental_preventWindowScrollY(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`experimental_preventWindowScrollY\` option has been renamed to \`preventScroll\`.`);
|
|
}
|
|
return NaN;
|
|
},
|
|
swipeVelocity(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`swipeVelocity\` option has been renamed to \`swipe.velocity\`. Use it as in \`{ swipe: { velocity: 0.5 } }\`.`);
|
|
}
|
|
return NaN;
|
|
},
|
|
swipeDistance(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`swipeDistance\` option has been renamed to \`swipe.distance\`. Use it as in \`{ swipe: { distance: 50 } }\`.`);
|
|
}
|
|
return NaN;
|
|
},
|
|
swipeDuration(value) {
|
|
if (value !== undefined) {
|
|
throw Error(`[@use-gesture]: \`swipeDuration\` option has been renamed to \`swipe.duration\`. Use it as in \`{ swipe: { duration: 250 } }\`.`);
|
|
}
|
|
return NaN;
|
|
}
|
|
});
|
|
}
|
|
|
|
function clampStateInternalMovementToBounds(state) {
|
|
const [ox, oy] = state.overflow;
|
|
const [dx, dy] = state._delta;
|
|
const [dirx, diry] = state._direction;
|
|
if (ox < 0 && dx > 0 && dirx < 0 || ox > 0 && dx < 0 && dirx > 0) {
|
|
state._movement[0] = state._movementBound[0];
|
|
}
|
|
if (oy < 0 && dy > 0 && diry < 0 || oy > 0 && dy < 0 && diry > 0) {
|
|
state._movement[1] = state._movementBound[1];
|
|
}
|
|
}
|
|
|
|
const SCALE_ANGLE_RATIO_INTENT_DEG = 30;
|
|
const PINCH_WHEEL_RATIO = 100;
|
|
class PinchEngine extends Engine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "ingKey", 'pinching');
|
|
_defineProperty(this, "aliasKey", 'da');
|
|
}
|
|
init() {
|
|
this.state.offset = [1, 0];
|
|
this.state.lastOffset = [1, 0];
|
|
this.state._pointerEvents = new Map();
|
|
}
|
|
reset() {
|
|
super.reset();
|
|
const state = this.state;
|
|
state._touchIds = [];
|
|
state.canceled = false;
|
|
state.cancel = this.cancel.bind(this);
|
|
state.turns = 0;
|
|
}
|
|
computeOffset() {
|
|
const {
|
|
type,
|
|
movement,
|
|
lastOffset
|
|
} = this.state;
|
|
if (type === 'wheel') {
|
|
this.state.offset = maths.V.add(movement, lastOffset);
|
|
} else {
|
|
this.state.offset = [(1 + movement[0]) * lastOffset[0], movement[1] + lastOffset[1]];
|
|
}
|
|
}
|
|
computeMovement() {
|
|
const {
|
|
offset,
|
|
lastOffset
|
|
} = this.state;
|
|
this.state.movement = [offset[0] / lastOffset[0], offset[1] - lastOffset[1]];
|
|
}
|
|
axisIntent() {
|
|
const state = this.state;
|
|
const [_m0, _m1] = state._movement;
|
|
if (!state.axis) {
|
|
const axisMovementDifference = Math.abs(_m0) * SCALE_ANGLE_RATIO_INTENT_DEG - Math.abs(_m1);
|
|
if (axisMovementDifference < 0) state.axis = 'angle';else if (axisMovementDifference > 0) state.axis = 'scale';
|
|
}
|
|
}
|
|
restrictToAxis(v) {
|
|
if (this.config.lockDirection) {
|
|
if (this.state.axis === 'scale') v[1] = 0;else if (this.state.axis === 'angle') v[0] = 0;
|
|
}
|
|
}
|
|
cancel() {
|
|
const state = this.state;
|
|
if (state.canceled) return;
|
|
setTimeout(() => {
|
|
state.canceled = true;
|
|
state._active = false;
|
|
this.compute();
|
|
this.emit();
|
|
}, 0);
|
|
}
|
|
touchStart(event) {
|
|
this.ctrl.setEventIds(event);
|
|
const state = this.state;
|
|
const ctrlTouchIds = this.ctrl.touchIds;
|
|
if (state._active) {
|
|
if (state._touchIds.every(id => ctrlTouchIds.has(id))) return;
|
|
}
|
|
if (ctrlTouchIds.size < 2) return;
|
|
this.start(event);
|
|
state._touchIds = Array.from(ctrlTouchIds).slice(0, 2);
|
|
const payload = touchDistanceAngle(event, state._touchIds);
|
|
if (!payload) return;
|
|
this.pinchStart(event, payload);
|
|
}
|
|
pointerStart(event) {
|
|
if (event.buttons != null && event.buttons % 2 !== 1) return;
|
|
this.ctrl.setEventIds(event);
|
|
event.target.setPointerCapture(event.pointerId);
|
|
const state = this.state;
|
|
const _pointerEvents = state._pointerEvents;
|
|
const ctrlPointerIds = this.ctrl.pointerIds;
|
|
if (state._active) {
|
|
if (Array.from(_pointerEvents.keys()).every(id => ctrlPointerIds.has(id))) return;
|
|
}
|
|
if (_pointerEvents.size < 2) {
|
|
_pointerEvents.set(event.pointerId, event);
|
|
}
|
|
if (state._pointerEvents.size < 2) return;
|
|
this.start(event);
|
|
const payload = distanceAngle(...Array.from(_pointerEvents.values()));
|
|
if (!payload) return;
|
|
this.pinchStart(event, payload);
|
|
}
|
|
pinchStart(event, payload) {
|
|
const state = this.state;
|
|
state.origin = payload.origin;
|
|
this.computeValues([payload.distance, payload.angle]);
|
|
this.computeInitial();
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
touchMove(event) {
|
|
if (!this.state._active) return;
|
|
const payload = touchDistanceAngle(event, this.state._touchIds);
|
|
if (!payload) return;
|
|
this.pinchMove(event, payload);
|
|
}
|
|
pointerMove(event) {
|
|
const _pointerEvents = this.state._pointerEvents;
|
|
if (_pointerEvents.has(event.pointerId)) {
|
|
_pointerEvents.set(event.pointerId, event);
|
|
}
|
|
if (!this.state._active) return;
|
|
const payload = distanceAngle(...Array.from(_pointerEvents.values()));
|
|
if (!payload) return;
|
|
this.pinchMove(event, payload);
|
|
}
|
|
pinchMove(event, payload) {
|
|
const state = this.state;
|
|
const prev_a = state._values[1];
|
|
const delta_a = payload.angle - prev_a;
|
|
let delta_turns = 0;
|
|
if (Math.abs(delta_a) > 270) delta_turns += Math.sign(delta_a);
|
|
this.computeValues([payload.distance, payload.angle - 360 * delta_turns]);
|
|
state.origin = payload.origin;
|
|
state.turns = delta_turns;
|
|
state._movement = [state._values[0] / state._initial[0] - 1, state._values[1] - state._initial[1]];
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
touchEnd(event) {
|
|
this.ctrl.setEventIds(event);
|
|
if (!this.state._active) return;
|
|
if (this.state._touchIds.some(id => !this.ctrl.touchIds.has(id))) {
|
|
this.state._active = false;
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
}
|
|
pointerEnd(event) {
|
|
const state = this.state;
|
|
this.ctrl.setEventIds(event);
|
|
try {
|
|
event.target.releasePointerCapture(event.pointerId);
|
|
} catch (_unused) {}
|
|
if (state._pointerEvents.has(event.pointerId)) {
|
|
state._pointerEvents.delete(event.pointerId);
|
|
}
|
|
if (!state._active) return;
|
|
if (state._pointerEvents.size < 2) {
|
|
state._active = false;
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
}
|
|
gestureStart(event) {
|
|
if (event.cancelable) event.preventDefault();
|
|
const state = this.state;
|
|
if (state._active) return;
|
|
this.start(event);
|
|
this.computeValues([event.scale, event.rotation]);
|
|
state.origin = [event.clientX, event.clientY];
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
gestureMove(event) {
|
|
if (event.cancelable) event.preventDefault();
|
|
if (!this.state._active) return;
|
|
const state = this.state;
|
|
this.computeValues([event.scale, event.rotation]);
|
|
state.origin = [event.clientX, event.clientY];
|
|
const _previousMovement = state._movement;
|
|
state._movement = [event.scale - 1, event.rotation];
|
|
state._delta = maths.V.sub(state._movement, _previousMovement);
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
gestureEnd(event) {
|
|
if (!this.state._active) return;
|
|
this.state._active = false;
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
wheel(event) {
|
|
const modifierKey = this.config.modifierKey;
|
|
if (modifierKey && (Array.isArray(modifierKey) ? !modifierKey.find(k => event[k]) : !event[modifierKey])) return;
|
|
if (!this.state._active) this.wheelStart(event);else this.wheelChange(event);
|
|
this.timeoutStore.add('wheelEnd', this.wheelEnd.bind(this));
|
|
}
|
|
wheelStart(event) {
|
|
this.start(event);
|
|
this.wheelChange(event);
|
|
}
|
|
wheelChange(event) {
|
|
const isR3f = ('uv' in event);
|
|
if (!isR3f) {
|
|
if (event.cancelable) {
|
|
event.preventDefault();
|
|
}
|
|
if (process.env.NODE_ENV === 'development' && !event.defaultPrevented) {
|
|
console.warn(`[@use-gesture]: To properly support zoom on trackpads, try using the \`target\` option.\n\nThis message will only appear in development mode.`);
|
|
}
|
|
}
|
|
const state = this.state;
|
|
state._delta = [-wheelValues(event)[1] / PINCH_WHEEL_RATIO * state.offset[0], 0];
|
|
maths.V.addTo(state._movement, state._delta);
|
|
clampStateInternalMovementToBounds(state);
|
|
this.state.origin = [event.clientX, event.clientY];
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
wheelEnd() {
|
|
if (!this.state._active) return;
|
|
this.state._active = false;
|
|
this.compute();
|
|
this.emit();
|
|
}
|
|
bind(bindFunction) {
|
|
const device = this.config.device;
|
|
if (!!device) {
|
|
bindFunction(device, 'start', this[device + 'Start'].bind(this));
|
|
bindFunction(device, 'change', this[device + 'Move'].bind(this));
|
|
bindFunction(device, 'end', this[device + 'End'].bind(this));
|
|
bindFunction(device, 'cancel', this[device + 'End'].bind(this));
|
|
bindFunction('lostPointerCapture', '', this[device + 'End'].bind(this));
|
|
}
|
|
if (this.config.pinchOnWheel) {
|
|
bindFunction('wheel', '', this.wheel.bind(this), {
|
|
passive: false
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
const pinchConfigResolver = _objectSpread2(_objectSpread2({}, commonConfigResolver), {}, {
|
|
device(_v, _k, {
|
|
shared,
|
|
pointer: {
|
|
touch = false
|
|
} = {}
|
|
}) {
|
|
const sharedConfig = shared;
|
|
if (sharedConfig.target && !SUPPORT.touch && SUPPORT.gesture) return 'gesture';
|
|
if (SUPPORT.touch && touch) return 'touch';
|
|
if (SUPPORT.touchscreen) {
|
|
if (SUPPORT.pointer) return 'pointer';
|
|
if (SUPPORT.touch) return 'touch';
|
|
}
|
|
},
|
|
bounds(_v, _k, {
|
|
scaleBounds = {},
|
|
angleBounds = {}
|
|
}) {
|
|
const _scaleBounds = state => {
|
|
const D = assignDefault(call(scaleBounds, state), {
|
|
min: -Infinity,
|
|
max: Infinity
|
|
});
|
|
return [D.min, D.max];
|
|
};
|
|
const _angleBounds = state => {
|
|
const A = assignDefault(call(angleBounds, state), {
|
|
min: -Infinity,
|
|
max: Infinity
|
|
});
|
|
return [A.min, A.max];
|
|
};
|
|
if (typeof scaleBounds !== 'function' && typeof angleBounds !== 'function') return [_scaleBounds(), _angleBounds()];
|
|
return state => [_scaleBounds(state), _angleBounds(state)];
|
|
},
|
|
threshold(value, _k, config) {
|
|
this.lockDirection = config.axis === 'lock';
|
|
const threshold = maths.V.toVector(value, this.lockDirection ? [0.1, 3] : 0);
|
|
return threshold;
|
|
},
|
|
modifierKey(value) {
|
|
if (value === undefined) return 'ctrlKey';
|
|
return value;
|
|
},
|
|
pinchOnWheel(value = true) {
|
|
return value;
|
|
}
|
|
});
|
|
|
|
class MoveEngine extends CoordinatesEngine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "ingKey", 'moving');
|
|
}
|
|
move(event) {
|
|
if (this.config.mouseOnly && event.pointerType !== 'mouse') return;
|
|
if (!this.state._active) this.moveStart(event);else this.moveChange(event);
|
|
this.timeoutStore.add('moveEnd', this.moveEnd.bind(this));
|
|
}
|
|
moveStart(event) {
|
|
this.start(event);
|
|
this.computeValues(pointerValues(event));
|
|
this.compute(event);
|
|
this.computeInitial();
|
|
this.emit();
|
|
}
|
|
moveChange(event) {
|
|
if (!this.state._active) return;
|
|
const values = pointerValues(event);
|
|
const state = this.state;
|
|
state._delta = maths.V.sub(values, state._values);
|
|
maths.V.addTo(state._movement, state._delta);
|
|
this.computeValues(values);
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
moveEnd(event) {
|
|
if (!this.state._active) return;
|
|
this.state._active = false;
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
bind(bindFunction) {
|
|
bindFunction('pointer', 'change', this.move.bind(this));
|
|
bindFunction('pointer', 'leave', this.moveEnd.bind(this));
|
|
}
|
|
}
|
|
|
|
const moveConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
|
|
mouseOnly: (value = true) => value
|
|
});
|
|
|
|
class ScrollEngine extends CoordinatesEngine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "ingKey", 'scrolling');
|
|
}
|
|
scroll(event) {
|
|
if (!this.state._active) this.start(event);
|
|
this.scrollChange(event);
|
|
this.timeoutStore.add('scrollEnd', this.scrollEnd.bind(this));
|
|
}
|
|
scrollChange(event) {
|
|
if (event.cancelable) event.preventDefault();
|
|
const state = this.state;
|
|
const values = scrollValues(event);
|
|
state._delta = maths.V.sub(values, state._values);
|
|
maths.V.addTo(state._movement, state._delta);
|
|
this.computeValues(values);
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
scrollEnd() {
|
|
if (!this.state._active) return;
|
|
this.state._active = false;
|
|
this.compute();
|
|
this.emit();
|
|
}
|
|
bind(bindFunction) {
|
|
bindFunction('scroll', '', this.scroll.bind(this));
|
|
}
|
|
}
|
|
|
|
const scrollConfigResolver = coordinatesConfigResolver;
|
|
|
|
class WheelEngine extends CoordinatesEngine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "ingKey", 'wheeling');
|
|
}
|
|
wheel(event) {
|
|
if (!this.state._active) this.start(event);
|
|
this.wheelChange(event);
|
|
this.timeoutStore.add('wheelEnd', this.wheelEnd.bind(this));
|
|
}
|
|
wheelChange(event) {
|
|
const state = this.state;
|
|
state._delta = wheelValues(event);
|
|
maths.V.addTo(state._movement, state._delta);
|
|
clampStateInternalMovementToBounds(state);
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
wheelEnd() {
|
|
if (!this.state._active) return;
|
|
this.state._active = false;
|
|
this.compute();
|
|
this.emit();
|
|
}
|
|
bind(bindFunction) {
|
|
bindFunction('wheel', '', this.wheel.bind(this));
|
|
}
|
|
}
|
|
|
|
const wheelConfigResolver = coordinatesConfigResolver;
|
|
|
|
class HoverEngine extends CoordinatesEngine {
|
|
constructor(...args) {
|
|
super(...args);
|
|
_defineProperty(this, "ingKey", 'hovering');
|
|
}
|
|
enter(event) {
|
|
if (this.config.mouseOnly && event.pointerType !== 'mouse') return;
|
|
this.start(event);
|
|
this.computeValues(pointerValues(event));
|
|
this.compute(event);
|
|
this.emit();
|
|
}
|
|
leave(event) {
|
|
if (this.config.mouseOnly && event.pointerType !== 'mouse') return;
|
|
const state = this.state;
|
|
if (!state._active) return;
|
|
state._active = false;
|
|
const values = pointerValues(event);
|
|
state._movement = state._delta = maths.V.sub(values, state._values);
|
|
this.computeValues(values);
|
|
this.compute(event);
|
|
state.delta = state.movement;
|
|
this.emit();
|
|
}
|
|
bind(bindFunction) {
|
|
bindFunction('pointer', 'enter', this.enter.bind(this));
|
|
bindFunction('pointer', 'leave', this.leave.bind(this));
|
|
}
|
|
}
|
|
|
|
const hoverConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
|
|
mouseOnly: (value = true) => value
|
|
});
|
|
|
|
const EngineMap = new Map();
|
|
const ConfigResolverMap = new Map();
|
|
function registerAction(action) {
|
|
EngineMap.set(action.key, action.engine);
|
|
ConfigResolverMap.set(action.key, action.resolver);
|
|
}
|
|
const dragAction = {
|
|
key: 'drag',
|
|
engine: DragEngine,
|
|
resolver: dragConfigResolver
|
|
};
|
|
const hoverAction = {
|
|
key: 'hover',
|
|
engine: HoverEngine,
|
|
resolver: hoverConfigResolver
|
|
};
|
|
const moveAction = {
|
|
key: 'move',
|
|
engine: MoveEngine,
|
|
resolver: moveConfigResolver
|
|
};
|
|
const pinchAction = {
|
|
key: 'pinch',
|
|
engine: PinchEngine,
|
|
resolver: pinchConfigResolver
|
|
};
|
|
const scrollAction = {
|
|
key: 'scroll',
|
|
engine: ScrollEngine,
|
|
resolver: scrollConfigResolver
|
|
};
|
|
const wheelAction = {
|
|
key: 'wheel',
|
|
engine: WheelEngine,
|
|
resolver: wheelConfigResolver
|
|
};
|
|
|
|
exports.ConfigResolverMap = ConfigResolverMap;
|
|
exports.EngineMap = EngineMap;
|
|
exports.SUPPORT = SUPPORT;
|
|
exports._defineProperty = _defineProperty;
|
|
exports._objectSpread2 = _objectSpread2;
|
|
exports.chain = chain;
|
|
exports.dragAction = dragAction;
|
|
exports.hoverAction = hoverAction;
|
|
exports.isTouch = isTouch;
|
|
exports.moveAction = moveAction;
|
|
exports.parseProp = parseProp;
|
|
exports.pinchAction = pinchAction;
|
|
exports.registerAction = registerAction;
|
|
exports.scrollAction = scrollAction;
|
|
exports.toDomEventType = toDomEventType;
|
|
exports.toHandlerProp = toHandlerProp;
|
|
exports.touchIds = touchIds;
|
|
exports.wheelAction = wheelAction;
|