0
votes

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.

2
Why do you expect something else setInterval Registers a function to be called ever n milliseconds? So every 5secs you register another function that should be call every refreshRate ms. - t.niese
so you think just clear it every 5 seconds, and then reregister it? @t.niese - Franklin Harvey
It is not clear to me what you try to achieve with that construct. - t.niese
I'm trying to call moveCircle every 10ms. Then when its done, or when perc returns to 0, wait 5 seconds, and start over. @t.niese - Franklin Harvey

2 Answers

2
votes

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!

0
votes

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