Framer motion gestures
Skill C-Jeril/framer-motion-skills/skills/framer-motion-gestures
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.From its SKILL.md
npx -y skills add C-Jeril/framer-motion-skills --skill framer-motion-gesturesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.2 KB, as published. Nobody here has run it
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:
<motion.div
drag="x"
dragConstraints={{ left: -100, right: 100 }}
whileDrag={{ scale: 1.1, cursor: "grabbing" }}
/>
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
<motion.div
drag
dragConstraints={{
left: -100,
right: 100,
top: -50,
bottom: 50
}}
/>
Ref-based Constraints
function Draggable() {
const constraintsRef = useRef(null);
return (
<>
<motion.div
ref={constraintsRef}
style={{
width: 500,
height: 500,
backgroundColor: "#eee"
}}
/>
<motion.div
drag
dragConstraints={constraintsRef}
/>
</>
);
}
Pan
Pan is similar to drag but for pointer/touch:
<motion.div
drag="x"
onDrag={(e, info) => {
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:
<motion.button
whileTap={{ scale: 0.95, opacity: 0.8 }}
whileHover={{ scale: 1.05 }}
>
Click me
</motion.button>
Hover (whileHover)
Animation on hover:
<motion.div
whileHover={{ scale: 1.1, backgroundColor: "#ff0000" }}
style={{ width: 100, height: 100, backgroundColor: "#00ff00" }}
/>
onHoverStart / onHoverEnd
<motion.div
onHoverStart={() => console.log("Hover started")}
onHoverEnd={() => console.log("Hover ended")}
/>
Focus (whileFocus)
Animation when focused (keyboard):
<motion.input
whileFocus={{ scale: 1.05, borderColor: "#00ff00" }}
style={{ borderWidth: 2 }}
/>
Drag with Spring Physics
<motion.div
drag="x"
dragConstraints={{ left: -200, right: 200 }}
dragTransition={{
type: "spring",
stiffness: 300,
damping: 20,
mass: 1
}}
/>
Drag Controls with Constraints
function DraggableBox() {
const constraintsRef = useRef(null);
return (
<>
<motion.div
ref={constraintsRef}
style={{
width: 500,
height: 500,
backgroundColor: "#f0f0f0"
}}
/>
{[1, 2, 3].map(i => (
<motion.div
key={i}
drag
dragConstraints={constraintsRef}
dragMomentum={false}
whileDrag={{ scale: 1.1 }}
/>
))}
</>
);
}
Swipe Detection
function Swipeable() {
const x = useMotionValue(0);
const { scrollYProgress } = useScroll();
const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0]);
return (
<motion.div
style={{ x, opacity }}
drag="x"
dragConstraints={{ left: 0, right: 0 }}
dragElastic={1}
/>
);
}
Gesture State Info
Callbacks receive PointInfo and DragInfo:
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
dragwithoutdragConstraintsif 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/