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

时间:2014-12-08 10:42:21

标签: 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();
};

此功能通过按钮事件处理程序触发。当isRunning为假时,循环将停止,但显然timeStamp将从再次调用循环之前增加。

1 个答案:

答案 0 :(得分:1)

之前有一个答案,但我认为那个人之后删除了它,但我记得并且在使用rAF的timeStamp时找到了一种方法。

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);
    };
};

它的工作原理是将timeStamp和原始timeElapsed之间的差异存储到pTime中。现在,当您计算经过的时间时,您需要做的就是从pTime - timeStamp中减去startTime

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

button.onClick({
    if(isRunning){
        isRunning = false;
        pause = true;
    }else{
        isRunning = true;
        requestAnimationFrame(loop);
    };
});

如果其他人想通过其他方式触发此循环。