Last active
September 26, 2024 02:03
-
-
Save ramiroaznar/44f8de5ab7db081cae19db4e67bf6d74 to your computer and use it in GitHub Desktop.
How to make your markers move with Leaflet.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
L.AnimatedMarker = L.Marker.extend({ | |
options: { | |
// meters | |
distance: 200, | |
// ms | |
interval: 1000, | |
// animate on add? | |
autoStart: true, | |
// callback onend | |
onEnd: function(){}, | |
clickable: false | |
}, | |
initialize: function (latlngs, options) { | |
this.setLine(latlngs); | |
L.Marker.prototype.initialize.call(this, latlngs[0], options); | |
}, | |
// Breaks the line up into tiny chunks (see options) ONLY if CSS3 animations | |
// are not supported. | |
_chunk: function(latlngs) { | |
var i, | |
len = latlngs.length, | |
chunkedLatLngs = []; | |
for (i=1;i<len;i++) { | |
var cur = latlngs[i-1], | |
next = latlngs[i], | |
dist = cur.distanceTo(next), | |
factor = this.options.distance / dist, | |
dLat = factor * (next.lat - cur.lat), | |
dLng = factor * (next.lng - cur.lng); | |
if (dist > this.options.distance) { | |
while (dist > this.options.distance) { | |
cur = new L.LatLng(cur.lat + dLat, cur.lng + dLng); | |
dist = cur.distanceTo(next); | |
chunkedLatLngs.push(cur); | |
} | |
} else { | |
chunkedLatLngs.push(cur); | |
} | |
} | |
chunkedLatLngs.push(latlngs[len-1]); | |
return chunkedLatLngs; | |
}, | |
onAdd: function (map) { | |
L.Marker.prototype.onAdd.call(this, map); | |
// Start animating when added to the map | |
if (this.options.autoStart) { | |
this.start(); | |
} | |
}, | |
animate: function() { | |
var self = this, | |
len = this._latlngs.length, | |
speed = this.options.interval; | |
// Normalize the transition speed from vertex to vertex | |
if (this._i < len && this.i > 0) { | |
speed = this._latlngs[this._i-1].distanceTo(this._latlngs[this._i]) / this.options.distance * this.options.interval; | |
} | |
// Only if CSS3 transitions are supported | |
if (L.DomUtil.TRANSITION) { | |
if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + speed + 'ms linear'); } | |
if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + speed + 'ms linear'; } | |
} | |
// Move to the next vertex | |
this.setLatLng(this._latlngs[this._i]); | |
this._i++; | |
// Queue up the animation to the next next vertex | |
this._tid = setTimeout(function(){ | |
if (self._i === len) { | |
self.options.onEnd.apply(self, Array.prototype.slice.call(arguments)); | |
} else { | |
self.animate(); | |
} | |
}, speed); | |
}, | |
// Start the animation | |
start: function() { | |
this.animate(); | |
}, | |
// Stop the animation in place | |
stop: function() { | |
if (this._tid) { | |
clearTimeout(this._tid); | |
} | |
}, | |
setLine: function(latlngs){ | |
if (L.DomUtil.TRANSITION) { | |
// No need to to check up the line if we can animate using CSS3 | |
this._latlngs = latlngs; | |
} else { | |
// Chunk up the lines into options.distance bits | |
this._latlngs = this._chunk(latlngs); | |
this.options.distance = 10; | |
this.options.interval = 30; | |
} | |
this._i = 0; | |
} | |
}); | |
L.animatedMarker = function (latlngs, options) { | |
return new L.AnimatedMarker(latlngs, options); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>How to make your markers move with Leaflet.js</title> | |
<meta charset="utf-8"> | |
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" /> | |
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script> | |
<script src="AnimatedMarker.js"></script> | |
<style type="text/css"> | |
html, body, #map{ | |
height: 100%; | |
padding: 0; | |
margin: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></map> | |
<script type="text/javascript"> | |
var map = L.map('map').setView([40.68576, -73.94149], 18); | |
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: 'OSM'}) | |
.addTo(map); | |
var line = L.polyline([[40.68510, -73.94136], [40.68576, -73.94149], [40.68649, -73.94165]]); | |
map.addLayer(line); | |
var animatedMarker = L.animatedMarker(line.getLatLngs()); | |
map.addLayer(animatedMarker); | |
</script> | |
</body> | |
</html> |
Hey Ramiro,
Is the function compatible with CircleMarker ? I would like to use the circle marker instead of the default icon.
Thanks
Hello,
Why with more then 100 coordinates it does not work?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how to set icon angle ?