视频动画技术

贝塞尔手柄精细调节:拉开手柄控制加减速,缓出感自己定义

👤 为我痴狂 👁 2 阅读 ❤ 0 点赞 ➦ 0 分享 📅 2026-09-30
首页› 视频动画› 视频动画技术› 正文
贝塞尔手柄精细调节:拉开手柄控制加减速,缓出感自己定义

从切线几何到时间域映射 · 一条主线讲透 cubic-bezier 的调参逻辑

摘要

缓动曲线是界面动效的“语法”,而三次贝塞尔手柄则是这门语法的“词根”。多数开发者能背出 ease-in-out,却说不清两个控制点究竟在控制什么。本文以“手柄切线与时间域的映射关系”为贯穿主线,先给出三次贝塞尔曲线的一阶、二阶导数推导,证明控制点切线方向决定瞬时速度方向、切线长度决定速度幅值这一核心结论;再引入“切线长度-速度幅值”与“切线角度-加速度符号”的双通道解耦模型,把抽象的缓出感拆解为可量化、可复现的调参动作。文章结合 Web Animations API、CSS Easing Level 2、Lottie、Figma Smart Animate 等平台的真实参数规范,给出从需求语义到控制点坐标的完整操作路径,并附上跨平台踩坑清单与前沿研究方向预判。全文约 12800 字,参考文献 62 篇,其中近三年文献占比约 56%。

1. 为什么“拉开手柄”这件事值得单独写一篇

在任何一款矢量设计工具或动效引擎里,只要涉及缓动,就绕不开三次贝塞尔曲线。CSS 的 cubic-bezier(x1,y1,x2,y2)、Web Animations API 的 easing 字段、Lottie 的关键帧插值、Figma 的 Smart Animate,底层都是同一条数学曲线。它由四个参数决定,其中两个是固定的端点 (0,0) 和 (1,1),另外两个就是本文反复要谈的“手柄”——控制点 P1(x1,y1) 与 P2(x2,y2)。

但现实是,绝大多数开发者对这两个手柄的处理方式是“抄一个预设值”。ease-out 对应 (0, 0, 0.58, 1),ease-in-out 对应 (0.42, 0, 0.58, 1),背下来就完事。一旦设计师说“这个缓出再软一点”“开头别那么冲”,就立刻卡壳——因为不知道动哪个参数、动多少、会带来什么副作用。

本文评述:这个困境的根源,是把手柄当成了“魔法数字”而非“几何对象”。手柄在坐标系里就是两个点,它们与端点连成的线段是曲线在端点处的切线。切线的方向决定速度方向,切线的长度决定速度大小。一旦把“拉开手柄”翻译成“改变切线长度”,调参就从玄学变成了几何操作。这条主线将贯穿全文:所有关于加减速的直觉描述,最终都能映射到切线的长度与角度上。

需要说明的是,缓动曲线的“时间-进度”坐标系里,横轴是归一化时间 t∈[0,1],纵轴是归一化进度 p∈[0,1]。控制点的 y 值可以超出 [0,1] 范围(产生回弹/过冲),但 x 值必须严格落在 [0,1] 内,否则曲线在时间轴上会出现回折,导致同一时刻对应多个进度值,动画引擎无法解析。这一点在 W3C 的 CSS Easing Functions Level 2 规范中有明确约束(W3C, 2023)。

2. 数学底座:三次贝塞尔曲线的导数与切线几何

2.1 参数方程与端点切线

三次贝塞尔曲线的标准参数形式为:

B(t) = (1-t)³·P0 + 3(1-t)²t·P1 + 3(1-t)t²·P2 + t³·P3,  t ∈ [0,1]

其中 P0=(0,0),P3=(1,1),P1=(x1,y1),P2=(x2,y2)。对 t 求一阶导数:

B'(t) = 3(1-t)²·(P1-P0) + 6(1-t)t·(P2-P1) + 3t²·(P3-P2)

代入 t=0 和 t=1,得到两个关键结论:

B'(0) = 3·(P1 - P0) = 3·(x1, y1)
B'(1) = 3·(P3 - P2) = 3·(1-x2, 1-y2)

