Oh MyUtils

CSS Cubic Bezier 生成器 - 在线创建缓动函数

使用交互式可视化编辑器创建自定义CSS缓动曲线。拖动控制点、预览动画并复制cubic-bezier()代码。

常见问题

什么是CSS cubic-bezier()函数?

CSS cubic-bezier()函数定义了一条三次贝塞尔缓动曲线,用于控制CSS过渡和动画的速度。它接受四个数字参数 — cubic-bezier(x1, y1, x2, y2) — 定义曲线上的两个控制点(P1和P2),其中X轴表示时间进度(0到1),Y轴表示动画进度(0到1)。起始点P0始终为(0,0),终点P3始终为(1,1)。通过调整控制点,您可以决定动画如何加速、减速或过冲。

如何使用这个cubic-bezier生成器?

在交互式图表上拖动两个控制点手柄(P1和P2)来塑造您想要的缓动曲线,或在X1、Y1、X2、Y2输入框中输入精确的数值。动画预览会实时更新。您也可以从预设库中选择一个起始点。切换「与Linear比较」来查看您的曲线与匀速运动的差异。使用复制按钮复制生成的CSS代码。

我的数据安全吗?会发送到服务器吗?

是的,您的数据完全安全。此工具完全在浏览器中使用客户端JavaScript运行。不会向任何服务器发送贝塞尔值、动画设置或任何数据。所有曲线计算、动画渲染和代码生成都在您的设备上本地完成。您可以放心地将其用于专有设计系统工作。

cubic-bezier()中的X和Y值是什么意思?

四个值定义了2D图表上的两个控制点。X值(x1和x2)代表时间轴上的点,必须在0到1之间。Y值(y1和y2)代表进度轴上的点,可以是任何数字。当Y值在0和1之间时,动画正常推进。当Y值低于0或高于1时,动画会暂时过冲或欠冲目标状态,从而产生弹跳或弹性效果。

ease、ease-in、ease-out和ease-in-out有什么区别?

这些是对应特定cubic-bezier值的CSS关键字。ease(0.25, 0.1, 0.25, 1)稍慢开始,快速加速,然后平滑减速——它是CSS过渡的默认值。ease-in(0.42, 0, 1, 1)慢速开始并加速,适用于离开屏幕的元素。ease-out(0, 0, 0.58, 1)快速开始并减速,适用于进入屏幕的元素。ease-in-out(0.42, 0, 0.58, 1)慢速开始,中间加速,然后减速。

如何创建过冲或弹跳效果?

将Y值(y1或y2)设置在[0, 1]范围之外。要在结尾处过冲(元素超过目标然后回弹),将y2设置大于1,例如cubic-bezier(0.34, 1.56, 0.64, 1)。要在开头处欠冲(元素在向前动画之前短暂后退),将y1设置小于0。生成器的图表会在0-1框之外进行视觉扩展,以显示这些过冲区域。

我应该为动画使用哪条缓动曲线?

最佳缓动取决于动画上下文。对于UI入场(模态框、下拉菜单出现),使用ease-out或Quart/Quint Out曲线实现自然减速。对于UI退场(元素消失),使用ease-in实现平滑加速。对于状态变化(颜色变化、大小调整),ease-in-out提供平衡的加速。对于趣味交互(按钮反馈、微交互),使用Back Out曲线添加微妙的过冲。大多数UI动画应避免使用linear,因为它感觉很机械。

代码示例

function evaluateBezier(t, p0, p1, p2, p3) {
  const u = 1 - t;
  return u * u * u * p0 + 3 * u * u * t * p1 + 3 * u * t * t * p2 + t * t * t * p3;
}

function cubicBezierY(x, x1, y1, x2, y2) {
  if (x <= 0) return 0;
  if (x >= 1) return 1;
  let low = 0, high = 1, mid;
  for (let i = 0; i < 20; i++) {
    mid = (low + high) / 2;
    const cx = evaluateBezier(mid, 0, x1, x2, 1);
    if (Math.abs(cx - x) < 0.0001) break;
    cx < x ? (low = mid) : (high = mid);
  }
  return evaluateBezier((low + high) / 2, 0, y1, y2, 1);
}

function formatCubicBezier(x1, y1, x2, y2) {
  const r = (n) => Math.round(n * 100) / 100;
  return `cubic-bezier(${r(x1)}, ${r(y1)}, ${r(x2)}, ${r(y2)})`;
}

console.log(formatCubicBezier(0.25, 0.1, 0.25, 1));
// cubic-bezier(0.25, 0.1, 0.25, 1)

// Animate using the bezier curve
function animate(x1, y1, x2, y2, durationMs, onProgress) {
  const start = performance.now();
  function tick(now) {
    const t = Math.min((now - start) / durationMs, 1);
    onProgress(cubicBezierY(t, x1, y1, x2, y2));
    if (t < 1) requestAnimationFrame(tick);
  }
  requestAnimationFrame(tick);
}

相关工具