0

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.

MrUpsidown
  • 21,592
  • 15
  • 77
  • 131
Frank
  • 735
  • 1
  • 12
  • 33
  • 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 Feb 05 '19 at 16:49
  • so you think just clear it every 5 seconds, and then reregister it? @t.niese – Frank Feb 05 '19 at 16:51
  • 1
    Please read this: https://stackoverflow.com/questions/38709923/why-is-requestanimationframe-better-than-setinterval-or-settimeout – Randy Casburn Feb 05 '19 at 16:51
  • 1
    It is not clear to me what you try to achieve with that construct. – t.niese Feb 05 '19 at 16:52
  • 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 – Frank Feb 05 '19 at 16:57
  • Just a tip:(at least in Chrome, check for other browsers) if you switch on other windows, the animation will be stuck but not the setInterval... so when you'll back to the window with your animation... it will be accelerated with "cumulated" setIntervals and it will be really messed up. Try to convert in setTimeout and stop the call when your window is not focued, then call it when you focus the window again – Sycraw Feb 05 '19 at 17:10

2 Answers2

2

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!

Mahesh More
  • 821
  • 1
  • 8
  • 23
0

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

Frank
  • 735
  • 1
  • 12
  • 33