{}}
onHoverEnd={(event, info) => {}}
onTap={(event, info) => {}}
onTapStart={(event, info) => {}}
onTapCancel={(event, info) => {}}
onDragStart={(event, info) => {}}
onDrag={(event, info) => {}}
onDragEnd={(event, info) => {}}
onViewportEnter={(entry) => {}}
onViewportLeave={(entry) => {}}
/>
```
**Event info objects contain:**
- `point: { x, y }` - Page coordinates
- `offset: { x, y }` - Offset from drag start
- `velocity: { x, y }` - Drag velocity
## Hooks
### useAnimate
Manually control animations with the `useAnimate` hook:
```jsx
import { useAnimate } from "framer-motion"
function Component() {
const [scope, animate] = useAnimate()
useEffect(() => {
// Animate multiple elements
animate([
[scope.current, { opacity: 1 }],
["li", { x: 0, opacity: 1 }, { delay: stagger(0.1) }],
[".button", { scale: 1.2 }]
])
}, [])
return (
)
}
```
**Animation controls:**
```jsx
const controls = animate(element, { x: 100 })
controls.play()
controls.pause()
controls.stop()
controls.speed = 0.5
controls.time = 0 // Seek to start
```
### useSpring
Create spring-animated motion values:
```jsx
import { useSpring } from "framer-motion"
function Component() {
const x = useSpring(0, { stiffness: 300, damping: 20 })
return (
)
}
```
### useInView
Detect when an element is in viewport:
```jsx
import { useInView } from "framer-motion"
function Component() {
const ref = useRef(null)
const isInView = useInView(ref, { once: true, amount: 0.5 })
return (
{isInView ? "In view!" : "Not in view"}
)
}
```
## Integration Patterns
### With GSAP
Combine Motion for React state-based animations and GSAP for complex timelines:
```jsx
import { motion } from "framer-motion"
import gsap from "gsap"
function Component() {
const boxRef = useRef()
const handleClick = () => {
// Use GSAP for complex timeline
const tl = gsap.timeline()
tl.to(boxRef.current, { rotation: 360, duration: 1 })
.to(boxRef.current, { scale: 1.5, duration: 0.5 })
}
return (
// Use Motion for hover/tap/layout animations
)
}
```
### With React Three Fiber
Animate 3D objects using Motion values:
```jsx
import { motion } from "framer-motion"
import { useFrame } from "@react-three/fiber"
function Box() {
const x = useMotionValue(0)
useFrame(() => {
// Sync Motion value with Three.js position
meshRef.current.position.x = x.get()
})
return (
<>
>
)
}
```
### With Form Libraries
Animate form validation states:
```jsx
import { motion, AnimatePresence } from "framer-motion"
function FormField({ error }) {
return (
)
}
```
## Performance Optimization
### 1. Use Transform Properties
Transform properties (x, y, scale, rotate) are hardware-accelerated:
```jsx
// ✅ Good - Hardware accelerated
// ❌ Avoid - Triggers layout/paint
```
### 2. Individual Transform Properties
Motion supports individual transform properties for cleaner code:
```jsx
// Individual properties (Motion feature)
// Traditional (also supported)
```
### 3. Reduce Motion for Accessibility
Respect user preferences for reduced motion:
```jsx
import { useReducedMotion } from "framer-motion"
function Component() {
const shouldReduceMotion = useReducedMotion()
return (
)
}
```
### 4. Layout Animations Performance
Layout animations can be expensive. Optimize with:
```jsx
// Specify what to animate
// Only position, not size
// Optimize transition
```
### 5. Use layoutId Sparingly
`layoutId` creates shared layout animations but tracks elements globally. Use only when needed.
## Common Pitfalls
### 1. Forgetting AnimatePresence for Exit Animations
**Problem:** Exit animations don't work
```jsx
// ❌ Wrong - No AnimatePresence
{show && }
```
```jsx
// ✅ Correct - Wrapped in AnimatePresence
{show && }
```
### 2. Missing key Prop in Lists
**Problem:** AnimatePresence can't track elements
```jsx
// ❌ Wrong - No key
{items.map(item => )}
```
```jsx
// ✅ Correct - Unique keys
{items.map(item => (
))}
```
### 3. Animating Non-Transform Properties
**Problem:** Janky animations, poor performance
```jsx
// ❌ Avoid - Not hardware accelerated
```
```jsx
// ✅ Better - Use transforms
```
### 4. Overusing Layout Animations
**Problem:** Performance issues with many layout-animated elements
```jsx
// ❌ Too many layout animations
{items.map(item => {item})}
```
```jsx
// ✅ Use layout only where needed, optimize others
{items.map(item => (
))}
```
### 5. Not Using Variants for Complex Animations
**Problem:** Duplicated animation code, no child orchestration
```jsx
// ❌ Repetitive
```
```jsx
// ✅ Use variants
const variants = {
hidden: { opacity: 0 },
visible: { opacity: 1 }
}
```
### 6. Incorrect Transition Timing
**Problem:** Transitions don't apply to specific gestures
```jsx
// ❌ Wrong - General transition won't apply to whileHover
```
```jsx
// ✅ Correct - Transition in whileHover or separate gesture transition
```
## Resources
### Official Documentation
- [Motion Docs](https://motion.dev/) - Official Motion documentation
- [Framer Motion Docs](https://www.framer.com/motion/) - Framer Motion (legacy)
- [Motion GitHub](https://github.com/framer/motion) - Source code & examples
### Bundled Resources
This skill includes:
**references/**
- `api_reference.md` - Complete Motion API reference
- `variants_patterns.md` - Variant patterns and orchestration
- `gesture_guide.md` - Comprehensive gesture handling guide
**scripts/**
- `animation_generator.py` - Generate Motion component boilerplate
- `variant_builder.py` - Interactive variant configuration tool
**assets/**
- `starter_motion/` - Complete Motion + Vite starter template
- `examples/` - Real-world Motion component patterns
### Community Resources
- [Motion Dev Discord](https://discord.gg/motion) - Official community
- [Framer Motion Examples](https://www.framer.com/motion/examples/) - Interactive examples
- [Motion Recipes](https://motion.dev/docs/recipes) - Common patterns
- [CodeSandbox Templates](https://codesandbox.io/s/framer-motion-examples) - Live demos