typescriptgoogle-mapsgoogle-maps-api-3google-polyline

how to stop animating symbol at end of polyline?


I'm using basic animation example from google-maps-docs.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: { lat: 20.291, lng: 153.027 },
      zoom: 6,
      mapTypeId: "terrain",
    }
  );

  // Define the symbol, using one of the predefined paths ('CIRCLE')
  // supplied by the Google Maps JavaScript API.
  const lineSymbol = {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 8,
    strokeColor: "#393",
  };

  // Create the polyline and add the symbol to it via the 'icons' property.
  const line = new google.maps.Polyline({
    path: [
      { lat: 22.291, lng: 153.027 },
      { lat: 18.291, lng: 153.027 },
    ],
    icons: [
      {
        icon: lineSymbol,
        offset: "100%",
      },
    ],
    map: map,
  });

  animateCircle(line);
}


function animateCircle(line: google.maps.Polyline) {
  let count = 0;

  const icons = line.get("icons");
  window.setInterval(() => {
    count = (count + 1) % 200;
    icons[0].offset = count / 2 + "%";
    line.set("icons", icons);
  }, 60);
}

How do I stop animation at 2nd point of polyline i.e last point and show marker at that point? As you can see in the doc the animation keeps repeating again again surely because of interval but I want to add clearInterval the moment my icon offset is at last point

I tried following:


const stopAni = ref<number | undefined>();
function animateCircle(line: google.maps.Polyline) {
  let count = 0;

  const icons = line.get("icons");
  stopAni.value = window.setInterval(() => { // setting interval to variable
    count = (count + 1) % 200;
    icons[0].offset = count / 2 + "%";
    line.set("icons", icons);
  }, 60);

// I want to clearInterval at last point but i don't know where to add that?
//clearInterval(stopAni.value)
}

Solution

  • Call clearInterval with the intervalID when the count is equal to the maximum value (199):

    if (count >= 199)
      window.clearTimeout(intervalHandler);
    

    full function that animates once:

    function animateCircle(line) {
      let count = 0;
    
      let intervalHandler = window.setInterval(() => {
        count = (count + 1) % 200;
    
        const icons = line.get("icons");
    
        icons[0].offset = count / 2 + "%";
        console.log("count="+count+" offset="+icons[0].offset);
        line.set("icons", icons);
        if (count >= 199)
            window.clearTimeout(intervalHandler);
       
      }, 20);
    

    proof of concept fiddle

    code snippet:

    // This example adds an animated symbol to a polyline.
    function initMap() {
      const map = new google.maps.Map(document.getElementById("map"), {
        center: {
          lat: 20.291,
          lng: 153.027
        },
        zoom: 6,
        mapTypeId: "terrain",
      });
      // Define the symbol, using one of the predefined paths ('CIRCLE')
      // supplied by the Google Maps JavaScript API.
      const lineSymbol = {
        path: google.maps.SymbolPath.CIRCLE,
        scale: 8,
        strokeColor: "#393",
      };
      // Create the polyline and add the symbol to it via the 'icons' property.
      const line = new google.maps.Polyline({
        path: [{
            lat: 22.291,
            lng: 153.027
          },
          {
            lat: 18.291,
            lng: 153.027
          },
        ],
        icons: [{
          icon: lineSymbol,
          offset: "100%",
        }, ],
        map: map,
      });
    
      animateCircle(line);
    }
    
    // Use the DOM setInterval() function to change the offset of the symbol
    // at fixed intervals, stop at the end.
    function animateCircle(line) {
      let count = 0;
    
      let intervalHandler = window.setInterval(() => {
        count = (count + 1) % 200;
    
        const icons = line.get("icons");
    
        icons[0].offset = count / 2 + "%";
        line.set("icons", icons);
        if (count >= 199)
          window.clearTimeout(intervalHandler);
    
      }, 20);
    }
    
    window.initMap = initMap;
    #map {
      height: 100%;
    }
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Animating Symbols</title>
      <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
      <!-- jsFiddle will insert css and js -->
    </head>
    
    <body>
      <div id="map"></div>
    
      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly" defer></script>
    </body>
    
    </html>