暂停和恢复转换

12

我正在使用setInterval函数,因此过渡效果会在一定时间间隔后发生。是否可能通过setInterval来实现暂停和恢复功能?

如果您能给出任何方向性的建议或提示,将非常有帮助。


你看过这篇文章吗? - Lars Kotthoff
是的,我看到了这篇文章,但我不确定它如何与具有特定时间间隔的setInterval函数配合使用。我在一定时间间隔后开始转换,一旦可视化完成,我就使用了clearInterval。是否可能使暂停和恢复功能与setInterval一起工作?还是需要我改变实现方式? - user3441959
原则上,您应该能够无问题地使用setInterval - Lars Kotthoff
你能告诉我为什么需要使用interval吗?使用.delay和'on start'处理程序通过d3.active创建重复函数不可以吗?示例 - mtx
1个回答

4
当时发布此问题时,D3 v3是最新版本。五年后,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);
svg {
  background-color: wheat;
  display: block;
};
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="600" height="100"></svg>

这个想法是在转换过程中打断,例如当用户按下一个按钮时:

selection.interrupt();

然后,使用本地变量,利用interrupt监听器获取当前位置:

.on("interrupt", function() {
    local.set(this, +d3.select(this).attr("cx"))
}); 

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

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

以下是演示:

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";
  }
})
svg {
  background-color: wheat;
  display: block;
};
<script src="https://d3js.org/d3.v5.min.js"></script>
<button>Stop</button>
<svg width="600" height="100"></svg>


你很厉害,请问为什么在 cx 中是 560 而不是 580? - yavg
@yavg 这可能是一个打字错误。 - Gerardo Furtado

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接