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)