UNPKG

framer-motion

Version:

A simple and powerful JavaScript animation library

63 lines (60 loc) • 2.31 kB
import { Feature, addPinchListeners } from 'motion-dom'; const valueKeys = ["scale", "rotate", "x", "y"]; class PinchGesture extends Feature { constructor() { super(...arguments); this.touchAction = ""; } mount() { const { current } = this.node; if (!current) return; this.touchAction = current.style.touchAction; this.update(); /** * The latest enabled options. addPinchListeners reads them before * each step of a gesture, so they're current when a callback runs, * and a pinch disabled mid-way still calls its `onEnd`. */ let options = {}; /** * Call the prop's `onStart`, `onMove` or `onEnd`, so each can * change mid-gesture. */ const call = (key) => (event, info) => options[key]?.(event, info); this.unmount = addPinchListeners(current, () => valueKeys.map((key) => this.node.getValue(key, key === "scale" ? 1 : 0)), () => { const { pinch } = this.node.getProps(); return pinch && (options = pinch === true ? {} : pinch); }, (_element, event, info) => { const setActive = (isActive) => this.node.animationState?.setActive("whilePinch", isActive); setActive(true); call("onStart")(event, info); return { onPinch: call("onMove"), onComplete: (event, info) => { setActive(false); call("onEnd")(event, info); }, }; }); } /** * Stop touches panning or zooming the page while pinch is on, unless * `style` sets a `touchAction` (like "pan-y" for a list that scrolls * with one finger). Set here rather than when rendering, so the default * bundle doesn't pay for it, and on every update, as React rewrites it * when drag's axis changes. */ update() { const style = this.node.current?.style; if (style) { const { pinch, style: props } = this.node.getProps(); style.touchAction = pinch ? props?.touchAction || "none" : this.touchAction; } } unmount() { } } export { PinchGesture }; //# sourceMappingURL=pinch.mjs.map