Search code examples
javascriptsvgrequestanimationframesvg-animate

How to use requestAnimationFrame inside function with arguments?


I trying to animate much svg paths, but function not working

Error:

Uncaught RangeError: Maximum call stack size exceeded

 function dashOffset(selector, dashStart, dashFinish, speed) {
    if (offsetStart >= offsetFinish){
        selector.style.strokeDashoffset = offsetStart;
        offsetStart -= speed;
    } else{
        return
    }
    requestAnimationFrame(dashOffset(selector, dashStart, dashFinish, speed));
}

with global variables it work perfect


Solution

  • You schedule a function that calls dashOffset, you don't call dashOffset itself:

    function dashOffset(selector, dashStart, dashFinish, speed) {
      // ...
      requestAnimationFrame(function() {
        dashOffset(selector, dashStart, dashFinish, speed);
      });
    }
    

    Or with ES6 syntax,

    function dashOffset(selector, dashStart, dashFinish, speed) {
      // ...
      requestAnimationFrame(() => dashOffset(selector, dashStart, dashFinish, speed));
    }
    

    Or, if your arguments will never change, you can explicitly prebind all your values:

    function processOffset(selector, dashStart, dashFinish, speed) {
      // ...no request here...
    }
    
    // and in some other part of your code (probably inside wherever
    // you have the actual argument instantiation available:
    var runOffset = processOffset.bind(this, selector, dashStart, dashFinish, speed);
    requestAnimationFrame(runOffset);
    

    Here bind() yields a new function with it's running context ("this") as well as any number of call arguments pre-filled as it were.

    However, the ES6 syntax solution is typically easiest to work with, as well as read for others.