D3转换,暂停和恢复

use*_*959 9 javascript transition d3.js

我正在使用setInterval,因此转换发生在一定的时间间隔之后.是否可以暂停和恢复使用setInterval?

任何正确方向的建议/指示都会非常有帮助.

谢谢!

Ger*_*ado 4

这个问题是在 D3 v3 是最新版本时发布的。5 年后,D3 v5 有了一些新方法,例如selection.interrupt()transition.on("interrupt"...)local variables,它们可以使任务变得更简单、更少痛苦。

cx那么,让我们假设一个圆上的简单过渡:

const svg = d3.select("svg");
const circle = svg.append("circle")
  .attr("r", 15)
  .attr("cx", 20)
  .attr("cy", 50)
  .style("fill", "teal")
  .style("stroke", "black");
circle.transition()
  .duration(10000)
  .ease(d3.easeLinear)
  .attr("cx", 580);
Run Code Online (Sandbox Code Playgroud)
svg {
  background-color: wheat;
  display: block;
};
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="600" height="100"></svg>
Run Code Online (Sandbox Code Playgroud)

这个想法是在按下按钮时中断转换:

selection.interrupt();
Run Code Online (Sandbox Code Playgroud)

然后,使用局部变量,使用监听器来interrupt获取当前位置:

.on("interrupt", function() {
    local.set(this, +d3.select(this).attr("cx"))
}); 
Run Code Online (Sandbox Code Playgroud)

最后,当再次按下按钮时,我们使用local.get(this)简单的数学运算来获得剩余的duration

还值得一提的是,这适用于线性缓动;如果您有其他缓动,例如默认缓动d3.easeCubic,您将需要更复杂的代码。

这是演示:

selection.interrupt();
Run Code Online (Sandbox Code Playgroud)
.on("interrupt", function() {
    local.set(this, +d3.select(this).attr("cx"))
}); 
Run Code Online (Sandbox Code Playgroud)
const svg = d3.select("svg");
const local = d3.local();
const button = d3.select("button");
const circle = svg.append("circle")
  .attr("r", 15)
  .attr("cx", 20)
  .attr("cy", 50)
  .style("fill", "teal")
  .style("stroke", "black");
circle.transition()
  .duration(10000)
  .ease(d3.easeLinear)
  .attr("cx", 580)
  .on("interrupt", function() {
    local.set(this, +d3.select(this).attr("cx"))
  });
button.on("click", function() {
  if (d3.active(circle.node())) {
    circle.interrupt();
    this.textContent = "Resume";
  } else {
    circle.transition()
      .ease(d3.easeLinear)
      .duration(function() {
        return 10000 * (560 - local.get(this)) / 560;
      })
      .attr("cx", 580)
    this.textContent = "Stop";
  }
})
Run Code Online (Sandbox Code Playgroud)