gpt4 book ai didi

javascript - 如何使用 d3 重新启动(恢复) Canvas 动画中暂停的计时器

转载 作者:行者123 更新时间:2023-11-28 17:17:38 25 4
gpt4 key购买 nike

我已经构建了以下玩具示例(jsfiddle here;请在 10 秒内单击停止按钮):

var width = 750, height = 400;
var canvas = d3.select("body")
.append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
var x=Math.random()*50;
var y=Math.random()*50;

d3.select("body")
.append("button")
.html("stop")
.on("click",function(){ti.stop()});
d3.select("body")
.append("button")
.html("restart")
.on("click",function(){ti.restart()});

var ti = d3.timer(function(elapsed) {
context.clearRect(0, 0, width, height); // Clear the canvas.
context.fillStyle="red";
var t=Math.min(1,elapsed/10000)
context.fillRect(x*(1-t)+width*t,y*(1-t)+height*t,10,10);
})

我需要从单击停止按钮后暂停的位置重新启动动画。单击重新启动按钮时,我的代码出现错误。无论如何,在另一个更麻烦的代码中,time.restart()命令也不起作用,所以我认为还没有理解如何在D3计时器中暂停/重新启动。

最佳答案

timer.restart() 并不像你想象的那么有用。来自 docs :

timer.restart(callback[, delay[, time]])
Restart a timer with the specified callback and optional delay and time. This is equivalent to stopping this timer and creating a new timer with the specified arguments, although this timer retains the original invocation priority.

所以它不会为你工作。它只是让您免于创建新计时器,并且(在有多个计时器的情况下)它将保持其优先级。

此外,正如您在函数定义中看到的,参数callback是必需的。这就是为什么您在控制台中收到 TypeError:callback is not a function 的原因。

基本上,您应该将匿名回调函数转换为命名函数,并将其传递给构造函数和 restart 方法。但是,如果您尝试这样做,您会发现重新启动意味着重新启动:它从头开始。

所以,你不能依靠elapsed来计算动画的位置,你需要自己计算时间。在使用 d3.now() 创建计时器之前设置开始时间减去动画已经运行的时间(即第一次调用中的 0)。

var totalElapsedTime = 0;
var startTime = d3.now() - totalElapsedTime;
var t = d3.timer(myCallback);

然后,在回调中计算耗时:

var elapsedTime = d3.now() - startTime;
// This is how d3.js calculates `elapsed`.
// The actual code is more complicated but the result is the same.

stop按钮的click事件处理程序中记录耗时:

on("click",function(){
totalElapsedTime = d3.now() - startTime;
ti.stop();
});

更新restart按钮的click事件处理程序中的startTime:

.on("click",function(){
startTime = d3.now() - totalElapsedTime;
ti.restart(myCallback);
});

你就完成了。

郑重声明,真正的暂停/恢复功能 was suggested on GitHub ,但已被解雇。其他开发者有forked the project来实现它,如果你有兴趣的话。

注意:在下面的代码片段中,我稍微简化了代码并减小了 Canvas 的大小,以便更容易在代码片段窗口中跟踪动画。

var width = 300,
height = 150;
var canvas = d3.select("body")
.append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");

d3.select("body")
.append("button")
.html("stop")
.on("click", function() {
totalElapsedTime = d3.now() - startTime;
ti.stop();
});
d3.select("body")
.append("button")
.html("restart")
.on("click", function() {
startTime = d3.now() - totalElapsedTime;
ti.restart(myCallback);
});

var startTime = d3.now();
var totalElapsedTime = 0;
var ti = d3.timer(myCallback);

function myCallback() {
var elapsedTime = d3.now() - startTime;
context.clearRect(0, 0, width, height);
context.fillStyle = "red";
var t = Math.min(1, elapsedTime / 10000)
context.fillRect( width * t, height * t, 10, 10);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

关于javascript - 如何使用 d3 重新启动(恢复) Canvas 动画中暂停的计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53091624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com