motion-dom
Version:
1 lines • 48.5 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../src/gestures/pinch/index.ts"],"sourcesContent":["import { clamp, type Point } from \"motion-utils\"\nimport { spring } from \"../../animation/generators/spring\"\nimport type { SpringOptions } from \"../../animation/types\"\nimport { readStyleValue, styleSubjectEffect } from \"../../effects/style\"\nimport { svgSubjectEffect } from \"../../effects/svg\"\nimport { cancelFrame, frame } from \"../../frameloop\"\nimport { time } from \"../../frameloop/sync-time\"\nimport { visualElementStore } from \"../../render/store\"\nimport { activeScope, addToScope } from \"../../scope/active\"\nimport { isSVGElement } from \"../../utils/is-svg-element\"\nimport { mixNumber } from \"../../utils/mix/number\"\nimport {\n resolveElements,\n type ElementOrSelector,\n} from \"../../utils/resolve-elements\"\nimport { motionValue, type MotionValue } from \"../../value\"\nimport { setDragLock } from \"../drag/state/set-active\"\nimport { applyConstraints, defaultElastic } from \"../drag/utils/constraints\"\nimport { elementDragControls } from \"../drag/VisualElementDragControls\"\n\n/**\n * @public\n */\nexport interface PinchInfo {\n /**\n * The gesture's focal point in client coordinates: the midpoint\n * between two touches, or the cursor for a trackpad pinch.\n */\n point: Point\n\n /**\n * How far the focal point has moved since the gesture started.\n */\n offset: Point\n\n /**\n * The gesture's scale relative to its start.\n */\n scale: number\n\n /**\n * The gesture's rotation since its start, in degrees.\n */\n rotate: number\n}\n\n/**\n * Called with the latest event and the gesture's info.\n *\n * @public\n */\nexport type OnPinchEvent = (event: Event, info: PinchInfo) => void\n\n/**\n * Handlers for a single pinch gesture, returned from the pinch start\n * callback.\n *\n * @public\n */\nexport interface PinchHandlers {\n /**\n * Called each frame the gesture changes, after the element's values\n * are updated.\n */\n onPinch?: OnPinchEvent\n\n /**\n * Called once when the gesture ends: a touch lifts or is cancelled, a\n * trackpad pinch stops, or the gesture is disabled or removed.\n *\n * Returning this function directly from the pinch start callback is\n * equivalent.\n */\n onComplete?: OnPinchEvent\n}\n\n/**\n * Called once when a pinch gesture starts: when a second touch lands, on\n * the first trackpad pinch event, or on Safari's `gesturestart`. Can\n * return a function to call when the pinch ends, or an object of\n * `PinchHandlers`.\n *\n * @public\n */\nexport type OnPinchStartEvent = (\n element: Element,\n event: Event\n) => OnPinchEvent | PinchHandlers | void\n\n/**\n * The limits of a pinch's scale or rotation.\n *\n * @public\n */\nexport interface PinchLimits {\n /**\n * The minimum. Past it, the gesture resists by `elastic`, and the\n * value springs back to it on release.\n */\n min?: number\n\n /**\n * The maximum. Past it, the gesture resists by `elastic`, and the\n * value springs back to it on release.\n */\n max?: number\n}\n\n/**\n * @public\n */\nexport interface PinchRotateOptions extends PinchLimits {\n /**\n * On release, rotate to the nearest multiple of this many degrees.\n */\n snap?: number\n}\n\n/**\n * @public\n */\nexport interface PinchOptions {\n /**\n * Scale the element. Defaults to `true`. Pass `{ min, max }` to limit\n * the scale.\n */\n scale?: boolean | PinchLimits\n\n /**\n * Rotate the element with the touches. Defaults to `true`. Pass\n * `{ min, max }` (in degrees) to limit the rotation, and `snap` to\n * rotate to the nearest multiple of `snap` degrees on release.\n */\n rotate?: boolean | PinchRotateOptions\n\n /**\n * Move the element with the focal point, and keep the point under the\n * fingers (or cursor) in place while scaling and rotating. Defaults to\n * `true`. Composes with drag: a drag that one of the touches started\n * carries on from wherever the pinch leaves the element (its offset\n * restarts there). Drag constraints aren't applied while pinching.\n *\n * Assumes the default `transform-origin` (the element's centre).\n */\n pan?: boolean\n\n /**\n * The point that scale and rotation pivot around. `\"pointer\"` (the\n * default) is the focal point between the touches, or the cursor.\n * `{ x, y }` is a point on the element, as a fraction of its width\n * and height: `{ x: 0.5, y: 0.5 }` is its centre. With `pan: false`,\n * the default is the centre.\n */\n origin?: \"pointer\" | Point\n\n /**\n * How far scale and rotation can go past their limits, as for\n * `dragElastic`: `0` stops at the limit, `1` doesn't resist. Pass\n * `{ min, max }` to set each side. Defaults to `0.35`.\n */\n elastic?: boolean | number | PinchLimits\n\n /**\n * On release, animate scale back to `1`, and rotation and `x`/`y`\n * back to `0`.\n */\n snapToOrigin?: boolean\n\n /**\n * The spring values use to animate back inside their limits, to a\n * `snap` angle or to their origin.\n */\n transition?: SpringOptions\n}\n\n/**\n * Options for the `pinch` prop.\n *\n * @public\n */\nexport interface PinchProps extends PinchOptions {\n /**\n * Called when the pinch starts.\n */\n onStart?: OnPinchEvent\n\n /**\n * Called each frame the pinch changes.\n */\n onMove?: OnPinchEvent\n\n /**\n * Called when the pinch ends.\n */\n onEnd?: OnPinchEvent\n}\n\nexport type PinchValues = [\n scale: MotionValue<number>,\n rotate: MotionValue<number>,\n x: MotionValue<number>,\n y: MotionValue<number>,\n]\n\n/**\n * A trackpad pinch arrives as a stream of `wheel` events with no end\n * event, so it ends once none have arrived for this long.\n */\nconst wheelTimeout = 150\n\n/**\n * Convert an `x`/`y` set in other units (e.g. `\"-50%\"` to centre an\n * element) to pixels, so the gesture can add to it.\n */\nconst toPixels = (value: MotionValue<number>, size: number) => {\n const latest = value.get() as number | string\n\n if (typeof latest === \"string\") {\n value.set(parseFloat(latest) * (latest.endsWith(\"%\") ? size / 100 : 1))\n }\n}\n\nconst limitsOf = (option?: boolean | PinchRotateOptions): PinchRotateOptions =>\n typeof option === \"object\" ? option : {}\n\n/**\n * Resolve `elastic` to a resistance for each side, as for `dragElastic`.\n */\nconst resolveElastic = (\n elastic: PinchOptions[\"elastic\"] = defaultElastic\n): { min: number; max: number } => {\n const side = (value?: number | boolean) =>\n value === true ? defaultElastic : +(value || 0)\n\n return typeof elastic === \"object\"\n ? { min: side(elastic.min), max: side(elastic.max) }\n : { min: side(elastic), max: side(elastic) }\n}\n\n/**\n * Whether the gesture writes `x`/`y`: to follow the focal point, or to\n * keep an `origin` on the element in place.\n */\nconst writesXY = ({ pan, origin }: PinchOptions) => pan !== false || !!origin\n\nconst clampTo = (value: number, { min = -Infinity, max = Infinity }) =>\n clamp(min, max, value)\n\n/**\n * The raw gesture value that elastic shows as `value`. A pinch that starts\n * while a value is still past its limit (like during a spring back) carries\n * on from it, rather than jumping.\n */\nconst unconstrain = (\n value: number,\n option: boolean | PinchRotateOptions | undefined,\n resistance: { min: number; max: number }\n) => {\n const limit = clampTo(value, limitsOf(option))\n const elastic = resistance[value < limit ? \"min\" : \"max\"]\n\n return elastic ? limit + (value - limit) / elastic : value\n}\n\n/**\n * Listen for pinch gestures on `element`: two touches (or pens), a trackpad\n * pinch (`wheel` with `ctrlKey`, as Chrome, Edge and Firefox report it),\n * and Safari's `gesture*` events.\n *\n * `getValues` is called each time a gesture starts, in the frame's read\n * step, for the scale/rotate/x/y values to write to. It runs alongside the\n * element measurement so neither forces a layout.\n *\n * `getOptions` is read whenever it's needed, so options can change while\n * listening. Return `false` to disable the gesture, which also ends one in\n * progress.\n *\n * `onPinchStart` is called once as each gesture starts, with the gesture's\n * info as a third argument. It can return the gesture's handlers, as for\n * `pinch()`.\n */\nexport function addPinchListeners(\n element: Element,\n getValues: () => PinchValues,\n getEnabledOptions: () => PinchOptions | false | undefined,\n onPinchStart: (\n element: Element,\n event: Event,\n info: PinchInfo\n ) => ReturnType<OnPinchStartEvent>\n): VoidFunction {\n const pointers = new Map<number, Point>()\n\n /**\n * The gesture as last reported: focal point, log of a distance and an\n * angle. Only changes in distance and angle matter, so trackpad and\n * Safari input write a virtual distance (the scale) here. Logs keep\n * a long trackpad pinch from overflowing.\n */\n const current = { x: 0, y: 0, l: 0, a: 0 }\n const start = { ...current }\n const prev = { ...current }\n\n let source: \"pointer\" | \"wheel\" | \"gesture\" | undefined\n let lastEvent: Event\n let values: PinchValues | undefined\n let originX = 0\n let originY = 0\n let width = 0\n let height = 0\n let lastX = 0\n let lastY = 0\n let hasMoved = false\n let wheelTime = 0\n let handlers: PinchHandlers = {}\n let unlock: VoidFunction | null | undefined\n\n /**\n * The gesture's scale and rotation before limits and elastic apply.\n */\n let rawScale = 1\n let rawRotate = 0\n let stopSnap = () => {}\n\n /**\n * The latest enabled options, so a gesture disabled mid-way can still\n * report its end.\n */\n let options: PinchOptions = {}\n const getOptions = () => (options = getEnabledOptions() || options)\n\n const info = (): PinchInfo => ({\n point: { x: current.x, y: current.y },\n offset: { x: current.x - start.x, y: current.y - start.y },\n scale: Math.exp(current.l - start.l),\n rotate: current.a - start.a,\n })\n\n /**\n * Read the element's box and values, and find its layout origin: its\n * centre without `x`/`y`. Scale and rotate are applied around the\n * centre (the default transform origin), so they don't move it.\n */\n const measure = () => {\n const box = element.getBoundingClientRect()\n const { left, top } = box\n const { scale, rotate, elastic } = getOptions()\n const [s, r, x, y] = (values = getValues())\n const resistance = resolveElastic(elastic)\n\n /**\n * Stop animations on values this gesture writes, and leave the\n * rest running.\n */\n scale !== false && s.stop()\n rotate !== false && r.stop()\n rawScale = unconstrain(s.get(), scale, resistance)\n rawRotate = unconstrain(r.get(), rotate, resistance)\n\n width = (element as HTMLElement).offsetWidth ?? box.width\n height = (element as HTMLElement).offsetHeight ?? box.height\n\n if (writesXY(options)) {\n x.stop()\n y.stop()\n toPixels(x, width)\n toPixels(y, height)\n }\n\n lastX = x.get()\n lastY = y.get()\n originX = left + box.width / 2 - lastX\n originY = top + box.height / 2 - lastY\n }\n\n /**\n * The point scale and rotation pivot around, in client coordinates:\n * the focal point, or `origin` on the element at scale `s`, rotation\n * `r` and offset `x`/`y`.\n */\n const pivot = (\n focal: Point,\n s: number,\n r: number,\n x: number,\n y: number\n ): Point => {\n const { origin } = options\n if (typeof origin !== \"object\") return focal\n\n const a = (r * Math.PI) / 180\n const u = (origin.x - 0.5) * width * s\n const v = (origin.y - 0.5) * height * s\n\n return {\n x: originX + x + Math.cos(a) * u - Math.sin(a) * v,\n y: originY + y + Math.sin(a) * u + Math.cos(a) * v,\n }\n }\n\n const dragControls = () =>\n elementDragControls.get(visualElementStore.get(element)!)\n\n /**\n * On release, spring scale and rotation back inside their limits (or\n * to a `snap` angle), keeping the focal point in place, or everything\n * back to its origin with `snapToOrigin`.\n */\n const snap = () => {\n const {\n scale: scaleOption,\n rotate: rotateOption,\n snapToOrigin,\n transition,\n } = options\n const [scale, rotate, x, y] = values!\n const s0 = scale.get()\n const r0 = rotate.get()\n const x0 = x.get()\n const y0 = y.get()\n const { snap: step } = limitsOf(rotateOption)\n let s1 = clampTo(s0, limitsOf(scaleOption))\n /**\n * Snap to the step nearest where the release velocity would carry\n * the rotation, found as inertia finds its target (with a lower power\n * than inertia's 0.8).\n */\n let r1 = clampTo(\n step\n ? Math.round((r0 + 0.2 * rotate.getVelocity()) / step) * step\n : r0,\n limitsOf(rotateOption)\n )\n\n if (snapToOrigin) {\n s1 = 1\n // The nearest upright angle, so it turns the shortest way\n r1 = Math.round(r0 / 360) * 360\n }\n\n /**\n * Keep the focal point in place, unless the element doesn't move\n * with it, or a drag carries on and owns x/y.\n */\n const moves = writesXY(options) && !dragControls()?.isDragging\n const p0 = pivot(current, s0, r0, x0, y0)\n const vx = originX + x0 - p0.x\n const vy = originY + y0 - p0.y\n\n /**\n * Scale, rotation and x/y at progress `p` of the snap, keeping the\n * focal point in place.\n */\n const at = (p: number) => {\n const k = mixNumber(s0, s1, p)\n const r = mixNumber(r0, r1, p)\n const angle = ((r - r0) * Math.PI) / 180\n const cos = (Math.cos(angle) * k) / s0\n const sin = (Math.sin(angle) * k) / s0\n return [\n k,\n r,\n x0 + cos * vx - sin * vy - vx,\n y0 + sin * vx + cos * vy - vy,\n ]\n }\n\n if (\n !s0 ||\n (s1 === s0 && r1 === r0 && !(snapToOrigin && moves && (x0 || y0)))\n ) {\n return\n }\n\n const generator = spring({\n keyframes: [0, 1],\n stiffness: 200,\n damping: 40,\n ...transition,\n })\n const startTime = time.now()\n\n /**\n * Drive the values from one spring, from 0 to 1, so they stay in\n * step and the focal point stays in place.\n */\n const tick = () => {\n const { value: p, done } = generator.next(time.now() - startTime)\n if (done) stopSnap()\n\n const [k, r, fx, fy] = at(p)\n\n scaleOption !== false && scale.set(k)\n rotateOption !== false && rotate.set(r)\n\n // A drag that starts mid-snap owns x/y from then on.\n if (moves && !dragControls()?.isDragging) {\n x.set(snapToOrigin ? mixNumber(x0, 0, p) : fx)\n y.set(snapToOrigin ? mixNumber(y0, 0, p) : fy)\n }\n }\n\n stopSnap = () => cancelFrame(tick)\n frame.update(tick, true)\n }\n\n /**\n * Apply the change in the gesture since the last frame as an\n * incremental scale and rotation around the previous focal point,\n * plus the focal point's movement.\n */\n const apply = () => {\n if (!values || !hasMoved) return\n hasMoved = false\n\n const {\n rotate: rotateOption,\n scale: scaleOption,\n pan,\n elastic,\n } = getOptions()\n const [scale, rotate, x, y] = values\n const resistance = resolveElastic(elastic)\n const latest = scale.get()\n const drag = dragControls()\n const isDragging = drag?.isDragging\n\n if (!isDragging) {\n lastX = x.get()\n lastY = y.get()\n }\n\n const p = pivot(prev, latest, rotate.get(), lastX, lastY)\n let theta = 0\n let k = 1\n\n /**\n * Apply limits and elastic to the gesture's raw scale and rotation.\n * At a hard limit, the raw value stops too, so moving back responds\n * straight away.\n */\n const constrain = (raw: number, option?: boolean | PinchLimits) => {\n const limits = limitsOf(option)\n const limit = clampTo(raw, limits)\n\n return resistance[raw < limit ? \"min\" : \"max\"]\n ? [applyConstraints(raw, limits, resistance), raw]\n : [limit, limit]\n }\n\n if (scaleOption !== false && latest) {\n const [next, raw] = constrain(\n clamp(1e-9, 1e9, rawScale * Math.exp(current.l - prev.l)),\n scaleOption\n )\n rawScale = raw\n k = next / latest\n scale.set(next)\n }\n\n if (rotateOption !== false) {\n const [next, raw] = constrain(\n rawRotate + current.a - prev.a,\n rotateOption\n )\n rawRotate = raw\n theta = next - rotate.get()\n if (theta) rotate.set(next)\n }\n\n if (writesXY(options)) {\n /**\n * Pinch owns x/y while it runs, so stop any animation started\n * on them since (like a drag's snap back) taking over after.\n */\n x.stop()\n y.stop()\n\n /**\n * If drag() or the drag prop is dragging this element with one\n * of the touches, it has set x/y this frame to where it started\n * plus the touch's offset. Carry on from our own values instead,\n * and restart the drag from them and the touch's latest point.\n * That way it continues from wherever the pinch leaves the\n * element, and its release velocity only counts movement after\n * the pinch, so a zoom doesn't end in a fling.\n */\n const angle = (theta * Math.PI) / 180\n const cos = Math.cos(angle) * k\n const sin = Math.sin(angle) * k\n const dx = p.x - originX - lastX\n const dy = p.y - originY - lastY\n const panX = pan !== false ? current.x - prev.x : 0\n const panY = pan !== false ? current.y - prev.y : 0\n\n /**\n * Move the centre so the pivot, scaled and rotated around the\n * centre, stays in place, plus the focal point's movement.\n */\n lastX += dx + panX - (cos * dx - sin * dy)\n lastY += dy + panY - (sin * dx + cos * dy)\n\n if (isDragging) {\n const history = drag!.panSession!.history\n history.splice(0, history.length - 1)\n\n /**\n * Date the point long ago, so drag only measures release\n * velocity from moves after the pinch. A move that drag\n * processes as the touch lifts is part of the pinch.\n */\n history[0].timestamp = -Infinity\n drag!.originPoint.x = lastX\n drag!.originPoint.y = lastY\n }\n\n x.set(lastX)\n y.set(lastY)\n }\n\n Object.assign(prev, current)\n handlers.onPinch?.(lastEvent, info())\n }\n\n /**\n * Runs after the update step, where drag sets x/y, so it has the final\n * say on them each frame.\n */\n const update = () => {\n if (!getEnabledOptions()) return end(lastEvent)\n\n apply()\n\n if (source === \"wheel\" && time.now() - wheelTime > wheelTimeout) {\n end(lastEvent)\n }\n }\n\n const begin = (event: Event, from: typeof source) => {\n if (!getEnabledOptions()) return\n\n stopSnap()\n source = from\n lastEvent = event\n hasMoved = false\n values = undefined\n handlers = {}\n Object.assign(start, current)\n Object.assign(prev, current)\n frame.read(measure)\n frame.preRender(update, true)\n\n const result = onPinchStart(element, event, info())\n handlers =\n typeof result === \"function\" ? { onComplete: result } : result || {}\n }\n\n const end = (event: Event) => {\n if (!source) return\n cancelFrame(measure)\n cancelFrame(update)\n\n if (getEnabledOptions()) {\n apply()\n values && snap()\n }\n\n source = undefined\n handlers.onComplete?.(event, info())\n }\n\n const moved = (event: Event) => {\n lastEvent = event\n hasMoved = true\n }\n\n const readPointers = () => {\n const [a, b] = pointers.values()\n const angle = (Math.atan2(b.y - a.y, b.x - a.x) * 180) / Math.PI\n const delta = angle - current.a\n\n current.x = (a.x + b.x) / 2\n current.y = (a.y + b.y) / 2\n current.l = Math.log(Math.hypot(b.x - a.x, b.y - a.y) || 1)\n\n /**\n * Take the shortest way round, so rotation keeps counting past\n * 180deg rather than flipping to -180deg.\n */\n current.a += delta - 360 * Math.round(delta / 360)\n }\n\n const setPointer = (event: PointerEvent) =>\n pointers.set(event.pointerId, { x: event.clientX, y: event.clientY })\n\n const onPointerMove = (event: PointerEvent) => {\n if (!pointers.has(event.pointerId)) return\n setPointer(event)\n\n if (source === \"pointer\") {\n readPointers()\n moved(event)\n }\n }\n\n const onPointerUp = (event: PointerEvent) => {\n if (!pointers.delete(event.pointerId)) return\n\n if (source === \"pointer\") end(event)\n\n if (!pointers.size) {\n toggleWindowListeners()\n release()\n }\n }\n\n /**\n * Once a touch is down on the element, listen on the window too, so\n * the second touch can land beside it (for instance on a small image).\n */\n const onPointerDown = (event: PointerEvent) => {\n if (\n source ||\n pointers.size > 1 ||\n pointers.has(event.pointerId) ||\n event.pointerType === \"mouse\"\n ) {\n return\n }\n\n if (!pointers.size) toggleWindowListeners(true)\n setPointer(event)\n\n if (pointers.size === 2) {\n readPointers()\n begin(event, \"pointer\")\n\n /**\n * Unless this element drags, hold the drag lock until every\n * touch lifts. A press on it then ends as a cancel, rather than\n * a tap, and a draggable parent doesn't drag.\n */\n if (\n source &&\n !unlock &&\n !elementDragControls.get(visualElementStore.get(element)!)\n ) {\n unlock = setDragLock(true)\n }\n }\n }\n\n /**\n * Release the drag lock a frame later, so a press ending on this same\n * pointerup still sees it.\n */\n const release = () => {\n const done = unlock\n unlock = undefined\n done && frame.postRender(done)\n }\n\n const toggleWindowListeners = (add?: boolean) => {\n const method = add ? \"addEventListener\" : \"removeEventListener\"\n window[method](\"pointerdown\", onPointerDown as EventListener)\n window[method](\"pointermove\", onPointerMove as EventListener)\n window[method](\"pointerup\", onPointerUp as EventListener)\n window[method](\"pointercancel\", onPointerUp as EventListener)\n }\n\n const onWheel = (event: WheelEvent) => {\n if (!event.ctrlKey || (source && source !== \"wheel\")) return\n\n current.x = event.clientX\n current.y = event.clientY\n\n if (!source) {\n current.l = 0\n begin(event, \"wheel\")\n if (!source) return\n }\n\n event.preventDefault()\n\n /**\n * Lines (Firefox's mouse wheel) to pixels, and cap each event so a\n * mouse wheel notch with ctrl held (about 100px) zooms a step.\n */\n current.l -=\n clamp(-50, 50, event.deltaY * (event.deltaMode ? 16 : 1)) / 100\n wheelTime = time.now()\n moved(event)\n }\n\n /**\n * Safari reports trackpad pinches as `gesture*` events. iOS Safari\n * fires them for touches too, alongside the pointer events we track.\n */\n const onGesture = (event: Event) => {\n if (!pointers.size && (!source || source === \"gesture\")) {\n const { scale, rotation, clientX, clientY } = event as any\n current.x = clientX\n current.y = clientY\n current.l = Math.log(scale)\n current.a = rotation\n\n if (source) {\n moved(event)\n if (event.type === \"gestureend\") end(event)\n } else if (event.type === \"gesturestart\") {\n begin(event, \"gesture\")\n }\n }\n\n if (source) event.preventDefault()\n }\n\n const listeners = {\n pointerdown: onPointerDown,\n wheel: onWheel,\n gesturestart: onGesture,\n gesturechange: onGesture,\n gestureend: onGesture,\n }\n\n for (const name in listeners) {\n element.addEventListener(\n name,\n listeners[name as keyof typeof listeners] as EventListener,\n { passive: false }\n )\n }\n\n return () => {\n for (const name in listeners) {\n element.removeEventListener(\n name,\n listeners[name as keyof typeof listeners] as EventListener\n )\n }\n toggleWindowListeners()\n end(lastEvent)\n stopSnap()\n pointers.clear()\n release()\n }\n}\n\nconst valueKeys = [\"scale\", \"rotate\", \"x\", \"y\"]\n\n/**\n * The element's scale/rotate/x/y motion values: those of its\n * VisualElement if it has one (it's a <motion.*> component, or drag() or\n * animateLayout() own it), otherwise those animate() binds to it, created\n * from its current style if this is the first time.\n */\nconst getElementValues = (element: HTMLElement | SVGElement) => {\n const visualElement = visualElementStore.get(element)\n const effect = isSVGElement(element) ? svgSubjectEffect : styleSubjectEffect\n\n return valueKeys.map((key) => {\n if (visualElement) {\n return visualElement.getValue(key, key === \"scale\" ? 1 : 0)\n }\n\n let value = effect.get(element as any, key)\n\n if (!value) {\n value = motionValue(readStyleValue(element, key))\n effect(element as any, { [key]: value })\n }\n\n return value\n }) as PinchValues\n}\n\n/**\n * Make elements pinchable. Returns a function that removes the gesture.\n * The start callback is optional:\n *\n * ```javascript\n * pinch(\"img\")\n * pinch(\"img\", { scale: { min: 1, max: 4 } })\n * ```\n *\n * ```javascript\n * const stop = pinch(\"#photo\", (element, startEvent) => {\n * return (endEvent, info) => {}\n * }, { scale: { min: 1, max: 4 } })\n * ```\n *\n * `onPinchStart` is called once as each pinch starts. It can return a\n * function to call when the pinch ends, or an object of handlers:\n *\n * ```javascript\n * pinch(\"#photo\", () => ({\n * onPinch: (event, { scale }) => {},\n * onComplete: (event, info) => {},\n * }))\n * ```\n *\n * Touches, trackpad pinches and Safari's gesture events scale the element\n * around the focal point and move it with the touches. Its `scale`,\n * `rotate`, `x` and `y` are motion values shared with `animate()`, so an\n * `onComplete` handler can animate the element after a pinch.\n *\n * @public\n */\nexport function pinch(\n elementOrSelector: ElementOrSelector,\n options?: PinchOptions\n): VoidFunction\nexport function pinch(\n elementOrSelector: ElementOrSelector,\n onPinchStart?: OnPinchStartEvent,\n options?: PinchOptions\n): VoidFunction\nexport function pinch(\n elementOrSelector: ElementOrSelector,\n startOrOptions?: OnPinchStartEvent | PinchOptions,\n options: PinchOptions = {}\n): VoidFunction {\n let onPinchStart: OnPinchStartEvent = () => {}\n\n if (typeof startOrOptions === \"function\") {\n onPinchStart = startOrOptions\n } else if (startOrOptions) {\n options = startOrOptions\n }\n\n const scope = activeScope.current\n\n /**\n * Run the start callback and the handlers it returns in the active\n * scope, so work they start is collected. A returned function is\n * bound by `scope.bind` itself.\n */\n if (scope) {\n const start = scope.bind(onPinchStart)\n onPinchStart = (element, event) => {\n const result = start(element, event)\n if (typeof result !== \"object\") return result\n\n const handlers: PinchHandlers = {}\n for (const key in result) {\n const name = key as keyof PinchHandlers\n const handler = result[name]\n handlers[name] = handler && scope.bind(handler)\n }\n return handlers\n }\n }\n\n const cleanups = resolveElements(elementOrSelector).map((element) => {\n scope?.track(element)\n\n const { style } = element as HTMLElement\n const touchAction = style.touchAction\n style.touchAction = \"none\"\n\n const remove = addPinchListeners(\n element,\n () => getElementValues(element as HTMLElement),\n () => options,\n onPinchStart\n )\n\n return () => {\n remove()\n style.touchAction = touchAction\n }\n })\n\n return addToScope(() => cleanups.forEach((cleanup) => cleanup()))\n}\n"],"names":[],"mappings":"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"}