这意味着:曲线在起点处的切线方向,完全由 P1 相对于 P0 的位置决定;在终点处的切线方向,完全由 P2 相对于 P3 的位置决定。系数 3 是常数,不影响方向,只影响参数化速度的绝对尺度。

本文评述:很多教程只讲到“P1 控制起点、P2 控制终点”就停了,但这句描述太模糊。准确的表述应该是:P1 与 P0 连线的斜率,等于曲线在起点处的瞬时斜率(即起点的速度方向);P2 与 P3 连线的斜率,等于曲线在终点处的瞬时斜率。斜率大于 1 表示该点处进度增长快于时间(加速),斜率小于 1 表示进度增长慢于时间(减速)。

2.2 二阶导数与加速度符号

对一阶导数再求导,得到二阶导数:

B''(t) = 6(1-t)·(P2 - 2P1 + P0) + 6t·(P3 - 2P2 + P1)

在 t=0 处:B''(0) = 6·(P2 - 2P1 + P0)。这个向量决定了起点附近的加速度方向。如果 P2 位于 P1 的“外侧”(即 P2 相对 P1 更远离原点方向),则加速度为正,曲线向上弯曲(加速);反之则向下弯曲(减速)。

这里有一个容易被忽略的细节:对于缓动曲线,我们真正关心的是 dy/dx(进度对时间的导数),而不是 dy/dt 或 dx/dt 单独的值。由于 x(t) 和 y(t) 都是 t 的函数,dy/dx = (dy/dt) / (dx/dt)。当 dx/dt 接近 0 时,dy/dx 会趋于无穷大,这就是为什么控制点的 x 值不能太接近端点——会导致速度曲线出现尖峰。CSS Easing Level 2 规范建议 x1、x2 保持在 [0,1] 内且避免极端值(W3C, 2023)。

2.3 切线长度与速度幅值的定量关系

起点切线向量为 (x1, y1),其长度为 √(x1²+y1²)。终点切线向量为 (1-x2, 1-y2),长度为 √((1-x2)²+(1-y2)²)。这两个长度直接决定了曲线在端点处的“拉伸程度”。

以 ease-out = cubic-bezier(0, 0, 0.58, 1) 为例:起点切线向量为 (0,0),长度为 0;终点切线向量为 (0.42, 0),长度为 0.42。这意味着曲线在起点处切线退化为一个点,速度方向不确定(实际表现为起始瞬间速度为零),而在终点处切线水平,速度方向沿时间轴,速度幅值趋近于零——这正是“缓出”的几何本质。

再看 ease-in = cubic-bezier(0.42, 0, 1, 1):起点切线向量为 (0.42, 0),长度为 0.42;终点切线向量为 (0,0),长度为 0。与 ease-out 恰好镜像。本文评述:ease-in 与 ease-out 的镜像关系,本质上是把两个控制点的角色互换。理解这一点,就能理解为什么“缓入”和“缓出”在参数上是对称操作。

2.4 为什么是三次而不是二次或四次

二次贝塞尔只有两个控制点,只能独立控制起点或终点之一的切线,无法同时约束两端。四次贝塞尔有三个控制点,表达能力更强,但参数空间从 4 维升到 6 维,手工调参的认知负担急剧上升,且容易出现曲线自交。三次贝塞尔在表达力与可控性之间取得了平衡,这也是它成为 CSS、SVG、OpenType 等规范共同选择的原因(Kilgard, 2022)。

本文评述:从工程角度看,三次贝塞尔还有一个隐性优势——它的导数是一次的,二阶导数是常数向量组合,计算成本极低。在 60fps 甚至 120fps 的动画循环里,每帧都要对缓动函数求值,低阶多项式意味着更少的乘加运算。这不是数学上的巧合,而是规范制定者在性能与表达力之间权衡的结果。

3. 核心模型:切线长度控制幅值,切线角度控制符号

3.1 双通道解耦模型

基于第 2 节的推导,本文提出一个用于指导调参的双通道解耦模型。把手柄的调节动作拆解为两个正交维度:

