@raruto/leaflet-elevation 1.7.4 → 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/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;
@@ -73,14 +50,13 @@ export function GeoJSONLoader(data, control) {
73
50
  }
74
51
  control = control || this;
75
52
 
76
- let distanceMarkers = (
53
+ let distanceMarkers = (
77
54
  control.options.distanceMarkers === true
78
55
  ? { lazy: true }
79
56
  : L.extend({ lazy: true }, control.options.distanceMarkers)
80
57
  );
81
58
 
82
- let wptIcons = control.options.wptIcons;
83
- let wptLabels = control.options.wptLabels;
59
+ let { wptIcons, wptLabels } = control.options;
84
60
 
85
61
  let layer = L.geoJson(data, {
86
62
  distanceMarkers: distanceMarkers,
@@ -99,33 +75,32 @@ export function GeoJSONLoader(data, control) {
99
75
  let name = prop.name ?? '';
100
76
  let sym = (prop.sym ?? name).replace(' ', '-').replace('"', '').replace("'", '').toLowerCase();
101
77
 
102
- // Handle waypoint lables (markers and dots)
103
- if (!wptLabels) {
104
- name = '';
105
- desc = '';
106
- }
107
-
108
- // Handle chart waypoints (dots)
109
- if ([true, "dots"].includes(control.options.waypoints)) {
110
- control._registerCheckPoint({latlng: latlng, label: name}, true);
111
- }
112
-
113
- // Handle map waypoints (markers)
114
- if ([true, "markers"].includes(control.options.waypoints) && wptIcons != false) {
115
- // generate and cache appropriate icon symbol
116
- if (!wptIcons.hasOwnProperty(sym)) {
117
- wptIcons[sym] = L.divIcon(
118
- L.extend({}, wptIcons[""].options, { html: '<i class="elevation-waypoint-icon ' + sym + '"></i>' } )
119
- );
120
- }
121
- let marker = L.marker(latlng, { icon: wptIcons[sym] });
122
- if (name || desc) {
123
- marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
124
- }
125
- control._addMarker(marker);
126
- control.fire('waypoint_added', { point: marker, element: latlng, properties: prop });
127
- return marker;
128
- }
78
+ // Handle chart waypoints (dots)
79
+ if ([true, 'dots'].includes(control.options.waypoints)) {
80
+ control._registerCheckPoint({
81
+ latlng: latlng,
82
+ label: ([true, 'dots'].includes(wptLabels) ? name : '')
83
+ },
84
+ true
85
+ );
86
+ }
87
+
88
+ // Handle map waypoints (markers)
89
+ if ([true, 'markers'].includes(control.options.waypoints) && wptIcons != false) {
90
+ // generate and cache appropriate icon symbol
91
+ if (!wptIcons.hasOwnProperty(sym)) {
92
+ wptIcons[sym] = L.divIcon(
93
+ L.extend({}, wptIcons[""].options, { html: '<i class="elevation-waypoint-icon ' + sym + '"></i>' } )
94
+ );
95
+ }
96
+ let marker = L.marker(latlng, { icon: wptIcons[sym] });
97
+ if ([true, 'markers'].includes(wptLabels) && (name || desc)) {
98
+ marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
99
+ }
100
+ control._addMarker(marker);
101
+ control.fire('waypoint_added', { point: marker, element: latlng, properties: prop });
102
+ return marker;
103
+ }
129
104
  },
130
105
  onEachFeature: (feature, layer) => {
131
106
  if (feature.geometry && feature.geometry.type == 'Point') return;
@@ -152,12 +127,12 @@ export function GeoJSONLoader(data, control) {
152
127
 
153
128
  // Postpone adding the distance markers (lazy: true)
154
129
  if(control.options.distanceMarkers && distanceMarkers.lazy) {
155
- layer.on('add remove', (e) => {
156
- let path = e.target;
157
- if (L.DistanceMarkers && path instanceof L.Polyline) {
130
+ layer.on('add remove', (e) => {
131
+ let path = e.target;
132
+ if (L.DistanceMarkers && path instanceof L.Polyline) {
158
133
  path[e.type + 'DistanceMarkers']();
159
- }
160
- });
134
+ }
135
+ });
161
136
  }
162
137
 
163
138
  control.track_info = L.extend({}, control.track_info, { type: "geojson", name: data.name });
@@ -171,13 +146,6 @@ export function GeoJSONLoader(data, control) {
171
146
  return layer;
172
147
  }
173
148
 
174
- /**
175
- * Check DOM element visibility.
176
- */
177
- export function isDomVisible(elem) {
178
- return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
179
- }
180
-
181
149
  /**
182
150
  * Check object type.
183
151
  */
@@ -185,47 +153,6 @@ export function isObject(item) {
185
153
  return (item && typeof item === 'object' && !Array.isArray(item));
186
154
  }
187
155
 
188
- /**
189
- * Check DOM element viewport visibility.
190
- */
191
- export function isVisible(elem) {
192
- if (!elem) return false;
193
-
194
- let styles = window.getComputedStyle(elem);
195
-
196
- function isVisibleByStyles(elem, styles) {
197
- return styles.visibility !== 'hidden' && styles.display !== 'none';
198
- }
199
-
200
- function isAboveOtherElements(elem, styles) {
201
- let boundingRect = elem.getBoundingClientRect();
202
- let left = boundingRect.left + 1;
203
- let right = boundingRect.right - 1;
204
- let top = boundingRect.top + 1;
205
- let bottom = boundingRect.bottom - 1;
206
- let above = true;
207
-
208
- let pointerEvents = elem.style.pointerEvents;
209
-
210
- if (styles['pointer-events'] == 'none') elem.style.pointerEvents = 'auto';
211
-
212
- if (document.elementFromPoint(left, top) !== elem) above = false;
213
- if (document.elementFromPoint(right, top) !== elem) above = false;
214
-
215
- // Only for completely visible elements
216
- // if (document.elementFromPoint(left, bottom) !== elem) above = false;
217
- // if (document.elementFromPoint(right, bottom) !== elem) above = false;
218
-
219
- elem.style.pointerEvents = pointerEvents;
220
-
221
- return above;
222
- }
223
-
224
- if (!isVisibleByStyles(elem, styles)) return false;
225
- if (!isAboveOtherElements(elem, styles)) return false;
226
- return true;
227
- }
228
-
229
156
  /**
230
157
  * Check JSON object type.
231
158
  */
@@ -260,6 +187,17 @@ export function isXMLDoc(doc, lazy) {
260
187
  }
261
188
  }
262
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
+
263
201
  /**
264
202
  * Async JS script download.
265
203
  */
@@ -278,39 +216,71 @@ export function lazyLoader(url, skip, loader) {
278
216
  });
279
217
  }
280
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
+
281
250
  /**
282
- * Generate download data event.
251
+ * Convert SVG Path into Path2D and then update canvas
283
252
  */
284
- export function saveFile(dataURI, fileName) {
285
- let a = create('a', '', { href: dataURI, target: '_new', download: fileName || "", style: "display:none;" });
286
- let b = document.body;
287
- b.appendChild(a);
288
- a.click();
289
- b.removeChild(a);
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();
290
276
  }
291
277
 
292
278
  /**
293
- * Wait for element visible before execute function.
279
+ * Limit a number between min / max values
294
280
  */
295
- export function waitHolder(elem) {
296
- return new Promise((resolve, reject) => {
297
- let ticking = false;
298
- let scrollFn = () => {
299
- if (!ticking) {
300
- L.Util.requestAnimFrame(() => {
301
- if (isVisible(elem)) {
302
- window.removeEventListener('scroll', scrollFn);
303
- resolve();
304
- }
305
- ticking = false;
306
- });
307
- ticking = true;
308
- }
309
- };
310
- window.addEventListener('scroll', scrollFn);
311
- if (elem) elem.addEventListener('mouseenter', scrollFn, { once: true });
312
- scrollFn();
313
- });
281
+ export function clamp(val, range) {
282
+ if (range) return val < range[0] ? range[0] : val > range[1] ? range[1] : val;
283
+ return val;
314
284
  }
315
285
 
316
286
  /**
@@ -332,8 +302,8 @@ export function toggleClass(targetNode, className, conditional) {
332
302
  }
333
303
 
334
304
  export function replaceClass(targetNode, removeClassName, addClassName) {
335
- if (removeClassName) removeClass(targetNode, removeClassName);
336
- if (addClassName) addClass(targetNode, addClassName);
305
+ if (removeClassName) removeClass(targetNode, removeClassName);
306
+ if (addClassName) addClass(targetNode, addClassName);
337
307
  }
338
308
 
339
309
  export function style(targetNode, name, value) {
@@ -342,7 +312,7 @@ export function style(targetNode, name, value) {
342
312
  }
343
313
 
344
314
  export function toggleStyle(targetNode, name, value, conditional) {
345
- return style(targetNode, name, conditional ? value : '');
315
+ return style(targetNode, name, conditional ? value : '');
346
316
  }
347
317
 
348
318
  export function toggleEvent(leafletElement, eventName, handler, conditional) {
@@ -403,10 +373,16 @@ export const off = L.DomEvent.off;
403
373
  export const hasClass = L.DomUtil.hasClass;
404
374
 
405
375
 
376
+ /**
377
+ * Generate a random string
378
+ */
406
379
  export function randomId() {
407
380
  return Math.random().toString(36).substr(2, 9);
408
381
  }
409
382
 
383
+ /**
384
+ * Execute a function foreach element in object
385
+ */
410
386
  export function each(obj, fn) {
411
387
  for (let i in obj) fn(obj[i], i);
412
- }
388
+ }