参数化 D3 中的 bounceOut 缓动效果

parametrize the bounceOut ease effect in D3

在下图中,黑线描述的是bounceOut函数,如D3-ease documentation所示。有什么办法可以让反弹变小,如红线所示?

没有更改特定缓动方法的本机方法。

但是,如果您查看 source code,您会发现反弹步骤是硬编码的:

var b1 = 4 / 11,
    b2 = 6 / 11,
    b3 = 8 / 11,
    b4 = 3 / 4,
    b5 = 9 / 11,
    b6 = 10 / 11,
    b7 = 15 / 16,
    b8 = 21 / 22,
    b9 = 63 / 64,
    b0 = 1 / b1 / b1;

因此,您可以轻松地使用一组不同的值创建自定义缓动。

为了比较,这里是 D3 缓动:

d3.select("svg")
  .append("circle")
  .attr("r", 20)
  .attr("cx", 20)
  .attr("cy", 50)
  .transition()
  .ease(d3.easeBounceOut)
  .duration(2000)
  .attr("cx", 280);
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>

这里是相同的代码,带有我们的自定义缓动:

d3.select("svg")
  .append("circle")
  .attr("r", 20)
  .attr("cx", 20)
  .attr("cy", 50)
  .transition()
  .ease(customBounce)
  .duration(2000)
  .attr("cx", 280);

function customBounce(t) {
  var b1 = 50 / 64,
    b2 = 54 / 64,
    b3 = 58 / 64,
    b4 = 60 / 64,
    b5 = 62 / 64,
    b6 = 63 / 64,
    b0 = 1 / b1 / b1;
  return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : b0 * (t -= b5) * t + b6;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>

我没有根据你想要的结果选择最好的数学,这只是一个笼统的解释,所以你可以自己做。

我在 Mike Bostock 在 bl.ocks.org 的 Custom Easing 页面上找到的以下代码正是我想要的,描述了参数化的反弹:

它定义了函数:

function bounce(h) {
  if (!arguments.length) h = 0.25;
  var b0 = 1 - h,
      b1 = b0 * (1 - b0) + b0,
      b2 = b0 * (1 - b1) + b1,
      x0 = 2 * Math.sqrt(h),
      x1 = x0 * Math.sqrt(h),
      x2 = x1 * Math.sqrt(h),
      t0 = 1 / (1 + x0 + x1 + x2),
      t1 = t0 + t0 * x0,
      t2 = t1 + t0 * x1,
      m0 = t0 + t0 * x0 / 2,
      m1 = t1 + t0 * x1 / 2,
      m2 = t2 + t0 * x2 / 2,
      a = 1 / (t0 * t0);
  return function(t) {
    return t >= 1 ? 1
        : t < t0 ? a * t * t
        : t < t1 ? a * (t -= m0) * t + b0
        : t < t2 ? a * (t -= m1) * t + b1
        : a * (t -= m2) * t + b2;
  };
}

然后在转换中将其指定为 ease 参数:

  d3element.transition()
      .duration(1500)
      .ease(bounce(0.2))
      ...omissis...