Prevent requestAnimationFrame from running all the time

前端 未结 2 1688
北荒
北荒 2021-01-07 12:20

I\'d like to know how to call the animate function through requestAnimationFrame only when it\'s realy needed. Currently the animate i

2条回答
  •  南方客
    南方客 (楼主)
    2021-01-07 12:34

    The reason your animate function is being called continuously is because you start off by calling requestAnimationFrame(animate); and then each call to animate unconditionally calls requestAnimationFrame(animate); again. The cycle is never going to be broken unless you use cancelAnimationFrame at some point (which you don't), or make sure that animate only requests another frame if it's needed.

    Another issue is the fact that radius will currently never reach either targetRadius nor baseRadius, and therefore neither of the following will ever be true:

    if(radius > targetRadius) radius = targetRadius;
    if(radius < baseRadius) radius = baseRadius;
    

    This isn't directly responsible for the continual calls to animate, but since targetRadius and baseRadius are being used to indicate the end-points of your animation then we need to form some sort of sensible conditional with them.

    So, you could do something like: http://jsfiddle.net/PLDUq/9/

    var radius = baseRadius = 50,
        targetRadius = 110,
        ease = 50,
        speed = 12,
        currentAnim;
    
    function animate(){
        if(mouseover){
            radius += ((targetRadius-radius)/ease)*speed;
        } else {
            radius -= ((radius-baseRadius)/ease)*speed;
        }
    
        drawDday(radius);
    
        if(Math.round(radius) >= targetRadius) {
            // uses Math.round() to ensure condition can be fulfilled
    
            radius = targetRadius;
            return; // doesn't call next frame
        }
        if(Math.round(radius) <= baseRadius) {
            radius = baseRadius;
            return; // doesn't call next frame
        }
    
        requestAnimationFrame(animate);
    }
    
    canvas.on('mouseenter mouseleave', function (e) {
        if (currentAnim) {requestAnimationFrame(currentAnim);}
        // cancels current animation if one is playing to
        // prevent several concurrent loops calling animate()
    
        mouseover = (e.type === 'mouseenter');
    
        requestAnimationFrame(animate);
    });
    

提交回复
热议问题