--- name: framer-motion-gestures description: Official Framer Motion skill for gesture animations — drag, pan, tap, hover, focus, touch animations. Use when building interactive elements with drag, pan, tap, hover, or touch gestures, or when asking about Framer Motion drag constraints, gesture handlers, or interactive animations. license: MIT --- # Framer Motion Gestures ## When to Use This Skill Apply when implementing gesture-driven animations: drag, pan, tap, hover, focus, or touch interactions. When the user asks about drag-and-drop, interactive elements, or gesture-based UI in Framer Motion. **Related skills:** For core animation use **framer-motion-core**; for variants use **framer-motion-variants**; for layout animations use **framer-motion-layout**. ## Drag Enable dragging with the `drag` prop: ```jsx ``` ### Drag Props | Prop | Type | Description | |------|------|-------------| | **drag** | `bool \| "x" \| "y"` | Enable drag on axis | | **dragConstraints** | `object \| RefObject` | Movement constraints | | **dragMomentum** | `boolean` | Continue momentum after release (default: true) | | **dragElastic** | `number \| object` | Elasticity of bounds (default: 0) | | **dragTransition** | `Transition` | Spring config for momentum | | **whileDrag** | `MotionProps` | Animation while dragging | | **onDrag** | `function` | Callback during drag | | **onDragStart** | `function` | Callback when drag starts | | **onDragEnd** | `function` | Callback when drag ends | ### Drag Constraints ```jsx ``` ### Ref-based Constraints ```jsx function Draggable() { const constraintsRef = useRef(null); return ( <> ); } ``` ## Pan Pan is similar to drag but for pointer/touch: ```jsx { console.log("Position:", info.point); console.log("Velocity:", info.velocity); }} /> ``` ### Pan vs Drag - **Drag**: Mouse/touch with visual feedback, momentum, and constraints - **Pan**: Lower-level pointer tracking without momentum ## Tap (whileTap) Animation when pressed: ```jsx Click me ``` ## Hover (whileHover) Animation on hover: ```jsx ``` ### onHoverStart / onHoverEnd ```jsx console.log("Hover started")} onHoverEnd={() => console.log("Hover ended")} /> ``` ## Focus (whileFocus) Animation when focused (keyboard): ```jsx ``` ## Drag with Spring Physics ```jsx ``` ## Drag Controls with Constraints ```jsx function DraggableBox() { const constraintsRef = useRef(null); return ( <> {[1, 2, 3].map(i => ( ))} ); } ``` ## Swipe Detection ```jsx function Swipeable() { const x = useMotionValue(0); const { scrollYProgress } = useScroll(); const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0]); return ( ); } ``` ## Gesture State Info Callbacks receive `PointInfo` and `DragInfo`: ```jsx onDrag={(e, info) => { info.point // { x, y } position info.velocity // { x, y } velocity info.offset // { x, y } offset from start }} ``` ## Best practices - ✅ Use **dragConstraints** to keep elements within bounds. - ✅ Use **dragElastic** for bounce-back effects. - ✅ Use **whileDrag** for visual feedback during drag. - ✅ Use **dragMomentum** for natural continuation. - ✅ Use **dragTransition** with spring for physics-based drag. - ✅ Use refs for constraints when dragging within a container. ## Do Not - ❌ Use `drag` without `dragConstraints` if the element should stay within bounds. - ❌ Forget that drag events only fire after the pointer moves a threshold. - ❌ Use excessive `dragElastic` — it can cause visual glitches. - ❌ Animate conflicting properties during drag (e.g., scale and x). ### Learn More https://www.framer.com/motion/gestures/ https://www.framer.com/motion/drag/