Frank
Frank

Reputation: 745

setInterval inside another setInterval speeding up over time

I spent a long time trying to figure out how to animate a symbol on a polyline with the Google Maps API with CSS-style easing functions. I got this to work with this Gist and this Google Maps API example. Now I'm trying to run a setInterval(myFunc, 10) every ~5 seconds. Here's the relevant code snippet:

function animateCircle(line) {
    var count = 0;
    let refreshRate = 10;
    let countFunc = EasingFunctions.easeInOutCubic;
    let perc = 0

    function moveCircle() {
      count = count < 1 ? (count + 0.005) : 0;

      perc = countFunc(count) * 100 <= 100 ? countFunc(count) * 100 :  countFunc(count) * 100 - 100
      perc = perc >= 0 ? perc : 100 + perc
      perc === 0 ? window.clearInterval(moveCircInterval) : ''
      // console.log(count + " // " + perc)

      var icons = line.get('icons');
      icons[0].offset = perc + '%';

      line.set('icons', icons);
    }

    var moveCircInterval = window.setInterval(moveCircle, refreshRate);

    window.setInterval(() => moveCircInterval = window.setInterval(moveCircle, refreshRate), 5000)
  }

And a full JSFiddle to see it in action.

This code is not great, but nearly working. On my end, it speeds over time, especially if you navigate away from the tab and go back.

Upvotes: 0

Views: 78

Answers (2)

Frank
Frank

Reputation: 745

I ended up doing this:

function animateCircle(line) {
  var remove = window.setInterval(function() {
    var count = 0;
    let refreshRate = 20;
    let countFunc = EasingFunctions.easeInOutQuint;
    let perc = 0
    var now, before = new Date();
    var move = window.setInterval(function() {
      now = new Date();
      var elapsedTime = (now.getTime() - before.getTime());
      var icons = line.get('icons');

      if (elapsedTime > refreshRate + 5000) {
        // reset if navigate away from tab
        count = 0.005
        window.clearInterval(move)
      } else {
        count = count < 1 ? (count + 0.005) : 0;
      }

      perc = countFunc(count) * 100 <= 100 ? countFunc(count) * 100 : countFunc(count) * 100 - 100
      perc = perc >= 0 ? perc : 100 + perc
      perc === 0 || perc === 100 ? (window.clearInterval(move)) : ''

      icons[0].icon.path = svgTrans(perc)
      icons[0].offset = perc + '%';

      line.set('icons', icons);
    }, refreshRate)

  }, 5000)
}

here's the JSFiddle

Upvotes: 0

Mahesh More
Mahesh More

Reputation: 855

If I understood your concern correctly we can tweak your code like below:

function animateCircle(line) {
    var count = 0;
    let refreshRate = 10;
    let countFunc = EasingFunctions.easeInOutCubic;
    let perc = 0

    function moveCircle() {
      count = count < 1 ? (count + 0.005) : 0;

      perc = countFunc(count) * 100 <= 100 ? countFunc(count) * 100 :  countFunc(count) * 100 - 100
      perc = perc >= 0 ? perc : 100 + perc
      if (perc === 0) {
        clearInterval(moveCircInterval);
        setTimeout(() => {
            moveCircInterval = setInterval(moveCircle, refreshRate);
        }, 5000);
    }

      var icons = line.get('icons');
      icons[0].offset = perc + '%';

      line.set('icons', icons);
    }

    var moveCircInterval = setInterval(moveCircle, refreshRate);
  }

Please try it and let me know if it works for you!

Upvotes: 2

Related Questions