Motion System 是一套把动效作为系统性设计令牌层来定义的方法,而不是一堆一次性动画的集合。它的目标是为产品建立统一的动效词汇——时长刻度、缓动曲线、编排规则和无障碍处理——让动画决策保持一致、有目的,并且任何团队都能实现。
为什么需要动效系统
没有系统时,动画决策往往是临时做出的:每个组件有自己的时长和缓动,过渡效果不一致,设计与工程之间也缺乏共享语言。动效系统让动画决策像颜色或字体选择一样经过深思熟虑。
时长令牌
定义一小组具名时长值。示例刻度:
| 令牌 | 值 | 用途 |
|---|---|---|
| duration-instant | 50ms | 必须感觉即时的状态变化(复选框勾选、开关) |
| duration-fast | 100ms | 小元素过渡(工具提示出现、标签关闭) |
| duration-normal | 200ms | 大多数过渡的默认值(下拉打开、焦点环) |
| duration-moderate | 300ms | 中等元素过渡(模态进入、面板滑动) |
| duration-slow | 400ms | 页面级过渡、复杂编排 |
| duration-deliberate | 600ms | 有意放慢的高强调时刻(引导揭示) |
不要创建超过实际不同用例数量的令牌,通常 4–6 个值就足够。
缓动令牌
定义具名缓动曲线并映射到语义用途:
| 令牌 | 曲线 | 用途 |
|---|---|---|
| ease-standard | cubic-bezier(0.2, 0, 0, 1) | 大多数 UI 过渡——元素在状态间移动 |
| ease-decelerate | cubic-bezier(0, 0, 0.2, 1) | 元素进入屏幕 |
| ease-accelerate | cubic-bezier(0.3, 0, 1, 0.3) | 元素离开屏幕 |
| ease-spring | spring / cubic-bezier(0.34, 1.56, 0.64, 1) | 活泼或有触感的交互(FAB 展开、抽屉回弹) |
| ease-linear | linear | 仅用于循环动画(进度旋转器、微光) |
编排规则
当多个元素一起动画时:
- 错峰:一起进入的相关元素错峰 30–50ms,以最重要的元素领衔
- 协调:同一语义组内的元素使用相同的时长和缓动
- 序列总时长:错峰序列的总时长不应超过 500ms
- 方向一致:如果元素从右侧滑入,相关的退出元素应向左滑出
减少动效
prefers-reduced-motion: reduce 媒体查询必须在系统层面处理,而不是逐个组件处理:
- 禁用:移除滑动、缩放和旋转动画
- 替换:替换为即时状态变化或简单的透明度渐变(透明度过渡通常可接受)
- 保留:保留传达必要状态信息的动画(加载旋转器、进度)
- 令牌方式:在减少动效下为所有时长令牌定义 duration-instant(0ms 或 1ms)覆盖,并全局应用
实现
- 将时长和缓动值定义为 CSS 自定义属性(或平台等价令牌)
- 在 prefers-reduced-motion 查询内的 :root 层应用减少动效覆盖
- 为每个令牌记录:名称、值、用例和实时示例
- 将动效令牌纳入设计令牌导出流程——它们应与颜色和间距令牌放在一起
动效原则(按产品定义)
每个产品的动效系统都应基于 3–5 条原则:
- 示例:“有目的——每个动画都传达状态变化或关系”
- 示例:“快速——UI 动效从不缓慢;我们尊重用户的时间”
- 示例:“物理——动效遵循自然物理;进入时减速,退出时加速”
- 示例:“无障碍——所有动效尊重用户偏好,绝不引起不适”
最佳实践
- 从较少的令牌开始,只有当新用例确实不匹配现有值时才添加
- 在低性能设备上测试所有动效——在设计工具中流畅的效果在生产环境中可能卡顿
- 将动效与颜色、间距一起纳入设计 QA 检查清单
- 像记录什么应该动一样清楚地记录什么不应该动——并非所有东西都要移动