| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- /**
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Igor Vladyka <igor.vladyka@gmail.com> (https://github.com/Igor-Vladyka/leaflet.motion)
- **/
- L.Motion = L.Motion || {
- Event: {
- Started:"motion-started",
- Paused: "motion-paused",
- Resumed: "motion-resumed",
- Section: "motion-section",
- Ended: "motion-ended"
- }
- };
- L.motion = L.motion || {};
- L.Motion.Animate = {
- options: {
- pane: "polymotionPane",
- attribution: "Leaflet.Motion © " + (new Date()).getFullYear() + " Igor Vladyka"
- },
- motionOptions: {
- auto: false,
- easing: function(x){ return x; }, // linear
- speed: 0, // KM/H
- duration: 0 // ms
- },
- markerOptions: undefined,
- initialize: function (latlngs, options, motionOptions, markerOptions) {
- L.Util.setOptions(this, options);
- if (motionOptions) {
- this.motionOptions = L.Util.extend({}, this.motionOptions, motionOptions);
- }
- if (markerOptions) {
- this.markerOptions = L.Util.extend({}, markerOptions);
- }
- this._bounds = L.latLngBounds();
- this._linePoints = this._convertLatLngs(latlngs);
- if (!L.Motion.Utils.isFlat(this._linePoints)) {
- this._linePoints = this._linePoints[0];
- }
- this._initializeMarker();
- this._latlngs = [];
- L.Util.stamp(this); // Enforce proper animation order;
- },
- addLatLng: function(latLng, ring) {
- latLng = L.Motion.Utils.toLatLng(latLng);
- this._linePoints.push(latLng);
- if (this._latlngs.length) {
- this._latlngs.push(latLng);
- }
- return this;
- },
- /**
- @param {Map} map the Leaflet Map
- */
- beforeAdd: function (map) {
- if (!map.getPane(this.options.pane)) {
- map.createPane(this.options.pane).style.zIndex = 599;
- }
- this._renderer = map.getRenderer(this);
- },
- /**
- @param {Map} map the Leaflet Map
- @return {MotionObject} this
- */
- onAdd: function (map) {
- this._renderer._initPath(this);
- this._reset();
- this._renderer._addPath(this);
- if (this.__marker && this.markerOptions.showMarker) {
- this.__marker.addTo(map);
- if(this.__marker._icon && this.__marker._icon.children.length){
- Array.from(this.__marker._icon.children).forEach(function(icon) {
- var baseRotationAngle = icon.getAttribute("motion-base");
- if (baseRotationAngle) {
- icon.style.transform = "rotate(" + baseRotationAngle + "deg)";
- }
- });
- }
- }
- if (this.motionOptions.auto) {
- this.motionStart();
- }
- return this;
- },
- /**
- @param {Map} map the Leaflet Map
- */
- onRemove: function (map) {
- this.motionStop();
- if (this.__marker) {
- map.removeLayer(this.__marker);
- }
- this._renderer._removePath(this);
- },
- /**
- @param {DateTime} startTime time from start animation
- */
- _motion: function (startTime) {
- var ellapsedTime = (new Date()).getTime() - startTime;
- var durationRatio = 1; // 0 - 1
- if (this.motionOptions.duration) {
- durationRatio = ellapsedTime / this.motionOptions.duration;
- }
- if (durationRatio < 1) {
- durationRatio = this.motionOptions.easing(durationRatio, ellapsedTime, 0, 1, this.motionOptions.duration);
- var interpolatedLine = L.Motion.Utils.interpolateOnLine(this._map, this._linePoints, durationRatio);
- this.setLatLngs(interpolatedLine.traveledPath);
- this._drawMarker(interpolatedLine.latLng);
- this.__ellapsedTime = ellapsedTime;
- this.animation = L.Util.requestAnimFrame(function(){
- this._motion(startTime);
- }, this);
- } else {
- this.motionStop(true);
- }
- },
- /**
- Draws marker according to line position
- @param {LatLng} nextPoint next animation point
- */
- _drawMarker: function (nextPoint) {
- var marker = this.getMarker();
- if (marker) {
- var prevPoint = marker.getLatLng();
- // [0, 0] Means that marker is not added yet to the map
- var initialPoints = this._linePoints[0];
- if (prevPoint.lat === initialPoints.lat && prevPoint.lng === initialPoints.lng) {
- marker.addTo(this._map);
- marker.addEventParent(this);
- } else {
- if (marker._icon && marker._icon.children.length) {
- Array.from(marker._icon.children).forEach(function(icon) {
- var needToRotateMarker = icon.getAttribute("motion-base");
- if (needToRotateMarker) {
- var motionMarkerOnLine = 0;
- if (needToRotateMarker && !isNaN(+needToRotateMarker)) {
- motionMarkerOnLine = +needToRotateMarker;
- }
- icon.style.transform = "rotate(-" + Math.round(L.Motion.Utils.getAngle(prevPoint, nextPoint) + motionMarkerOnLine) +"deg)";
- }
- });
- }
- }
- marker.setLatLng(nextPoint);
- }
- },
- /**
- Removes marker from the map
- */
- _removeMarker: function (animEnded) {
- if (this.markerOptions && this.__marker) {
- if (!animEnded || this.markerOptions.removeOnEnd) {
- this._map.removeLayer(this.__marker);
- }
- }
- },
- /**
- Initialize marker from marker options and add it to the map if needed
- */
- _initializeMarker: function () {
- if (this.markerOptions) {
- this.__marker = L.marker(this._linePoints[0], this.markerOptions);
- }
- },
- /**
- Starts animation of current object
- */
- motionStart: function () {
- if (this._map && !this.animation) {
- if (!this.motionOptions.duration) {
- if (this.motionOptions.speed) {
- this.motionOptions.duration = L.Motion.Utils.getDuration(this._map, this._linePoints, this.motionOptions.speed);
- } else {
- this.motionOptions.duration = 0;
- }
- }
- this.setLatLngs([]);
- this._motion((new Date).getTime());
- this.fire(L.Motion.Event.Started, {layer: this}, false);
- }
- return this;
- },
- /**
- Stops animation of current object
- @param {LatLng[]} points full object points collection or empty collection for cleanup
- */
- motionStop: function (animEnded) {
- this.motionPause();
- this.setLatLngs(this._linePoints);
- this.__ellapsedTime = null;
- this._removeMarker(animEnded);
- this.fire(L.Motion.Event.Ended, {layer: this}, false);
- return this;
- },
- /**
- Pauses animation of current object
- */
- motionPause: function () {
- if (this.animation) {
- L.Util.cancelAnimFrame(this.animation);
- this.animation = null;
- this.fire(L.Motion.Event.Paused, {layer: this}, false);
- }
- return this;
- },
- /**
- Resume animation of current object
- */
- motionResume: function () {
- if (!this.animation && this.__ellapsedTime) {
- if (!this.motionOptions.duration) {
- if (this.motionOptions.speed) {
- this.motionOptions.duration = L.Motion.Utils.getDuration(this._map, this._linePoints, this.motionOptions.speed);
- } else {
- this.motionOptions.duration = 0;
- }
- }
- this._motion((new Date).getTime() - (this.__ellapsedTime));
- this.fire(L.Motion.Event.Resumed, {layer: this}, false);
- }
- return this;
- },
- /**
- Toggles animation of current object; Start/Pause/Resume;
- */
- motionToggle: function () {
- if (this.animation) {
- if (this.__ellapsedTime) {
- this.motionPause();
- }
- } else {
- if (this.__ellapsedTime) {
- this.motionResume();
- } else {
- this.motionStart();
- }
- }
- return this;
- },
- /**
- Setup motion duration at any time
- */
- motionDuration: function (duration) {
- var prevDuration = this.motionSpeed.duration;
- this.motionOptions.duration = duration || 0;
- if (this.animation && prevDuration) {
- this.motionPause();
- this.__ellapsedTime = this.__ellapsedTime * (prevDuration / duration);
- this.motionOptions.duration = duration;
- this.motionResume();
- }
- return this;
- },
- /**
- Setup motion speed at any time
- */
- motionSpeed: function (speed) {
- var prevSpeed = this.motionOptions.speed;
- this.motionOptions.speed = speed || 0;
- if (this.animation && prevSpeed) {
- this.motionPause();
- this.__ellapsedTime = this.__ellapsedTime * (prevSpeed / speed);
- this.motionOptions.duration = L.Motion.Utils.getDuration(this._map, this._linePoints, this.motionOptions.speed);
- this.motionResume();
- }
- return this;
- },
- /**
- Returns current constructed marker
- */
- getMarker: function () {
- return this.__marker;
- },
- /**
- Returns markers array from all inner layers without flattering.
- */
- getMarkers: function () {
- return [this.getMarker()];
- }
- }
|