一段时间后取消requestAnimationFrame循环

问题描述

我想在超时后取消动画。这是我的代码

function animate(){
        id = requestAnimationFrame(animate);
        console.log(id);
        c.clearRect(0,window.innerWidth,window.innerHeight);
        for(let i = 0; i < circleArray.length; i++){
            circleArray[i].scatter();
        }
        setTimeout(function(){
            id = requestAnimationFrame(animate);
            cancelAnimationFrame(id);
            update();
        },5000)
    }
    
    function update(){
        requestAnimationFrame(update);
        c.clearRect(0,window.innerHeight);
        for(let i = 0; i < circleArray.length; i++){
            circleArray[i].update();
        }
    }

在这里,我想停止动画功能的递归并启动更新功能。但是动画不会停止,并且更新功能会在给定时间后并发运行。

解决方法

只需使用一个变量来引用当前的渲染函数并在计时器事件上更改该变量即可。

示例

var currentFrameRender = animate;  // set current render
requestAnimationFrame(currentFrameRender); // request first frame
setTimeout(() => currentFrameRender = update,5000); // switch render in 5s
setTimeout(() => currentFrameRender = undefined,10000); // stop animation in 10s

function animate(){
    c.clearRect(0,c.canvas.width,c.canvas.height);
    for(let i = 0; i < circles.length; i++){
        circleArray[i].scatter();
    }

    // request frame only if currentFrameRender is defined
    currentFrameRender && requestAnimationFrame(currentFrameRender);
}

function update(){
    c.clearRect(0,c.canvas.height);
    for(let i = 0; i < circles.length; i++){
        circleArray[i].update();
    }

    // request frame only if currentFrameRender is defined
    currentFrameRender && requestAnimationFrame(currentFrameRender);
}