frontend-ui-animator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFrontend UI Animator
前端UI动画实现指南
Implement purposeful, performant animations that enhance UX without overwhelming users. Focus on key moments: hero intros, hover feedback, content reveals, and navigation transitions.
为用户体验增添价值的同时,实现高效、有明确目标的动画效果,避免过度使用动画。重点关注关键场景:首页开场动效、悬停反馈、内容展示动效以及导航过渡效果。
Core Philosophy
核心理念
"You don't need animations everywhere" - Prioritize:
| Priority | Area | Purpose |
|---|---|---|
| 1 | Hero Intro | First impression, brand personality |
| 2 | Hover Interactions | Feedback, discoverability |
| 3 | Content Reveal | Guide attention, reduce cognitive load |
| 4 | Background Effects | Atmosphere, depth |
| 5 | Navigation Transitions | Spatial awareness, continuity |
“无需处处添加动画” - 按优先级排序:
| 优先级 | 应用场景 | 目的 |
|---|---|---|
| 1 | 首页开场 | 第一印象,传递品牌个性 |
| 2 | 悬停交互 | 反馈操作,提升可发现性 |
| 3 | 内容展示 | 引导注意力,降低认知负荷 |
| 4 | 背景效果 | 营造氛围,增加层次感 |
| 5 | 导航过渡 | 强化空间感知,保持体验连贯性 |
Workflow
实施流程
Execute phases sequentially. Complete each before proceeding.
按阶段依次执行,完成上一阶段后再推进下一阶段。
Phase 1: Analyze
阶段1:分析
- Scan project structure - Identify all pages in and components in
app/components/ - Check existing setup - Review for existing animations/keyframes
tailwind.config.ts - Identify animation candidates - List components by priority category
- Document constraints - Note installed animation libraries (framer-motion, etc.)
Output: Animation audit table. See .
references/component-checklist.md- 扫描项目结构 - 识别目录下的所有页面和
app/目录下的所有组件components/ - 检查现有配置 - 查看中的现有动画/关键帧配置
tailwind.config.ts - 确定动画候选对象 - 按优先级类别列出组件
- 记录约束条件 - 记录已安装的动画库(如framer-motion等)
输出:动画审计表。参考。
references/component-checklist.mdPhase 2: Plan
阶段2:规划
- Map animations to components - Assign specific animation patterns
- Determine triggers - Load, scroll (intersection), hover, click
- Estimate effort - Low (CSS only), Medium (hooks needed), High (library required)
- Propose phased rollout - Quick wins first
Output: Implementation plan with component → animation mapping.
- 为组件匹配动画 - 为组件分配具体的动画模式
- 确定触发条件 - 页面加载、滚动(交叉观察)、悬停、点击
- 评估实现难度 - 低(仅需CSS)、中(需要hooks)、高(需要使用动画库)
- 建议分阶段推出 - 先实现快速见效的动画
输出:包含组件→动画映射的实施计划。
Phase 3: Implement
阶段3:实现
- Extend Tailwind config - Add keyframes and animation utilities
- Add reduced-motion support - Accessibility first
- Create reusable hooks - ,
useScrollRevealif neededuseMousePosition - Apply animations per component - Follow patterns in
references/animation-patterns.md
Performance rules:
tsx
// ✅ DO: Use transforms and opacity only
transform: translateY(20px);
opacity: 0.5;
filter: blur(4px);
// ❌ DON'T: Animate layout properties
margin-top: 20px;
height: 100px;
width: 200px;- 扩展Tailwind配置 - 添加关键帧和动画工具类
- 支持减少动效模式 - 优先考虑无障碍访问
- 创建可复用Hooks - 按需创建、
useScrollReveal等useMousePosition - 为组件应用动画 - 遵循中的模式
references/animation-patterns.md
性能规则:
tsx
// ✅ 推荐:仅使用transform和opacity属性
transform: translateY(20px);
opacity: 0.5;
filter: blur(4px);
// ❌ 避免:对布局属性执行动画
margin-top: 20px;
height: 100px;
width: 200px;Phase 4: Verify
阶段4:验证
- Test in browser - Visual QA all animations
- Test reduced-motion - Verify works
prefers-reduced-motion - Check CLS - No layout shifts from animations
- Performance audit - No jank on scroll animations
- 浏览器测试 - 对所有动画进行视觉质量检查
- 减少动效测试 - 验证是否正常工作
prefers-reduced-motion - 检查CLS - 确保动画不会导致布局偏移
- 性能审计 - 滚动动画无卡顿
Quick Reference
快速参考
Animation Triggers
动画触发条件
| Trigger | Implementation |
|---|---|
| Page load | CSS |
| Scroll into view | |
| Hover | Tailwind |
| Click/Tap | State-driven with |
| 触发条件 | 实现方式 |
|---|---|
| 页面加载 | 使用CSS |
| 滚动进入视图 | 使用 |
| 悬停 | 使用Tailwind |
| 点击/触摸 | 通过 |
Common Patterns
常见动画模式
Staggered children:
tsx
{items.map((item, i) => (
<div
key={item.id}
style={{ animationDelay: `${i * 100}ms` }}
className="animate-fade-slide-in"
/>
))}Scroll reveal hook:
tsx
const useScrollReveal = (threshold = 0.1) => {
const ref = useRef<HTMLDivElement>(null);
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => entry.isIntersecting && setIsVisible(true),
{ threshold }
);
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, [threshold]);
return { ref, isVisible };
};Usage:
tsx
const { ref, isVisible } = useScrollReveal();
<div ref={ref} className={isVisible ? 'animate-fade-in' : 'opacity-0'} />** stagger 子元素动画:**
tsx
{items.map((item, i) => (
<div
key={item.id}
style={{ animationDelay: `${i * 100}ms` }}
className="animate-fade-slide-in"
/>
))}滚动显示Hook:
tsx
const useScrollReveal = (threshold = 0.1) => {
const ref = useRef<HTMLDivElement>(null);
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => entry.isIntersecting && setIsVisible(true),
{ threshold }
);
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, [threshold]);
return { ref, isVisible };
};使用示例:
tsx
const { ref, isVisible } = useScrollReveal();
<div ref={ref} className={isVisible ? 'animate-fade-in' : 'opacity-0'} />Resources
资源
- Animation patterns: See
references/animation-patterns.md - Audit template: See
references/component-checklist.md - Tailwind presets: See
references/tailwind-presets.md
- 动画模式:参考
references/animation-patterns.md - 审计模板:参考
references/component-checklist.md - Tailwind预设:参考
references/tailwind-presets.md
Technical Stack
技术栈
- CSS animations: Default for simple effects
- Tailwind utilities: For hover states and basic animations
- Framer Motion: For complex orchestration, gestures, layout animations
- GSAP: For timeline-based sequences (if already installed)
- CSS动画:适用于简单效果
- Tailwind工具类:用于悬停状态和基础动画
- Framer Motion:用于复杂动画编排、手势交互和布局动画
- GSAP:用于基于时间线的动画序列(若已安装)
Accessibility (Required)
无障碍访问(必填)
Always include in global CSS:
css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
}
}务必在全局CSS中添加以下代码:
css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
}
}