如何使用 requestAnimationFrame 暂停和重新启动秒表计时器?

Jim*_*Bee 2 javascript canvas timer requestanimationframe

我正在将 requestAnimationFrame 循环用于秒表和其他一些动画。我使用从 rAF 返回的时间戳来获取时间,但是当我停止循环以暂停计时器,等待几秒钟,然后再次启动循环时,计时器将显示总时间。

我需要能够暂停计时器并从暂停的时间继续。有没有办法在暂停计时器后重置时间戳变量?如果您需要我发布一些代码,请告诉我,或者如果您需要我进一步解释自己,我会这样做。

编辑

    var frames = 0,
    startTime = null,
    lastTime = null,
    fps = 1000/120,
    isRunning = false,
    pTime = 0,
    timeElapsed;

function loop(timeStamp){

        if(!startTime) startTime = timeStamp;
        var timeDiff = lastTime ? (timeStamp - lastTime) : fps,
            timeScale = timeDiff / fps,
            timeElapsed += (timeStamp - startTime)/1000,
            lastTime = timeStamp;

        if(isRunning){ 
            requestAnimationFrame(loop);
            gField.t.text = ++frames + "f / "+parseInt(timeElapsed - pTime)+"s = "+parseInt(frames/(timeElapsed-pTime)) + "fps\n"+(timeDiff).toFixed(2);
        }
        /*      
        canvas manipulation e.g.
        particle.x += acc*timeElapsed;
        */
        time.text = (timeElapsed).toFixed(2);
        canvas.redraw();
};
Run Code Online (Sandbox Code Playgroud)

该函数通过按钮事件处理程序触发。当isRunning为 false 时,循环将停止,但显然当再次调用循环时,timeStamp 会比之前增加。

Jim*_*Bee 5

之前有一个答案,但我认为那家伙后来删除了它,但我记得并找到了一种方法,同时仍然使用 rAF 的时间戳。

var startTime = null,
    isRunning = false,
    timeElapsed = 0,
    pause = false,
    pTime = 0;

function loop(timeStamp){
    if(!startTime) startTime = timeStamp;

    if(isRunning && !pause){
        timeElapsed = (timeStamp - startTime) - pTime;

        time.text = (timeElapsed/1000).toFixed(2);
        canvas.redraw();

        requestAnimationFrame(loop);
    }else if(isRunning && pause){
        pTime = (timeStamp - startTime) - timeElapsed;
        timeElapsed = (timeStamp - startTime) - pTime;


        time.text = (timeElapsed/1000).toFixed(2);
        canvas.redraw();

        pause = false;

        requestAnimationFrame(loop);
    };
};
Run Code Online (Sandbox Code Playgroud)

timeStamp它的工作原理是将与原始数据之间的差异存储timeElapsedpTime. 现在,当您计算经过的时间时,您所需要做的就是pTime从 ( timeStamp- startTime) 中减去。

循环由按钮触发。这是一些示例代码:

button.onClick({
    if(isRunning){
        isRunning = false;
        pause = true;
    }else{
        isRunning = true;
        requestAnimationFrame(loop);
    };
});
Run Code Online (Sandbox Code Playgroud)

万一其他人想通过其他方式触发这个循环。