我有一个函数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()
功能?
答案 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>)
}
}