You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为D3.js动画创建自定义cubic-bezier缓动函数?

解决D3.js中自定义Cubic-Bezier缓动函数的问题

针对你要将cubic-bezier(0.42, 0, 1, 1)转换成D3可用缓动函数的需求,有两种可行方案:

方案一:直接使用D3内置的贝塞尔缓动生成器

D3 v5及以上版本提供了d3.easeCubicBezier(x1, y1, x2, y2)方法,可以直接生成对应CSS cubic-bezier值的缓动函数,无需手动实现曲线计算:

// 对应CSS的cubic-bezier(0.42, 0, 1, 1)
const customEase = d3.easeCubicBezier(0.42, 0, 1, 1);

// 应用到蓝色矩形的D3动画中
d3.select(".blue-rect")
  .transition()
  .duration(1000) // 动画时长建议和CSS保持一致
  .ease(customEase) // 指定自定义缓动
  .attr("x", 300); // 替换为你的实际目标属性

方案二:手动实现贝塞尔曲线求值(用于理解原理)

如果需要手动实现贝塞尔曲线的参数映射,核心是根据时间进度t(0-1区间),通过牛顿迭代法求解对应贝塞尔曲线的进度值:

// 自定义贝塞尔缓动生成函数
function cubicBezierEase(x1, y1, x2, y2) {
  return function(t) {
    // 计算贝塞尔曲线上某点的值
    const bezier = (tVal, p0, p1, p2, p3) => {
      const tp = 1 - tVal;
      return tp ** 3 * p0 + 3 * tp ** 2 * tVal * p1 + 3 * tp * tVal ** 2 * p2 + tVal ** 3 * p3;
    };

    // 用牛顿迭代法找到对应时间t的进度值
    let x = t;
    for (let i = 0; i < 8; i++) {
      const tx = bezier(x, 0, x1, x2, 1);
      if (Math.abs(tx - t) < 1e-6) break;
      const dx = 3 * (1 - x) ** 2 * x1 + 6 * (1 - x) * x * (x2 - x1) + 3 * x ** 2 * (1 - x2);
      x -= (tx - t) / dx;
    }
    return bezier(x, 0, y1, y2, 1);
  };
}

// 生成目标缓动函数并应用
const customEase = cubicBezierEase(0.42, 0, 1, 1);
d3.select(".blue-rect")
  .transition()
  .duration(1000)
  .ease(customEase)
  .attr("x", 300);

关于你之前的progress1函数无效的原因

D3的缓动函数要求输入一个0到1之间的时间参数t,返回一个0到1之间的进度值。如果progress1没有实现正确的贝塞尔曲线参数映射,或者输出范围不符合要求,就无法生效。上述两种方案都严格遵循D3缓动函数的规范,可以直接替换使用。

内容的提问来源于stack exchange,提问作者smpa01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:54:06