javascriptgoogle-maps

google-maps animated symbols (stop the icon after reaching the destination point of the path)


I'm doing a school project and I'm using the Google Map API for it.
The API is great but I need some help in the code.
After reaching the destination point , I want the icon to stay there and should not repeat the whole path again.

function initMap() {
  var 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.
var lineSymbol = {
path: google.maps.SymbolPath.CIRCLE,
scale: 8,
strokeColor: '#393'
};

// Create the polyline and add the symbol to it via the 'icons' property.
var line = new google.maps.Polyline({
path: [{lat: -33.918861, lng: 18.423300}, {lat: -35.842160, lng: 18.863525}, {lat: -39.170387, lng: 35.189209}, {lat: -26.331494, lng: 54.228516}, {lat: 0.462885, lng: 61.083984}, {lat: 19.075984, lng: 72.877656}],
icons: [{
  icon: lineSymbol,
  offset: '100%'
}],
map: map
});

animateCircle(line);
}

// Use the DOM setInterval() function to change the offset of the symbol
// at fixed intervals.
function animateCircle(line) {
var count = 0;
window.setInterval(function() {
  count = (count + 1) % 200;

  var icons = line.get('icons');
  icons[0].offset = (count / 2) + '%';
  line.set('icons', icons);
}, 20);
}

Solution

  • Stop the animation when the icon gets to the end of the line. To stop the setInterval, use clearInterval (documentation)

    function animateCircle(line) {
      var count = 0;
      var listener = window.setInterval(function() {
        count = (count + 1) % 200;
    
        var icons = line.get('icons');
        icons[0].offset = (count / 2) + '%';
        line.set('icons', icons);
        if (count == 199) clearInterval(listener);
      }, 20);
    }
    

    proof of concept fiddle

    code snippet:

    // Use the DOM setInterval() function to change the offset of the symbol
    // at fixed intervals.
    function animateCircle(line) {
      var count = 0;
      var listener = window.setInterval(function() {
        count = (count + 1) % 200;
    
        var icons = line.get('icons');
        icons[0].offset = (count / 2) + '%';
        line.set('icons', icons);
        if (count == 199) clearInterval(listener);
      }, 20);
    }
    function initMap() {
      var map = new google.maps.Map(document.getElementById('map'), {
        center: {
          lat: 20.291,
          lng: 153.027
        },
        zoom: 2,
        mapTypeId: 'terrain'
      });
    
      // Define the symbol, using one of the predefined paths ('CIRCLE')
      // supplied by the Google Maps JavaScript API.
      var lineSymbol = {
        path: google.maps.SymbolPath.CIRCLE,
        scale: 8,
        strokeColor: '#393'
      };
    
      // Create the polyline and add the symbol to it via the 'icons' property.
      var line = new google.maps.Polyline({
        path: [{
          lat: -33.918861,
          lng: 18.423300
        }, {
          lat: -35.842160,
          lng: 18.863525
        }, {
          lat: -39.170387,
          lng: 35.189209
        }, {
          lat: -26.331494,
          lng: 54.228516
        }, {
          lat: 0.462885,
          lng: 61.083984
        }, {
          lat: 19.075984,
          lng: 72.877656
        }],
        icons: [{
          icon: lineSymbol,
          offset: '100%'
        }],
        map: map
      });
      var bounds = new google.maps.LatLngBounds();
      for (var i = 0; i < line.getPath().getLength(); i++) {
        bounds.extend(line.getPath().getAt(i));
      }
      map.fitBounds(bounds);
      animateCircle(line);
    }
    google.maps.event.addDomListener(window, "load", initMap);
    html,
    body,
    #map {
      height: 100%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map"></div>