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



>我有一个函数triggerWave(),它使画布上的点以波形动画化。我正在使用d3.ease('quad-in')进行缓和,我想使用d3.timer()200ms时间范围内进行triggerWave()函数调用。我不走运地在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触发计时器((。

如何了解如何使用d3.timer()函数?

(编辑:我完全完全错过了问题标题中的巨大">V3"。不好意思。我将把这个答案留在这里作为v4用户的参考(

由于您在triggerWave函数本身中调用triggerWave,因此您不需要d3.timer,而是d3.timeout。根据 API,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>

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

在 Gerardo 的回答中,他出色地解释了如何使用d3 timeout,这将是解决问题的有效解决方案,即在一段时间内一遍又一遍地调用函数。但是看看你对杰拉尔多答案的评论,我认为你正在寻找别的东西。

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

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

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.
}

我希望这有所帮助。

我使用 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>)
}
}

最新更新