animate / 中文方法笔记

动画决策与设计总纲

整理于 2026.10.23 · 15 个小节

适合已有前端经验、希望理解动画取舍的读者。本章完整整理我们已学过的内容,后续章节深入实现。来源:animate/SKILL.md,配套的 CSS、Motion、SVG 文件分别并入第 02、03 章与附录 A。

1.1 先判断是否值得动

动画的价值可以是操作反馈、状态提示、空间关系、解释过程、缓和画面突变,以及低频场景的趣味。先完成“这里动起来,是为了让用户理解……”这句话,再选技术。

频率作者的倾向实际判断
高频键盘操作、命令面板、连续列表选择立即响应不让动画阻挡下一次操作
经常出现的 hover、导航少动或不动检查是否滞后于指针
偶尔打开弹窗、抽屉、通知标准短动画表达操作与状态的关系
首次引导、庆祝、营销可更有表现力仍然不能妨碍任务

原文的“100 次/天绝不动画”是作者强调效率的设计规则,并非浏览器规范或实证分界。键盘用户同样需要可理解的反馈。保存成功需要明确反馈,动画是加强反馈的手段。

1.2 Easing:时间如何分配

情境起点选择
元素进入、退出强 ease-out,快速响应后停稳
屏幕内移动、变形ease-in-out,启动与刹车
颜色、背景、小幅 hoverease 或适合产品的自定义曲线
时间进度、匀速旋转、跑马灯linear

同样 200ms,先慢后快会把明显变化推迟,先快后慢则较早给出反馈。作者偏爱自定义曲线,但内置曲线并非技术错误,ease-in 也不是所有退出场景的禁令。

:root {
  --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
  --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
  --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);
  --ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-height: cubic-bezier(0.25, 1, 0.5, 1);
}

三次贝塞尔的横轴是时间、纵轴是进度;给定时间时需要先求曲线上对应的横坐标,不能把参数 t 直接当成时间代入纵坐标。更陡的开头把大部分变化提前,后面留出停稳时间。

1.3 Duration:总时长与感知速度

按钮按压约 150ms;hover 约 100–150ms;小提示 125–200ms;下拉菜单 150–250ms;弹窗、抽屉 200–500ms;大距离移动可能接近 1s。以上是原文调试起点,不是验收硬阈值。

先确定曲线,再调时长;尺寸、距离、使用频率一起考虑。500ms 的陡曲线可能很快到位,随后缓慢收尾。退出通常可以更短更简单。不要把所有组件一律改成 50ms。

尺寸变化很小时,时长也可以减小。原文配方:把高度差除以 500,再限制在 0.15–0.27 秒;这个 500 是经验比例,单位必须明确,并需保存上一次高度。

1.4 尺度与变换原点

按钮按压从 scale(0.97)、hover 放大从 1–2% 开始;弹层入场从 0.9–0.95 配合透明度开始,大菜单可用 0.98。同样 3% 对大卡片造成的边缘位移更大。避免机械地把 scale(0) 用于所有入场,但徽标等刻意的缩放效果可以另作设计。

由按钮打开的菜单围绕触发位置缩放,例如 transform-origin: top right;居中弹窗通常围绕中心。原点决定缩放/旋转的锚点,不决定菜单摆放位置。使用组件库时优先采用它提供的动态原点,以适应碰撞翻转。

1.5 稳定命中区域

Hover 抬升直接移动命中目标,可能导致“移开鼠标→落回→再次命中”的抖动。外层负责 hover,内层负责 transform。按压缩小与拖动把手也应考虑命中范围是否稳定。触屏使用 hover 能力查询;键盘需要对应的 focus 反馈。

1.6 Spring:位置、速度与目标

缓动通常按起终点和时长计算进度;物理弹簧根据当前位置、目标和速度演化。

拉力 = -k × (x - target)
阻力 = -c × v
加速度 = (拉力 + 阻力) / m
临界阻尼 c = 2 × √(k × m)

刚度越大,拉回越有力;质量越大,同样作用力下越难改变速度;增加阻尼可以抑制振荡,但超过临界后继续增加,会让归位变慢。不要孤立背一个 damping 数字。