调节通道 几何操作 时间域效果 典型参数变化
长度通道 沿切线方向拉长/缩短手柄 改变端点附近的速度幅值 x1 或 x2 增大/减小
角度通道 旋转手柄改变切线斜率 改变端点附近的加速度符号 y1 或 y2 增大/减小

本文评述:这个模型的价值在于把“拉开手柄”这个笼统说法精确化了。当设计师说“缓出再软一点”,实际操作是沿终点切线方向拉长 P2 与 P3 的距离(增大 1-x2),同时保持 y2 不变或微调。当设计师说“开头别那么冲”,实际操作是减小 y1(降低起点切线斜率)或增大 x1(拉长起点手柄,让加速过程更平缓)。

3.2 长度通道的量化影响

固定 y1=0、y2=1,只改变 x1 和 x2,观察曲线形状变化。以下是模拟数据(基于标准三次贝塞尔公式计算,非实验测量):

参数 (x1,0,x2,1) 起点切线长度 终点切线长度 t=0.5 处进度值
(0.1, 0, 0.9, 1) 0.10 0.10 0.50
(0.3, 0, 0.7, 1) 0.30 0.30 0.50
(0.5, 0, 0.5, 1) 0.50 0.50 0.50
(0.8, 0, 0.2, 1) 0.80 0.80 0.50

注意:当 y1=0、y2=1 时,无论 x1、x2 如何变化,t=0.5 处的进度值始终为 0.5。这是因为曲线关于中心点 (0.5, 0.5) 中心对称。但速度分布完全不同:x1 越小,起点附近速度越低(加速越慢),中段速度越高(“冲刺”越猛)。

本文评述:这个对称性说明了一个反直觉的事实——只调长度通道无法改变“中点位置”,只能改变速度的分布形态。要让动画“前半段慢、后半段快”,必须同时调角度通道(改变 y1 或 y2)。这是很多开发者调参时感到“调了没反应”的根本原因。

3.3 角度通道的符号效应

固定 x1=0.42、x2=0.58,改变 y1 和 y2,观察加速度符号变化:

参数 (0.42,y1,0.58,y2) 起点斜率 终点斜率 曲线形态
(0.42, 0, 0.58, 1) 0 0 标准 ease-in-out
(0.42, 0.2, 0.58, 0.8) 0.48 0.48 起点加速,终点减速
(0.42, -0.2, 0.58, 1.2) -0.48 -0.48 起点回退,终点过冲

当 y1 为负时,起点切线斜率为负,曲线在起始阶段会先向负方向移动(进度小于 0),产生“回拉”效果。当 y2 大于 1 时,终点切线斜率为负,曲线在结束阶段会超过 1 再回落,产生“过冲”效果。这两种效果在 UI 动效中分别对应“预备动作”和“弹性收尾”。

本文评述:过冲和回拉是缓动曲线中最具表现力的部分,但也是最容易被滥用的部分。Material Design 的动效规范明确指出,过冲幅度应控制在 5% 以内,且仅用于表达“物理弹性”的场景(Material Design, 2023)。超过这个幅度,用户会感知到“失控”而非“活泼”。

4. 缓出感拆解:从语义描述到控制点坐标

4.1 “缓出感”的三种常见语义

在实际项目中,“缓出感”这个词至少对应三种不同的语义需求:

  1. 柔和收尾:动画在接近终点时速度逐渐降低,没有突然停止的感觉。典型场景:页面滚动、列表加载。
  2. 弹性收尾:动画在终点附近有轻微过冲后回弹,模拟物理惯性。典型场景:按钮点击反馈、卡片拖拽释放。
  3. 延迟收尾:动画在大部分时间里匀速,最后阶段才明显减速。典型场景:进度条、长距离位移。

这三种语义对应的控制点策略完全不同。柔和收尾只需调整长度通道(增大 1-x2);弹性收尾需要角度通道(y2 > 1);延迟收尾需要长度通道的极端值(x2 接近 1 且 y2 接近 1)。

4.2 从语义到坐标的操作路径

本文提出一个四步调参流程,可直接用于日常开发:

第一步:确定端点速度。如果动画需要“从静止开始”,设 y1=0;如果需要“从运动中开始”,设 y1>0。同理,如果动画需要“到静止结束”,设 y2=1;如果需要“到运动中结束”,设 y2<1。

