"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // src/pan-event.ts var pan_event_exports = {}; __export(pan_event_exports, { PanSession: () => PanSession }); module.exports = __toCommonJS(pan_event_exports); var import_framesync = __toESM(require("framesync")); // src/dom.ts function getEventWindow(event) { var _a; return (_a = event.view) != null ? _a : window; } function canUseDOM() { return !!(typeof window !== "undefined" && window.document && window.document.createElement); } var isBrowser = /* @__PURE__ */ canUseDOM(); function addDomEvent(target, eventName, handler, options) { target.addEventListener(eventName, handler, options); return () => { target.removeEventListener(eventName, handler, options); }; } // src/assertion.ts function isNumber(value) { return typeof value === "number"; } var __DEV__ = process.env.NODE_ENV !== "production"; var __TEST__ = process.env.NODE_ENV === "test"; // src/function.ts var noop = () => { }; var pipe = (...fns) => (v) => fns.reduce((a, b) => b(a), v); var distance1D = (a, b) => Math.abs(a - b); var isPoint = (point) => "x" in point && "y" in point; function distance(a, b) { if (isNumber(a) && isNumber(b)) { return distance1D(a, b); } if (isPoint(a) && isPoint(b)) { const xDelta = distance1D(a.x, b.x); const yDelta = distance1D(a.y, b.y); return Math.sqrt(xDelta ** 2 + yDelta ** 2); } return 0; } // src/pointer-event.ts function isMouseEvent(event) { const win = getEventWindow(event); if (typeof win.PointerEvent !== "undefined" && event instanceof win.PointerEvent) { return !!(event.pointerType === "mouse"); } return event instanceof win.MouseEvent; } function isTouchEvent(event) { const hasTouches = !!event.touches; return hasTouches; } function filterPrimaryPointer(eventHandler) { return (event) => { const win = getEventWindow(event); const isMouseEvent2 = event instanceof win.MouseEvent; const isPrimaryPointer = !isMouseEvent2 || isMouseEvent2 && event.button === 0; if (isPrimaryPointer) { eventHandler(event); } }; } var defaultPagePoint = { pageX: 0, pageY: 0 }; function pointFromTouch(e, pointType = "page") { const primaryTouch = e.touches[0] || e.changedTouches[0]; const point = primaryTouch || defaultPagePoint; return { x: point[`${pointType}X`], y: point[`${pointType}Y`] }; } function pointFromMouse(point, pointType = "page") { return { x: point[`${pointType}X`], y: point[`${pointType}Y`] }; } function extractEventInfo(event, pointType = "page") { return { point: isTouchEvent(event) ? pointFromTouch(event, pointType) : pointFromMouse(event, pointType) }; } var wrapPointerEventHandler = (handler, shouldFilterPrimaryPointer = false) => { const listener = (event) => handler(event, extractEventInfo(event)); return shouldFilterPrimaryPointer ? filterPrimaryPointer(listener) : listener; }; var supportsPointerEvents = () => isBrowser && window.onpointerdown === null; var supportsTouchEvents = () => isBrowser && window.ontouchstart === null; var supportsMouseEvents = () => isBrowser && window.onmousedown === null; var mouseEventNames = { pointerdown: "mousedown", pointermove: "mousemove", pointerup: "mouseup", pointercancel: "mousecancel", pointerover: "mouseover", pointerout: "mouseout", pointerenter: "mouseenter", pointerleave: "mouseleave" }; var touchEventNames = { pointerdown: "touchstart", pointermove: "touchmove", pointerup: "touchend", pointercancel: "touchcancel" }; function getPointerEventName(name) { if (supportsPointerEvents()) { return name; } if (supportsTouchEvents()) { return touchEventNames[name]; } if (supportsMouseEvents()) { return mouseEventNames[name]; } return name; } function addPointerEvent(target, eventName, handler, options) { return addDomEvent( target, getPointerEventName(eventName), wrapPointerEventHandler(handler, eventName === "pointerdown"), options ); } function isMultiTouchEvent(event) { return isTouchEvent(event) && event.touches.length > 1; } // src/pan-event.ts var PanSession = class { constructor(event, handlers, threshold) { __publicField(this, "history", []); __publicField(this, "startEvent", null); __publicField(this, "lastEvent", null); __publicField(this, "lastEventInfo", null); __publicField(this, "handlers", {}); __publicField(this, "removeListeners", noop); __publicField(this, "threshold", 3); __publicField(this, "win"); __publicField(this, "updatePoint", () => { if (!(this.lastEvent && this.lastEventInfo)) return; const info = getPanInfo(this.lastEventInfo, this.history); const isPanStarted = this.startEvent !== null; const isDistancePastThreshold = distance(info.offset, { x: 0, y: 0 }) >= this.threshold; if (!isPanStarted && !isDistancePastThreshold) return; const { timestamp } = (0, import_framesync.getFrameData)(); this.history.push({ ...info.point, timestamp }); const { onStart, onMove } = this.handlers; if (!isPanStarted) { onStart == null ? void 0 : onStart(this.lastEvent, info); this.startEvent = this.lastEvent; } onMove == null ? void 0 : onMove(this.lastEvent, info); }); __publicField(this, "onPointerMove", (event, info) => { this.lastEvent = event; this.lastEventInfo = info; if (isMouseEvent(event) && event.buttons === 0) { this.onPointerUp(event, info); return; } import_framesync.default.update(this.updatePoint, true); }); __publicField(this, "onPointerUp", (event, info) => { const panInfo = getPanInfo(info, this.history); const { onEnd, onSessionEnd } = this.handlers; onSessionEnd == null ? void 0 : onSessionEnd(event, panInfo); this.end(); if (!onEnd || !this.startEvent) return; onEnd == null ? void 0 : onEnd(event, panInfo); }); this.win = getEventWindow(event); if (isMultiTouchEvent(event)) return; this.handlers = handlers; if (threshold) { this.threshold = threshold; } event.stopPropagation(); event.preventDefault(); const info = extractEventInfo(event); const { timestamp } = (0, import_framesync.getFrameData)(); this.history = [{ ...info.point, timestamp }]; const { onSessionStart } = handlers; onSessionStart == null ? void 0 : onSessionStart(event, getPanInfo(info, this.history)); this.removeListeners = pipe( addPointerEvent(this.win, "pointermove", this.onPointerMove), addPointerEvent(this.win, "pointerup", this.onPointerUp), addPointerEvent(this.win, "pointercancel", this.onPointerUp) ); } updateHandlers(handlers) { this.handlers = handlers; } end() { var _a; (_a = this.removeListeners) == null ? void 0 : _a.call(this); import_framesync.cancelSync.update(this.updatePoint); } }; function subtractPoint(a, b) { return { x: a.x - b.x, y: a.y - b.y }; } function startPanPoint(history) { return history[0]; } function lastPanPoint(history) { return history[history.length - 1]; } function getPanInfo(info, history) { return { point: info.point, delta: subtractPoint(info.point, lastPanPoint(history)), offset: subtractPoint(info.point, startPanPoint(history)), velocity: getVelocity(history, 0.1) }; } function lastDevicePoint(history) { return history[history.length - 1]; } var toMilliseconds = (seconds) => seconds * 1e3; function getVelocity(history, timeDelta) { if (history.length < 2) { return { x: 0, y: 0 }; } let i = history.length - 1; let timestampedPoint = null; const lastPoint = lastDevicePoint(history); while (i >= 0) { timestampedPoint = history[i]; if (lastPoint.timestamp - timestampedPoint.timestamp > toMilliseconds(timeDelta)) { break; } i--; } if (!timestampedPoint) { return { x: 0, y: 0 }; } const time = (lastPoint.timestamp - timestampedPoint.timestamp) / 1e3; if (time === 0) { return { x: 0, y: 0 }; } const currentVelocity = { x: (lastPoint.x - timestampedPoint.x) / time, y: (lastPoint.y - timestampedPoint.y) / time }; if (currentVelocity.x === Infinity) { currentVelocity.x = 0; } if (currentVelocity.y === Infinity) { currentVelocity.y = 0; } return currentVelocity; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { PanSession });