如何在d3 V3中使用定时器?

时间:2017-08-02 22:54:19

标签: javascript d3.js timer

我有一个函数triggerWave(),它使画布上的点以波形形式生成动画。我使用d3.ease('quad-in')进行缓和,我想使用d3.timer()triggerWave()时间范围内进行200ms函数调用。我很难找到关于d3.timer的教程或示例。

triggerWave() {
  //function logic
  let count = 0;
  let xScale = d3.scale.linear().range([1,2]); // want the value to change from 1 to 2.
  let zScale = d3.scale.linear().domain([0, 200]); // 200 ms.
  let value = xScale(d3.ease('quad-in')(zScale(count)));
  if(count < 200){
   count++;
   d3.timer(() => triggerWave());
  } else {
    // do something
  }
  this.wave.next({currentFrame: value});
}

当我按上述方式调用d3.timer()时,triggerWave()函数会被无限次调用,并且永不停止。我想操纵或控制时间。就我而言,我希望为200ms触发timer()。

如何理解如何使用d3.timer()功能?

3 个答案:

答案 0 :(得分:4)

编辑:在问题的标题中,我完全错过了那个巨大的,大的“ V3 ”,就在那里。抱歉。我会保留这个答案在这里作为v4用户的参考)

由于您在triggerWave功能本身内拨打triggerWave,因此您不需要d3.timer,而是d3.timeout。根据{{​​3}},d3.timeout

  

与计时器一样,除了计时器在第一次回调时自动停止。保证不在后台运行的setTimeout的合适替代品。回调是经过的时间。

另外,请注意每次运行该函数时重置count的事实,这将无法正常工作。将其初始值设置为函数。

这是一个包含这些更改的演示。我每隔200毫秒调用一次函数,直到count到达50

var p = d3.select("p")
var count = 0;

triggerWave();

function triggerWave() {
  p.html("Count is " + count)
  if (count < 50) {
    count++;
    d3.timeout(triggerWave, 200)
  } else {
    return
  }
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<p></p>

您还可以使用triggerWave传递给d3.timeout的参数跟踪总耗用时间:

var p = d3.select("p")
var count = 0;
var elapsed = 0;
var format = d3.format(".2")

triggerWave();

function triggerWave(t) {
  elapsed = t ? elapsed + t : elapsed;
  p.html("Count is " + count + ", and the elapsed time is " + format(elapsed/1000) + " seconds")
  if (count < 50) {
    count++;
    d3.timeout(triggerWave, 200)
  } else {
    return
  }
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<p></p>

由于您使用的是D3 v3,并且由于v3中没有d3.timeout,因此您可以使用vanilla JavaScript执行相同的方法:setTimeout

这是一个演示:

var p = d3.select("p")
var count = 0;

triggerWave();

function triggerWave() {
  p.html("Count is " + count)
  if (count < 50) {
    count++;
    setTimeout(triggerWave, 200)
  } else {
    return
  }
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<p></p>

答案 1 :(得分:4)

在版本3中,没有d3.timer.stop()功能。您必须在一段时间后返回true才能停止计时器。

在Gerardo的回答中,他非常精巧地解释了如何使用d3 timeout来解决你的问题,即在一段时间内反复调用函数。但是看看你对Gerardo答案的评论,我认为你正在寻找其他的东西。

这是我想出的,我认为这就是你要找的东西:

您可以创建另一个名为activateTriggerWave()的函数,该函数将在按钮单击时调用,在此函数内部,您可以使用triggerWave()调用d3 timer方法。

function activateTriggerWave() {
  d3.timer(elapsed => {
  this.triggerWave();
  if(elapsed >= 200){
    return true; // this will stop the d3 timer. 
  }
});
}

triggerWave() {
 // here you can do whatever logic you want to implement.
}

我希望这会有所帮助。

答案 2 :(得分:-1)

我使用d3.js v3,任何用户操作都可以停止计时器。在d3.js文档中,它显示为使用它:

d3.timer(function(elapsed) {
  console.log(elapsed);
  return elapsed >= 1000;
});

我有几个动画永远的例子,没有理由对它设置限制。检查stop()附带的独立d3.timer,我发现它与v3工具集中包含的默认计时器相比表现得相当慢,可能是因为某些版本不兼容。

解决方案的用途是:

var timer_1_stop=false;

将其设置为来自页面范围的全局var可访问。然后计时器:

const run=function(){
  //...
  d3.timer(function() {
    voronoi = d3.geom.voronoi(points).map(function(cell) { return bounds.clip(cell); });
    path.attr("d", function(point, i) { return line(resample(voronoi[i])); });

    return timer_1_stop;
  });
}

const stopVoro=function(){
  timer_1_stop=true;
}

允许这样做:

class Menu extends React.Component {
  render(){
    return(<ul>
      <li><span onClick={()=>{stopVoro()}}>StopVoro</span></li>
    </ul>)
  }
}