我正在尝试在一些 Canvas 动画旁边创建一个计时器。该动画使用设置为 60 fps 的函数循环来刷新 Canvas 并重新绘制对象。我能想到的制作秒表的唯一方法是使用相同的循环来获取每帧的毫秒数并将其添加到文本对象中。我只是想知道是否有更有效的方法来做到这一点?
var frame = 0;
canvas.setLoop(function() {
if(particle.x < 1080 && particle.x > 0){
frame++;
particle.x = 540 + (acc*frame*frame)/120;
gField.t.text = "g = 9.81ms⁻²\nMass = "+particle.mass+"kg\nF = ma\nFrame: " + frame + "\nDistance: " + (particle.x - 540).toFixed(1);
stopwatch();
}else{
canvas.timeline.stop();
}
})
var sec = 0;
var tsec = 0;
var hsec = 0;
function stopwatch(){
hsec+= (5/3);
if(hsec >= 10){
tsec++;
hsec = hsec -10;
}
if(tsec >= 10){
sec++;
tsec = tsec-10;
}
time.text = (sec)+":"+(tsec)+(hsec).toFixed(0);
}
var clicks = 0
control.button.bind("click tap", function() {
clicks++;
if(clicks == 1){
canvas.timeline.start();
}else{
clicks = 0;
canvas.timeline.stop();
}
})
P.s.这是一个动力学模拟程序。我正在使用 oCanvas 库来实现 Canvas 动画。
最佳答案
使用 requestAnimationFrame,因为这是使用 JavaScript 获得的最准确的计时器,而且好处是它将为您提供高分辨率的时间戳:
var ctx = canvas.getContext('2d'),
startTime = null,
lastTime = null, // for scale
isRunning = false,
FPS = 1000/60,
x = 0,
dx = 4; // ideal frame rate
function loop(timeStamp) {
if (!startTime) startTime = timeStamp;
var timeDiff = lastTime ? timeStamp - lastTime : FPS,
timeElapsed = timeStamp - startTime,
timeScale = timeDiff / FPS; // adjust variations in frame rates
lastTime = timeStamp;
ctx.clearRect(0,0,canvas.width, canvas.height);
// do your stuff using timeScale, ie:
// pos.x += velocity.x * timeScale
x += dx * timeScale;
if (x < 0 || x > canvas.width-1) dx = -dx;
ctx.fillRect(x,0,8,8);
ctx.fillText((timeElapsed*0.001).toFixed(4), 10, 50);
ctx.fillText(timeScale.toFixed(1), 10, 90);
if (isRunning) requestAnimationFrame(loop);
}
ctx.font = "40px sans-serif";
btnToggle.addEventListener("click", function() {
if (isRunning) {
isRunning = false;
this.innerHTML = "Start";
} else {
startTime = lastTime = null;
isRunning = true;
requestAnimationFrame(loop)
this.innerHTML = "Stop";
}
}, false);
<canvas id=canvas width=360 height=100></canvas>
<br><button id="btnToggle">Start</button>
要重置开始时间,请将其初始化为 null(或 0)。此处使用 isRunning
只是作为如何停止循环的示例(通过将其设置为 false)。
请注意,timeScale
用于补偿帧速率变化。如果循环未以 60 FPS 运行,则 timeScale
将对此进行补偿,即。如果 FPS 为 30,timeScale
将为 2 等,以便您可以根据时间正确更新参数。
关于javascript - 创建秒表/计时器以及 60fps 的 Canvas 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27134879/