贝塞尔曲线生成器
以可视化方式设计 CSS 时间函数并复制 cubic-bezier 值
拖拽两个控制点塑造曲线。水平方向限制在框内;垂直方向可超出框外,实现回弹效果。
当前曲线
线性(参考)
cubic-bezier 生成器让你通过拖拽两个控制点,可视化地设计 CSS 时间函数,再复制出精确的 cubic-bezier(x1, y1, x2, y2) 值。编辑器把水平坐标钳制在单位框内,允许垂直坐标越出框外以实现过冲,并用真实 CSS transition 预览曲线,让你在粘进样式表之前就判断出手感。
读懂曲线
时间函数是一条三次贝塞尔曲线,端点固定为 P0 = (0,0)、P3 = (1,1),两个手柄决定 P1 = (x1, y1) 和 P2 = (x2, y2)。给定时间进度 x,浏览器先找出满足 x(t) = x 的曲线参数 t,再返回 y(t):
x(t) = 3(1−t)²t·x1 + 3(1−t)t²·x2 + t³
y(t) = 3(1−t)²t·y1 + 3(1−t)t²·y2 + t³
由于 x1 和 x2 被限制在 [0,1],x(t) 单调上升,所以每个 x 都恰好有一个 t 与之对应。画布上的虚线对角线是线性函数 y = x,是每条曲线用来对照的基准。
操作步骤
- 从预设开始——点击 ease、ease-in-out、easeOutBack 或其他内置预设,载入已知的控制点。
- 拖拽手柄——拉动任意一个圆形控制点。水平拖动被钳制在单位框内;垂直拖动不受限制。
- 观察实时数值——
cubic-bezier(...)输出随每一次指针移动更新。 - 播放预览——用你生成的确切值驱动示例圆点,并与旁边的线性圆点对比。
- 复制——点击复制,把数值粘进
transition-timing-function或animation-timing-function。
实操示例:三种缓动在 50% 时刻
| 预设 | 数值 | 半程时的输出进度 | 特征 |
|---|---|---|---|
ease | cubic-bezier(0.25, 0.1, 0.25, 1) | y ≈ 0.802 | 略快于线性,收尾柔和 |
easeOutBack | cubic-bezier(0.175, 0.885, 0.32, 1.275) | y ≈ 1.068 | 半程已越过终点;峰值接近 1.087 |
easeInExpo | cubic-bezier(0.95, 0.05, 0.795, 0.035) | y ≈ 0.037 | 几乎不动,末尾猛冲 |
easeOutBack 的数字最值得记住:在 400 毫秒的过渡里,它会在约 63% 处超出最终位置约 9%,然后回落。缩短时长,这个回弹会显得干脆;拉长时长,过冲则显得拖沓。
过冲、预备与 x/y 规则
x 与 y 的不对称不是这个工具的怪癖,而是 CSS 规范本身。浏览器需要 x(t) 是一个函数,所以 x1、x2 必须落在 [0,1] 内,生成器替你钳制好。y1、y2 可以是任意实数:
- y > 1——元素越过目标位置再返回。用于 toast、弹窗和按钮的弹跳。
- y < 0——元素先向后退再向前走。用于预备动作,比如滑动前的蓄力。
- 两者兼有——easeInOutBack 把低于 0 的下沉与高于 1 的过冲结合在一起。
精度与局限
- 数值在打印前四舍五入到四位小数,与这些曲线通常被分享的精度一致。
- 屏幕上的曲线通过数值求解 t 得到(牛顿-拉夫森法,迭代八次)。在极端的控制点取值下,可视曲线与浏览器的曲线可能相差一条亚像素级的轨迹,但打印出来的 CSS 值是精确的。
- 工具只输出时间函数。它不生成
transition或@keyframes块,不选择时长,也不决定对哪个属性做动画。 - 曲线救不了不可动画的属性,也无法让
display淡入淡出。这个工具设计的是运动,而不是让属性变得可动画。
从曲线到样式表
生成的字符串就是时间函数,所以可以直接放进任何过渡或动画:
.button { transition: transform 180ms cubic-bezier(0.175, 0.885, 0.32, 1.275); }
@keyframes pop { from { transform: scale(0.9); } to { transform: scale(1); } }
.toast { animation: pop 320ms cubic-bezier(0.68, -0.55, 0.265, 1.55) both; }
两个习惯会让这件事更省心。第一,让曲线匹配距离和时长:强烈的过冲放在长过渡里读起来像晃动,同一条曲线放在 150 毫秒里读起来则像干脆的一弹。第二,把少量常用曲线存进 CSS 变量,比如 --ease-snappy 和 --ease-bounce,让不同组件保持一致的运动质感,而不是各自发明一套。
常见错误
- 什么都过冲。 按钮、卡片、弹窗都在弹跳的界面会显得嘈杂。每个视图里只为一两处焦点交互保留过冲。
- 只复制曲线却不管时长。 手感来自这对组合;150 毫秒和 800 毫秒的 easeOutBack 是截然不同的效果。
- 以为负的 y 是非法值。 不是——那是预备动作,浏览器会渲染它,工具也是有意允许的。
- 用位移预览去判断所有属性。 transform 上的运动几乎说明不了 opacity 或颜色会如何插值,因为曲线是分别作用于每个属性的。
相关工具
- CSS 盒阴影生成器 — 实时预览设计多层盒阴影。
- 圆角生成器 — 以可视化方式设计圆角,支持椭圆半径。
- CSS Flexbox 生成器 — 以可视化方式设计 Flexbox 布局并复制 CSS。
- CSS 文字阴影生成器 — 为文本添加多层阴影。
常见问题
cubic-bezier(x1, y1, x2, y2) 里的四个数值是什么意思?
它们是一条锚定在 (0,0) 和 (1,1) 的三次贝塞尔曲线的两个控制点坐标:(x1, y1) 是第一个控制点,(x2, y2) 是第二个。x 轴表示时间进度,y 轴表示动画的输出进度,因此曲线的形状决定了运动如何加速与减速。
为什么 y 能高于 1 或低于 0,而 x 不行?
控制点的 x 必须保持在 [0,1] 内,因为时间不能倒流——曲线必须始终是进度的函数。控制点的 y 则自由:大于 1 会让动画冲过目标再回落(easeOutBack),小于 0 会让它先向后退(easeInBack)。回弹和预备动作正是这样构造出来的。
怎么做出过冲或回弹的效果?
把第二个控制点拖到方框顶边之上,让 y2 大于 1。`cubic-bezier(0.175, 0.885, 0.32, 1.275)` 会在超过终值约 8.7% 处达到峰值,然后回落。想做预备动作,就把第一个控制点拖到方框底边之下,令 y1 为负。
预览是真实的 CSS 动画还是模拟的?
是真实的。演示圆点使用真正的 `transition`,应用的就是你生成的 cubic-bezier 值,旁边还有一个线性参考圆点作对比。你看到的就是浏览器实际渲染的样子,包括任何过冲。
为什么 cubic-bezier 时间函数在某些属性上好像没效果?
时间函数只对可动画的属性做插值。像 `display` 这样的离散属性,无论给什么曲线都只在中点切换;不可动画的属性则瞬间跳变。如果什么都没有动,问题出在属性本身,而不是缓动。
怎样精确复刻设计系统里的缓动?
设计系统通常会公布四个控制点数值。你可以在编辑器里按这些值拖出对应位置,或从最接近的内置预设出发,每次只微调一个手柄。真正重要的是输出值,所以请直接复制 `cubic-bezier(...)` 字符串,而不是凭肉眼去凑。
由 HandyTools Hub 团队审校 · 最后更新