Skip to content

Leaflet animated marker

   

Using the extension functionalities of Leaflet library, I'll be creating an animated marker that looks like this:

Full code here

I want to be able to assign a set of icons (instead of only one as happens in the default marker implementation) and a speed in milliseconds.
The marker will switch through the icons according to the passed speed.

To achieve this, I'll extend the common leaflet Marker.

I will use the L.Marker.extend(...) method to create a new marker prototype that provides the animation functionalities that we need.

    
var MyAnimatedMarker = L.Marker.extend({

	options: {
	},

	initialize: function(latlng, options) {
		L.Marker.prototype.initialize.call(this, latlng);
		this.options.currentFrame = 0;
		this.options.icon = options.iconSet[this.options.currentFrame];
		L.Util.setOptions(this, options);
	},

	startAnimation: function () {
		let self = this;
		this.options.interval = setInterval(function(){

			if(self.options.currentFrame == self.options.iconSet.length) {
				self.options.currentFrame = 0;
			}
			L.Marker.prototype.setIcon.call(self, self.options.iconSet[self.options.currentFrame]);
			self.options.currentFrame++;
		}, self.options.animationSpeed);
	},

	stopAnimation: function () {
		clearInterval(this.options.interval);
	},

	setAnimationSpeed: function (speedMillis) {
		this.options.animationSpeed = speedMillis;
		this.stopAnimation();
		this.startAnimation();
	},

});
    
  

Then I can easily use the new defined prototype "MyAnimatedMarker" to do something like this:

    
var greenIcon = L.icon({
	iconUrl: '/leaflet/leaf-green.png',
	iconSize:     [38, 95],
	shadowSize:   [50, 64],
	iconAnchor:   [22, 94],
	popupAnchor:  [-3, -76]
});
var redIcon = L.icon({
	iconUrl: '/leaflet/leaf-red.png',
	iconSize:     [38, 95],
	shadowSize:   [50, 64],
	iconAnchor:   [22, 94],
	popupAnchor:  [-3, -76]
});
var orangeIcon = L.icon({
	iconUrl: '/leaflet/leaf-orange.png',

	iconSize:     [38, 95],
	shadowSize:   [50, 64],
	iconAnchor:   [22, 94],
	popupAnchor:  [-3, -76]
});

var marker = new MyAnimatedMarker([51.5, -0.09], {iconSet: [greenIcon, redIcon, orangeIcon], animationSpeed: 300});
marker.addTo(mymap).bindPopup("Faster animation").openPopup();
marker.startAnimation();
    
  

So, the newly defined MyAnimatedMarker prototype behaves just like the normal marker with the addition that you can pass an "iconSet" and "animationSpeed".
It also provides 3 methods to interact with it:

+ startAnimation()
+ stopAnimation()
+ setAnimationSpeed(speedInMillis)

Related Posts

  1. Protobuf communication between Js-client and Go-server