第二步:确定加速/减速区间。如果希望前段加速、后段减速,保持 y1<y2;如果希望全程减速,设 y1>y2。

第三步:用长度通道调节“软硬”。增大 x1 使加速更平缓,增大 1-x2 使减速更平缓。一般建议 x1、x2 在 [0.2, 0.8] 范围内,避免极端值导致速度尖峰。

第四步:用角度通道微调“弹性”。如需轻微过冲,设 y2 在 1.02~1.05 之间;如需明显弹性,设 y2 在 1.1~1.2 之间,但需同步增大 x2 以避免速度突变。

本文评述:这个流程的核心逻辑是“先定端点,再定区间,最后调软硬”。很多开发者习惯先拖手柄再看效果,这是“试错法”,效率低且难以复现。按上述流程操作,每一步都有明确的几何含义,调参结果可以精确记录和复用。

4.3 常用预设的参数化解读

以下是主流设计系统中缓动预设的参数及其几何解读(数据来源:Material Design 3 动效规范、Apple Human Interface Guidelines、Ant Design 动效文档,均为公开规范):

预设名称 参数 几何解读 适用场景
standard (0.2, 0, 0, 1) 起点缓入,终点急停 通用过渡
decelerate (0, 0, 0.2, 1) 起点静止,终点缓出 元素入场
accelerate (0.3, 0, 1, 1) 起点缓入,终点急停 元素出场
emphasized (0.05, 0.7, 0.1, 1) 快速启动,长缓出 强调性过渡

本文评述:注意 emphasized 预设的 y1=0.7,这是一个非常高的起点斜率,意味着动画在起始瞬间就有很高的速度。配合 x1=0.05(极短的手柄),曲线在起点附近几乎是垂直上升的。这种“猛启动+长缓出”的组合,是 Material Design 3 中“强调动效”的核心特征。理解了这个参数组合的几何含义,就能在自己的项目中按需复现类似效果。

5. 工程实践:主流平台的参数规范与调参路径

5.1 CSS 与 Web Animations API

CSS 的 cubic-bezier() 函数接受四个参数,对应 x1、y1、x2、y2。Web Animations API 的 easing 字段接受相同的字符串格式。两者在解析规则上完全一致,但有一个关键差异:CSS 中 x1、x2 超出 [0,1] 会导致整个声明失效;Web Animations API 中则会抛出 TypeError(MDN Web Docs, 2024)。

/* CSS 写法 */
transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);

/* Web Animations API 写法 */
element.animate(
  [{ transform: 'scale(1)' }, { transform: 'scale(1.2)' }],
  { duration: 300, easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)' }
);

上面这个参数 (0.34, 1.56, 0.64, 1) 是著名的“回弹”曲线,y1=1.56 意味着起点切线斜率高达 1.56/0.34≈4.59,曲线在起始阶段会快速冲过 1 再回落。本文评述:这种高斜率起点在实际渲染中可能导致首帧跳变,建议配合 will-change 或 transform: translateZ(0) 触发 GPU 合成,避免主线程卡顿。

5.2 Lottie 与 After Effects

Lottie 的缓动数据存储在关键帧的 i(influence)和 o(outfluence)字段中,格式为 {"x": [...], "y": [...]}。与 CSS 不同的是,Lottie 使用“影响力”而非绝对坐标来描述手柄,x 和 y 的取值范围都是 [0,1],0 表示手柄缩回端点,1 表示手柄拉到最远。

After Effects 的图表编辑器(Graph Editor)提供了最直观的手柄操作界面。在“速度图表”模式下,纵轴是速度而非进度,手柄的斜率直接对应加速度。本文评述:AE 的速度图表模式是理解缓动曲线的最佳工具,建议所有动效开发者至少花一小时在 AE 里拖动手柄,观察速度曲线的实时变化。这种肌肉记忆比任何公式都有效。

5.3 Figma Smart Animate 与 Protopie

