如何为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
相关产品推荐
相关产品推荐

