{"version":3,"file":"PanSession.mjs","sources":["../../../../src/gestures/pan/PanSession.ts"],"sourcesContent":["import { addDomEvent } from \"../../events/add-dom-event\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { cancelFrame, frame } from \"../../frameloop/frame\"\nimport { time } from \"../../frameloop/sync-time\"\nimport type { EventInfo } from \"../../node/types\"\nimport { distance2D } from \"../../utils/distance\"\nimport { isPrimaryPointer } from \"../utils/is-primary-pointer\"\nimport type { PanHandler } from \"./types\"\nimport {\n    millisecondsToSeconds,\n    pipe,\n    Point,\n    secondsToMilliseconds,\n    TransformPoint,\n} from \"motion-utils\"\n\ninterface PanSessionHandlers {\n    onSessionStart: PanHandler\n    onStart: PanHandler\n    onMove: PanHandler\n    onEnd: PanHandler\n    onSessionEnd: PanHandler\n    resumeAnimation: () => void\n}\n\ninterface PanSessionOptions {\n    transformPagePoint?: TransformPoint\n    dragSnapToOrigin?: boolean | \"x\" | \"y\"\n    distanceThreshold?: number\n    contextWindow?: (Window & typeof globalThis) | null\n    /**\n     * Element being dragged. When provided, scroll events on its\n     * ancestors and window are compensated so the gesture continues\n     * smoothly during scroll.\n     */\n    element?: HTMLElement | null\n    /**\n     * Start panning from `event` straight away, as if the pointer had moved\n     * there, rather than waiting for it to move past `distanceThreshold`.\n     */\n    immediate?: boolean\n}\n\ninterface TimestampedPoint extends Point {\n    timestamp: number\n}\n\nconst overflowStyles = /*#__PURE__*/ new Set([\"auto\", \"scroll\"])\n\nexport class PanSession {\n    /**\n     * The pointer's points since the session started. The first is where\n     * offsets are measured from. Public so pinch() can restart a drag\n     * from where it leaves the element.\n     */\n    history: TimestampedPoint[]\n\n    private startEvent: PointerEvent | null = null\n\n    private lastMoveEvent: PointerEvent | null = null\n\n    private lastMoveEventInfo: EventInfo | null = null\n\n    /**\n     * Raw (untransformed) event info, re-transformed each frame\n     * so transformPagePoint sees the current parent matrix.\n     */\n    private lastRawMoveEventInfo: EventInfo | null = null\n\n    /**\n     * Whether a pointermove has arrived since the last updatePoint.\n     */\n    private hasPendingMove?: boolean\n\n    private transformPagePoint?: TransformPoint\n\n    private handlers: Partial<PanSessionHandlers> = {}\n\n    private removeListeners?: Function\n\n    /**\n     * For determining if an animation should resume after it is interrupted\n     */\n    private dragSnapToOrigin: boolean | \"x\" | \"y\"\n\n    /**\n     * The distance after which panning should start.\n     */\n    private distanceThreshold: number\n\n    private contextWindow: PanSessionOptions[\"contextWindow\"] = window\n\n    /**\n     * Scroll positions of scrollable ancestors and window.\n     */\n    private scrollPositions: Map<Element | Window, Point> = new Map()\n\n    /**\n     * Cleanup function for scroll listeners.\n     */\n    private removeScrollListeners?: Function\n\n    constructor(\n        event: PointerEvent,\n        handlers: Partial<PanSessionHandlers>,\n        {\n            transformPagePoint,\n            contextWindow = window,\n            dragSnapToOrigin = false,\n            distanceThreshold = 3,\n            element,\n            immediate,\n        }: PanSessionOptions = {}\n    ) {\n        // If we have more than one touch, don't start detecting this gesture\n        if (!isPrimaryPointer(event)) return\n\n        this.dragSnapToOrigin = dragSnapToOrigin\n        this.handlers = handlers\n        this.transformPagePoint = transformPagePoint\n        this.distanceThreshold = immediate ? 0 : distanceThreshold\n        this.contextWindow = contextWindow || window\n\n        const info = extractEventInfo(event)\n        const initialInfo = transformPoint(info, this.transformPagePoint)\n        const { point } = initialInfo\n\n        /**\n         * Stamp the origin with time.now(), not frameData.timestamp: when\n         * the frameloop is idle, frameData.timestamp is from the last frame\n         * that ran, which can be seconds old, and a fast flick from a\n         * standstill would then report near-zero velocity. See #1747.\n         */\n        this.history = [{ ...point, timestamp: time.now() }]\n\n        const { onSessionStart } = handlers\n        onSessionStart &&\n            onSessionStart(event, getPanInfo(initialInfo, this.history))\n\n        // Listen in the capture phase so a descendant calling\n        // stopPropagation() (e.g. in its own pointerup handler) can't\n        // prevent the gesture from ending. See #2794.\n        const eventOptions = { passive: true, capture: true }\n        this.removeListeners = pipe(\n            addPointerEvent(\n                this.contextWindow,\n                \"pointermove\",\n                this.handlePointerMove,\n                eventOptions\n            ),\n            addPointerEvent(\n                this.contextWindow,\n                \"pointerup\",\n                this.handlePointerUp,\n                eventOptions\n            ),\n            addPointerEvent(\n                this.contextWindow,\n                \"pointercancel\",\n                this.handlePointerUp,\n                eventOptions\n            )\n        )\n\n        // Start scroll tracking if element provided\n        if (element) {\n            this.startScrollTracking(element)\n        }\n\n        if (immediate) {\n            this.handlePointerMove(event, info)\n            this.updatePoint()\n        }\n    }\n\n    /**\n     * Start tracking scroll on ancestors and window.\n     */\n    private startScrollTracking(element: HTMLElement): void {\n        // Store initial scroll positions for scrollable ancestors\n        let current = element.parentElement\n        while (current) {\n            const style = getComputedStyle(current)\n            if (\n                overflowStyles.has(style.overflowX) ||\n                overflowStyles.has(style.overflowY)\n            ) {\n                this.scrollPositions.set(current, getScroll(current))\n            }\n            current = current.parentElement\n        }\n\n        // Track window scroll\n        this.scrollPositions.set(window, getScroll(window))\n\n        this.removeScrollListeners = pipe(\n            // Capture listener catches element scroll events as they bubble\n            addDomEvent(window, \"scroll\", this.onElementScroll, {\n                capture: true,\n            }),\n            // Direct window scroll listener (window scroll doesn't bubble)\n            addDomEvent(window, \"scroll\", this.onWindowScroll, {})\n        )\n    }\n\n    private onElementScroll = (event: Event): void => {\n        this.handleScroll(event.target as Element)\n    }\n\n    private onWindowScroll = (): void => {\n        this.handleScroll(window)\n    }\n\n    /**\n     * Handle scroll compensation during drag.\n     *\n     * For element scroll: adjusts history origin since pageX/pageY doesn't change.\n     * For window scroll: adjusts lastMoveEventInfo since pageX/pageY would change.\n     */\n    private handleScroll(target: Element | Window): void {\n        const initial = this.scrollPositions.get(target)\n        if (!initial) return\n\n        const isWindow = target === window\n        const current = getScroll(target)\n\n        const delta = { x: current.x - initial.x, y: current.y - initial.y }\n        if (delta.x === 0 && delta.y === 0) return\n\n        if (isWindow) {\n            // Window scroll: pageX/pageY changes, so update lastMoveEventInfo\n            if (this.lastMoveEventInfo) {\n                this.lastMoveEventInfo.point.x += delta.x\n                this.lastMoveEventInfo.point.y += delta.y\n            }\n        } else {\n            // Element scroll: pageX/pageY unchanged, so adjust history origin\n            if (this.history.length > 0) {\n                this.history[0].x -= delta.x\n                this.history[0].y -= delta.y\n            }\n        }\n\n        this.scrollPositions.set(target, current)\n        frame.update(this.updatePoint, true)\n    }\n\n    private updatePoint = () => {\n        if (!(this.lastMoveEvent && this.lastMoveEventInfo)) return\n        this.hasPendingMove = false\n\n        // Re-transform raw point through current transformPagePoint so\n        // animated parent transforms (e.g. rotation) are picked up each frame\n        if (this.lastRawMoveEventInfo) {\n            this.lastMoveEventInfo = transformPoint(\n                this.lastRawMoveEventInfo,\n                this.transformPagePoint\n            )\n        }\n\n        const info = getPanInfo(this.lastMoveEventInfo, this.history)\n        const isPanStarted = this.startEvent !== null\n\n        // Only start panning if the offset is larger than 3 pixels. If we make it\n        // any larger than this we'll want to reset the pointer history\n        // on the first update to avoid visual snapping to the cursor.\n        const isDistancePastThreshold =\n            distance2D(info.offset, { x: 0, y: 0 }) >= this.distanceThreshold\n\n        if (!isPanStarted && !isDistancePastThreshold) return\n\n        const { point } = info\n        this.history.push({ ...point, timestamp: time.now() })\n\n        const { onStart, onMove } = this.handlers\n\n        if (!isPanStarted) {\n            onStart?.(this.lastMoveEvent, info)\n            this.startEvent = this.lastMoveEvent\n        }\n\n        onMove?.(this.lastMoveEvent, info)\n    }\n\n    private handlePointerMove = (event: PointerEvent, info: EventInfo) => {\n        /**\n         * This event's pageX/pageY already include any window scroll that\n         * hasn't fired its scroll event yet. Settle it now, so that scroll\n         * event doesn't add it to the new point a second time.\n         */\n        this.handleScroll(window)\n\n        this.lastMoveEvent = event\n        this.lastRawMoveEventInfo = info\n        this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint)\n        this.hasPendingMove = true\n\n        // Throttle mouse move event to once per frame\n        frame.update(this.updatePoint, true)\n    }\n\n    private handlePointerUp = (event: PointerEvent, info: EventInfo) => {\n        // Browsers flush a coalesced pointermove immediately before\n        // pointerup, so the final move can still be waiting for a frame.\n        this.hasPendingMove && this.updatePoint()\n        this.end()\n\n        const { onEnd, onSessionEnd, resumeAnimation } = this.handlers\n\n        // Resume animation if dragSnapToOrigin is set OR if no drag started (user just clicked)\n        // This ensures constraint animations continue when interrupted by a click\n        if (this.dragSnapToOrigin || !this.startEvent) {\n            resumeAnimation?.()\n        }\n        if (!(this.lastMoveEvent && this.lastMoveEventInfo)) return\n\n        const panInfo = getPanInfo(\n            event.type === \"pointercancel\"\n                ? this.lastMoveEventInfo\n                : transformPoint(info, this.transformPagePoint),\n            this.history\n        )\n\n        this.startEvent && onEnd?.(event, panInfo)\n        onSessionEnd?.(event, panInfo)\n    }\n\n    updateHandlers(handlers: Partial<PanSessionHandlers>) {\n        this.handlers = handlers\n    }\n\n    end() {\n        this.removeListeners?.()\n        this.removeScrollListeners?.()\n        this.scrollPositions.clear()\n        cancelFrame(this.updatePoint)\n    }\n}\n\nconst getScroll = (target: Element | Window): Point =>\n    target === window\n        ? { x: window.scrollX, y: window.scrollY }\n        : {\n              x: (target as Element).scrollLeft,\n              y: (target as Element).scrollTop,\n          }\n\nfunction transformPoint(\n    info: EventInfo,\n    transformPagePoint?: (point: Point) => Point\n) {\n    return transformPagePoint ? { point: transformPagePoint(info.point) } : info\n}\n\nfunction subtractPoint(a: Point, b: Point): Point {\n    return { x: a.x - b.x, y: a.y - b.y }\n}\n\nfunction getPanInfo({ point }: EventInfo, history: TimestampedPoint[]) {\n    return {\n        point,\n        delta: subtractPoint(point, lastDevicePoint(history)),\n        offset: subtractPoint(point, startDevicePoint(history)),\n        velocity: getVelocity(history, 0.1),\n    }\n}\n\nfunction startDevicePoint(history: TimestampedPoint[]): TimestampedPoint {\n    return history[0]\n}\n\nfunction lastDevicePoint(history: TimestampedPoint[]): TimestampedPoint {\n    return history[history.length - 1]\n}\n\nfunction getVelocity(history: TimestampedPoint[], timeDelta: number): Point {\n    if (history.length < 2) {\n        return { x: 0, y: 0 }\n    }\n\n    let i = history.length - 1\n    let timestampedPoint: TimestampedPoint | null = null\n    const lastPoint = lastDevicePoint(history)\n    while (i >= 0) {\n        timestampedPoint = history[i]\n        if (\n            lastPoint.timestamp - timestampedPoint.timestamp >\n            secondsToMilliseconds(timeDelta)\n        ) {\n            break\n        }\n        i--\n    }\n\n    if (!timestampedPoint) {\n        return { x: 0, y: 0 }\n    }\n\n    /**\n     * If the selected point is the pointer-down origin (history[0]),\n     * there are better movement points available, and the time gap\n     * is suspiciously large (>2x timeDelta), use the next point instead.\n     * This prevents stale pointer-down points from diluting velocity\n     * in hold-then-flick gestures.\n     */\n    if (\n        timestampedPoint === history[0] &&\n        history.length > 2 &&\n        lastPoint.timestamp - timestampedPoint.timestamp >\n            secondsToMilliseconds(timeDelta) * 2\n    ) {\n        timestampedPoint = history[1]\n    }\n\n    const seconds = millisecondsToSeconds(\n        lastPoint.timestamp - timestampedPoint.timestamp\n    )\n    if (seconds === 0) {\n        return { x: 0, y: 0 }\n    }\n\n    const currentVelocity = {\n        x: (lastPoint.x - timestampedPoint.x) / seconds,\n        y: (lastPoint.y - timestampedPoint.y) / seconds,\n    }\n\n    if (currentVelocity.x === Infinity) {\n        currentVelocity.x = 0\n    }\n    if (currentVelocity.y === Infinity) {\n        currentVelocity.y = 0\n    }\n\n    return currentVelocity\n}\n"],"names":[],"mappings":"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"}