动画工程与动效设计 是做什么的?
此技能使代理能够运用行业标准实践、生产就绪模式以及数学物理模型,为 Web 和应用程序界面设计和编写流畅、高性能的动画。
1. 动效性能黄金法则
- 仅对复合属性进行动画处理:
- 始终优先使用
transform(translate3d、scale、rotate)和opacity。 - 绝不要对几何属性(
width、height、top、left、margin、padding)进行动画处理,除非使用 FLIP 技术(First、Last、Invert、Play)。对几何属性进行动画会触发昂贵的布局重算(Reflow)和 CPU 上的 Paint 操作。
- 始终优先使用
- 负责任地提升至 GPU:
- 仅对正在动画处理中的元素使用
will-change: transform, opacity;,并在动画完成后移除它(如果内存受限)。 - 需要时,使用
transform: translateZ(0)或backface-visibility: hidden强制 GPU 层合成。
- 仅对正在动画处理中的元素使用
- 尊重用户无障碍访问:
- 始终支持
@media (prefers-reduced-motion: reduce):@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } }
- 始终支持
- 自然的计时与持续时间:
- 微交互(按钮按下、切换、工具提示):
100ms - 200ms - 标准过渡(下拉菜单、对话框、抽屉、卡片):
200ms - 350ms - 复杂场景过渡/页面过渡:
350ms - 500ms - 超过
500ms的动画会显得缓慢,除非是持续的大气背景循环或叙事性故事。
- 微交互(按钮按下、切换、工具提示):
2. 技术选择矩阵
| 场景/需求 | 推荐工具 | 原因 |
|---|---|---|
| 简单的悬停、聚焦、激活状态、淡入/滑动 | CSS 过渡与 @keyframes 或 Tailwind CSS | 零 JavaScript 开销,120 FPS 硬件加速。 |
| React / Next.js UI、模态框、共享布局过渡 | Framer Motion (motion) | 声明式 API、弹簧物理、自动 FLIP (layoutId)、AnimatePresence。 |
| 复杂时间轴、SVG 形变、滚动驱动 UI | GSAP (GreenSock) + ScrollTrigger | 无与伦比的编排控制、精确的拖拽回放、跨浏览器一致性。 |
| 3D 体验、粒子网络、着色器 | Three.js / React Three Fiber / Canvas 2D | 直接 WebGL GPU 渲染,支持数十万个粒子。 |
| 矢量动效图形与角色插画 | Lottie / dotLottie / Rive | 小巧的 JSON/二进制数据负载、可缩放矢量保真度、交互式状态机。 |
3. 运动曲线(缓动令牌)
切勿对 UI 运动使用 linear,除非模拟匀速传送带或无限旋转加载器。自然运动会加速和减速:
- 快速进入(标准 UI 弹出/打开):
cubic-bezier(0.16, 1, 0.3, 1)(Expo Out - 快速初始爆发,平滑减速) - 平滑退出(关闭/消除):
cubic-bezier(0.7, 0, 0.84, 0)(Expo In - 加速离开屏幕) - 自然动态/强调:
cubic-bezier(0.34, 1.56, 0.64, 1)(轻微过冲反弹) - 弹簧物理(触摸和拖拽首选):
- 刚度:
300-400 - 阻尼:
25-35 - 质量:
0.8-1.0
- 刚度:
4. 深度指南与参考
有关全面的代码模式和详细的操作指南,请查阅参考文档:
- CSS 与 Tailwind 动画参考
- Framer Motion 与 Motion One 模式
- GSAP 与 ScrollTrigger 精通
- Three.js 与 Canvas 动效
- UI 动效原理与无障碍
5. 验证清单
在构建动画组件时:
- 动画是否流畅(60-120 FPS),无卡顿或丢帧?
- 是否避免了动画期间的布局偏移(CLS)?
- 退出动画是否在元素卸载前正确等待其完成?
- UI 是否能在快速点击/轻触时无故障运行(可中断动画)?
- 是否实现了
prefers-reduced-motion?