
Motion Animation Patterns
- 30 installs
- 213 repo stars
- Updated August 4, 2026
- yonatangross/orchestkit
Helps with ai & agent building tasks.
About
motion-animation-patterns is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- motion-animation-patterns
- AI & Agent Building
- AI-coding skill
Motion Animation Patterns by the numbers
- 30 all-time installs (skills.sh)
- Ranked #9,276 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yonatangross/orchestkit --skill motion-animation-patternsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 30 |
|---|---|
| repo stars | ★ 213 |
| Last updated | August 4, 2026 |
| Repository | yonatangross/orchestkit ↗ |
What it does
Helps with ai & agent building tasks.
Files
Motion Animation Patterns
Overview
This skill provides comprehensive guidance for implementing Motion (Framer Motion) animations in React 19 applications. It ensures consistent, performant, and accessible animations across the UI using centralized animation presets.
When to use this skill:
- Adding page transition animations
- Implementing modal/dialog entrance/exit animations
- Creating staggered list animations
- Adding hover and tap micro-interactions
- Implementing skeleton loading states
- Creating collapse/expand animations
- Building toast/notification animations
Bundled Resources:
references/animation-presets.md- Complete preset API referenceexamples/component-patterns.md- Common animation patterns
---
Core Architecture
Animation Presets Library (frontend/src/lib/animations.ts)
All animations MUST use the centralized animations.ts presets. This ensures:
- Consistent motion language across the app
- RTL-aware animations (Hebrew support)
- Performance optimization
- Easy maintainability
// ✅ CORRECT: Import from animations.ts
import { motion, AnimatePresence } from 'motion/react';
import { fadeIn, slideUp, staggerContainer, modalContent } from '@/lib/animations';
// ❌ WRONG: Inline animation values
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }}>---
Available Presets
Transition Timing
| Preset | Duration | Ease | Use For |
|---|---|---|---|
transitions.fast | 0.15s | easeOut | Micro-interactions |
transitions.normal | 0.2s | easeOut | Most animations |
transitions.slow | 0.3s | easeInOut | Emphasis effects |
transitions.spring | spring | 300/25 | Playful elements |
transitions.gentleSpring | spring | 200/20 | Modals/overlays |
Basic Animations
| Preset | Effect | Use For |
|---|---|---|
fadeIn | Opacity fade | Simple reveal |
fadeScale | Fade + slight scale | Subtle emphasis |
scaleIn | Fade + scale from center | Badges, buttons |
Slide Animations (RTL-Aware)
| Preset | Direction | Use For |
|---|---|---|
slideInRight | Right to center | RTL Hebrew UI (natural) |
slideInLeft | Left to center | LTR content |
slideUp | Bottom to center | Cards, panels |
slideDown | Top to center | Dropdowns |
List/Stagger Animations
| Preset | Effect | Use For |
|---|---|---|
staggerContainer | Parent with stagger | List wrappers |
staggerContainerFast | Fast stagger | Quick lists |
staggerItem | Fade + slide child | List items |
staggerItemRight | RTL slide child | Hebrew lists |
Modal/Dialog Animations
| Preset | Effect | Use For |
|---|---|---|
modalBackdrop | Overlay fade | Modal background |
modalContent | Scale + fade | Modal body |
sheetContent | Slide from bottom | Mobile sheets |
dropdownDown | Scale from top | Dropdown menus |
dropdownUp | Scale from bottom | Context menus |
Page Transitions
| Preset | Effect | Use For |
|---|---|---|
pageFade | Simple fade | Route changes |
pageSlide | RTL slide | Navigation |
Micro-Interactions
| Preset | Effect | Use For |
|---|---|---|
tapScale | Scale on tap | Buttons, cards |
hoverLift | Lift + shadow | Cards, list items |
buttonPress | Press effect | Interactive buttons |
cardHover | Hover emphasis | Card components |
Loading States
| Preset | Effect | Use For |
|---|---|---|
pulse | Opacity pulse | Skeleton loaders |
shimmer | Sliding highlight | Shimmer effect |
Utility Animations
| Preset | Effect | Use For |
|---|---|---|
toastSlideIn | Slide + scale | Notifications |
collapse | Height animation | Accordions |
---
Implementation Patterns
1. Page Transitions
Wrap routes with AnimatePresence for smooth page changes:
// frontend/src/components/AnimatedRoutes.tsx
import { Routes, Route, useLocation } from 'react-router';
import { AnimatePresence, motion } from 'motion/react';
import { pageFade } from '@/lib/animations';
export function AnimatedRoutes() {
const location = useLocation();
return (
<AnimatePresence mode="wait">
<motion.div key={location.pathname} {...pageFade} className="min-h-screen">
<Routes location={location}>
{/* routes */}
</Routes>
</motion.div>
</AnimatePresence>
);
}2. Modal Animations
Use AnimatePresence for enter/exit animations:
import { motion, AnimatePresence } from 'motion/react';
import { modalBackdrop, modalContent } from '@/lib/animations';
function Modal({ isOpen, onClose, children }) {
return (
<AnimatePresence>
{isOpen && (
<>
<motion.div
{...modalBackdrop}
className="fixed inset-0 z-50 bg-black/50"
onClick={onClose}
/>
<motion.div
{...modalContent}
className="fixed inset-0 z-50 flex items-center justify-center p-4 pointer-events-none"
>
<div className="bg-white rounded-2xl p-6 pointer-events-auto">
{children}
</div>
</motion.div>
</>
)}
</AnimatePresence>
);
}3. Staggered List Animations
Use parent container with child variants:
import { motion } from 'motion/react';
import { staggerContainer, staggerItem } from '@/lib/animations';
function ItemList({ items }) {
return (
<motion.ul
variants={staggerContainer}
initial="initial"
animate="animate"
className="space-y-2"
>
{items.map((item) => (
<motion.li key={item.id} variants={staggerItem}>
<ItemCard item={item} />
</motion.li>
))}
</motion.ul>
);
}4. Card Hover Interactions
Apply micro-interactions to cards:
import { motion } from 'motion/react';
import { cardHover, tapScale } from '@/lib/animations';
function Card({ onClick, children }) {
return (
<motion.div
{...cardHover}
{...tapScale}
onClick={onClick}
className="p-4 rounded-lg bg-white cursor-pointer"
>
{children}
</motion.div>
);
}5. Skeleton Loaders with Motion
Use Motion pulse for consistent animation:
import { motion } from 'motion/react';
import { pulse } from '@/lib/animations';
function Skeleton({ className }) {
return (
<motion.div
variants={pulse}
initial="initial"
animate="animate"
className={"bg-gray-200 rounded " + className}
aria-hidden="true"
/>
);
}6. Collapse/Expand Animations
For accordions and expandable sections:
import { motion, AnimatePresence } from 'motion/react';
import { collapse } from '@/lib/animations';
function Accordion({ isExpanded, children }) {
return (
<AnimatePresence>
{isExpanded && (
<motion.div {...collapse} className="overflow-hidden">
{children}
</motion.div>
)}
</AnimatePresence>
);
}---
AnimatePresence Rules
MANDATORY: Use AnimatePresence for exit animations:
// ✅ CORRECT: Wrap conditional renders
<AnimatePresence>
{isVisible && (
<motion.div {...fadeIn}>Content</motion.div>
)}
</AnimatePresence>
// ❌ WRONG: No exit animation
{isVisible && (
<motion.div {...fadeIn}>Content</motion.div>
)}Mode options:
mode="wait"- Wait for exit before enter (page transitions)mode="popLayout"- Layout animations for removing items- Default - Simultaneous enter/exit
---
RTL/Hebrew Considerations
The animation presets are RTL-aware:
slideInRight- Natural entry direction for HebrewstaggerItemRight- RTL list animationspageSlide- Pages slide from left (correct for RTL)
---
Performance Best Practices
1. Use preset transitions: Already optimized 2. Avoid layout animations on large lists: Can cause jank 3. Use `layout` prop sparingly: Only when needed 4. Prefer opacity/transform: Hardware accelerated 5. Don't animate width/height directly: Use collapse preset
// ✅ CORRECT: Transform-based
<motion.div {...slideUp}>
// ❌ AVOID: Layout-heavy
<motion.div animate={{ width: '100%', marginLeft: '20px' }}>---
Testing Animations
Verify 60fps performance: 1. Open Chrome DevTools > Performance tab 2. Record while triggering animations 3. Check for frame drops below 60fps
---
Checklist for New Components
When adding animations:
- [ ] Import from
@/lib/animations, not inline values - [ ] Use
AnimatePresencefor conditional renders - [ ] Apply appropriate preset for the interaction type
- [ ] Test with RTL locale (Hebrew)
- [ ] Verify 60fps performance
- [ ] Ensure animations don't block user interaction
---
Anti-Patterns (FORBIDDEN)
// ❌ NEVER use inline animation values
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
// ❌ NEVER animate without AnimatePresence for conditionals
{isOpen && <motion.div exit={{ opacity: 0 }}>}
// ❌ NEVER animate layout-heavy properties
<motion.div animate={{ width: newWidth, height: newHeight }}>
// ❌ NEVER use CSS transitions alongside Motion
<motion.div {...fadeIn} className="transition-all duration-300">---
Integration with Agents
Frontend UI Developer
- Uses animation presets for all motion effects
- References this skill for implementation patterns
- Ensures consistent animation language
Rapid UI Designer
- Specifies animation types in design specs
- References available presets for motion design
Code Quality Reviewer
- Checks for inline animation anti-patterns
- Validates AnimatePresence usage
- Ensures performance best practices
---
Skill Version: 1.0.0 Last Updated: 2026-01-06 Maintained by: Yonatan Gross
Related Skills
a11y-testing- Testing animations for reduced motion preferences and focus visibilityfocus-management- Focus management during modal animations and page transitionsdesign-system-starter- Integrating animation presets into design system componentsi18n-date-patterns- RTL-aware animations for Hebrew and Arabic layouts
Key Decisions
| Decision | Choice | Rationale |
|---|---|---|
| Animation Library | Motion (Framer Motion) | Declarative API, AnimatePresence, spring physics |
| Animation Strategy | Centralized Presets | Consistency, maintainability, RTL awareness |
| Performance Target | 60fps | Hardware-accelerated transforms only |
| Exit Animations | AnimatePresence Required | Proper cleanup, layout stability |
| Transition Timing | Spring-based | Natural motion, responsive feel |
Capability Details
animation-presets
Keywords: animation, motion, preset, fadeIn, slideUp, scaleIn Solves:
- How do I create consistent animations?
- What animation presets are available?
- Where should I define animations?
page-transitions
Keywords: page, transition, route, navigation, AnimatePresence Solves:
- How do I animate page transitions?
- Add route change animations
- AnimatePresence for page exits
modal-animations
Keywords: modal, dialog, overlay, backdrop, entrance, exit Solves:
- How do I animate modals?
- Dialog entrance/exit animations
- Backdrop fade effects
stagger-animations
Keywords: stagger, list, children, delay, sequence Solves:
- How do I stagger list animations?
- Animate children sequentially
- List item entrance effects
hover-interactions
Keywords: hover, tap, whileHover, whileTap, micro-interaction Solves:
- How do I add hover effects?
- Button press animations
- Micro-interactions for buttons
skeleton-loaders
Keywords: skeleton, loading, pulse, placeholder, shimmer Solves:
- How do I create skeleton loaders?
- Animated loading placeholders
- Pulse animation for loading states
rtl-animations
Keywords: rtl, ltr, hebrew, arabic, direction, i18n Solves:
- How do I handle RTL animations?
- Direction-aware slide animations
- Hebrew/Arabic animation support
collapse-expand
Keywords: collapse, expand, accordion, height, auto Solves:
- How do I animate height changes?
- Accordion expand/collapse
- Animate to auto height
Animation Presets Reference
Complete API reference for frontend/src/lib/animations.ts.
Import
import {
// Transitions
transitions,
// Basic animations
fadeIn, fadeScale, scaleIn,
// Slides
slideInRight, slideInLeft, slideUp, slideDown,
// Stagger
staggerContainer, staggerContainerFast, staggerItem, staggerItemRight,
// Modals
modalBackdrop, modalContent, sheetContent,
// Dropdowns
dropdownDown, dropdownUp,
// Pages
pageFade, pageSlide,
// Micro-interactions
tapScale, hoverLift, buttonPress, cardHover,
// Loading
pulse, shimmer,
// Toasts
toastSlideIn,
// Collapse
collapse
} from '@/lib/animations';---
Transition Timings
transitions.fast
- Duration: 150ms
- Ease: easeOut
- Use for: Button clicks, toggles, micro-interactions
transitions.normal
- Duration: 200ms
- Ease: easeOut
- Use for: Default animations, fades, slides
transitions.slow
- Duration: 300ms
- Ease: easeInOut
- Use for: Emphasis effects, page transitions
transitions.spring
- Type: Spring
- Stiffness: 300
- Damping: 25
- Use for: Playful elements, bouncy effects
transitions.gentleSpring
- Type: Spring
- Stiffness: 200
- Damping: 20
- Use for: Modals, overlays, subtle spring
---
Basic Animations
fadeIn
Simple opacity transition.
<motion.div {...fadeIn}>Content</motion.div>| State | Opacity | Duration |
|---|---|---|
| initial | 0 | - |
| animate | 1 | 200ms |
| exit | 0 | 150ms |
fadeScale
Opacity with subtle scale effect.
<motion.div {...fadeScale}>Content</motion.div>| State | Opacity | Scale |
|---|---|---|
| initial | 0 | 0.95 |
| animate | 1 | 1 |
| exit | 0 | 0.95 |
scaleIn
Prominent scale-in with spring animation.
<motion.div {...scaleIn}>Badge</motion.div>| State | Opacity | Scale | Transition |
|---|---|---|---|
| initial | 0 | 0.8 | - |
| animate | 1 | 1 | spring |
| exit | 0 | 0.8 | fast |
---
Slide Animations
slideInRight (RTL-Friendly)
Content slides in from right. Natural for Hebrew/RTL layouts.
<motion.div {...slideInRight}>Hebrew Content</motion.div>slideInLeft
Content slides in from left. For LTR content in RTL context.
slideUp
Content rises from bottom.
<motion.div {...slideUp}>Card</motion.div>slideDown
Content drops from top.
<motion.div {...slideDown}>Dropdown</motion.div>---
Stagger Animations
staggerContainer + staggerItem
Parent-child pattern for animating lists.
<motion.ul variants={staggerContainer} initial="initial" animate="animate">
{items.map(item => (
<motion.li key={item.id} variants={staggerItem}>
{item.name}
</motion.li>
))}
</motion.ul>staggerContainer:
staggerChildren: 50ms delay between itemsdelayChildren: 100ms initial delay
staggerItem:
- Fade + slide up (y: 10 → 0)
staggerContainerFast
Quick stagger for rapid lists.
staggerChildren: 30msdelayChildren: 50ms
staggerItemRight
RTL stagger variant. Slides from right.
---
Modal Animations
modalBackdrop
Dark overlay fade.
<AnimatePresence>
{isOpen && (
<motion.div {...modalBackdrop} className="fixed inset-0 bg-black/50" />
)}
</AnimatePresence>modalContent
Modal body animation with gentle spring.
<motion.div {...modalContent} className="bg-white rounded-2xl p-6">
Modal content
</motion.div>| State | Opacity | Scale | Y |
|---|---|---|---|
| initial | 0 | 0.95 | 10 |
| animate | 1 | 1 | 0 |
| exit | 0 | 0.95 | 10 |
sheetContent
Mobile bottom sheet animation.
<motion.div {...sheetContent} className="fixed bottom-0 bg-white">
Sheet content
</motion.div>---
Dropdown Animations
dropdownDown
Menu appearing below trigger.
<motion.div {...dropdownDown} className="absolute top-full">
Options...
</motion.div>dropdownUp
Menu appearing above trigger.
---
Page Transitions
pageFade
Simple page fade for route changes.
<AnimatePresence mode="wait">
<motion.div key={location.pathname} {...pageFade}>
<Routes />
</motion.div>
</AnimatePresence>pageSlide
RTL page slide (new pages enter from left).
---
Micro-Interactions
tapScale
Press feedback for buttons.
<motion.button {...tapScale}>Click me</motion.button>Effect: Scale to 0.97 on tap
hoverLift
Subtle lift on hover for cards/list items.
<motion.div {...hoverLift}>Hoverable</motion.div>Effect: Y -2px + shadow
buttonPress
Combined hover/tap for buttons.
<motion.button {...buttonPress}>Action</motion.button>Effect: Scale 1.02 on hover, 0.98 on tap
cardHover
Card hover enhancement.
<motion.div {...cardHover}>Card content</motion.div>Effect: Y -4px + enhanced shadow
---
Loading States
pulse
Opacity pulse for skeleton loaders.
<motion.div variants={pulse} initial="initial" animate="animate" className="bg-gray-200 rounded h-4" />Effect: Opacity cycles 0.6 → 1 → 0.6 (1.5s, infinite)
shimmer
Sliding highlight effect.
<div className="relative overflow-hidden">
<motion.div variants={shimmer} initial="initial" animate="animate" className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent" />
</div>Effect: X slides -100% → 100% (1.5s, infinite)
---
Toast/Notification
toastSlideIn
Slide-in for toast notifications.
<motion.div {...toastSlideIn}>Success!</motion.div>Effect: Slides from right with spring + scale
---
Collapse/Expand
collapse
For accordions and expandable sections.
<AnimatePresence>
{isExpanded && (
<motion.div {...collapse} className="overflow-hidden">
Expandable content
</motion.div>
)}
</AnimatePresence>IMPORTANT: Always use overflow-hidden on the animated element.
| State | Height | Opacity | Duration |
|---|---|---|---|
| initial | 0 | 0 | - |
| animate | auto | 1 | 200ms |
| exit | 0 | 0 | 150ms |
---
Combining Presets
You can spread multiple presets:
<motion.div {...cardHover} {...tapScale}>
Interactive card
</motion.div>---
Custom Variants Extension
Extend presets for custom needs:
const customFade = {
...fadeIn,
animate: {
...fadeIn.animate,
y: 0,
transition: { duration: 0.5 } // Override
},
};