@raruto/leaflet-elevation 1.7.6 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/leaflet-elevation.js +506 -737
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +2 -2
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/package.json +1 -1
- package/src/acceleration.js +10 -20
- package/src/altitude.js +18 -25
- package/src/chart.js +54 -153
- package/src/components.js +130 -94
- package/src/control.js +111 -207
- package/src/distance.js +12 -15
- package/src/marker.js +38 -81
- package/src/options.js +0 -8
- package/src/slope.js +8 -17
- package/src/speed.js +9 -19
- package/src/time.js +7 -7
- package/src/utils.js +77 -99
package/src/marker.js
CHANGED
|
@@ -7,39 +7,28 @@ export var Marker = L.Class.extend({
|
|
|
7
7
|
initialize: function(options) {
|
|
8
8
|
this.options = options;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
switch(this.options.marker) {
|
|
11
|
+
case 'elevation-line':
|
|
12
|
+
// this._container = d3.create("g").attr("class", "height-focus-group");
|
|
13
|
+
this._container = d3.select(map.getPane('elevationPane')).select("svg > g")
|
|
14
|
+
.attr("class", "height-focus-group");
|
|
15
|
+
break;
|
|
16
|
+
case 'position-marker':
|
|
17
|
+
// this._marker = L.circleMarker([0, 0], { pane: 'overlayPane', radius: 6, fillColor: '#fff', fillOpacity:1, color: '#000', weight:1, interactive: false });
|
|
18
|
+
this._marker = L.marker([0, 0], { icon: this.options.markerIcon, zIndexOffset: 1000000, interactive: false });
|
|
19
|
+
break;
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
// this._container = d3.create("g").attr("class", "height-focus-group");
|
|
20
|
-
this._focusline = d3.create('svg:line');
|
|
21
|
-
this._focusmarker = d3.create("svg:circle");
|
|
22
|
-
this._focuslabel = d3.create("svg:text");
|
|
23
|
-
} else if (this.options.marker == 'position-marker') {
|
|
24
|
-
// this._marker = L.circleMarker([0, 0], { pane: 'overlayPane', radius: 6, fillColor: '#fff', fillOpacity:1, color: '#000', weight:1, interactive: false });
|
|
25
|
-
this._marker = L.marker([0, 0], { icon: this.options.markerIcon, zIndexOffset: 1000000, interactive: false });
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
this._focuslabels = {};
|
|
22
|
+
this._labels = {};
|
|
29
23
|
|
|
30
24
|
return this;
|
|
31
25
|
},
|
|
32
26
|
|
|
33
27
|
addTo: function(map) {
|
|
34
28
|
this._map = map;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
g.append(() => this._focusline.node());
|
|
39
|
-
g.append(() => this._focusmarker.node());
|
|
40
|
-
g.append(() => this._focuslabel.node());
|
|
41
|
-
} else if (this.options.marker == 'position-marker') {
|
|
42
|
-
this._marker.addTo(map, { pane: 'overlayPane' });
|
|
29
|
+
switch(this.options.marker) {
|
|
30
|
+
case 'elevation-line': this._container.call(D3.PositionMarker({})); break;
|
|
31
|
+
case 'position-marker': this._marker.addTo(map, { pane: 'overlayPane' }); break;
|
|
43
32
|
}
|
|
44
33
|
return this;
|
|
45
34
|
},
|
|
@@ -56,58 +45,27 @@ export var Marker = L.Class.extend({
|
|
|
56
45
|
if (props.options) this.options = props.options;
|
|
57
46
|
if (!this._map) this.addTo(props.map);
|
|
58
47
|
|
|
59
|
-
let opts = this.options;
|
|
60
|
-
let map = this._map;
|
|
61
|
-
|
|
62
48
|
this._latlng = props.item.latlng;
|
|
63
49
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
xCoord: point.x,
|
|
84
|
-
yCoord: point.y,
|
|
85
|
-
}));
|
|
86
|
-
|
|
87
|
-
this._focusline
|
|
88
|
-
.call(
|
|
89
|
-
D3.HeightFocusLine({
|
|
90
|
-
theme : opts.theme,
|
|
91
|
-
xCoord: point.x,
|
|
92
|
-
yCoord: point.y,
|
|
93
|
-
length: normalizedY
|
|
94
|
-
})
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
this._focuslabel
|
|
98
|
-
.call(
|
|
99
|
-
D3.HeightFocusLabel({
|
|
100
|
-
theme : opts.theme,
|
|
101
|
-
xCoord: point.x,
|
|
102
|
-
yCoord: normalizedY,
|
|
103
|
-
labels: this._focuslabels,
|
|
104
|
-
item: point
|
|
105
|
-
})
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
} else if (this.options.marker == 'position-marker') {
|
|
109
|
-
_.removeClass(this._marker.getElement(), 'leaflet-hidden');
|
|
110
|
-
this._marker.setLatLng(this._latlng);
|
|
50
|
+
switch(this.options.marker) {
|
|
51
|
+
case 'elevation-line':
|
|
52
|
+
let point = this._map.latLngToLayerPoint(this._latlng);
|
|
53
|
+
point = L.extend({}, props.item, this._map._rotate ? this._map.rotatedPointToMapPanePoint(point) : point);
|
|
54
|
+
|
|
55
|
+
this._container.classed("leaflet-hidden", false);
|
|
56
|
+
this._container.call(D3.PositionMarker({
|
|
57
|
+
theme : this.options.theme,
|
|
58
|
+
xCoord: point.x,
|
|
59
|
+
yCoord: point.y,
|
|
60
|
+
length: point.y - (this._height() / props.maxElevation * point.z), // normalized Y
|
|
61
|
+
labels: this._labels,
|
|
62
|
+
item: point
|
|
63
|
+
}));
|
|
64
|
+
break;
|
|
65
|
+
case 'position-marker':
|
|
66
|
+
_.removeClass(this._marker.getElement(), 'leaflet-hidden');
|
|
67
|
+
this._marker.setLatLng(this._latlng);
|
|
68
|
+
break;
|
|
111
69
|
}
|
|
112
70
|
},
|
|
113
71
|
|
|
@@ -116,10 +74,9 @@ export var Marker = L.Class.extend({
|
|
|
116
74
|
*/
|
|
117
75
|
remove: function() {
|
|
118
76
|
this._props = null;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
_.addClass(this._marker.getElement(), 'leaflet-hidden');
|
|
77
|
+
switch(this.options.marker) {
|
|
78
|
+
case 'elevation-line': this._container && this._container.classed("leaflet-hidden", true); break;
|
|
79
|
+
case 'position-marker': _.addClass(this._marker.getElement(), 'leaflet-hidden'); break;
|
|
123
80
|
}
|
|
124
81
|
},
|
|
125
82
|
|
|
@@ -135,8 +92,8 @@ export var Marker = L.Class.extend({
|
|
|
135
92
|
return opts.height - opts.margins.top - opts.margins.bottom;
|
|
136
93
|
},
|
|
137
94
|
|
|
138
|
-
|
|
139
|
-
this.
|
|
95
|
+
_registerTooltip: function(props) {
|
|
96
|
+
this._labels[props.name] = props;
|
|
140
97
|
}
|
|
141
98
|
|
|
142
99
|
});
|
package/src/options.js
CHANGED
|
@@ -9,7 +9,6 @@ export var Options = {
|
|
|
9
9
|
collapsed: false,
|
|
10
10
|
detached: true,
|
|
11
11
|
distance: true,
|
|
12
|
-
distanceFactor: 1,
|
|
13
12
|
distanceMarkers: false,
|
|
14
13
|
decimalsX: 2,
|
|
15
14
|
decimalsY: 0,
|
|
@@ -19,15 +18,10 @@ export var Options = {
|
|
|
19
18
|
followMarker: true,
|
|
20
19
|
forceAxisBounds: false,
|
|
21
20
|
height: 200,
|
|
22
|
-
heightFactor: 1,
|
|
23
21
|
imperial: false,
|
|
24
22
|
interpolation: "curveLinear",
|
|
25
23
|
lazyLoadJS: true,
|
|
26
24
|
legend: true,
|
|
27
|
-
loadData: {
|
|
28
|
-
defer: false,
|
|
29
|
-
lazy: false,
|
|
30
|
-
},
|
|
31
25
|
margins: {
|
|
32
26
|
top: 30,
|
|
33
27
|
right: 30,
|
|
@@ -41,7 +35,6 @@ export var Options = {
|
|
|
41
35
|
iconSize: [32, 32],
|
|
42
36
|
iconAnchor: [16, 16],
|
|
43
37
|
}),
|
|
44
|
-
placeholder: false,
|
|
45
38
|
position: "topright",
|
|
46
39
|
polyline: {
|
|
47
40
|
className: 'elevation-polyline',
|
|
@@ -60,7 +53,6 @@ export var Options = {
|
|
|
60
53
|
ruler: true,
|
|
61
54
|
skipNullZCoords: false,
|
|
62
55
|
theme: "lightblue-theme",
|
|
63
|
-
responsive: true,
|
|
64
56
|
summary: 'inline',
|
|
65
57
|
slope: false,
|
|
66
58
|
speed: false,
|
package/src/slope.js
CHANGED
|
@@ -74,26 +74,17 @@ Elevation.addInitHook(function() {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// Range of acceptable slope values.
|
|
77
|
-
|
|
78
|
-
let range = this.options.sRange;
|
|
79
|
-
if (slope < range[0]) slope = range[0];
|
|
80
|
-
else if (slope > range[1]) slope = range[1];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
slope = L.Util.formatNum(slope, 2);
|
|
84
|
-
|
|
85
|
-
if (slope > sMax) sMax = slope;
|
|
86
|
-
if (slope < sMin) sMin = slope;
|
|
87
|
-
|
|
88
|
-
data[i].slope = slope;
|
|
77
|
+
slope = _.clamp(slope, this.options.sRange);
|
|
89
78
|
|
|
90
79
|
track.ascent = tAsc;
|
|
91
80
|
track.descent = tDes;
|
|
92
|
-
track.slope_max = sMax;
|
|
93
|
-
track.slope_min = sMin;
|
|
81
|
+
track.slope_max = slope > sMax ? slope : sMax;
|
|
82
|
+
track.slope_min = slope < sMin ? slope : sMin;
|
|
83
|
+
|
|
84
|
+
data[i].slope = L.Util.formatNum(slope, 2);
|
|
94
85
|
});
|
|
95
86
|
|
|
96
|
-
this.
|
|
87
|
+
this._registerTooltip({
|
|
97
88
|
name: 'slope',
|
|
98
89
|
chart: (item) => L._("m: ") + item.slope + slope.label,
|
|
99
90
|
marker: (item) => Math.round(item.slope) + slope.label
|
|
@@ -102,11 +93,11 @@ Elevation.addInitHook(function() {
|
|
|
102
93
|
this._registerSummary({
|
|
103
94
|
"ascent" : {
|
|
104
95
|
label: "Total Ascent: ",
|
|
105
|
-
value: (track) => Math.round(track.ascent || 0) + ' ' + this.
|
|
96
|
+
value: (track) => Math.round(track.ascent || 0) + ' ' + (this.options.imperial ? 'ft' : 'm')
|
|
106
97
|
},
|
|
107
98
|
"descent" : {
|
|
108
99
|
label: "Total Descent: ",
|
|
109
|
-
value: (track) => Math.round(track.descent || 0) + ' ' + this.
|
|
100
|
+
value: (track) => Math.round(track.descent || 0) + ' ' + (this.options.imperial ? 'ft' : 'm')
|
|
110
101
|
},
|
|
111
102
|
"minslope": {
|
|
112
103
|
label: "Min Slope: ",
|
package/src/speed.js
CHANGED
|
@@ -10,8 +10,8 @@ Elevation.addInitHook(function() {
|
|
|
10
10
|
let opts = this.options;
|
|
11
11
|
let speed = {};
|
|
12
12
|
|
|
13
|
-
speed.label
|
|
14
|
-
|
|
13
|
+
speed.label = opts.speedLabel || L._(opts.imperial ? 'mph' : 'km/h');
|
|
14
|
+
opts.speedFactor = opts.speedFactor || 1;
|
|
15
15
|
|
|
16
16
|
if (this.options.speed && this.options.speed != "summary") {
|
|
17
17
|
|
|
@@ -60,7 +60,7 @@ Elevation.addInitHook(function() {
|
|
|
60
60
|
|
|
61
61
|
if (deltaT > 0) {
|
|
62
62
|
let delta = (data[i].dist - data[i > 0 ? i - 1 : i].dist) * 1000;
|
|
63
|
-
speed = Math.abs((delta / deltaT) *
|
|
63
|
+
speed = Math.abs((delta / deltaT) * opts.timeFactor) * opts.speedFactor;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// Try to smooth "crazy" speed values.
|
|
@@ -73,28 +73,18 @@ Elevation.addInitHook(function() {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// Range of acceptable speed values.
|
|
76
|
-
|
|
77
|
-
let range = this.options.speedRange;
|
|
78
|
-
if (speed < range[0]) speed = range[0];
|
|
79
|
-
else if (speed > range[1]) speed = range[1];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
speed = L.Util.formatNum(speed, 2);
|
|
83
|
-
|
|
84
|
-
sMax = speed > sMax ? speed : sMax;
|
|
85
|
-
sMin = speed < sMin ? speed : sMin;
|
|
86
|
-
sAvg = (speed + sAvg) / 2.0;
|
|
76
|
+
speed = _.clamp(speed, this.options.speedRange);
|
|
87
77
|
|
|
88
|
-
|
|
78
|
+
track.speed_max = speed > sMax ? speed : sMax;
|
|
79
|
+
track.speed_min = speed < sMin ? speed : sMin;
|
|
80
|
+
track.speed_avg = (speed + sAvg) / 2.0;
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
track.speed_min = sMin;
|
|
92
|
-
track.speed_avg = sAvg;
|
|
82
|
+
data[i].speed = L.Util.formatNum(speed, 2);
|
|
93
83
|
});
|
|
94
84
|
|
|
95
85
|
if (this.options.speed) {
|
|
96
86
|
|
|
97
|
-
this.
|
|
87
|
+
this._registerTooltip({
|
|
98
88
|
name: 'speed',
|
|
99
89
|
chart: (item) => L._('v: ') + item.speed + " " + speed.label,
|
|
100
90
|
marker: (item) => Math.round(item.speed) + " " + speed.label,
|
package/src/time.js
CHANGED
|
@@ -8,8 +8,8 @@ Elevation.addInitHook(function() {
|
|
|
8
8
|
let opts = this.options;
|
|
9
9
|
let time = {};
|
|
10
10
|
|
|
11
|
-
time.label
|
|
12
|
-
|
|
11
|
+
time.label = opts.timeLabel || 't';
|
|
12
|
+
opts.timeFactor = opts.timeFactor || 3600;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Common AVG speeds:
|
|
@@ -75,7 +75,7 @@ Elevation.addInitHook(function() {
|
|
|
75
75
|
e.point.meta.time = new Date(
|
|
76
76
|
(
|
|
77
77
|
i > 0
|
|
78
|
-
? data[i - 1].time.getTime() + ((( delta / speed) *
|
|
78
|
+
? data[i - 1].time.getTime() + ((( delta / speed) * opts.timeFactor) * 1000)
|
|
79
79
|
: Date.now()
|
|
80
80
|
)
|
|
81
81
|
);
|
|
@@ -94,22 +94,22 @@ Elevation.addInitHook(function() {
|
|
|
94
94
|
let deltaT = Math.abs(currT - prevT);
|
|
95
95
|
let duration = (this.track_info.time || 0) + deltaT;
|
|
96
96
|
|
|
97
|
+
this.track_info.time = duration;
|
|
98
|
+
|
|
97
99
|
data[i].time = time;
|
|
98
100
|
data[i].duration = duration;
|
|
99
|
-
|
|
100
|
-
this.track_info.time = duration;
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
if (this.options.timestamps) {
|
|
105
|
-
this.
|
|
105
|
+
this._registerTooltip({
|
|
106
106
|
name: 'date',
|
|
107
107
|
chart: (item) => L._("t: ") + this.options.timeFormat(item.time)
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
if (this.options.time) {
|
|
112
|
-
this.
|
|
112
|
+
this._registerTooltip({
|
|
113
113
|
name: 'time',
|
|
114
114
|
chart: (item) => L._("T: ") + _.formatTime(item.duration || 0)
|
|
115
115
|
});
|
package/src/utils.js
CHANGED
|
@@ -22,29 +22,6 @@ export function deepMerge(target, ...sources) {
|
|
|
22
22
|
return deepMerge(target, ...sources);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/**
|
|
26
|
-
* Wait for document load before execute function.
|
|
27
|
-
*/
|
|
28
|
-
export function deferFunc(f) {
|
|
29
|
-
if (document.readyState !== 'complete') window.addEventListener("load", f, { once: true });
|
|
30
|
-
else f();
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Debounce function to limit events are being fired.
|
|
34
|
-
*/
|
|
35
|
-
export function debounce(func, wait, context, immediate) {
|
|
36
|
-
var timeout;
|
|
37
|
-
return function() {
|
|
38
|
-
var args = arguments;
|
|
39
|
-
clearTimeout(timeout);
|
|
40
|
-
timeout = setTimeout(function() {
|
|
41
|
-
timeout = null;
|
|
42
|
-
if (!immediate) func.apply(context, args);
|
|
43
|
-
}, wait);
|
|
44
|
-
if (immediate && !timeout) func.apply(context, args);
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
25
|
const SEC = 1000;
|
|
49
26
|
const MIN = SEC * 60;
|
|
50
27
|
const HOUR = MIN * 60;
|
|
@@ -169,13 +146,6 @@ export function GeoJSONLoader(data, control) {
|
|
|
169
146
|
return layer;
|
|
170
147
|
}
|
|
171
148
|
|
|
172
|
-
/**
|
|
173
|
-
* Check DOM element visibility.
|
|
174
|
-
*/
|
|
175
|
-
export function isDomVisible(elem) {
|
|
176
|
-
return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
149
|
/**
|
|
180
150
|
* Check object type.
|
|
181
151
|
*/
|
|
@@ -183,47 +153,6 @@ export function isObject(item) {
|
|
|
183
153
|
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
184
154
|
}
|
|
185
155
|
|
|
186
|
-
/**
|
|
187
|
-
* Check DOM element viewport visibility.
|
|
188
|
-
*/
|
|
189
|
-
export function isVisible(elem) {
|
|
190
|
-
if (!elem) return false;
|
|
191
|
-
|
|
192
|
-
let styles = window.getComputedStyle(elem);
|
|
193
|
-
|
|
194
|
-
function isVisibleByStyles(elem, styles) {
|
|
195
|
-
return styles.visibility !== 'hidden' && styles.display !== 'none';
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function isAboveOtherElements(elem, styles) {
|
|
199
|
-
let boundingRect = elem.getBoundingClientRect();
|
|
200
|
-
let left = boundingRect.left + 1;
|
|
201
|
-
let right = boundingRect.right - 1;
|
|
202
|
-
let top = boundingRect.top + 1;
|
|
203
|
-
let bottom = boundingRect.bottom - 1;
|
|
204
|
-
let above = true;
|
|
205
|
-
|
|
206
|
-
let pointerEvents = elem.style.pointerEvents;
|
|
207
|
-
|
|
208
|
-
if (styles['pointer-events'] == 'none') elem.style.pointerEvents = 'auto';
|
|
209
|
-
|
|
210
|
-
if (document.elementFromPoint(left, top) !== elem) above = false;
|
|
211
|
-
if (document.elementFromPoint(right, top) !== elem) above = false;
|
|
212
|
-
|
|
213
|
-
// Only for completely visible elements
|
|
214
|
-
// if (document.elementFromPoint(left, bottom) !== elem) above = false;
|
|
215
|
-
// if (document.elementFromPoint(right, bottom) !== elem) above = false;
|
|
216
|
-
|
|
217
|
-
elem.style.pointerEvents = pointerEvents;
|
|
218
|
-
|
|
219
|
-
return above;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (!isVisibleByStyles(elem, styles)) return false;
|
|
223
|
-
if (!isAboveOtherElements(elem, styles)) return false;
|
|
224
|
-
return true;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
156
|
/**
|
|
228
157
|
* Check JSON object type.
|
|
229
158
|
*/
|
|
@@ -258,6 +187,17 @@ export function isXMLDoc(doc, lazy) {
|
|
|
258
187
|
}
|
|
259
188
|
}
|
|
260
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Generate download data event.
|
|
192
|
+
*/
|
|
193
|
+
export function saveFile(dataURI, fileName) {
|
|
194
|
+
let a = create('a', '', { href: dataURI, target: '_new', download: fileName || "", style: "display:none;" });
|
|
195
|
+
let b = document.body;
|
|
196
|
+
b.appendChild(a);
|
|
197
|
+
a.click();
|
|
198
|
+
b.removeChild(a);
|
|
199
|
+
}
|
|
200
|
+
|
|
261
201
|
/**
|
|
262
202
|
* Async JS script download.
|
|
263
203
|
*/
|
|
@@ -276,39 +216,71 @@ export function lazyLoader(url, skip, loader) {
|
|
|
276
216
|
});
|
|
277
217
|
}
|
|
278
218
|
|
|
219
|
+
export function lazyLoad(src, control) {
|
|
220
|
+
if (!control.options.lazyLoadJS) return Promise.resolve();
|
|
221
|
+
|
|
222
|
+
const Elevation = L.Control.Elevation;
|
|
223
|
+
let loader = '';
|
|
224
|
+
let condition = false;
|
|
225
|
+
|
|
226
|
+
switch(src) {
|
|
227
|
+
case control.__D3:
|
|
228
|
+
loader = '_d3LazyLoader';
|
|
229
|
+
condition = typeof d3 !== 'object';
|
|
230
|
+
break;
|
|
231
|
+
case control.__TOGEOJSON:
|
|
232
|
+
loader = '_togeojsonLazyLoader';
|
|
233
|
+
condition = typeof toGeoJSON !== 'object';
|
|
234
|
+
break;
|
|
235
|
+
case control.__LGEOMUTIL:
|
|
236
|
+
loader = '_geomutilLazyLoader';
|
|
237
|
+
condition = typeof L.GeometryUtil !== 'object';
|
|
238
|
+
case control.__LALMOSTOVER:
|
|
239
|
+
loader = '_almostoverLazyLoader';
|
|
240
|
+
condition = typeof L.Handler.AlmostOver !== 'function ';
|
|
241
|
+
break;
|
|
242
|
+
case control.__LDISTANCEM:
|
|
243
|
+
loader = '_distanceMarkersLazyLoader';
|
|
244
|
+
condition = typeof L.DistanceMarkers !== 'function';
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
return Elevation[loader] = lazyLoader(src, condition, Elevation[loader]);
|
|
248
|
+
}
|
|
249
|
+
|
|
279
250
|
/**
|
|
280
|
-
*
|
|
251
|
+
* Convert SVG Path into Path2D and then update canvas
|
|
281
252
|
*/
|
|
282
|
-
export function
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
253
|
+
export function drawCanvas(ctx, path) {
|
|
254
|
+
path.classed('canvas-path', true);
|
|
255
|
+
|
|
256
|
+
ctx.beginPath();
|
|
257
|
+
ctx.moveTo(0, 0);
|
|
258
|
+
let p = new Path2D(path.attr('d'));
|
|
259
|
+
|
|
260
|
+
ctx.strokeStyle = path.attr('stroke');
|
|
261
|
+
ctx.fillStyle = path.attr('fill');
|
|
262
|
+
ctx.lineWidth = 1.25;
|
|
263
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
264
|
+
|
|
265
|
+
// stroke opacity
|
|
266
|
+
ctx.globalAlpha = path.attr('stroke-opacity') || 0.3;
|
|
267
|
+
ctx.stroke(p);
|
|
268
|
+
|
|
269
|
+
// fill opacity
|
|
270
|
+
ctx.globalAlpha = path.attr('fill-opacity') || 0.45;
|
|
271
|
+
ctx.fill(p);
|
|
272
|
+
|
|
273
|
+
ctx.globalAlpha = 1;
|
|
274
|
+
|
|
275
|
+
ctx.closePath();
|
|
288
276
|
}
|
|
289
277
|
|
|
290
278
|
/**
|
|
291
|
-
*
|
|
279
|
+
* Limit a number between min / max values
|
|
292
280
|
*/
|
|
293
|
-
export function
|
|
294
|
-
return
|
|
295
|
-
|
|
296
|
-
let scrollFn = () => {
|
|
297
|
-
if (!ticking) {
|
|
298
|
-
L.Util.requestAnimFrame(() => {
|
|
299
|
-
if (isVisible(elem)) {
|
|
300
|
-
window.removeEventListener('scroll', scrollFn);
|
|
301
|
-
resolve();
|
|
302
|
-
}
|
|
303
|
-
ticking = false;
|
|
304
|
-
});
|
|
305
|
-
ticking = true;
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
window.addEventListener('scroll', scrollFn);
|
|
309
|
-
if (elem) elem.addEventListener('mouseenter', scrollFn, { once: true });
|
|
310
|
-
scrollFn();
|
|
311
|
-
});
|
|
281
|
+
export function clamp(val, range) {
|
|
282
|
+
if (range) return val < range[0] ? range[0] : val > range[1] ? range[1] : val;
|
|
283
|
+
return val;
|
|
312
284
|
}
|
|
313
285
|
|
|
314
286
|
/**
|
|
@@ -401,10 +373,16 @@ export const off = L.DomEvent.off;
|
|
|
401
373
|
export const hasClass = L.DomUtil.hasClass;
|
|
402
374
|
|
|
403
375
|
|
|
376
|
+
/**
|
|
377
|
+
* Generate a random string
|
|
378
|
+
*/
|
|
404
379
|
export function randomId() {
|
|
405
380
|
return Math.random().toString(36).substr(2, 9);
|
|
406
381
|
}
|
|
407
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Execute a function foreach element in object
|
|
385
|
+
*/
|
|
408
386
|
export function each(obj, fn) {
|
|
409
387
|
for (let i in obj) fn(obj[i], i);
|
|
410
|
-
}
|
|
388
|
+
}
|