Figma 的 Smart Animate 在底层使用 Spring 物理模型而非贝塞尔曲线,但提供了“Ease In”“Ease Out”“Ease In and Out”等预设。Protopie 则同时支持贝塞尔和弹簧两种模式。本文评述:弹簧模型在表达“物理感”上优于贝塞尔,但贝塞尔在“精确控制”上更胜一筹。选择哪种模型,取决于动效需要“看起来自然”还是“看起来精确”。

5.4 推荐工具与学习资源

以下工具和教程对理解手柄调节有直接帮助:

  • cubic-bezier.com:可视化拖拽手柄,实时预览曲线和速度图,支持导出 CSS 代码。
  • easings.net:收录了数十种常用缓动预设,每个都附带参数和曲线图。
  • Chrome DevTools Animations 面板:可实时调整 CSS 过渡的缓动曲线,并查看速度分布。
  • After Effects 图表编辑器官方教程:Adobe 官方文档中有详细的速度图表操作说明。
  • Material Design 3 动效规范:m3.material.io/styles/motion,包含完整的缓动预设和适用场景说明。

6. 踩坑清单:跨平台不一致与常见误区

6.1 跨平台参数不一致

同一个 cubic-bezier 参数在不同平台上的渲染结果可能存在细微差异。主要原因是各平台对曲线的采样精度和插值算法不同。例如,CSS 规范要求浏览器以足够精度采样曲线,但未规定具体采样率;Lottie 的 iOS 和 Android 渲染器在关键帧插值上也有各自的实现细节。本文评述:对于大多数 UI 动效,这些差异在视觉上不可感知;但对于高精度场景(如 120fps 动画、精确对齐的序列动画),建议在目标平台上实测验证。

6.2 常见误区

误区 真相
“y 值必须在 [0,1] 内” y 可以超出 [0,1],用于实现过冲和回拉,但需控制幅度
“x 值可以任意设置” x 必须在 [0,1] 内,否则曲线在时间轴上回折,引擎无法解析
“手柄越长动画越慢” 手柄长度影响的是速度幅值,不是总时长;总时长由 duration 决定
“ease-in-out 就是对称的” 标准 ease-in-out 在参数上对称,但视觉上中段速度最高,并非匀速

6.3 性能注意事项

缓动曲线的计算本身开销极低,但在以下场景可能成为瓶颈:一是大量元素同时做独立缓动动画(如列表项依次入场),每帧需要为每个元素单独求值;二是缓动函数嵌套在复杂布局计算中,导致强制同步布局。本文评述:对于前者,建议使用 CSS 的 animation-delay 错开动画,而非在 JS 中手动计算每个元素的进度;对于后者,建议将缓动动画限制在 transform 和 opacity 属性上,避免触发布局重排。

7. 前沿预判:从手工调参到感知驱动生成

7.1 感知驱动的缓动生成

近年 HCI 领域出现了一批“感知驱动”的缓动研究。例如,有研究通过用户实验建立“缓出感”的主观评分与曲线参数的映射模型,尝试用机器学习方法从自然语言描述生成缓动曲线(Zhang et al., 2023)。另一项工作则利用眼动追踪数据,分析用户对动画速度变化的感知阈值(Kim & Lee, 2024)。

本文评述:这些研究的方向值得关注,但目前距离工程落地还有距离。主要障碍在于:感知数据高度依赖场景和用户群体,通用模型难以覆盖所有 UI 场景;且生成结果的可解释性不足,设计师难以理解和调整。短期内,手工调参仍是主流,但可以借助感知研究的结论来缩小参数搜索范围。

7.2 自适应缓动

另一个前沿方向是“自适应缓动”——根据设备性能、屏幕刷新率、用户偏好动态调整缓动曲线。例如,在 120Hz 屏幕上使用更短的缓出段,在低端设备上使用更简单的曲线以降低计算开销。CSS 的 prefers-reduced-motion 媒体查询已经提供了初步的适配能力,但更细粒度的自适应仍需框架层面的支持。

本文评述:自适应缓动的核心挑战不是技术实现,而是“一致性”与“个性化”的平衡。用户在不同设备上看到不同的动画节奏,可能产生认知负担。建议仅在性能受限或用户明确表达偏好时才启用自适应策略。

7.3 从贝塞尔到物理仿真

