UNPKG

leaflet-trackplayer-xiaoai

Version:

一个 Leaflet 轨迹播放插件,可以根据实际行进方向自动旋转标记图标,动态调整已行进和未行进路径的颜色以清晰显示当前进度。支持自定义行驶速度等功能,并提供完整的 TypeScript 类型定义。

921 lines (920 loc) 31.4 kB
var N = (e, s, t) => new Promise((n, r) => { var o = (l) => { try { u(t.next(l)); } catch (p) { r(p); } }, f = (l) => { try { u(t.throw(l)); } catch (p) { r(p); } }, u = (l) => l.done ? n(l.value) : Promise.resolve(l.value).then(o, f); u((t = t.apply(e, s)).next()); }); import _ from "leaflet"; var b = 63710088e-1, Z = { centimeters: b * 100, centimetres: b * 100, degrees: b / 111325, feet: b * 3.28084, inches: b * 39.37, kilometers: b / 1e3, kilometres: b / 1e3, meters: b, metres: b, miles: b / 1609.344, millimeters: b * 1e3, millimetres: b * 1e3, nauticalmiles: b / 1852, radians: 1, yards: b * 1.0936 }; function C(e, s, t) { t === void 0 && (t = {}); var n = { type: "Feature" }; return (t.id === 0 || t.id) && (n.id = t.id), t.bbox && (n.bbox = t.bbox), n.properties = s || {}, n.geometry = e, n; } function O(e, s, t) { if (t === void 0 && (t = {}), !e) throw new Error("coordinates is required"); if (!Array.isArray(e)) throw new Error("coordinates must be an Array"); if (e.length < 2) throw new Error("coordinates must be at least 2 numbers long"); if (!H(e[0]) || !H(e[1])) throw new Error("coordinates must contain numbers"); var n = { type: "Point", coordinates: e }; return C(n, s, t); } function S(e, s, t) { if (t === void 0 && (t = {}), e.length < 2) throw new Error("coordinates must be an array of two or more positions"); var n = { type: "LineString", coordinates: e }; return C(n, s, t); } function K(e, s) { s === void 0 && (s = "kilometers"); var t = Z[s]; if (!t) throw new Error(s + " units is invalid"); return e * t; } function Q(e, s) { s === void 0 && (s = "kilometers"); var t = Z[s]; if (!t) throw new Error(s + " units is invalid"); return e / t; } function F(e) { var s = e % (2 * Math.PI); return s * 180 / Math.PI; } function M(e) { var s = e % 360; return s * Math.PI / 180; } function H(e) { return !isNaN(e) && e !== null && !Array.isArray(e); } function X(e) { return !!e && e.constructor === Object; } function J(e, s, t) { if (e !== null) for (var n, r, o, f, u, l, p, v = 0, g = 0, k, a = e.type, i = a === "FeatureCollection", h = a === "Feature", c = i ? e.features.length : 1, d = 0; d < c; d++) { p = i ? e.features[d].geometry : h ? e.geometry : e, k = p ? p.type === "GeometryCollection" : !1, u = k ? p.geometries.length : 1; for (var y = 0; y < u; y++) { var m = 0, w = 0; if (f = k ? p.geometries[y] : p, f !== null) { l = f.coordinates; var P = f.type; switch (v = 0, P) { case null: break; case "Point": if (s( l, g, d, m, w ) === !1) return !1; g++, m++; break; case "LineString": case "MultiPoint": for (n = 0; n < l.length; n++) { if (s( l[n], g, d, m, w ) === !1) return !1; g++, P === "MultiPoint" && m++; } P === "LineString" && m++; break; case "Polygon": case "MultiLineString": for (n = 0; n < l.length; n++) { for (r = 0; r < l[n].length - v; r++) { if (s( l[n][r], g, d, m, w ) === !1) return !1; g++; } P === "MultiLineString" && m++, P === "Polygon" && w++; } P === "Polygon" && m++; break; case "MultiPolygon": for (n = 0; n < l.length; n++) { for (w = 0, r = 0; r < l[n].length; r++) { for (o = 0; o < l[n][r].length - v; o++) { if (s( l[n][r][o], g, d, m, w ) === !1) return !1; g++; } w++; } m++; } break; case "GeometryCollection": for (n = 0; n < f.geometries.length; n++) if (J(f.geometries[n], s) === !1) return !1; break; default: throw new Error("Unknown Geometry Type"); } } } } } function Y(e, s) { var t, n, r, o, f, u, l, p, v, g, k = 0, a = e.type === "FeatureCollection", i = e.type === "Feature", h = a ? e.features.length : 1; for (t = 0; t < h; t++) { for (u = a ? e.features[t].geometry : i ? e.geometry : e, p = a ? e.features[t].properties : i ? e.properties : {}, v = a ? e.features[t].bbox : i ? e.bbox : void 0, g = a ? e.features[t].id : i ? e.id : void 0, l = u ? u.type === "GeometryCollection" : !1, f = l ? u.geometries.length : 1, r = 0; r < f; r++) { if (o = l ? u.geometries[r] : u, o === null) { if (s( null, k, p, v, g ) === !1) return !1; continue; } switch (o.type) { case "Point": case "LineString": case "MultiPoint": case "Polygon": case "MultiLineString": case "MultiPolygon": { if (s( o, k, p, v, g ) === !1) return !1; break; } case "GeometryCollection": { for (n = 0; n < o.geometries.length; n++) if (s( o.geometries[n], k, p, v, g ) === !1) return !1; break; } default: throw new Error("Unknown Geometry Type"); } } k++; } } function j(e, s) { Y(e, function(t, n, r, o, f) { var u = t === null ? null : t.type; switch (u) { case null: case "Point": case "LineString": case "Polygon": return s( C(t, r, { bbox: o, id: f }), n, 0 ) === !1 ? !1 : void 0; } var l; switch (u) { case "MultiPoint": l = "Point"; break; case "MultiLineString": l = "LineString"; break; case "MultiPolygon": l = "Polygon"; break; } for (var p = 0; p < t.coordinates.length; p++) { var v = t.coordinates[p], g = { type: l, coordinates: v }; if (s(C(g, r), n, p) === !1) return !1; } }); } function $(e, s) { j(e, function(t, n, r) { var o = 0; if (t.geometry) { var f = t.geometry.type; if (!(f === "Point" || f === "MultiPoint")) { var u, l = 0, p = 0, v = 0; if (J( t, function(g, k, a, i, h) { if (u === void 0 || n > l || i > p || h > v) { u = g, l = n, p = i, v = h, o = 0; return; } var c = S( [u, g], t.properties ); if (s( c, n, r, h, o ) === !1) return !1; o++, u = g; } ) === !1) return !1; } } }); } function tt(e, s, t) { var n = t, r = !1; return $( e, function(o, f, u, l, p) { r === !1 && t === void 0 ? n = o : n = s( n, o, f, u, l, p ), r = !0; } ), n; } function E(e) { if (!e) throw new Error("coord is required"); if (!Array.isArray(e)) { if (e.type === "Feature" && e.geometry !== null && e.geometry.type === "Point") return e.geometry.coordinates; if (e.type === "Point") return e.coordinates; } if (Array.isArray(e) && e.length >= 2 && !Array.isArray(e[0]) && !Array.isArray(e[1])) return e; throw new Error("coord must be GeoJSON Point or an Array of numbers"); } function et(e) { return e.type === "Feature" ? e.geometry : e; } var it = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : {}; function U(e, s, t) { t === void 0 && (t = {}); var n = E(e), r = E(s), o = M(r[1] - n[1]), f = M(r[0] - n[0]), u = M(n[1]), l = M(r[1]), p = Math.pow(Math.sin(o / 2), 2) + Math.pow(Math.sin(f / 2), 2) * Math.cos(u) * Math.cos(l); return K(2 * Math.atan2(Math.sqrt(p), Math.sqrt(1 - p)), t.units); } function B(e, s, t, n) { n === void 0 && (n = {}); var r = E(e), o = M(r[0]), f = M(r[1]), u = M(t), l = Q(s, n.units), p = Math.asin(Math.sin(f) * Math.cos(l) + Math.cos(f) * Math.sin(l) * Math.cos(u)), v = o + Math.atan2(Math.sin(u) * Math.sin(l) * Math.cos(f), Math.cos(l) - Math.sin(f) * Math.sin(p)), g = F(v), k = F(p); return O([g, k], n.properties); } function T(e, s, t) { if (t === void 0 && (t = {}), t.final === !0) return st(e, s); var n = E(e), r = E(s), o = M(n[0]), f = M(r[0]), u = M(n[1]), l = M(r[1]), p = Math.sin(f - o) * Math.cos(l), v = Math.cos(u) * Math.sin(l) - Math.sin(u) * Math.cos(l) * Math.cos(f - o); return F(Math.atan2(p, v)); } function st(e, s) { var t = T(s, e); return t = (t + 180) % 360, t; } function rt(e, s, t) { t === void 0 && (t = {}); for (var n = et(e), r = n.coordinates, o = 0, f = 0; f < r.length && !(s >= o && f === r.length - 1); f++) if (o >= s) { var u = s - o; if (u) { var l = T(r[f], r[f - 1]) - 180, p = B(r[f], u, l, t); return p; } else return O(r[f]); } else o += U(r[f], r[f + 1], t); return O(r[r.length - 1]); } function q(e, s) { return s === void 0 && (s = {}), tt(e, function(t, n) { var r = n.geometry.coordinates; return t + U(r[0], r[1], s); }, 0); } function V(e, s, t, n) { if (n = n || {}, !X(n)) throw new Error("options is invalid"); var r, o = []; if (e.type === "Feature") r = e.geometry.coordinates; else if (e.type === "LineString") r = e.coordinates; else throw new Error("input must be a LineString Feature or Geometry"); for (var f = r.length, u = 0, l, p, v, g = 0; g < r.length && !(s >= u && g === r.length - 1); g++) { if (u > s && o.length === 0) { if (l = s - u, !l) return o.push(r[g]), S(o); p = T(r[g], r[g - 1]) - 180, v = B(r[g], l, p, n), o.push(v.geometry.coordinates); } if (u >= t) return l = t - u, l ? (p = T(r[g], r[g - 1]) - 180, v = B(r[g], l, p, n), o.push(v.geometry.coordinates), S(o)) : (o.push(r[g]), S(o)); if (u >= s && o.push(r[g]), g === r.length - 1) return S(o); u += U(r[g], r[g + 1], n); } if (u < s && r.length === f) throw new Error("Start position is beyond line"); var k = r[r.length - 1]; return S([k, k]); } (function(e, s) { (function(t, n) { n(_); })(it, function(t) { t = t && t.hasOwnProperty("default") ? t.default : t; function n(a, i) { var h = i.x - a.x, c = i.y - a.y; return Math.sqrt(h * h + c * c); } var r = function(i, h) { return (Math.atan2(h.y - i.y, h.x - i.x) * 180 / Math.PI + 90 + 360) % 360; }, o = function(i, h) { var c = i.value, d = i.isInPixels; return d ? c / h : c; }; function f(a) { if (typeof a == "string" && a.indexOf("%") !== -1) return { value: parseFloat(a) / 100, isInPixels: !1 }; var i = a ? parseFloat(a) : 0; return { value: i, isInPixels: i > 0 }; } var u = function(i, h) { return i.x === h.x && i.y === h.y; }; function l(a) { return a.reduce(function(i, h, c, d) { if (c > 0 && !u(h, d[c - 1])) { var y = d[c - 1], m = i.length > 0 ? i[i.length - 1].distB : 0, w = n(y, h); i.push({ a: y, b: h, distA: m, distB: m + w, heading: r(y, h) }); } return i; }, []); } function p(a, i) { var h = l(a), c = h.length; if (c === 0) return []; var d = h[c - 1].distB, y = o(i.offset, d), m = o(i.endOffset, d), w = o(i.repeat, d), P = d * w, R = y > 0 ? d * y : 0, D = m > 0 ? d * m : 0, x = [], G = R; do x.push(G), G += P; while (P > 0 && G < d - D); var z = 0, A = h[0]; return x.map(function(I) { for (; I > A.distB && z < c - 1; ) z++, A = h[z]; var W = (I - A.distA) / (A.distB - A.distA); return { pt: v(A.a, A.b, W), heading: A.heading }; }); } function v(a, i, h) { return i.x !== a.x ? { x: a.x + h * (i.x - a.x), y: a.y + h * (i.y - a.y) } : { x: a.x, y: a.y + (i.y - a.y) * h }; } (function() { var a = L.Marker.prototype._initIcon, i = L.Marker.prototype._setPos, h = L.DomUtil.TRANSFORM === "msTransform"; L.Marker.addInitHook(function() { var c = this.options.icon && this.options.icon.options, d = c && this.options.icon.options.iconAnchor; d && (d = d[0] + "px " + d[1] + "px"), this.options.rotationOrigin = this.options.rotationOrigin || d || "center bottom", this.options.rotationAngle = this.options.rotationAngle || 0, this.on("drag", function(y) { y.target._applyRotation(); }); }), L.Marker.include({ _initIcon: function() { a.call(this); }, _setPos: function(c) { i.call(this, c), this._applyRotation(); }, _applyRotation: function() { this.options.rotationAngle && (this._icon.style[L.DomUtil.TRANSFORM + "Origin"] = this.options.rotationOrigin, h ? this._icon.style[L.DomUtil.TRANSFORM] = "rotate(" + this.options.rotationAngle + "deg)" : this._icon.style[L.DomUtil.TRANSFORM] += " rotateZ(" + this.options.rotationAngle + "deg)"); }, setRotationAngle: function(c) { return this.options.rotationAngle = c, this.update(), this; }, setRotationOrigin: function(c) { return this.options.rotationOrigin = c, this.update(), this; } }); })(), t.Symbol = t.Symbol || {}, t.Symbol.Dash = t.Class.extend({ options: { pixelSize: 10, pathOptions: {} }, initialize: function(i) { t.Util.setOptions(this, i), this.options.pathOptions.clickable = !1; }, buildSymbol: function(i, h, c, d, y) { var m = this.options, w = Math.PI / 180; if (m.pixelSize <= 1) return t.polyline([i.latLng, i.latLng], m.pathOptions); var P = c.project(i.latLng), R = -(i.heading - 90) * w, D = t.point(P.x + m.pixelSize * Math.cos(R + Math.PI) / 2, P.y + m.pixelSize * Math.sin(R) / 2), x = P.add(P.subtract(D)); return t.polyline([c.unproject(D), c.unproject(x)], m.pathOptions); } }), t.Symbol.dash = function(a) { return new t.Symbol.Dash(a); }, t.Symbol.ArrowHead = t.Class.extend({ options: { polygon: !0, pixelSize: 10, headAngle: 60, pathOptions: { stroke: !1, weight: 2 } }, initialize: function(i) { t.Util.setOptions(this, i), this.options.pathOptions.clickable = !1; }, buildSymbol: function(i, h, c, d, y) { return this.options.polygon ? t.polygon(this._buildArrowPath(i, c), this.options.pathOptions) : t.polyline(this._buildArrowPath(i, c), this.options.pathOptions); }, _buildArrowPath: function(i, h) { var c = Math.PI / 180, d = h.project(i.latLng), y = -(i.heading - 90) * c, m = this.options.headAngle / 2 * c, w = y + m, P = y - m, R = t.point(d.x - this.options.pixelSize * Math.cos(w), d.y + this.options.pixelSize * Math.sin(w)), D = t.point(d.x - this.options.pixelSize * Math.cos(P), d.y + this.options.pixelSize * Math.sin(P)); return [h.unproject(R), i.latLng, h.unproject(D)]; } }), t.Symbol.arrowHead = function(a) { return new t.Symbol.ArrowHead(a); }, t.Symbol.Marker = t.Class.extend({ options: { markerOptions: {}, rotate: !1 }, initialize: function(i) { t.Util.setOptions(this, i), this.options.markerOptions.clickable = !1, this.options.markerOptions.draggable = !1; }, buildSymbol: function(i, h, c, d, y) { return this.options.rotate && (this.options.markerOptions.rotationAngle = i.heading + (this.options.angleCorrection || 0)), t.marker(i.latLng, this.options.markerOptions); } }), t.Symbol.marker = function(a) { return new t.Symbol.Marker(a); }; var g = function(i) { return i instanceof t.LatLng || Array.isArray(i) && i.length === 2 && typeof i[0] == "number"; }, k = function(i) { return Array.isArray(i) && g(i[0]); }; t.PolylineDecorator = t.FeatureGroup.extend({ options: { patterns: [] }, initialize: function(i, h) { t.FeatureGroup.prototype.initialize.call(this), t.Util.setOptions(this, h), this._map = null, this._paths = this._initPaths(i), this._bounds = this._initBounds(), this._patterns = this._initPatterns(this.options.patterns); }, /** * Deals with all the different cases. input can be one of these types: * array of LatLng, array of 2-number arrays, Polyline, Polygon, * array of one of the previous. */ _initPaths: function(i, h) { var c = this; if (k(i)) { var d = h ? i.concat([i[0]]) : i; return [d]; } return i instanceof t.Polyline ? this._initPaths(i.getLatLngs(), i instanceof t.Polygon) : Array.isArray(i) ? i.reduce(function(y, m) { return y.concat(c._initPaths(m, h)); }, []) : []; }, // parse pattern definitions and precompute some values _initPatterns: function(i) { return i.map(this._parsePatternDef); }, /** * Changes the patterns used by this decorator * and redraws the new one. */ setPatterns: function(i) { this.options.patterns = i, this._patterns = this._initPatterns(this.options.patterns), this.redraw(); }, /** * Changes the patterns used by this decorator * and redraws the new one. */ setPaths: function(i) { this._paths = this._initPaths(i), this._bounds = this._initBounds(), this.redraw(); }, /** * Parse the pattern definition */ _parsePatternDef: function(i, h) { return { symbolFactory: i.symbol, // Parse offset and repeat values, managing the two cases: // absolute (in pixels) or relative (in percentage of the polyline length) offset: f(i.offset), endOffset: f(i.endOffset), repeat: f(i.repeat) }; }, onAdd: function(i) { this._map = i, this._draw(), this._map.on("moveend", this.redraw, this); }, onRemove: function(i) { this._map.off("moveend", this.redraw, this), this._map = null, t.FeatureGroup.prototype.onRemove.call(this, i); }, /** * As real pattern bounds depends on map zoom and bounds, * we just compute the total bounds of all paths decorated by this instance. */ _initBounds: function() { var i = this._paths.reduce(function(h, c) { return h.concat(c); }, []); return t.latLngBounds(i); }, getBounds: function() { return this._bounds; }, /** * Returns an array of ILayers object */ _buildSymbols: function(i, h, c) { var d = this; return c.map(function(y, m) { return h.buildSymbol(y, i, d._map, m, c.length); }); }, /** * Compute pairs of LatLng and heading angle, * that define positions and directions of the symbols on the path */ _getDirectionPoints: function(i, h) { var c = this; if (i.length < 2) return []; var d = i.map(function(y) { return c._map.project(y); }); return p(d, h).map(function(y) { return { latLng: c._map.unproject(t.point(y.pt)), heading: y.heading }; }); }, redraw: function() { this._map && (this.clearLayers(), this._draw()); }, /** * Returns all symbols for a given pattern as an array of FeatureGroup */ _getPatternLayers: function(i) { var h = this, c = this._map.getBounds().pad(0.1); return this._paths.map(function(d) { var y = h._getDirectionPoints(d, i).filter(function(m) { return c.contains(m.latLng); }); return t.featureGroup(h._buildSymbols(d, i.symbolFactory, y)); }); }, /** * Draw all patterns */ _draw: function() { var i = this; this._patterns.map(function(h) { return i._getPatternLayers(h); }).forEach(function(h) { i.addLayer(t.featureGroup(h)); }); } }), t.polylineDecorator = function(a, i) { return new t.PolylineDecorator(a, i); }; }); })(); (function() { var e = L.Marker.prototype._initIcon, s = L.Marker.prototype._setPos, t = L.DomUtil.TRANSFORM === "msTransform"; L.Marker.addInitHook(function() { var n = this.options.icon && this.options.icon.options, r = n && this.options.icon.options.iconAnchor; r && (r = r[0] + "px " + r[1] + "px"), this.options.rotationOrigin = this.options.rotationOrigin || r || "center bottom", this.options.rotationAngle = this.options.rotationAngle || 0, this.on("drag", function(o) { o.target._applyRotation(); }); }), L.Marker.include({ _initIcon: function() { e.call(this); }, _setPos: function(n) { s.call(this, n), this._applyRotation(); }, _applyRotation: function() { this.options.rotationAngle && (this._icon.style[L.DomUtil.TRANSFORM + "Origin"] = this.options.rotationOrigin, t ? this._icon.style[L.DomUtil.TRANSFORM] = "rotate(" + this.options.rotationAngle + "deg)" : this._icon.style[L.DomUtil.TRANSFORM] += " rotateZ(" + this.options.rotationAngle + "deg)"); }, setRotationAngle: function(n) { return this.options.rotationAngle = n, this.update(), this; }, setRotationOrigin: function(n) { return this.options.rotationOrigin = n, this.update(), this; } }); })(); _.TrackPlayer = class { constructor(e, s = {}) { var n, r, o, f, u, l, p, v, g, k; let t = _.polyline(e)._latlngs; this.track = S( t.map(({ lng: a, lat: i }) => [a, i]) ), this.distanceSlice = [0], this.track.geometry.coordinates.forEach((a, i, h) => { if (i !== 0) { let c = S(h.slice(0, i + 1)); this.distanceSlice.push(q(c)); } }), this.distance = q(this.track), this.addedToMap = !1, this.options = { speed: (n = s.speed) != null ? n : 600, weight: (r = s.weight) != null ? r : 8, markerIcon: s.markerIcon, polylineDecoratorOptions: (o = s.polylineDecoratorOptions) != null ? o : { patterns: [ { offset: 30, repeat: 60, symbol: _.Symbol.arrowHead({ pixelSize: 5, headAngle: 75, polygon: !1, pathOptions: { stroke: !0, weight: 3, color: "#fff" } }) } ] }, passedLineColor: (f = s.passedLineColor) != null ? f : "#0000ff", notPassedLineColor: (u = s.notPassedLineColor) != null ? u : "#ff0000", panTo: (l = s.panTo) != null ? l : !0, markerRotationOrigin: (p = s.markerRotationOrigin) != null ? p : "center", markerRotationOffset: (v = s.markerRotationOffset) != null ? v : 0, markerRotation: (g = s.markerRotation) != null ? g : !0, progress: (k = s.progress) != null ? k : 0 }, this.initProgress = s.progress, this.isPaused = !0, this.walkedDistance = 0, this.walkedDistanceTemp = 0, this.trackIndex = 0, this.listenedEvents = { start: [], pause: [], finished: [], progressCallback: [] }; } addTo(e) { if (this.addedToMap) return; if (this.map = e, this.addedToMap = !0, this.options.markerIcon) { let t = this.track.geometry.coordinates[0]; if (this.marker = _.marker([t[1], t[0]], { icon: this.options.markerIcon }).addTo(this.map), this.options.markerRotation) { let n = this.track.geometry.coordinates; this.marker.setRotationAngle( T(n[0], n[1]) / 2 + this.options.markerRotationOffset / 2 ), this.marker.setRotationOrigin( this.options.markerRotationOrigin ); } } let s = this.track.geometry.coordinates.map(([t, n]) => [ n, t ]); return this.notPassedLine = _.polyline(s, { weight: this.options.weight, color: this.options.notPassedLineColor }).addTo(this.map), this.passedLine = _.polyline([], { weight: this.options.weight, color: this.options.passedLineColor }).addTo(this.map), this.polylineDecorator = _.polylineDecorator( s, this.options.polylineDecoratorOptions ).addTo(this.map), this.initProgress && this.setProgress(this.initProgress), this; } remove() { this.addedToMap && (this.addedToMap = !1, this.polylineDecorator.remove(), this.polylineDecorator = null, this.notPassedLine.remove(), this.notPassedLine = null, this.passedLine.remove(), this.passedLine = null, this.marker && (this.marker.remove(), this.marker = null), this.finished = !1, this.startTimestamp = 0, this.pauseTimestamp = 0, this.walkedDistanceTemp = 0, this.walkedDistance = 0, this.trackIndex = 0, this.isPaused = !0, this.options.progress = this.initProgress); } start() { !this.isPaused && !this.finished || !this.addedToMap || ((this.options.progress === 0 || this.options.progress === 1) && (this.startTimestamp = 0, this.pauseTimestamp = 0, this.walkedDistanceTemp = 0, this.walkedDistance = 0), this.isPaused = !1, this.finished = !1, this.pauseTimestamp && this.startTimestamp && (this.startTimestamp = this.startTimestamp + (Date.now() - this.pauseTimestamp)), this.startAction(), this.listenedEvents.start.forEach((e) => e()), this.initProgress && this.setProgress(this.initProgress)); } pause() { this.isPaused || this.finished || (this.pauseTimestamp = Date.now(), this.isPaused = !0, this.listenedEvents.pause.forEach((e) => e())); } startAction() { let e = this.distance, s = (t) => { if (t && this.addedToMap) { let n = e / this.options.speed * 3600 * 1e3; this.startTimestamp || (this.startTimestamp = t); let r = t - this.startTimestamp; this.walkedDistance = e * (r / n) + this.walkedDistanceTemp, this.playAction(); } !this.isPaused && !this.finished && requestAnimationFrame(s); }; s(); } playAction(e = !1) { if (this.isPaused && !e) return; let s = this.distance; this.trackIndex = this.distanceSlice.findIndex((r, o, f) => { var u; return this.walkedDistance >= r && this.walkedDistance < ((u = f[o + 1]) != null ? u : 1 / 0); }); let [t, n] = rt(this.track, this.walkedDistance).geometry.coordinates; if (this.markerPoint = [n, t], this.options.panTo && this.map.panTo(this.markerPoint, { animate: !1 }), this.marker && this.marker.setLatLng(this.markerPoint), this.walkedDistance >= s) this.notPassedLine.setLatLngs([]); else { let r = V(this.track, this.walkedDistance); this.notPassedLine.setLatLngs( r.geometry.coordinates.map(([o, f]) => [f, o]) ); } if (this.walkedDistance > 0) { let r = V( this.track, 0, this.walkedDistance ); this.passedLine.setLatLngs( r.geometry.coordinates.map(([o, f]) => [f, o]) ); } else this.passedLine.setLatLngs([]); if (this.polylineDecorator.setPaths([ ...this.passedLine.getLatLngs(), ...this.notPassedLine.getLatLngs() ]), this.walkedDistance < s && this.options.markerRotation && this.marker) { let r = 0; r = T( O([t, n]), O( this.track.geometry.coordinates[this.trackIndex + 1] ) ), this.marker.setRotationAngle( r / 2 + this.options.markerRotationOffset / 2 ); } if (this.options.progress = Math.min(1, this.walkedDistance / s), this.listenedEvents.progressCallback.forEach( (r) => r( this.options.progress, _.latLng(...this.markerPoint), this.trackIndex ) ), this.walkedDistance >= s && (this.walkedDistance = s, this.finished = !0, this.listenedEvents.finished.forEach((r) => r()), this.options.markerRotation && this.marker)) { let r = this.track.geometry.coordinates, o = T( O(r.at(-2)), O(r.at(-1)) ); this.marker.setRotationAngle( o / 2 + this.options.markerRotationOffset / 2 ); } } setSpeedAction(e) { this.options.speed = e, this.walkedDistanceTemp = this.walkedDistance, this.startTimestamp = 0; } setSpeed(e, s = 20) { return N(this, null, function* () { s && (clearTimeout(this.setSpeedTimeout), yield new Promise((t) => { this.setSpeedTimeout = setTimeout(t, s); })), this.setSpeedAction(e); }); } setProgress(e) { this.addedToMap && (this.options.progress == 1 && e == 1 || this.options.progress == 0 && e == 0 || (this.options.progress = e, this.walkedDistanceTemp = this.distance * e, this.startTimestamp = 0, (this.isPaused || this.finished) && (this.walkedDistance = this.walkedDistanceTemp, this.isPaused ? this.playAction(!0) : (this.finished = !1, this.isPaused = !1, this.startAction())))); } on(e, s) { switch (e) { case "start": this.listenedEvents.start.push(s); break; case "pause": this.listenedEvents.pause.push(s); break; case "finished": this.listenedEvents.finished.push(s); break; case "progress": this.listenedEvents.progressCallback.push(s); break; } } off(e, s) { if (!s) { this.listenedEvents[e] = []; return; } switch (e) { case "start": this.listenedEvents.start = this.listenedEvents.start.filter( (t) => t !== s ); break; case "pause": this.listenedEvents.pause = this.listenedEvents.pause.filter( (t) => t !== s ); break; case "finished": this.listenedEvents.finished = this.listenedEvents.finished.filter( (t) => t !== s ); break; case "progress": this.listenedEvents.progressCallback = this.listenedEvents.progressCallback.filter( (t) => t !== s ); break; } } };