framer-motion 12.24.7 → 12.24.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client.js +1 -1
- package/dist/cjs/{feature-bundle-C6mMBZjn.js → feature-bundle-Cw8jj9v7.js} +20 -7
- package/dist/cjs/{feature-bundle-C6mMBZjn.js.map → feature-bundle-Cw8jj9v7.js.map} +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/dom.js +1 -1
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +16 -6
- package/dist/es/gestures/drag/VisualElementDragControls.mjs.map +1 -1
- package/dist/es/gestures/pan/PanSession.mjs +4 -1
- package/dist/es/gestures/pan/PanSession.mjs.map +1 -1
- package/dist/framer-motion.dev.js +53 -9
- package/dist/framer-motion.js +1 -1
- package/dist/projection.d.ts +912 -0
- package/dist/size-rollup-animate.js +1 -1
- package/dist/size-rollup-animate.js.map +1 -1
- package/dist/size-rollup-dom-animation-assets.js +1 -1
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js.map +1 -1
- package/dist/size-rollup-motion.js +1 -1
- package/dist/size-rollup-motion.js.map +1 -1
- package/dist/size-rollup-scroll.js.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisualElementDragControls.mjs","sources":["../../../../src/gestures/drag/VisualElementDragControls.ts"],"sourcesContent":["import {\n PanInfo,\n ResolvedConstraints,\n Transition,\n frame,\n mixNumber,\n percent,\n setDragLock,\n} from \"motion-dom\"\nimport { Axis, Point, invariant } from \"motion-utils\"\nimport { animateMotionValue } from \"../../animation/interfaces/motion-value\"\nimport { addDomEvent } from \"../../events/add-dom-event\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { MotionProps } from \"../../motion/types\"\nimport {\n convertBoundingBoxToBox,\n convertBoxToBoundingBox,\n} from \"../../projection/geometry/conversion\"\nimport { calcLength } from \"../../projection/geometry/delta-calc\"\nimport { createBox } from \"../../projection/geometry/models\"\nimport { LayoutUpdateData } from \"../../projection/node/types\"\nimport { eachAxis } from \"../../projection/utils/each-axis\"\nimport { measurePageBox } from \"../../projection/utils/measure\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { getContextWindow } from \"../../utils/get-context-window\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { addValueToWillChange } from \"../../value/use-will-change/add-will-change\"\nimport { PanSession } from \"../pan/PanSession\"\nimport {\n applyConstraints,\n calcOrigin,\n calcRelativeConstraints,\n calcViewportConstraints,\n defaultElastic,\n rebaseAxisConstraints,\n resolveDragElastic,\n} from \"./utils/constraints\"\n\nexport const elementDragControls = new WeakMap<\n VisualElement,\n VisualElementDragControls\n>()\n\nexport interface DragControlOptions {\n /**\n * This distance after which dragging starts and a direction is locked in.\n *\n * @public\n */\n distanceThreshold?: number\n\n /**\n * Whether to immediately snap to the cursor when dragging starts.\n *\n * @public\n */\n snapToCursor?: boolean\n}\n\ntype DragDirection = \"x\" | \"y\"\n\nexport class VisualElementDragControls {\n private visualElement: VisualElement<HTMLElement>\n\n private panSession?: PanSession\n\n private openDragLock: VoidFunction | null = null\n\n isDragging = false\n private currentDirection: DragDirection | null = null\n\n private originPoint: Point = { x: 0, y: 0 }\n\n /**\n * The permitted boundaries of travel, in pixels.\n */\n private constraints: ResolvedConstraints | false = false\n\n private hasMutatedConstraints = false\n\n /**\n * The per-axis resolved elastic values.\n */\n private elastic = createBox()\n\n /**\n * The latest pointer event. Used as fallback when the `cancel` and `stop` functions are called without arguments.\n */\n private latestPointerEvent: PointerEvent | null = null\n\n /**\n * The latest pan info. Used as fallback when the `cancel` and `stop` functions are called without arguments.\n */\n private latestPanInfo: PanInfo | null = null\n\n constructor(visualElement: VisualElement<HTMLElement>) {\n this.visualElement = visualElement\n }\n\n start(\n originEvent: PointerEvent,\n { snapToCursor = false, distanceThreshold }: DragControlOptions = {}\n ) {\n /**\n * Don't start dragging if this component is exiting\n */\n const { presenceContext } = this.visualElement\n if (presenceContext && presenceContext.isPresent === false) return\n\n const onSessionStart = (event: PointerEvent) => {\n const { dragSnapToOrigin } = this.getProps()\n\n // Stop or pause any animations on both axis values immediately. This allows the user to throw and catch\n // the component.\n dragSnapToOrigin ? this.pauseAnimation() : this.stopAnimation()\n\n if (snapToCursor) {\n this.snapToCursor(extractEventInfo(event).point)\n }\n }\n\n const onStart = (event: PointerEvent, info: PanInfo) => {\n // Attempt to grab the global drag gesture lock - maybe make this part of PanSession\n const { drag, dragPropagation, onDragStart } = this.getProps()\n\n if (drag && !dragPropagation) {\n if (this.openDragLock) this.openDragLock()\n\n this.openDragLock = setDragLock(drag)\n\n // If we don 't have the lock, don't start dragging\n if (!this.openDragLock) return\n }\n\n this.latestPointerEvent = event\n this.latestPanInfo = info\n this.isDragging = true\n\n this.currentDirection = null\n\n this.resolveConstraints()\n\n if (this.visualElement.projection) {\n this.visualElement.projection.isAnimationBlocked = true\n this.visualElement.projection.target = undefined\n }\n\n /**\n * Record gesture origin\n */\n eachAxis((axis) => {\n let current = this.getAxisMotionValue(axis).get() || 0\n\n /**\n * If the MotionValue is a percentage value convert to px\n */\n if (percent.test(current)) {\n const { projection } = this.visualElement\n\n if (projection && projection.layout) {\n const measuredAxis = projection.layout.layoutBox[axis]\n\n if (measuredAxis) {\n const length = calcLength(measuredAxis)\n current = length * (parseFloat(current) / 100)\n }\n }\n }\n\n this.originPoint[axis] = current\n })\n\n // Fire onDragStart event\n if (onDragStart) {\n frame.postRender(() => onDragStart(event, info))\n }\n\n addValueToWillChange(this.visualElement, \"transform\")\n\n const { animationState } = this.visualElement\n animationState && animationState.setActive(\"whileDrag\", true)\n }\n\n const onMove = (event: PointerEvent, info: PanInfo) => {\n this.latestPointerEvent = event\n this.latestPanInfo = info\n\n const {\n dragPropagation,\n dragDirectionLock,\n onDirectionLock,\n onDrag,\n } = this.getProps()\n\n // If we didn't successfully receive the gesture lock, early return.\n if (!dragPropagation && !this.openDragLock) return\n\n const { offset } = info\n // Attempt to detect drag direction if directionLock is true\n if (dragDirectionLock && this.currentDirection === null) {\n this.currentDirection = getCurrentDirection(offset)\n\n // If we've successfully set a direction, notify listener\n if (this.currentDirection !== null) {\n onDirectionLock && onDirectionLock(this.currentDirection)\n }\n\n return\n }\n\n // Update each point with the latest position\n this.updateAxis(\"x\", info.point, offset)\n this.updateAxis(\"y\", info.point, offset)\n\n /**\n * Ideally we would leave the renderer to fire naturally at the end of\n * this frame but if the element is about to change layout as the result\n * of a re-render we want to ensure the browser can read the latest\n * bounding box to ensure the pointer and element don't fall out of sync.\n */\n this.visualElement.render()\n\n /**\n * This must fire after the render call as it might trigger a state\n * change which itself might trigger a layout update.\n */\n onDrag && onDrag(event, info)\n }\n\n const onSessionEnd = (event: PointerEvent, info: PanInfo) => {\n this.latestPointerEvent = event\n this.latestPanInfo = info\n\n this.stop(event, info)\n\n this.latestPointerEvent = null\n this.latestPanInfo = null\n }\n\n const resumeAnimation = () =>\n eachAxis(\n (axis) =>\n this.getAnimationState(axis) === \"paused\" &&\n this.getAxisMotionValue(axis).animation?.play()\n )\n\n const { dragSnapToOrigin } = this.getProps()\n this.panSession = new PanSession(\n originEvent,\n {\n onSessionStart,\n onStart,\n onMove,\n onSessionEnd,\n resumeAnimation,\n },\n {\n transformPagePoint: this.visualElement.getTransformPagePoint(),\n dragSnapToOrigin,\n distanceThreshold,\n contextWindow: getContextWindow(this.visualElement),\n }\n )\n }\n\n /**\n * @internal\n */\n stop(event?: PointerEvent, panInfo?: PanInfo) {\n const finalEvent = event || this.latestPointerEvent\n const finalPanInfo = panInfo || this.latestPanInfo\n\n const isDragging = this.isDragging\n this.cancel()\n if (!isDragging || !finalPanInfo || !finalEvent) return\n\n const { velocity } = finalPanInfo\n this.startAnimation(velocity)\n\n const { onDragEnd } = this.getProps()\n if (onDragEnd) {\n frame.postRender(() => onDragEnd(finalEvent, finalPanInfo))\n }\n }\n\n /**\n * @internal\n */\n cancel() {\n this.isDragging = false\n\n const { projection, animationState } = this.visualElement\n\n if (projection) {\n projection.isAnimationBlocked = false\n }\n\n this.panSession && this.panSession.end()\n this.panSession = undefined\n\n const { dragPropagation } = this.getProps()\n\n if (!dragPropagation && this.openDragLock) {\n this.openDragLock()\n this.openDragLock = null\n }\n\n animationState && animationState.setActive(\"whileDrag\", false)\n }\n\n private updateAxis(axis: DragDirection, _point: Point, offset?: Point) {\n const { drag } = this.getProps()\n\n // If we're not dragging this axis, do an early return.\n if (!offset || !shouldDrag(axis, drag, this.currentDirection)) return\n\n const axisValue = this.getAxisMotionValue(axis)\n let next = this.originPoint[axis] + offset[axis]\n\n // Apply constraints\n if (this.constraints && this.constraints[axis]) {\n next = applyConstraints(\n next,\n this.constraints[axis],\n this.elastic[axis]\n )\n }\n\n axisValue.set(next)\n }\n\n private resolveConstraints() {\n const { dragConstraints, dragElastic } = this.getProps()\n\n const layout =\n this.visualElement.projection &&\n !this.visualElement.projection.layout\n ? this.visualElement.projection.measure(false)\n : this.visualElement.projection?.layout\n\n const prevConstraints = this.constraints\n\n if (dragConstraints && isRefObject(dragConstraints)) {\n if (!this.constraints) {\n this.constraints = this.resolveRefConstraints()\n }\n } else {\n if (dragConstraints && layout) {\n this.constraints = calcRelativeConstraints(\n layout.layoutBox,\n dragConstraints\n )\n } else {\n this.constraints = false\n }\n }\n\n this.elastic = resolveDragElastic(dragElastic)\n\n /**\n * If we're outputting to external MotionValues, we want to rebase the measured constraints\n * from viewport-relative to component-relative.\n */\n if (\n prevConstraints !== this.constraints &&\n layout &&\n this.constraints &&\n !this.hasMutatedConstraints\n ) {\n eachAxis((axis) => {\n if (\n this.constraints !== false &&\n this.getAxisMotionValue(axis)\n ) {\n this.constraints[axis] = rebaseAxisConstraints(\n layout.layoutBox[axis],\n this.constraints[axis]\n )\n }\n })\n }\n }\n\n private resolveRefConstraints() {\n const { dragConstraints: constraints, onMeasureDragConstraints } =\n this.getProps()\n if (!constraints || !isRefObject(constraints)) return false\n\n const constraintsElement = constraints.current as HTMLElement\n\n invariant(\n constraintsElement !== null,\n \"If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.\",\n \"drag-constraints-ref\"\n )\n\n const { projection } = this.visualElement\n\n // TODO\n if (!projection || !projection.layout) return false\n\n const constraintsBox = measurePageBox(\n constraintsElement,\n projection.root!,\n this.visualElement.getTransformPagePoint()\n )\n\n let measuredConstraints = calcViewportConstraints(\n projection.layout.layoutBox,\n constraintsBox\n )\n\n /**\n * If there's an onMeasureDragConstraints listener we call it and\n * if different constraints are returned, set constraints to that\n */\n if (onMeasureDragConstraints) {\n const userConstraints = onMeasureDragConstraints(\n convertBoxToBoundingBox(measuredConstraints)\n )\n\n this.hasMutatedConstraints = !!userConstraints\n\n if (userConstraints) {\n measuredConstraints = convertBoundingBoxToBox(userConstraints)\n }\n }\n\n return measuredConstraints\n }\n\n private startAnimation(velocity: Point) {\n const {\n drag,\n dragMomentum,\n dragElastic,\n dragTransition,\n dragSnapToOrigin,\n onDragTransitionEnd,\n } = this.getProps()\n\n const constraints: Partial<ResolvedConstraints> = this.constraints || {}\n\n const momentumAnimations = eachAxis((axis) => {\n if (!shouldDrag(axis, drag, this.currentDirection)) {\n return\n }\n\n let transition = (constraints && constraints[axis]) || {}\n\n if (dragSnapToOrigin) transition = { min: 0, max: 0 }\n\n /**\n * Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame\n * of spring animations so we should look into adding a disable spring option to `inertia`.\n * We could do something here where we affect the `bounceStiffness` and `bounceDamping`\n * using the value of `dragElastic`.\n */\n const bounceStiffness = dragElastic ? 200 : 1000000\n const bounceDamping = dragElastic ? 40 : 10000000\n\n const inertia: Transition = {\n type: \"inertia\",\n velocity: dragMomentum ? velocity[axis] : 0,\n bounceStiffness,\n bounceDamping,\n timeConstant: 750,\n restDelta: 1,\n restSpeed: 10,\n ...dragTransition,\n ...transition,\n }\n\n // If we're not animating on an externally-provided `MotionValue` we can use the\n // component's animation controls which will handle interactions with whileHover (etc),\n // otherwise we just have to animate the `MotionValue` itself.\n return this.startAxisValueAnimation(axis, inertia)\n })\n\n // Run all animations and then resolve the new drag constraints.\n return Promise.all(momentumAnimations).then(onDragTransitionEnd)\n }\n\n private startAxisValueAnimation(\n axis: DragDirection,\n transition: Transition\n ) {\n const axisValue = this.getAxisMotionValue(axis)\n\n addValueToWillChange(this.visualElement, axis)\n\n return axisValue.start(\n animateMotionValue(\n axis,\n axisValue,\n 0,\n transition,\n this.visualElement,\n false\n )\n )\n }\n\n private stopAnimation() {\n eachAxis((axis) => this.getAxisMotionValue(axis).stop())\n }\n\n private pauseAnimation() {\n eachAxis((axis) => this.getAxisMotionValue(axis).animation?.pause())\n }\n\n private getAnimationState(axis: DragDirection) {\n return this.getAxisMotionValue(axis).animation?.state\n }\n\n /**\n * Drag works differently depending on which props are provided.\n *\n * - If _dragX and _dragY are provided, we output the gesture delta directly to those motion values.\n * - Otherwise, we apply the delta to the x/y motion values.\n */\n private getAxisMotionValue(axis: DragDirection) {\n const dragKey =\n `_drag${axis.toUpperCase()}` as `_drag${Uppercase<DragDirection>}`\n const props = this.visualElement.getProps()\n const externalMotionValue = props[dragKey]\n\n return externalMotionValue\n ? externalMotionValue\n : this.visualElement.getValue(\n axis,\n (props.initial\n ? props.initial[axis as keyof typeof props.initial]\n : undefined) || 0\n )\n }\n\n private snapToCursor(point: Point) {\n eachAxis((axis) => {\n const { drag } = this.getProps()\n\n // If we're not dragging this axis, do an early return.\n if (!shouldDrag(axis, drag, this.currentDirection)) return\n\n const { projection } = this.visualElement\n const axisValue = this.getAxisMotionValue(axis)\n\n if (projection && projection.layout) {\n const { min, max } = projection.layout.layoutBox[axis]\n\n /**\n * The layout measurement includes the current transform value,\n * so we need to add it back to get the correct snap position.\n * This fixes an issue where elements with initial coordinates\n * would snap to the wrong position on the first drag.\n */\n const current = axisValue.get() || 0\n\n axisValue.set(point[axis] - mixNumber(min, max, 0.5) + current)\n }\n })\n }\n\n /**\n * When the viewport resizes we want to check if the measured constraints\n * have changed and, if so, reposition the element within those new constraints\n * relative to where it was before the resize.\n */\n scalePositionWithinConstraints() {\n if (!this.visualElement.current) return\n\n const { drag, dragConstraints } = this.getProps()\n const { projection } = this.visualElement\n if (!isRefObject(dragConstraints) || !projection || !this.constraints)\n return\n\n /**\n * Stop current animations as there can be visual glitching if we try to do\n * this mid-animation\n */\n this.stopAnimation()\n\n /**\n * Record the relative position of the dragged element relative to the\n * constraints box and save as a progress value.\n */\n const boxProgress = { x: 0, y: 0 }\n eachAxis((axis) => {\n const axisValue = this.getAxisMotionValue(axis)\n if (axisValue && this.constraints !== false) {\n const latest = axisValue.get()\n boxProgress[axis] = calcOrigin(\n { min: latest, max: latest },\n this.constraints[axis] as Axis\n )\n }\n })\n\n /**\n * Update the layout of this element and resolve the latest drag constraints\n */\n const { transformTemplate } = this.visualElement.getProps()\n this.visualElement.current.style.transform = transformTemplate\n ? transformTemplate({}, \"\")\n : \"none\"\n projection.root && projection.root.updateScroll()\n projection.updateLayout()\n this.resolveConstraints()\n\n /**\n * For each axis, calculate the current progress of the layout axis\n * within the new constraints.\n */\n eachAxis((axis) => {\n if (!shouldDrag(axis, drag, null)) return\n\n /**\n * Calculate a new transform based on the previous box progress\n */\n const axisValue = this.getAxisMotionValue(axis)\n const { min, max } = (this.constraints as ResolvedConstraints)[\n axis\n ] as Axis\n axisValue.set(mixNumber(min, max, boxProgress[axis]))\n })\n }\n\n addListeners() {\n if (!this.visualElement.current) return\n elementDragControls.set(this.visualElement, this)\n const element = this.visualElement.current\n\n /**\n * Attach a pointerdown event listener on this DOM element to initiate drag tracking.\n */\n const stopPointerListener = addPointerEvent(\n element,\n \"pointerdown\",\n (event) => {\n const { drag, dragListener = true } = this.getProps()\n drag && dragListener && this.start(event)\n }\n )\n\n const measureDragConstraints = () => {\n const { dragConstraints } = this.getProps()\n if (isRefObject(dragConstraints) && dragConstraints.current) {\n this.constraints = this.resolveRefConstraints()\n }\n }\n\n const { projection } = this.visualElement\n\n const stopMeasureLayoutListener = projection!.addEventListener(\n \"measure\",\n measureDragConstraints\n )\n\n if (projection && !projection!.layout) {\n projection.root && projection.root.updateScroll()\n projection.updateLayout()\n }\n\n frame.read(measureDragConstraints)\n\n /**\n * Attach a window resize listener to scale the draggable target within its defined\n * constraints as the window resizes.\n */\n const stopResizeListener = addDomEvent(window, \"resize\", () =>\n this.scalePositionWithinConstraints()\n )\n\n /**\n * If the element's layout changes, calculate the delta and apply that to\n * the drag gesture's origin point.\n */\n const stopLayoutUpdateListener = projection!.addEventListener(\n \"didUpdate\",\n (({ delta, hasLayoutChanged }: LayoutUpdateData) => {\n if (this.isDragging && hasLayoutChanged) {\n eachAxis((axis) => {\n const motionValue = this.getAxisMotionValue(axis)\n if (!motionValue) return\n\n this.originPoint[axis] += delta[axis].translate\n motionValue.set(\n motionValue.get() + delta[axis].translate\n )\n })\n\n this.visualElement.render()\n }\n }) as any\n )\n\n return () => {\n stopResizeListener()\n stopPointerListener()\n stopMeasureLayoutListener()\n stopLayoutUpdateListener && stopLayoutUpdateListener()\n }\n }\n\n getProps(): MotionProps {\n const props = this.visualElement.getProps()\n const {\n drag = false,\n dragDirectionLock = false,\n dragPropagation = false,\n dragConstraints = false,\n dragElastic = defaultElastic,\n dragMomentum = true,\n } = props\n return {\n ...props,\n drag,\n dragDirectionLock,\n dragPropagation,\n dragConstraints,\n dragElastic,\n dragMomentum,\n }\n }\n}\n\nfunction shouldDrag(\n direction: DragDirection,\n drag: boolean | DragDirection | undefined,\n currentDirection: null | DragDirection\n) {\n return (\n (drag === true || drag === direction) &&\n (currentDirection === null || currentDirection === direction)\n )\n}\n\n/**\n * Based on an x/y offset determine the current drag direction. If both axis' offsets are lower\n * than the provided threshold, return `null`.\n *\n * @param offset - The x/y offset from origin.\n * @param lockThreshold - (Optional) - the minimum absolute offset before we can determine a drag direction.\n */\nfunction getCurrentDirection(\n offset: Point,\n lockThreshold = 10\n): DragDirection | null {\n let direction: DragDirection | null = null\n\n if (Math.abs(offset.y) > lockThreshold) {\n direction = \"y\"\n } else if (Math.abs(offset.x) > lockThreshold) {\n direction = \"x\"\n }\n\n return direction\n}\n\nexport function expectsResolvedDragConstraints({\n dragConstraints,\n onMeasureDragConstraints,\n}: MotionProps) {\n return isRefObject(dragConstraints) && !!onMeasureDragConstraints\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VisualElementDragControls.mjs","sources":["../../../../src/gestures/drag/VisualElementDragControls.ts"],"sourcesContent":["import {\n isElementKeyboardAccessible,\n PanInfo,\n ResolvedConstraints,\n Transition,\n frame,\n mixNumber,\n percent,\n setDragLock,\n} from \"motion-dom\"\nimport { Axis, Point, invariant } from \"motion-utils\"\nimport { animateMotionValue } from \"../../animation/interfaces/motion-value\"\nimport { addDomEvent } from \"../../events/add-dom-event\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { MotionProps } from \"../../motion/types\"\nimport {\n convertBoundingBoxToBox,\n convertBoxToBoundingBox,\n} from \"../../projection/geometry/conversion\"\nimport { calcLength } from \"../../projection/geometry/delta-calc\"\nimport { createBox } from \"../../projection/geometry/models\"\nimport { LayoutUpdateData } from \"../../projection/node/types\"\nimport { eachAxis } from \"../../projection/utils/each-axis\"\nimport { measurePageBox } from \"../../projection/utils/measure\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { getContextWindow } from \"../../utils/get-context-window\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { addValueToWillChange } from \"../../value/use-will-change/add-will-change\"\nimport { PanSession } from \"../pan/PanSession\"\nimport {\n applyConstraints,\n calcOrigin,\n calcRelativeConstraints,\n calcViewportConstraints,\n defaultElastic,\n rebaseAxisConstraints,\n resolveDragElastic,\n} from \"./utils/constraints\"\n\nexport const elementDragControls = new WeakMap<\n VisualElement,\n VisualElementDragControls\n>()\n\nexport interface DragControlOptions {\n /**\n * This distance after which dragging starts and a direction is locked in.\n *\n * @public\n */\n distanceThreshold?: number\n\n /**\n * Whether to immediately snap to the cursor when dragging starts.\n *\n * @public\n */\n snapToCursor?: boolean\n}\n\ntype DragDirection = \"x\" | \"y\"\n\nexport class VisualElementDragControls {\n private visualElement: VisualElement<HTMLElement>\n\n private panSession?: PanSession\n\n private openDragLock: VoidFunction | null = null\n\n isDragging = false\n private currentDirection: DragDirection | null = null\n\n private originPoint: Point = { x: 0, y: 0 }\n\n /**\n * The permitted boundaries of travel, in pixels.\n */\n private constraints: ResolvedConstraints | false = false\n\n private hasMutatedConstraints = false\n\n /**\n * The per-axis resolved elastic values.\n */\n private elastic = createBox()\n\n /**\n * The latest pointer event. Used as fallback when the `cancel` and `stop` functions are called without arguments.\n */\n private latestPointerEvent: PointerEvent | null = null\n\n /**\n * The latest pan info. Used as fallback when the `cancel` and `stop` functions are called without arguments.\n */\n private latestPanInfo: PanInfo | null = null\n\n constructor(visualElement: VisualElement<HTMLElement>) {\n this.visualElement = visualElement\n }\n\n start(\n originEvent: PointerEvent,\n { snapToCursor = false, distanceThreshold }: DragControlOptions = {}\n ) {\n /**\n * Don't start dragging if this component is exiting\n */\n const { presenceContext } = this.visualElement\n if (presenceContext && presenceContext.isPresent === false) return\n\n const onSessionStart = (event: PointerEvent) => {\n // Stop or pause animations based on context:\n // - snapToCursor: stop because we'll set new position values\n // - otherwise: pause to allow resume if no drag starts (for constraint animations)\n if (snapToCursor) {\n this.stopAnimation()\n this.snapToCursor(extractEventInfo(event).point)\n } else {\n this.pauseAnimation()\n }\n }\n\n const onStart = (event: PointerEvent, info: PanInfo) => {\n // Stop any paused animation so motion values reflect true current position\n // (pauseAnimation was called in onSessionStart to allow resume if no drag started)\n this.stopAnimation()\n\n // Attempt to grab the global drag gesture lock - maybe make this part of PanSession\n const { drag, dragPropagation, onDragStart } = this.getProps()\n\n if (drag && !dragPropagation) {\n if (this.openDragLock) this.openDragLock()\n\n this.openDragLock = setDragLock(drag)\n\n // If we don 't have the lock, don't start dragging\n if (!this.openDragLock) return\n }\n\n this.latestPointerEvent = event\n this.latestPanInfo = info\n this.isDragging = true\n\n this.currentDirection = null\n\n this.resolveConstraints()\n\n if (this.visualElement.projection) {\n this.visualElement.projection.isAnimationBlocked = true\n this.visualElement.projection.target = undefined\n }\n\n /**\n * Record gesture origin\n */\n eachAxis((axis) => {\n let current = this.getAxisMotionValue(axis).get() || 0\n\n /**\n * If the MotionValue is a percentage value convert to px\n */\n if (percent.test(current)) {\n const { projection } = this.visualElement\n\n if (projection && projection.layout) {\n const measuredAxis = projection.layout.layoutBox[axis]\n\n if (measuredAxis) {\n const length = calcLength(measuredAxis)\n current = length * (parseFloat(current) / 100)\n }\n }\n }\n\n this.originPoint[axis] = current\n })\n\n // Fire onDragStart event\n if (onDragStart) {\n frame.postRender(() => onDragStart(event, info))\n }\n\n addValueToWillChange(this.visualElement, \"transform\")\n\n const { animationState } = this.visualElement\n animationState && animationState.setActive(\"whileDrag\", true)\n }\n\n const onMove = (event: PointerEvent, info: PanInfo) => {\n this.latestPointerEvent = event\n this.latestPanInfo = info\n\n const {\n dragPropagation,\n dragDirectionLock,\n onDirectionLock,\n onDrag,\n } = this.getProps()\n\n // If we didn't successfully receive the gesture lock, early return.\n if (!dragPropagation && !this.openDragLock) return\n\n const { offset } = info\n // Attempt to detect drag direction if directionLock is true\n if (dragDirectionLock && this.currentDirection === null) {\n this.currentDirection = getCurrentDirection(offset)\n\n // If we've successfully set a direction, notify listener\n if (this.currentDirection !== null) {\n onDirectionLock && onDirectionLock(this.currentDirection)\n }\n\n return\n }\n\n // Update each point with the latest position\n this.updateAxis(\"x\", info.point, offset)\n this.updateAxis(\"y\", info.point, offset)\n\n /**\n * Ideally we would leave the renderer to fire naturally at the end of\n * this frame but if the element is about to change layout as the result\n * of a re-render we want to ensure the browser can read the latest\n * bounding box to ensure the pointer and element don't fall out of sync.\n */\n this.visualElement.render()\n\n /**\n * This must fire after the render call as it might trigger a state\n * change which itself might trigger a layout update.\n */\n onDrag && onDrag(event, info)\n }\n\n const onSessionEnd = (event: PointerEvent, info: PanInfo) => {\n this.latestPointerEvent = event\n this.latestPanInfo = info\n\n this.stop(event, info)\n\n this.latestPointerEvent = null\n this.latestPanInfo = null\n }\n\n const resumeAnimation = () =>\n eachAxis(\n (axis) =>\n this.getAnimationState(axis) === \"paused\" &&\n this.getAxisMotionValue(axis).animation?.play()\n )\n\n const { dragSnapToOrigin } = this.getProps()\n this.panSession = new PanSession(\n originEvent,\n {\n onSessionStart,\n onStart,\n onMove,\n onSessionEnd,\n resumeAnimation,\n },\n {\n transformPagePoint: this.visualElement.getTransformPagePoint(),\n dragSnapToOrigin,\n distanceThreshold,\n contextWindow: getContextWindow(this.visualElement),\n }\n )\n }\n\n /**\n * @internal\n */\n stop(event?: PointerEvent, panInfo?: PanInfo) {\n const finalEvent = event || this.latestPointerEvent\n const finalPanInfo = panInfo || this.latestPanInfo\n\n const isDragging = this.isDragging\n this.cancel()\n if (!isDragging || !finalPanInfo || !finalEvent) return\n\n const { velocity } = finalPanInfo\n this.startAnimation(velocity)\n\n const { onDragEnd } = this.getProps()\n if (onDragEnd) {\n frame.postRender(() => onDragEnd(finalEvent, finalPanInfo))\n }\n }\n\n /**\n * @internal\n */\n cancel() {\n this.isDragging = false\n\n const { projection, animationState } = this.visualElement\n\n if (projection) {\n projection.isAnimationBlocked = false\n }\n\n this.panSession && this.panSession.end()\n this.panSession = undefined\n\n const { dragPropagation } = this.getProps()\n\n if (!dragPropagation && this.openDragLock) {\n this.openDragLock()\n this.openDragLock = null\n }\n\n animationState && animationState.setActive(\"whileDrag\", false)\n }\n\n private updateAxis(axis: DragDirection, _point: Point, offset?: Point) {\n const { drag } = this.getProps()\n\n // If we're not dragging this axis, do an early return.\n if (!offset || !shouldDrag(axis, drag, this.currentDirection)) return\n\n const axisValue = this.getAxisMotionValue(axis)\n let next = this.originPoint[axis] + offset[axis]\n\n // Apply constraints\n if (this.constraints && this.constraints[axis]) {\n next = applyConstraints(\n next,\n this.constraints[axis],\n this.elastic[axis]\n )\n }\n\n axisValue.set(next)\n }\n\n private resolveConstraints() {\n const { dragConstraints, dragElastic } = this.getProps()\n\n const layout =\n this.visualElement.projection &&\n !this.visualElement.projection.layout\n ? this.visualElement.projection.measure(false)\n : this.visualElement.projection?.layout\n\n const prevConstraints = this.constraints\n\n if (dragConstraints && isRefObject(dragConstraints)) {\n if (!this.constraints) {\n this.constraints = this.resolveRefConstraints()\n }\n } else {\n if (dragConstraints && layout) {\n this.constraints = calcRelativeConstraints(\n layout.layoutBox,\n dragConstraints\n )\n } else {\n this.constraints = false\n }\n }\n\n this.elastic = resolveDragElastic(dragElastic)\n\n /**\n * If we're outputting to external MotionValues, we want to rebase the measured constraints\n * from viewport-relative to component-relative.\n */\n if (\n prevConstraints !== this.constraints &&\n layout &&\n this.constraints &&\n !this.hasMutatedConstraints\n ) {\n eachAxis((axis) => {\n if (\n this.constraints !== false &&\n this.getAxisMotionValue(axis)\n ) {\n this.constraints[axis] = rebaseAxisConstraints(\n layout.layoutBox[axis],\n this.constraints[axis]\n )\n }\n })\n }\n }\n\n private resolveRefConstraints() {\n const { dragConstraints: constraints, onMeasureDragConstraints } =\n this.getProps()\n if (!constraints || !isRefObject(constraints)) return false\n\n const constraintsElement = constraints.current as HTMLElement\n\n invariant(\n constraintsElement !== null,\n \"If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.\",\n \"drag-constraints-ref\"\n )\n\n const { projection } = this.visualElement\n\n // TODO\n if (!projection || !projection.layout) return false\n\n const constraintsBox = measurePageBox(\n constraintsElement,\n projection.root!,\n this.visualElement.getTransformPagePoint()\n )\n\n let measuredConstraints = calcViewportConstraints(\n projection.layout.layoutBox,\n constraintsBox\n )\n\n /**\n * If there's an onMeasureDragConstraints listener we call it and\n * if different constraints are returned, set constraints to that\n */\n if (onMeasureDragConstraints) {\n const userConstraints = onMeasureDragConstraints(\n convertBoxToBoundingBox(measuredConstraints)\n )\n\n this.hasMutatedConstraints = !!userConstraints\n\n if (userConstraints) {\n measuredConstraints = convertBoundingBoxToBox(userConstraints)\n }\n }\n\n return measuredConstraints\n }\n\n private startAnimation(velocity: Point) {\n const {\n drag,\n dragMomentum,\n dragElastic,\n dragTransition,\n dragSnapToOrigin,\n onDragTransitionEnd,\n } = this.getProps()\n\n const constraints: Partial<ResolvedConstraints> = this.constraints || {}\n\n const momentumAnimations = eachAxis((axis) => {\n if (!shouldDrag(axis, drag, this.currentDirection)) {\n return\n }\n\n let transition = (constraints && constraints[axis]) || {}\n\n if (dragSnapToOrigin) transition = { min: 0, max: 0 }\n\n /**\n * Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame\n * of spring animations so we should look into adding a disable spring option to `inertia`.\n * We could do something here where we affect the `bounceStiffness` and `bounceDamping`\n * using the value of `dragElastic`.\n */\n const bounceStiffness = dragElastic ? 200 : 1000000\n const bounceDamping = dragElastic ? 40 : 10000000\n\n const inertia: Transition = {\n type: \"inertia\",\n velocity: dragMomentum ? velocity[axis] : 0,\n bounceStiffness,\n bounceDamping,\n timeConstant: 750,\n restDelta: 1,\n restSpeed: 10,\n ...dragTransition,\n ...transition,\n }\n\n // If we're not animating on an externally-provided `MotionValue` we can use the\n // component's animation controls which will handle interactions with whileHover (etc),\n // otherwise we just have to animate the `MotionValue` itself.\n return this.startAxisValueAnimation(axis, inertia)\n })\n\n // Run all animations and then resolve the new drag constraints.\n return Promise.all(momentumAnimations).then(onDragTransitionEnd)\n }\n\n private startAxisValueAnimation(\n axis: DragDirection,\n transition: Transition\n ) {\n const axisValue = this.getAxisMotionValue(axis)\n\n addValueToWillChange(this.visualElement, axis)\n\n return axisValue.start(\n animateMotionValue(\n axis,\n axisValue,\n 0,\n transition,\n this.visualElement,\n false\n )\n )\n }\n\n private stopAnimation() {\n eachAxis((axis) => this.getAxisMotionValue(axis).stop())\n }\n\n private pauseAnimation() {\n eachAxis((axis) => this.getAxisMotionValue(axis).animation?.pause())\n }\n\n private getAnimationState(axis: DragDirection) {\n return this.getAxisMotionValue(axis).animation?.state\n }\n\n /**\n * Drag works differently depending on which props are provided.\n *\n * - If _dragX and _dragY are provided, we output the gesture delta directly to those motion values.\n * - Otherwise, we apply the delta to the x/y motion values.\n */\n private getAxisMotionValue(axis: DragDirection) {\n const dragKey =\n `_drag${axis.toUpperCase()}` as `_drag${Uppercase<DragDirection>}`\n const props = this.visualElement.getProps()\n const externalMotionValue = props[dragKey]\n\n return externalMotionValue\n ? externalMotionValue\n : this.visualElement.getValue(\n axis,\n (props.initial\n ? props.initial[axis as keyof typeof props.initial]\n : undefined) || 0\n )\n }\n\n private snapToCursor(point: Point) {\n eachAxis((axis) => {\n const { drag } = this.getProps()\n\n // If we're not dragging this axis, do an early return.\n if (!shouldDrag(axis, drag, this.currentDirection)) return\n\n const { projection } = this.visualElement\n const axisValue = this.getAxisMotionValue(axis)\n\n if (projection && projection.layout) {\n const { min, max } = projection.layout.layoutBox[axis]\n\n /**\n * The layout measurement includes the current transform value,\n * so we need to add it back to get the correct snap position.\n * This fixes an issue where elements with initial coordinates\n * would snap to the wrong position on the first drag.\n */\n const current = axisValue.get() || 0\n\n axisValue.set(point[axis] - mixNumber(min, max, 0.5) + current)\n }\n })\n }\n\n /**\n * When the viewport resizes we want to check if the measured constraints\n * have changed and, if so, reposition the element within those new constraints\n * relative to where it was before the resize.\n */\n scalePositionWithinConstraints() {\n if (!this.visualElement.current) return\n\n const { drag, dragConstraints } = this.getProps()\n const { projection } = this.visualElement\n if (!isRefObject(dragConstraints) || !projection || !this.constraints)\n return\n\n /**\n * Stop current animations as there can be visual glitching if we try to do\n * this mid-animation\n */\n this.stopAnimation()\n\n /**\n * Record the relative position of the dragged element relative to the\n * constraints box and save as a progress value.\n */\n const boxProgress = { x: 0, y: 0 }\n eachAxis((axis) => {\n const axisValue = this.getAxisMotionValue(axis)\n if (axisValue && this.constraints !== false) {\n const latest = axisValue.get()\n boxProgress[axis] = calcOrigin(\n { min: latest, max: latest },\n this.constraints[axis] as Axis\n )\n }\n })\n\n /**\n * Update the layout of this element and resolve the latest drag constraints\n */\n const { transformTemplate } = this.visualElement.getProps()\n this.visualElement.current.style.transform = transformTemplate\n ? transformTemplate({}, \"\")\n : \"none\"\n projection.root && projection.root.updateScroll()\n projection.updateLayout()\n this.resolveConstraints()\n\n /**\n * For each axis, calculate the current progress of the layout axis\n * within the new constraints.\n */\n eachAxis((axis) => {\n if (!shouldDrag(axis, drag, null)) return\n\n /**\n * Calculate a new transform based on the previous box progress\n */\n const axisValue = this.getAxisMotionValue(axis)\n const { min, max } = (this.constraints as ResolvedConstraints)[\n axis\n ] as Axis\n axisValue.set(mixNumber(min, max, boxProgress[axis]))\n })\n }\n\n addListeners() {\n if (!this.visualElement.current) return\n elementDragControls.set(this.visualElement, this)\n const element = this.visualElement.current\n\n /**\n * Attach a pointerdown event listener on this DOM element to initiate drag tracking.\n */\n const stopPointerListener = addPointerEvent(\n element,\n \"pointerdown\",\n (event) => {\n const { drag, dragListener = true } = this.getProps()\n if (\n drag &&\n dragListener &&\n !isElementKeyboardAccessible(event.target as Element)\n ) {\n this.start(event)\n }\n }\n )\n\n const measureDragConstraints = () => {\n const { dragConstraints } = this.getProps()\n if (isRefObject(dragConstraints) && dragConstraints.current) {\n this.constraints = this.resolveRefConstraints()\n }\n }\n\n const { projection } = this.visualElement\n\n const stopMeasureLayoutListener = projection!.addEventListener(\n \"measure\",\n measureDragConstraints\n )\n\n if (projection && !projection!.layout) {\n projection.root && projection.root.updateScroll()\n projection.updateLayout()\n }\n\n frame.read(measureDragConstraints)\n\n /**\n * Attach a window resize listener to scale the draggable target within its defined\n * constraints as the window resizes.\n */\n const stopResizeListener = addDomEvent(window, \"resize\", () =>\n this.scalePositionWithinConstraints()\n )\n\n /**\n * If the element's layout changes, calculate the delta and apply that to\n * the drag gesture's origin point.\n */\n const stopLayoutUpdateListener = projection!.addEventListener(\n \"didUpdate\",\n (({ delta, hasLayoutChanged }: LayoutUpdateData) => {\n if (this.isDragging && hasLayoutChanged) {\n eachAxis((axis) => {\n const motionValue = this.getAxisMotionValue(axis)\n if (!motionValue) return\n\n this.originPoint[axis] += delta[axis].translate\n motionValue.set(\n motionValue.get() + delta[axis].translate\n )\n })\n\n this.visualElement.render()\n }\n }) as any\n )\n\n return () => {\n stopResizeListener()\n stopPointerListener()\n stopMeasureLayoutListener()\n stopLayoutUpdateListener && stopLayoutUpdateListener()\n }\n }\n\n getProps(): MotionProps {\n const props = this.visualElement.getProps()\n const {\n drag = false,\n dragDirectionLock = false,\n dragPropagation = false,\n dragConstraints = false,\n dragElastic = defaultElastic,\n dragMomentum = true,\n } = props\n return {\n ...props,\n drag,\n dragDirectionLock,\n dragPropagation,\n dragConstraints,\n dragElastic,\n dragMomentum,\n }\n }\n}\n\nfunction shouldDrag(\n direction: DragDirection,\n drag: boolean | DragDirection | undefined,\n currentDirection: null | DragDirection\n) {\n return (\n (drag === true || drag === direction) &&\n (currentDirection === null || currentDirection === direction)\n )\n}\n\n/**\n * Based on an x/y offset determine the current drag direction. If both axis' offsets are lower\n * than the provided threshold, return `null`.\n *\n * @param offset - The x/y offset from origin.\n * @param lockThreshold - (Optional) - the minimum absolute offset before we can determine a drag direction.\n */\nfunction getCurrentDirection(\n offset: Point,\n lockThreshold = 10\n): DragDirection | null {\n let direction: DragDirection | null = null\n\n if (Math.abs(offset.y) > lockThreshold) {\n direction = \"y\"\n } else if (Math.abs(offset.x) > lockThreshold) {\n direction = \"x\"\n }\n\n return direction\n}\n\nexport function expectsResolvedDragConstraints({\n dragConstraints,\n onMeasureDragConstraints,\n}: MotionProps) {\n return isRefObject(dragConstraints) && !!onMeasureDragConstraints\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -59,8 +59,11 @@ class PanSession {
|
|
|
59
59
|
this.handlePointerUp = (event, info) => {
|
|
60
60
|
this.end();
|
|
61
61
|
const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
|
|
62
|
-
if (
|
|
62
|
+
// Resume animation if dragSnapToOrigin is set OR if no drag started (user just clicked)
|
|
63
|
+
// This ensures constraint animations continue when interrupted by a click
|
|
64
|
+
if (this.dragSnapToOrigin || !this.startEvent) {
|
|
63
65
|
resumeAnimation && resumeAnimation();
|
|
66
|
+
}
|
|
64
67
|
if (!(this.lastMoveEvent && this.lastMoveEventInfo))
|
|
65
68
|
return;
|
|
66
69
|
const panInfo = getPanInfo(event.type === "pointercancel"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PanSession.mjs","sources":["../../../../src/gestures/pan/PanSession.ts"],"sourcesContent":["import type { EventInfo, PanHandler } from \"motion-dom\"\nimport { cancelFrame, frame, frameData, isPrimaryPointer } from \"motion-dom\"\nimport {\n millisecondsToSeconds,\n pipe,\n Point,\n secondsToMilliseconds,\n TransformPoint,\n} from \"motion-utils\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { distance2D } from \"../../utils/distance\"\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\n distanceThreshold?: number\n contextWindow?: (Window & typeof globalThis) | null\n}\n\ninterface TimestampedPoint extends Point {\n timestamp: number\n}\n\n/**\n * @internal\n */\nexport class PanSession {\n /**\n * @internal\n */\n private history: TimestampedPoint[]\n\n /**\n * @internal\n */\n private startEvent: PointerEvent | null = null\n\n /**\n * @internal\n */\n private lastMoveEvent: PointerEvent | null = null\n\n /**\n * @internal\n */\n private lastMoveEventInfo: EventInfo | null = null\n\n /**\n * @internal\n */\n private transformPagePoint?: TransformPoint\n\n /**\n * @internal\n */\n private handlers: Partial<PanSessionHandlers> = {}\n\n /**\n * @internal\n */\n private removeListeners: Function\n\n /**\n * For determining if an animation should resume after it is interupted\n *\n * @internal\n */\n private dragSnapToOrigin: boolean\n\n /**\n * The distance after which panning should start.\n *\n * @internal\n */\n private distanceThreshold: number\n\n /**\n * @internal\n */\n private contextWindow: PanSessionOptions[\"contextWindow\"] = window\n\n constructor(\n event: PointerEvent,\n handlers: Partial<PanSessionHandlers>,\n {\n transformPagePoint,\n contextWindow = window,\n dragSnapToOrigin = false,\n distanceThreshold = 3,\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 = 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 const { timestamp } = frameData\n\n this.history = [{ ...point, timestamp }]\n\n const { onSessionStart } = handlers\n onSessionStart &&\n onSessionStart(event, getPanInfo(initialInfo, this.history))\n\n this.removeListeners = pipe(\n addPointerEvent(\n this.contextWindow,\n \"pointermove\",\n this.handlePointerMove\n ),\n addPointerEvent(\n this.contextWindow,\n \"pointerup\",\n this.handlePointerUp\n ),\n addPointerEvent(\n this.contextWindow,\n \"pointercancel\",\n this.handlePointerUp\n )\n )\n }\n\n private updatePoint = () => {\n if (!(this.lastMoveEvent && this.lastMoveEventInfo)) return\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 const { timestamp } = frameData\n this.history.push({ ...point, timestamp })\n\n const { onStart, onMove } = this.handlers\n\n if (!isPanStarted) {\n onStart && onStart(this.lastMoveEvent, info)\n this.startEvent = this.lastMoveEvent\n }\n\n onMove && onMove(this.lastMoveEvent, info)\n }\n\n private handlePointerMove = (event: PointerEvent, info: EventInfo) => {\n this.lastMoveEvent = event\n this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint)\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 this.end()\n\n const { onEnd, onSessionEnd, resumeAnimation } = this.handlers\n\n if (this.dragSnapToOrigin) resumeAnimation && resumeAnimation()\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 if (this.startEvent && onEnd) {\n onEnd(event, panInfo)\n }\n\n onSessionEnd && onSessionEnd(event, panInfo)\n }\n\n updateHandlers(handlers: Partial<PanSessionHandlers>) {\n this.handlers = handlers\n }\n\n end() {\n this.removeListeners && this.removeListeners()\n cancelFrame(this.updatePoint)\n }\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 const time = millisecondsToSeconds(\n lastPoint.timestamp - timestampedPoint.timestamp\n )\n if (time === 0) {\n return { x: 0, y: 0 }\n }\n\n const currentVelocity = {\n x: (lastPoint.x - timestampedPoint.x) / time,\n y: (lastPoint.y - timestampedPoint.y) / time,\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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"}
|
|
1
|
+
{"version":3,"file":"PanSession.mjs","sources":["../../../../src/gestures/pan/PanSession.ts"],"sourcesContent":["import type { EventInfo, PanHandler } from \"motion-dom\"\nimport { cancelFrame, frame, frameData, isPrimaryPointer } from \"motion-dom\"\nimport {\n millisecondsToSeconds,\n pipe,\n Point,\n secondsToMilliseconds,\n TransformPoint,\n} from \"motion-utils\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { distance2D } from \"../../utils/distance\"\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\n distanceThreshold?: number\n contextWindow?: (Window & typeof globalThis) | null\n}\n\ninterface TimestampedPoint extends Point {\n timestamp: number\n}\n\n/**\n * @internal\n */\nexport class PanSession {\n /**\n * @internal\n */\n private history: TimestampedPoint[]\n\n /**\n * @internal\n */\n private startEvent: PointerEvent | null = null\n\n /**\n * @internal\n */\n private lastMoveEvent: PointerEvent | null = null\n\n /**\n * @internal\n */\n private lastMoveEventInfo: EventInfo | null = null\n\n /**\n * @internal\n */\n private transformPagePoint?: TransformPoint\n\n /**\n * @internal\n */\n private handlers: Partial<PanSessionHandlers> = {}\n\n /**\n * @internal\n */\n private removeListeners: Function\n\n /**\n * For determining if an animation should resume after it is interupted\n *\n * @internal\n */\n private dragSnapToOrigin: boolean\n\n /**\n * The distance after which panning should start.\n *\n * @internal\n */\n private distanceThreshold: number\n\n /**\n * @internal\n */\n private contextWindow: PanSessionOptions[\"contextWindow\"] = window\n\n constructor(\n event: PointerEvent,\n handlers: Partial<PanSessionHandlers>,\n {\n transformPagePoint,\n contextWindow = window,\n dragSnapToOrigin = false,\n distanceThreshold = 3,\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 = 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 const { timestamp } = frameData\n\n this.history = [{ ...point, timestamp }]\n\n const { onSessionStart } = handlers\n onSessionStart &&\n onSessionStart(event, getPanInfo(initialInfo, this.history))\n\n this.removeListeners = pipe(\n addPointerEvent(\n this.contextWindow,\n \"pointermove\",\n this.handlePointerMove\n ),\n addPointerEvent(\n this.contextWindow,\n \"pointerup\",\n this.handlePointerUp\n ),\n addPointerEvent(\n this.contextWindow,\n \"pointercancel\",\n this.handlePointerUp\n )\n )\n }\n\n private updatePoint = () => {\n if (!(this.lastMoveEvent && this.lastMoveEventInfo)) return\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 const { timestamp } = frameData\n this.history.push({ ...point, timestamp })\n\n const { onStart, onMove } = this.handlers\n\n if (!isPanStarted) {\n onStart && onStart(this.lastMoveEvent, info)\n this.startEvent = this.lastMoveEvent\n }\n\n onMove && onMove(this.lastMoveEvent, info)\n }\n\n private handlePointerMove = (event: PointerEvent, info: EventInfo) => {\n this.lastMoveEvent = event\n this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint)\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 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 && 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 if (this.startEvent && onEnd) {\n onEnd(event, panInfo)\n }\n\n onSessionEnd && onSessionEnd(event, panInfo)\n }\n\n updateHandlers(handlers: Partial<PanSessionHandlers>) {\n this.handlers = handlers\n }\n\n end() {\n this.removeListeners && this.removeListeners()\n cancelFrame(this.updatePoint)\n }\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 const time = millisecondsToSeconds(\n lastPoint.timestamp - timestampedPoint.timestamp\n )\n if (time === 0) {\n return { x: 0, y: 0 }\n }\n\n const currentVelocity = {\n x: (lastPoint.x - timestampedPoint.x) / time,\n y: (lastPoint.y - timestampedPoint.y) / time,\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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"}
|
|
@@ -606,6 +606,17 @@
|
|
|
606
606
|
return singleCssVariableRegex.test(value.split("/*")[0].trim());
|
|
607
607
|
};
|
|
608
608
|
const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
|
|
609
|
+
/**
|
|
610
|
+
* Check if a value contains a CSS variable anywhere (e.g. inside calc()).
|
|
611
|
+
* Unlike isCSSVariableToken which checks if the value IS a var() token,
|
|
612
|
+
* this checks if the value CONTAINS var() somewhere in the string.
|
|
613
|
+
*/
|
|
614
|
+
function containsCSSVariable(value) {
|
|
615
|
+
if (typeof value !== "string")
|
|
616
|
+
return false;
|
|
617
|
+
// Strip comments to avoid false positives
|
|
618
|
+
return value.split("/*")[0].includes("var(--");
|
|
619
|
+
}
|
|
609
620
|
|
|
610
621
|
const number = {
|
|
611
622
|
test: (v) => typeof v === "number",
|
|
@@ -3326,6 +3337,16 @@
|
|
|
3326
3337
|
const [origin, target] = unresolvedKeyframes;
|
|
3327
3338
|
const originType = findDimensionValueType(origin);
|
|
3328
3339
|
const targetType = findDimensionValueType(target);
|
|
3340
|
+
/**
|
|
3341
|
+
* If one keyframe contains embedded CSS variables (e.g. in calc()) and the other
|
|
3342
|
+
* doesn't, we need to measure to convert to pixels. This handles GitHub issue #3410.
|
|
3343
|
+
*/
|
|
3344
|
+
const originHasVar = containsCSSVariable(origin);
|
|
3345
|
+
const targetHasVar = containsCSSVariable(target);
|
|
3346
|
+
if (originHasVar !== targetHasVar && positionalValues[name]) {
|
|
3347
|
+
this.needsMeasurement = true;
|
|
3348
|
+
return;
|
|
3349
|
+
}
|
|
3329
3350
|
/**
|
|
3330
3351
|
* Either we don't recognise these value types or we can animate between them.
|
|
3331
3352
|
*/
|
|
@@ -4198,16 +4219,24 @@
|
|
|
4198
4219
|
}
|
|
4199
4220
|
};
|
|
4200
4221
|
|
|
4201
|
-
const
|
|
4222
|
+
const interactiveElements = new Set([
|
|
4202
4223
|
"BUTTON",
|
|
4203
4224
|
"INPUT",
|
|
4204
4225
|
"SELECT",
|
|
4205
4226
|
"TEXTAREA",
|
|
4206
4227
|
"A",
|
|
4207
4228
|
]);
|
|
4229
|
+
/**
|
|
4230
|
+
* Checks if an element is an interactive form element that should prevent
|
|
4231
|
+
* drag gestures from starting when clicked.
|
|
4232
|
+
*
|
|
4233
|
+
* This specifically targets form controls, buttons, and links - not just any
|
|
4234
|
+
* element with tabIndex, since motion elements with tap handlers automatically
|
|
4235
|
+
* get tabIndex=0 for keyboard accessibility.
|
|
4236
|
+
*/
|
|
4208
4237
|
function isElementKeyboardAccessible(element) {
|
|
4209
|
-
return (
|
|
4210
|
-
element.
|
|
4238
|
+
return (interactiveElements.has(element.tagName) ||
|
|
4239
|
+
element.isContentEditable === true);
|
|
4211
4240
|
}
|
|
4212
4241
|
|
|
4213
4242
|
const isPressing = new WeakSet();
|
|
@@ -10826,8 +10855,11 @@
|
|
|
10826
10855
|
this.handlePointerUp = (event, info) => {
|
|
10827
10856
|
this.end();
|
|
10828
10857
|
const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
|
|
10829
|
-
if (
|
|
10858
|
+
// Resume animation if dragSnapToOrigin is set OR if no drag started (user just clicked)
|
|
10859
|
+
// This ensures constraint animations continue when interrupted by a click
|
|
10860
|
+
if (this.dragSnapToOrigin || !this.startEvent) {
|
|
10830
10861
|
resumeAnimation && resumeAnimation();
|
|
10862
|
+
}
|
|
10831
10863
|
if (!(this.lastMoveEvent && this.lastMoveEventInfo))
|
|
10832
10864
|
return;
|
|
10833
10865
|
const panInfo = getPanInfo(event.type === "pointercancel"
|
|
@@ -11076,15 +11108,21 @@
|
|
|
11076
11108
|
if (presenceContext && presenceContext.isPresent === false)
|
|
11077
11109
|
return;
|
|
11078
11110
|
const onSessionStart = (event) => {
|
|
11079
|
-
|
|
11080
|
-
//
|
|
11081
|
-
//
|
|
11082
|
-
dragSnapToOrigin ? this.pauseAnimation() : this.stopAnimation();
|
|
11111
|
+
// Stop or pause animations based on context:
|
|
11112
|
+
// - snapToCursor: stop because we'll set new position values
|
|
11113
|
+
// - otherwise: pause to allow resume if no drag starts (for constraint animations)
|
|
11083
11114
|
if (snapToCursor) {
|
|
11115
|
+
this.stopAnimation();
|
|
11084
11116
|
this.snapToCursor(extractEventInfo(event).point);
|
|
11085
11117
|
}
|
|
11118
|
+
else {
|
|
11119
|
+
this.pauseAnimation();
|
|
11120
|
+
}
|
|
11086
11121
|
};
|
|
11087
11122
|
const onStart = (event, info) => {
|
|
11123
|
+
// Stop any paused animation so motion values reflect true current position
|
|
11124
|
+
// (pauseAnimation was called in onSessionStart to allow resume if no drag started)
|
|
11125
|
+
this.stopAnimation();
|
|
11088
11126
|
// Attempt to grab the global drag gesture lock - maybe make this part of PanSession
|
|
11089
11127
|
const { drag, dragPropagation, onDragStart } = this.getProps();
|
|
11090
11128
|
if (drag && !dragPropagation) {
|
|
@@ -11450,7 +11488,11 @@
|
|
|
11450
11488
|
*/
|
|
11451
11489
|
const stopPointerListener = addPointerEvent(element, "pointerdown", (event) => {
|
|
11452
11490
|
const { drag, dragListener = true } = this.getProps();
|
|
11453
|
-
drag &&
|
|
11491
|
+
if (drag &&
|
|
11492
|
+
dragListener &&
|
|
11493
|
+
!isElementKeyboardAccessible(event.target)) {
|
|
11494
|
+
this.start(event);
|
|
11495
|
+
}
|
|
11454
11496
|
});
|
|
11455
11497
|
const measureDragConstraints = () => {
|
|
11456
11498
|
const { dragConstraints } = this.getProps();
|
|
@@ -14353,6 +14395,7 @@
|
|
|
14353
14395
|
exports.collectMotionValues = collectMotionValues;
|
|
14354
14396
|
exports.color = color;
|
|
14355
14397
|
exports.complex = complex;
|
|
14398
|
+
exports.containsCSSVariable = containsCSSVariable;
|
|
14356
14399
|
exports.convertOffsetToTimes = convertOffsetToTimes;
|
|
14357
14400
|
exports.createBox = createBox;
|
|
14358
14401
|
exports.createGeneratorEasing = createGeneratorEasing;
|
|
@@ -14415,6 +14458,7 @@
|
|
|
14415
14458
|
exports.isDragActive = isDragActive;
|
|
14416
14459
|
exports.isDragging = isDragging;
|
|
14417
14460
|
exports.isEasingArray = isEasingArray;
|
|
14461
|
+
exports.isElementKeyboardAccessible = isElementKeyboardAccessible;
|
|
14418
14462
|
exports.isGenerator = isGenerator;
|
|
14419
14463
|
exports.isHTMLElement = isHTMLElement;
|
|
14420
14464
|
exports.isMotionComponent = isMotionComponent;
|