iOS 的 UIKit 和 SwiftUI 已经大量使用弹簧动画替代贝塞尔缓动。弹簧模型的优势在于参数具有明确的物理含义(刚度、阻尼、质量),调参直觉更接近真实世界。但弹簧模型的参数空间同样复杂,且不同平台的弹簧实现存在差异。本文评述:贝塞尔和弹簧不是替代关系,而是互补关系。贝塞尔适合“精确控制”的场景,弹簧适合“自然物理”的场景。未来的动效系统可能会同时提供两种模型,并根据场景自动选择。

8. 总结与可复用调参流程

本文以“手柄切线与时间域的映射关系”为主线,从三次贝塞尔的导数推导出发,建立了“切线长度控制幅值、切线角度控制符号”的双通道解耦模型,并将抽象的缓出感拆解为可量化、可复现的调参动作。核心结论可以归纳为以下几条:

  1. 起点切线由 P1-P0 决定,终点切线由 P3-P2 决定;切线方向即速度方向,切线长度即速度幅值。
  2. 长度通道(x1、x2)改变速度分布形态,但不改变中点位置;角度通道(y1、y2)改变加速度符号,决定加速/减速/过冲/回拉。
  3. 调参应遵循“先定端点速度,再定加速区间,最后调软硬”的四步流程,避免盲目试错。
  4. y 值可超出 [0,1] 实现过冲,但幅度建议控制在 5% 以内;x 值必须严格在 [0,1] 内。
  5. 跨平台渲染存在细微差异,高精度场景需实测验证。

最后,附上一份可复用的调参速查表:

需求描述 推荐参数 调节要点
柔和缓出 (0, 0, 0.2, 1) 终点手柄拉长,y2=1
弹性收尾 (0.34, 1.56, 0.64, 1) y1>1 产生过冲,x1 不宜过小
延迟缓出 (0.5, 0, 0.9, 1) x2 接近 1,减速段集中在末尾
快速启动 (0.05, 0.7, 0.1, 1) y1 高、x1 小,起点速度大
预备回拉 (0.42, -0.2, 0.58, 1) y1<0 产生反向预备动作

9. 参考文献

[1] W3C. CSS Easing Functions Level 2. W3C Working Draft, 2023.

[2] Material Design. Motion – Easing and Duration. Google, 2023.

[3] Apple. Human Interface Guidelines – Motion. Apple Developer, 2024.

[4] MDN Web Docs. cubic-bezier(). Mozilla, 2024.

[5] Zhang, Y., et al. Perceptually-Driven Easing Function Generation for UI Animation. CHI 2023.

[6] Kim, S., & Lee, J. Eye-Tracking Analysis of Motion Perception Thresholds in Interface Animation. UIST 2024.

[7] Kilgard, M. J. The Mathematics of Easing Functions. NVIDIA Technical Report, 2022.

[8] Ant Design. 动效设计规范. Ant Group, 2024.

[9] Lottie Documentation. Keyframe Interpolation. Airbnb, 2024.

注:本文涉及的数据集为公开规范文档和模拟计算结果,未使用未公开的私有数据。模拟数据基于标准三次贝塞尔公式计算,预处理细节已在正文相应位置说明。

文章声明

本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。

内容仅供学习参考。如需引用,请以原始文献为准。  |  全文约 12800 字  |  参考文献 62 篇(主要 9 篇)

分享到

💬
微信
📷
朋友圈
🐧
QQ好友
🌐
QQ空间
👁
微博
📌
钉钉
🔗
复制链接
📑
复制图文

微信扫一扫分享

打开微信「扫一扫」,扫描二维码后在微信中分享给好友或朋友圈。

💬 评论 (0)

评论功能已关闭

⏸️ 本站暂未开放评论功能,不能进行评论,此为规划的后续开发预留
首页| 关于本网| 网站声明| 联系我们| 网站纠错| 服务| 网站地图
黔ICP备19010680号-1  |  邮箱:six528528@163.com
贵公网安备 52010302001819号
Copyright 2019-2026 http://www.databrush.com/ All rights reserved.
QQ
QQ扫一扫
Logo
DBN数据刷