motion-animation-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMotion Animation Patterns
Motion 动画模式
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:
- - Complete preset API reference
references/animation-presets.md - - Common animation patterns
examples/component-patterns.md
本技能为在React 19应用中实现Motion(Framer Motion)动画提供全面指导。通过集中式动画预设,确保UI中的动画一致、高性能且具备可访问性。
何时使用此技能:
- 添加页面过渡动画
- 实现模态框/对话框的进入/退出动画
- 创建列表交错动画
- 添加悬停和点击微交互
- 实现骨架屏加载状态
- 创建展开/收起动画
- 构建提示框/通知动画
附带资源:
- - 完整的预设API参考文档
references/animation-presets.md - - 常见动画模式示例
examples/component-patterns.md
Core Architecture
核心架构
Animation Presets Library (frontend/src/lib/animations.ts
)
frontend/src/lib/animations.ts动画预设库(frontend/src/lib/animations.ts
)
frontend/src/lib/animations.tsAll animations MUST use the centralized presets. This ensures:
animations.ts- Consistent motion language across the app
- RTL-aware animations (Hebrew support)
- Performance optimization
- Easy maintainability
typescript
// ✅ 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 }}>所有动画必须使用集中式的预设,这能确保:
animations.ts- 应用内动画语言的一致性
- 支持RTL(从右到左)布局的动画(适配希伯来语)
- 性能优化
- 易于维护
typescript
// ✅ 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 |
|---|---|---|---|
| 0.15s | easeOut | Micro-interactions |
| 0.2s | easeOut | Most animations |
| 0.3s | easeInOut | Emphasis effects |
| spring | 300/25 | Playful elements |
| spring | 200/20 | Modals/overlays |
| 预设 | 时长 | 缓动效果 | 适用场景 |
|---|---|---|---|
| 0.15s | easeOut | 微交互 |
| 0.2s | easeOut | 大多数动画 |
| 0.3s | easeInOut | 强调效果 |
| spring | 300/25 | 活泼元素 |
| spring | 200/20 | 模态框/浮层 |
Basic Animations
基础动画
| Preset | Effect | Use For |
|---|---|---|
| Opacity fade | Simple reveal |
| Fade + slight scale | Subtle emphasis |
| Fade + scale from center | Badges, buttons |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 透明度淡入 | 简单的内容展示 |
| 淡入+轻微缩放 | 微妙的强调效果 |
| 淡入+从中心缩放 | 徽章、按钮 |
Slide Animations (RTL-Aware)
滑动动画(支持RTL)
| Preset | Direction | Use For |
|---|---|---|
| Right to center | RTL Hebrew UI (natural) |
| Left to center | LTR content |
| Bottom to center | Cards, panels |
| Top to center | Dropdowns |
| 预设 | 方向 | 适用场景 |
|---|---|---|
| 从右侧到中心 | RTL希伯来语UI(符合自然阅读方向) |
| 从左侧到中心 | LTR内容 |
| 从底部到中心 | 卡片、面板 |
| 从顶部到中心 | 下拉菜单 |
List/Stagger Animations
列表/交错动画
| Preset | Effect | Use For |
|---|---|---|
| Parent with stagger | List wrappers |
| Fast stagger | Quick lists |
| Fade + slide child | List items |
| RTL slide child | Hebrew lists |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 父容器带动画交错 | 列表容器 |
| 快速交错 | 短列表 |
| 子元素淡入+滑动 | 列表项 |
| RTL方向滑动子元素 | 希伯来语列表 |
Modal/Dialog Animations
模态框/对话框动画
| Preset | Effect | Use For |
|---|---|---|
| Overlay fade | Modal background |
| Scale + fade | Modal body |
| Slide from bottom | Mobile sheets |
| Scale from top | Dropdown menus |
| Scale from bottom | Context menus |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 遮罩层淡入 | 模态框背景 |
| 缩放+淡入 | 模态框主体 |
| 从底部滑入 | 移动端底部弹窗 |
| 从顶部缩放 | 下拉菜单 |
| 从底部缩放 | 上下文菜单 |
Page Transitions
页面过渡
| Preset | Effect | Use For |
|---|---|---|
| Simple fade | Route changes |
| RTL slide | Navigation |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 简单淡入淡出 | 路由切换 |
| RTL方向滑动 | 页面导航 |
Micro-Interactions
微交互
| Preset | Effect | Use For |
|---|---|---|
| Scale on tap | Buttons, cards |
| Lift + shadow | Cards, list items |
| Press effect | Interactive buttons |
| Hover emphasis | Card components |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 点击时缩放 | 按钮、卡片 |
| 悬停时抬起+阴影 | 卡片、列表项 |
| 按压效果 | 交互按钮 |
| 悬停强调 | 卡片组件 |
Loading States
加载状态
| Preset | Effect | Use For |
|---|---|---|
| Opacity pulse | Skeleton loaders |
| Sliding highlight | Shimmer effect |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 透明度脉冲 | 骨架屏加载器 |
| 滑动高亮 | 闪光效果 |
Utility Animations
工具类动画
| Preset | Effect | Use For |
|---|---|---|
| Slide + scale | Notifications |
| Height animation | Accordions |
| 预设 | 效果 | 适用场景 |
|---|---|---|
| 滑动+缩放 | 通知提示 |
| 高度动画 | 折叠面板 |
Implementation Patterns
实现模式
1. Page Transitions
1. 页面过渡
Wrap routes with for smooth page changes:
AnimatePresencetsx
// 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>
);
}使用包裹路由,实现流畅的页面切换:
AnimatePresencetsx
// 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
2. 模态框动画
Use for enter/exit animations:
AnimatePresencetsx
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>
);
}使用实现进入/退出动画:
AnimatePresencetsx
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
3. 列表交错动画
Use parent container with child variants:
tsx
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>
);
}使用父容器搭配子元素变体:
tsx
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
4. 卡片悬停交互
Apply micro-interactions to cards:
tsx
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>
);
}为卡片添加微交互:
tsx
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
5. 基于Motion的骨架屏加载器
Use Motion pulse for consistent animation:
tsx
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"
/>
);
}使用Motion的脉冲动画实现一致的加载效果:
tsx
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
6. 展开/收起动画
For accordions and expandable sections:
tsx
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>
);
}适用于折叠面板和可展开区域:
tsx
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
AnimatePresence 使用规则
MANDATORY: Use for exit animations:
AnimatePresencetsx
// ✅ 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:
- - Wait for exit before enter (page transitions)
mode="wait" - - Layout animations for removing items
mode="popLayout" - Default - Simultaneous enter/exit
强制要求:使用实现退出动画:
AnimatePresencetsx
// ✅ 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="wait" - - 移除元素时的布局动画
mode="popLayout" - 默认 - 同时执行进入和退出动画
RTL/Hebrew Considerations
RTL/希伯来语适配注意事项
The animation presets are RTL-aware:
- - Natural entry direction for Hebrew
slideInRight - - RTL list animations
staggerItemRight - - Pages slide from left (correct for RTL)
pageSlide
动画预设已适配RTL布局:
- - 希伯来语内容的自然进入方向
slideInRight - - RTL列表动画
staggerItemRight - - 页面从左侧滑入(符合RTL布局逻辑)
pageSlide
Performance Best Practices
性能最佳实践
- Use preset transitions: Already optimized
- Avoid layout animations on large lists: Can cause jank
- Use prop sparingly: Only when needed
layout - Prefer opacity/transform: Hardware accelerated
- Don't animate width/height directly: Use preset
collapse
tsx
// ✅ CORRECT: Transform-based
<motion.div {...slideUp}>
// ❌ AVOID: Layout-heavy
<motion.div animate={{ width: '100%', marginLeft: '20px' }}>- 使用预设过渡效果:已完成性能优化
- 避免在大型列表上使用布局动画:可能导致卡顿
- 谨慎使用属性:仅在必要时使用
layout - 优先使用透明度/变换动画:由硬件加速
- 不要直接动画化宽度/高度:使用预设
collapse
tsx
// ✅ CORRECT: Transform-based
<motion.div {...slideUp}>
// ❌ AVOID: Layout-heavy
<motion.div animate={{ width: '100%', marginLeft: '20px' }}>Testing Animations
动画测试
Verify 60fps performance:
- Open Chrome DevTools > Performance tab
- Record while triggering animations
- Check for frame drops below 60fps
验证动画性能是否达到60fps:
- 打开Chrome开发者工具 > 性能面板
- 触发动画时进行录制
- 检查是否存在帧率低于60fps的情况
Checklist for New Components
新组件开发检查清单
When adding animations:
- Import from , not inline values
@/lib/animations - Use for conditional renders
AnimatePresence - Apply appropriate preset for the interaction type
- Test with RTL locale (Hebrew)
- Verify 60fps performance
- Ensure animations don't block user interaction
添加动画时需确认:
- 从导入,而非使用内联值
@/lib/animations - 对条件渲染的元素使用
AnimatePresence - 根据交互类型选择合适的预设
- 在RTL语言环境(希伯来语)下测试
- 验证帧率达到60fps
- 确保动画不会阻碍用户交互
Anti-Patterns (FORBIDDEN)
反模式(禁止使用)
tsx
// ❌ 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">tsx
// ❌ 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
前端UI开发者
- Uses animation presets for all motion effects
- References this skill for implementation patterns
- Ensures consistent animation language
- 使用动画预设实现所有动效
- 参考本技能获取实现模式
- 确保动画语言的一致性
Rapid UI Designer
快速UI设计师
- 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
- 检查是否存在内联动画的反模式
- 验证的使用是否正确
AnimatePresence - 确保符合性能最佳实践
技能版本:1.0.0
最后更新:2026-01-06
维护者:Yonatan Gross
Related Skills
相关技能
- - Testing animations for reduced motion preferences and focus visibility
a11y-testing - - Focus management during modal animations and page transitions
focus-management - - Integrating animation presets into design system components
design-system-starter - - RTL-aware animations for Hebrew and Arabic layouts
i18n-date-patterns
- - 针对减少动效偏好和焦点可见性测试动画
a11y-testing - - 模态框动画和页面过渡中的焦点管理
focus-management - - 将动画预设集成到设计系统组件中
design-system-starter - - 适配希伯来语和阿拉伯语布局的RTL动画
i18n-date-patterns
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 |
| 决策 | 选择 | 理由 |
|---|---|---|
| 动画库 | Motion(Framer Motion) | 声明式API、AnimatePresence支持、弹簧物理动效 |
| 动画策略 | 集中式预设 | 一致性、可维护性、RTL适配 |
| 性能目标 | 60fps | 仅使用硬件加速的变换动画 |
| 退出动画 | 强制使用AnimatePresence | 正确清理、布局稳定性 |
| 过渡时长 | 基于弹簧动效 | 自然的运动感、响应式体验 |
Capability Details
功能详情
animation-presets
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?
关键词: animation, motion, preset, fadeIn, slideUp, scaleIn
解决问题:
- 如何创建一致的动画?
- 有哪些可用的动画预设?
- 应该在哪里定义动画?
page-transitions
page-transitions
Keywords: page, transition, route, navigation, AnimatePresence
Solves:
- How do I animate page transitions?
- Add route change animations
- AnimatePresence for page exits
关键词: page, transition, route, navigation, AnimatePresence
解决问题:
- 如何实现页面过渡动画?
- 添加路由切换动画
- 使用AnimatePresence实现页面退出动画
modal-animations
modal-animations
Keywords: modal, dialog, overlay, backdrop, entrance, exit
Solves:
- How do I animate modals?
- Dialog entrance/exit animations
- Backdrop fade effects
关键词: modal, dialog, overlay, backdrop, entrance, exit
解决问题:
- 如何实现模态框动画?
- 对话框进入/退出动画
- 遮罩层淡入效果
stagger-animations
stagger-animations
Keywords: stagger, list, children, delay, sequence
Solves:
- How do I stagger list animations?
- Animate children sequentially
- List item entrance effects
关键词: stagger, list, children, delay, sequence
解决问题:
- 如何实现列表交错动画?
- 按顺序动画化子元素
- 列表项进入效果
hover-interactions
hover-interactions
Keywords: hover, tap, whileHover, whileTap, micro-interaction
Solves:
- How do I add hover effects?
- Button press animations
- Micro-interactions for buttons
关键词: hover, tap, whileHover, whileTap, micro-interaction
解决问题:
- 如何添加悬停效果?
- 按钮按压动画
- 按钮微交互
skeleton-loaders
skeleton-loaders
Keywords: skeleton, loading, pulse, placeholder, shimmer
Solves:
- How do I create skeleton loaders?
- Animated loading placeholders
- Pulse animation for loading states
关键词: skeleton, loading, pulse, placeholder, shimmer
解决问题:
- 如何创建骨架屏加载器?
- 动画化加载占位符
- 加载状态的脉冲动画
rtl-animations
rtl-animations
Keywords: rtl, ltr, hebrew, arabic, direction, i18n
Solves:
- How do I handle RTL animations?
- Direction-aware slide animations
- Hebrew/Arabic animation support
关键词: rtl, ltr, hebrew, arabic, direction, i18n
解决问题:
- 如何处理RTL布局下的动画?
- 适配方向的滑动动画
- 希伯来语/阿拉伯语动画支持
collapse-expand
collapse-expand
Keywords: collapse, expand, accordion, height, auto
Solves:
- How do I animate height changes?
- Accordion expand/collapse
- Animate to auto height
关键词: collapse, expand, accordion, height, auto
解决问题:
- 如何实现高度变化动画?
- 折叠面板展开/收起
- 动画化自适应高度