目标突然从右改到左,弹簧可能先继续向右,刹车后再左转,这是速度连续。默认不回弹;拖拽释放、趣味场景可以有小幅回弹。物理弹簧的结束取决于收敛阈值;库也可以提供感知时长与 bounce 等易调参数,两种配置不宜随意混用。

1.7 可中断性

透明度到 0.4 时关闭,应从 0.4 继续,而非跳到写死的 1 再退出。CSS transition 通常能保证当前值连续,但不保证新旧速度连续;弹簧可以继续使用当前速度。

Keyframes 并非天生不能中断:同一个 Animation 可以暂停、反向或定位时间。原文警惕的是反复切换动画名称、重挂载,导致从固定起点重播。快速开关、Toast 堆叠尤其要测这一点。

1.8 性能的两个问题

先问“什么属性变化”,再问“谁逐帧驱动”。transform、opacity 是优先选择,但不保证硬件加速。JS 每帧写 transform 仍受主线程阻塞;CSS/WAAPI 的符合条件动画可由合成线程推进。高度变化若必须推开内容,不能用压扁文字的 scaleY 生硬替代。详见第 06 章。

1.9 错峰与层级

组内错峰可从 30–80ms 开始:标题先出现,说明稍后,次要内容只淡入。等权列表可以均匀错峰;有主次时再变化延迟与距离。

总结束时间约为 最后一个 delay + 它的 duration。10 项间隔 80ms、各 200ms,整组约 920ms。限制错峰数量,不能让装饰动画阻挡操作。

1.10 一层入场

抽屉整体滑入时,内容通常已经就位;静止的首屏容器才考虑少量子元素错峰。父子都位移会叠加运动,父子 opacity 都是 0.5 时,子内容可见程度约为 0.25。先测整组,而不是只看每个元素单独的动画。

1.11 空间关系与对象恒常性

右侧抽屉从右进入、退回右侧;导航前进时旧页向左,新页从右来,返回反向。所谓一致,是空间来源和去处一致,不是出入速度方向相同。

缩略图扩展成大图、关闭后缩回,是让用户持续认出同一个对象;共享元素动画服务于这个目的。不同产品、RTL 语言环境可采用不同方向规则,但需要整体一致。

1.12 非对称时间与 crossfade

长按确认可以匀速、较慢地显示进度;取消要快速退回。短文本/结构相近内容切换,优先试小幅位移配淡入淡出,而非整屏滑动。原文给出约 8px 位移与约 2px blur 的起点;先解决对齐、高度和时间交接,再尝试模糊。

1.13 无障碍与完整流程

普通和 reduced-motion 两套行为都需要检查:移除装饰位移、视差、回弹,保留必要的信息,必要时直接切换或逐帧查看。业务状态不能依赖 animationend 才成立。

记录参考→慢放并逐帧看→一次只改一个变量→正常速度验收→真实手机验证→隔一段时间复看。下一天复看是原文的打磨建议,不是必须等一天才能完成任务。

1.14 这个 skill 怎样实现

description 负责告诉宿主什么时候考虑加载;主文件安排判断顺序;三个同目录引用文件按技术拆分,避免每次加载全部代码。审查时用 Before / After / Why 表格约束输出。这种“决策层+按需参考”比把全部动画代码塞进一个文件更易维护。

自测与答案

  1. 保存成功一定需要动画吗?需要明确反馈,动画可选。

  2. 200ms 一定比 400ms 感觉更快吗?还取决于曲线、延迟和运动幅度。

  3. 高阻尼一定更快归位吗?不是,过阻尼可能更慢。

  4. 关闭到一半再次打开,应观察什么?位置跳变、速度突变、输入是否被忽略。

完成标志:能为一个组件写出用途、频率、起终态、曲线时长、中断行为、性能风险和 reduced-motion 行为。

关于这份笔记

来自作者已整理的 Skills 中文自学资料。数字和配方是调试起点,库与浏览器的行为需结合实际版本验证;教材中的原演示验收记录不等同于你的项目已通过测试。

技术校正与版本边界 ↗完整来源说明 ↗
继续下一篇CSS 机制与完整配方