leaflet-rotate 0.1.4 → 0.2.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 +2 -2
- package/build/rollup.config.js +4 -4
- package/dist/leaflet-rotate-src.js +625 -310
- package/dist/leaflet-rotate-src.js.map +1 -1
- package/dist/leaflet-rotate.js +1660 -1
- package/dist/leaflet-rotate.js.map +1 -1
- package/lib/debug.js +219 -25
- package/lib/debug.min.js +1 -9
- package/package.json +10 -7
- package/src/control/Rotate.js +10 -7
- package/src/dom/DomUtil.js +4 -1
- package/src/dom/Draggable.js +8 -5
- package/src/geometry/Point.js +22 -18
- package/src/index.js +5 -3
- package/src/layer/DivOverlay.js +13 -21
- package/src/layer/Popup.js +30 -10
- package/src/layer/Tooltip.js +10 -7
- package/src/layer/marker/Icon.js +5 -2
- package/src/layer/marker/Marker.js +42 -37
- package/src/layer/tile/GridLayer.js +5 -14
- package/src/layer/vector/Canvas.js +18 -15
- package/src/layer/vector/Renderer.js +21 -30
- package/src/layer/vector/SVG.js +10 -7
- package/src/map/Map.js +363 -93
- package/src/map/handler/CompassBearing.js +7 -11
- package/src/map/handler/ContainerMutation.js +12 -8
- package/src/map/handler/ShiftKeyRotate.js +5 -2
- package/src/map/handler/TouchGestures.js +16 -11
- package/src/map/handler/TouchRotate.js +4 -2
- package/src/map/handler/TouchZoom.js +16 -4
- package/test/index.html +29 -6
- package/build/rollup.config.min.js +0 -2
- package/src/map/handler/ShiftKeyRotate.min.js +0 -1
package/lib/debug.js
CHANGED
|
@@ -9,10 +9,14 @@ L.Rotate = {
|
|
|
9
9
|
width: 100%;
|
|
10
10
|
}
|
|
11
11
|
.leaflet-rotate-info td {
|
|
12
|
-
width: 7em;
|
|
12
|
+
/* width: 7em; */
|
|
13
13
|
overflow: hidden;
|
|
14
|
-
max-width: 7em;
|
|
14
|
+
/* max-width: 7em; */
|
|
15
15
|
text-overflow: ellipsis;
|
|
16
|
+
/* white-space: nowrap; */
|
|
17
|
+
}
|
|
18
|
+
.leaflet-rotate-info td:nth-of-type(3) {
|
|
19
|
+
font-family: Monospace;
|
|
16
20
|
}
|
|
17
21
|
.leaflet-rotate-info th {
|
|
18
22
|
text-align: left;
|
|
@@ -30,15 +34,31 @@ L.Rotate = {
|
|
|
30
34
|
position:absolute;
|
|
31
35
|
width:1px;
|
|
32
36
|
height:1px;
|
|
33
|
-
border:
|
|
34
|
-
|
|
37
|
+
border: 5px solid yellow;
|
|
38
|
+
border-radius: 100%;
|
|
39
|
+
z-index: 1000;
|
|
35
40
|
}
|
|
36
41
|
div.pixelorigin {
|
|
37
|
-
position:absolute;
|
|
38
|
-
width:1px;
|
|
39
|
-
height:1px;
|
|
40
|
-
border:
|
|
41
|
-
|
|
42
|
+
position: absolute;
|
|
43
|
+
width: 1px;
|
|
44
|
+
height: 1px;
|
|
45
|
+
border: 5px solid yellow;
|
|
46
|
+
border-radius: 100%;
|
|
47
|
+
z-index: 1000;
|
|
48
|
+
}
|
|
49
|
+
div.pivot:before {
|
|
50
|
+
left: -1.5em;
|
|
51
|
+
bottom: -2em;
|
|
52
|
+
position: absolute;
|
|
53
|
+
content: 'PIVOT';
|
|
54
|
+
color: yellow;
|
|
55
|
+
}
|
|
56
|
+
div.pixelorigin:before {
|
|
57
|
+
left: -1.75em;
|
|
58
|
+
top: -2em;
|
|
59
|
+
position: absolute;
|
|
60
|
+
content: 'ORIGIN';
|
|
61
|
+
color: yellow;
|
|
42
62
|
}
|
|
43
63
|
div.panebounds.main {
|
|
44
64
|
position:absolute;
|
|
@@ -111,6 +131,7 @@ L.Rotate = {
|
|
|
111
131
|
</td>
|
|
112
132
|
<td>
|
|
113
133
|
<button onclick="L.Rotate.randomRotateMarkers(L.Rotate._map);" title="markers.setRotation(Math.random() * Math.PI / 30 + 0.1)">Rotate Markers</button>
|
|
134
|
+
<button onclick="L.Rotate.randomMarkers(L.Rotate._map, 100);" title="add 100 random markers to map">Add Markers</button>
|
|
114
135
|
</td>
|
|
115
136
|
</tr>
|
|
116
137
|
<tr>
|
|
@@ -149,6 +170,12 @@ L.Rotate = {
|
|
|
149
170
|
<td id='ogy'></td>
|
|
150
171
|
<td class='long'>Negative pixel coords of the (0,0) CRS point relative to _rotatePane</td>
|
|
151
172
|
</tr>
|
|
173
|
+
<tr>
|
|
174
|
+
<th>Pixel bounds </th>
|
|
175
|
+
<td id='ogbx'></td>
|
|
176
|
+
<td id='ogby'></td>
|
|
177
|
+
<td class='long'>Bounds of the current map view in projected pixel coordinates {min, max}.</td>
|
|
178
|
+
</tr>
|
|
152
179
|
</table>`);
|
|
153
180
|
|
|
154
181
|
map.___rotatePixelOrigin = L.DomUtil.create('div', 'pixelorigin', map._rotatePane);
|
|
@@ -165,15 +192,25 @@ L.Rotate = {
|
|
|
165
192
|
|
|
166
193
|
padInput.addEventListener('change', L.Rotate.displayCenter.bind(this));
|
|
167
194
|
padInput.addEventListener('mousemove', L.Rotate.displayCenter.bind(this));
|
|
195
|
+
padInput.addEventListener('change', L.Rotate.displayBounds.bind(this));
|
|
196
|
+
padInput.addEventListener('mousemove', L.Rotate.displayBounds.bind(this));
|
|
197
|
+
padInput.addEventListener('change', L.Rotate.displayPixelBounds.bind(this));
|
|
198
|
+
padInput.addEventListener('mousemove', L.Rotate.displayPixelBounds.bind(this));
|
|
168
199
|
|
|
169
200
|
map.on('move rotate zoomend', this.updatePanePos);
|
|
170
201
|
map.on('rotate zoomend load', this.updatePixelOrigin);
|
|
202
|
+
map.on('rotate', this.updateRhoInput);
|
|
203
|
+
map.on('rotate', this.updatePivotDot);
|
|
171
204
|
map.on('moveend zoomend resetview rotate', this.displayCenter.bind(this));
|
|
205
|
+
map.on('moveend zoomend resetview rotate', this.displayBounds.bind(this));
|
|
206
|
+
map.on('moveend zoomend resetview rotate', this.displayPixelBounds.bind(this));
|
|
172
207
|
|
|
173
208
|
this.updatePixelOrigin.call(map);
|
|
209
|
+
this.updateRhoInput.call(map);
|
|
210
|
+
this.updatePivotDot.call(map);
|
|
174
211
|
this.displayCenter.call(this);
|
|
175
|
-
|
|
176
|
-
|
|
212
|
+
this.displayBounds.call(this);
|
|
213
|
+
this.displayPixelBounds.call(this);
|
|
177
214
|
|
|
178
215
|
if (L.Browser.mobile) {
|
|
179
216
|
map.compassBearing.enable();
|
|
@@ -204,10 +241,16 @@ L.Rotate = {
|
|
|
204
241
|
document.getElementById('cny').innerHTML = e.containerPoint.y;
|
|
205
242
|
},
|
|
206
243
|
|
|
244
|
+
/**
|
|
245
|
+
* Debug L.Map.setBearing()
|
|
246
|
+
*/
|
|
207
247
|
rotate: function(e) {
|
|
208
248
|
return e.buttons !== 0 && this._map.setBearing(e.target.valueAsNumber);
|
|
209
249
|
},
|
|
210
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Debug L.Map._pixelOrigin
|
|
253
|
+
*/
|
|
211
254
|
updatePixelOrigin: function() {
|
|
212
255
|
document.getElementById('ogx').innerHTML = this._pixelOrigin.x;
|
|
213
256
|
document.getElementById('ogy').innerHTML = this._pixelOrigin.y;
|
|
@@ -215,6 +258,9 @@ L.Rotate = {
|
|
|
215
258
|
this.___rotatePixelOrigin.style.top = (-this._pixelOrigin.y - 1) + 'px';
|
|
216
259
|
},
|
|
217
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Debug L.Map._pivot
|
|
263
|
+
*/
|
|
218
264
|
updatePivotDot: function() {
|
|
219
265
|
document.getElementById('pvx').innerHTML = this._pivot.x;
|
|
220
266
|
document.getElementById('pvy').innerHTML = this._pivot.y;
|
|
@@ -222,17 +268,33 @@ L.Rotate = {
|
|
|
222
268
|
this.___rotatePivotDot.style.top = (this._pivot.y - 1) + 'px';
|
|
223
269
|
},
|
|
224
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Debug L.Map._getMapPanePos()
|
|
273
|
+
*/
|
|
225
274
|
updatePanePos: function() {
|
|
226
275
|
var panePos = this._getMapPanePos();
|
|
227
276
|
document.getElementById('pox').innerHTML = panePos.x;
|
|
228
277
|
document.getElementById('poy').innerHTML = panePos.y;
|
|
229
278
|
},
|
|
230
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Debug L.Map.getBearing()
|
|
282
|
+
*/
|
|
283
|
+
updateRhoInput: function() {
|
|
284
|
+
document.getElementById('rho_input').value = this.getBearing();
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Debug L.Map.setBearing()
|
|
289
|
+
*/
|
|
231
290
|
rotateOneDegree: function() {
|
|
232
291
|
var angle = document.getElementById('rho_input').valueAsNumber++;
|
|
233
292
|
this.setBearing(angle < 360 ? angle : 0);
|
|
234
293
|
},
|
|
235
294
|
|
|
295
|
+
/**
|
|
296
|
+
* Debug L.Marker.setRotation()
|
|
297
|
+
*/
|
|
236
298
|
randomRotateMarkers: function(map) {
|
|
237
299
|
var markers = [],
|
|
238
300
|
steps = [];
|
|
@@ -254,27 +316,156 @@ L.Rotate = {
|
|
|
254
316
|
stepOn(25);
|
|
255
317
|
},
|
|
256
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Debug L.Map.panInside()
|
|
321
|
+
*/
|
|
322
|
+
randomMarkers: function(map, number) {
|
|
323
|
+
var map = this._map;
|
|
324
|
+
var populate = function() {
|
|
325
|
+
// populate map with a cluster of random markers
|
|
326
|
+
for (var i = 0; i < number; i++) {
|
|
327
|
+
var bounds = map.getBounds();
|
|
328
|
+
var southWest = bounds.getSouthWest();
|
|
329
|
+
var northEast = bounds.getNorthEast();
|
|
330
|
+
var lngSpan = northEast.lng - southWest.lng;
|
|
331
|
+
var latSpan = northEast.lat - southWest.lat;
|
|
332
|
+
var m = L.marker( L.latLng(southWest.lat + latSpan * Math.random(), southWest.lng + lngSpan * Math.random()) );
|
|
333
|
+
m.addTo(L.Rotate._map);
|
|
334
|
+
L.Rotate.___cluster.addLayer(m);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (!this.___cluster) {
|
|
338
|
+
// import and initialize "leaflet.markercluster" plugin
|
|
339
|
+
this.___cluster = import("https://unpkg.com/leaflet.markercluster@1.4.1/src/index.js")
|
|
340
|
+
.then(m => {
|
|
341
|
+
document.head.insertAdjacentHTML('beforeend', `
|
|
342
|
+
<!-- Leaflet-MarkerCluster -->
|
|
343
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css">
|
|
344
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css">
|
|
345
|
+
`);
|
|
346
|
+
Object.assign(globalThis.L, m);
|
|
347
|
+
this.___cluster = L.markerClusterGroup({
|
|
348
|
+
spiderfyOnMaxZoom: false,
|
|
349
|
+
showCoverageOnHover: false,
|
|
350
|
+
zoomToBoundsOnClick: false
|
|
351
|
+
})
|
|
352
|
+
.on('clusterclick', (a) => a.layer.spiderfy())
|
|
353
|
+
.addTo(map);
|
|
354
|
+
populate();
|
|
355
|
+
});
|
|
356
|
+
} else if (typeof L.markerClusterGroup === 'function') {
|
|
357
|
+
populate();
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Debug L.Map.getCenter()
|
|
363
|
+
*/
|
|
257
364
|
displayCenter: function() {
|
|
258
365
|
var map = this._map;
|
|
259
366
|
if (this.___centerMarker) {
|
|
260
367
|
this.___centerMarker.remove();
|
|
261
368
|
}
|
|
262
369
|
this.___centerMarker = L.circleMarker(map.getCenter(), {
|
|
263
|
-
radius:
|
|
264
|
-
color: '
|
|
265
|
-
}).addTo(map);
|
|
370
|
+
radius: 3,
|
|
371
|
+
color: 'red',
|
|
372
|
+
}).addTo(map).bindTooltip('<b>center</b>', { direction: 'right', permanent: true, });
|
|
373
|
+
this.___centerMarker.getTooltip().getElement().setAttribute("tabindex", "-1");
|
|
374
|
+
},
|
|
266
375
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
376
|
+
/**
|
|
377
|
+
* Debug L.Map.getCenter()
|
|
378
|
+
*/
|
|
379
|
+
displayBounds: function() {
|
|
380
|
+
var map = this._map;
|
|
381
|
+
if (this.___bounds) {
|
|
382
|
+
this.___bounds.remove();
|
|
383
|
+
}
|
|
384
|
+
var padding = document.getElementById('pad_input').valueAsNumber;
|
|
385
|
+
var latLngBounds = map.getBounds().pad(padding)
|
|
386
|
+
this.___bounds = L.rectangle(latLngBounds, {
|
|
387
|
+
fill: false,
|
|
388
|
+
lineCap: 'square',
|
|
389
|
+
color: 'yellow',
|
|
390
|
+
dashArray: '5, 10',
|
|
391
|
+
weight: 2,
|
|
392
|
+
// pane: 'norotatePane',
|
|
393
|
+
}).addTo(map);
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* @TODO Debug L.Map.getPixelBounds()
|
|
398
|
+
*/
|
|
399
|
+
displayPixelBounds: function() {
|
|
400
|
+
var map = this._map;
|
|
401
|
+
this.___corners && this.___corners.remove();
|
|
402
|
+
this.___pixelbounds && this.___pixelbounds.remove();
|
|
403
|
+
|
|
404
|
+
const size = map.getSize();
|
|
405
|
+
const rect = map._container.getBoundingClientRect();
|
|
406
|
+
const pixelBounds = map.getPixelBounds();
|
|
407
|
+
|
|
408
|
+
const TL = L.point(rect);
|
|
409
|
+
const TR = L.point(rect).add(L.point(rect.width, 0));
|
|
410
|
+
const BR = L.point(rect).add(L.point(rect.width, rect.height))
|
|
411
|
+
const BL = L.point(rect).add(L.point(0, rect.height));
|
|
412
|
+
|
|
413
|
+
const topLeft = L.marker( map.containerPointToLatLng(TL), { title: 'Top Left corner', rotation: 135 * L.DomUtil.DEG_TO_RAD } );
|
|
414
|
+
const topRight = L.marker( map.containerPointToLatLng(TR), { title: 'Top Right corner', rotation: -135 * L.DomUtil.DEG_TO_RAD } );
|
|
415
|
+
const bottomRight = L.marker( map.containerPointToLatLng(BR), { title: 'Bottom Right corner', rotation: -45 * L.DomUtil.DEG_TO_RAD } );
|
|
416
|
+
const bottomLeft = L.marker( map.containerPointToLatLng(BL), { title: 'Bottom Left corner', rotation: -135 * L.DomUtil.DEG_TO_RAD } );
|
|
417
|
+
|
|
418
|
+
this.___corners = L.featureGroup([topLeft, topRight, bottomRight, bottomLeft]).addTo(map).eachLayer(marker => marker.getElement().style.filter = 'hue-rotate(150deg)');
|
|
419
|
+
|
|
420
|
+
// L.polyline([
|
|
421
|
+
// [topLeft.getLatLng(), topRight.getLatLng()],
|
|
422
|
+
// [topRight.getLatLng(), bottomRight.getLatLng()],
|
|
423
|
+
// [bottomRight.getLatLng(), bottomLeft.getLatLng()],
|
|
424
|
+
// [bottomLeft.getLatLng(), topLeft.getLatLng()],
|
|
425
|
+
// ], {
|
|
426
|
+
// lineCap: 'square',
|
|
427
|
+
// dashArray: '5, 1, 5',
|
|
428
|
+
// color: 'yellow',
|
|
429
|
+
// weight: 2,
|
|
430
|
+
// }).addTo(this.___corners);
|
|
431
|
+
|
|
432
|
+
// this.___latLngBounds = L.latLngBounds([
|
|
433
|
+
// // map.containerPointToLatLng(TL),
|
|
434
|
+
// //map.containerPointToLatLng(BR)
|
|
435
|
+
// topLeft.getLatLng(),
|
|
436
|
+
// topRight.getLatLng(),
|
|
437
|
+
// bottomRight.getLatLng(),
|
|
438
|
+
// bottomLeft.getLatLng(),
|
|
439
|
+
// ]);
|
|
440
|
+
|
|
441
|
+
// this.___pixelbounds = L.rectangle(this.___latLngPixelBounds, {
|
|
442
|
+
// fill: false,
|
|
443
|
+
// lineCap: 'square',
|
|
444
|
+
// dashArray: '5, 1, 5',
|
|
445
|
+
// color: 'yellow',
|
|
446
|
+
// weight: 2,
|
|
447
|
+
// pane: 'norotatePane',
|
|
448
|
+
// }).addTo(map);
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
// this.___latLngPixelBounds = L.latLngBounds([
|
|
452
|
+
// map.layerPointToLatLng([0, 0]), // topleft
|
|
453
|
+
// map.layerPointToLatLng([size.x, 0]), // topright
|
|
454
|
+
// map.layerPointToLatLng([size.x, size.y]), // bottomright
|
|
455
|
+
// map.layerPointToLatLng([0, size.y]), // bottomleft
|
|
456
|
+
// ]);
|
|
457
|
+
|
|
458
|
+
// const paddingTL = L.point(L.Marker.prototype.options.icon.options.iconAnchor || [0, 0]),
|
|
459
|
+
// paddingBR = L.point(L.Marker.prototype.options.icon.options.iconSize || [0, 0]).subtract(paddingTL),
|
|
460
|
+
// pixelBounds = L.bounds([ L.point(rect), L.point(rect).add(map.getSize()) ]),
|
|
461
|
+
// paddedBounds = L.latLngBounds([
|
|
462
|
+
// map.layerPointToLatLng(pixelBounds.min.add(paddingTL)),
|
|
463
|
+
// map.layerPointToLatLng(pixelBounds.max.subtract(paddingBR))
|
|
464
|
+
// ]);
|
|
465
|
+
// // paddedSize = paddedBounds.getSize();
|
|
466
|
+
|
|
467
|
+
document.getElementById('ogbx').innerHTML = JSON.stringify(pixelBounds.min);
|
|
468
|
+
document.getElementById('ogby').innerHTML = JSON.stringify(pixelBounds.max);
|
|
278
469
|
},
|
|
279
470
|
|
|
280
471
|
resetHeading: function(e) {
|
|
@@ -283,6 +474,9 @@ L.Rotate = {
|
|
|
283
474
|
}
|
|
284
475
|
},
|
|
285
476
|
|
|
477
|
+
/**
|
|
478
|
+
* Debug L.Map.locate()
|
|
479
|
+
*/
|
|
286
480
|
locate: function() {
|
|
287
481
|
this._map.locate({
|
|
288
482
|
setView: true,
|
package/lib/debug.min.js
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
'use strict';L.Rotate={debug:function(map,options={}){this._map=map;document.head.insertAdjacentHTML("beforeend",`<style>\n .leaflet-rotate-info {\n width: 100%;\n }\n .leaflet-rotate-info td {\n width: 7em;\n overflow: hidden;\n max-width: 7em;\n text-overflow: ellipsis;\n }\n .leaflet-rotate-info th {\n text-align: left;\n }\n div.crosshair {\n position:absolute;\n width:1px;\n height:1px;\n border: 1px solid green;\n z-index: 100;\n left: 50%;\n right: 50%;\n }\n div.pivot {\n position:absolute;\n width:1px;\n height:1px;\n border: 1px solid purple;\n z-index: 100;\n }\n div.pixelorigin {\n position:absolute;\n width:1px;\n height:1px;\n border: 1px solid cyan;\n z-index: 100;\n }\n div.panebounds.main {\n position:absolute;\n width:800px;\n height:600px;\n border: 1px solid red;\n border-bottom: 1px red dashed;\n border-right: 1px red dashed;\n z-index: 100;\n }\n div.panebounds.rotate {\n position:absolute;\n width:800px;\n height:600px;\n border: 1px solid purple;\n border-bottom: 1px purple dashed;\n border-right: 1px purple dashed;\n z-index: 100;\n }\n div.crosshair.c1 {\n left:calc(50% - 5px);\n top:50%;\n height: 0;\n width: 10px;\n }\n div.crosshair.c2 {\n left:50%;\n top:calc(50% - 5px);\n width: 0;\n height: 10px;\n }\n #rho_input {\n vertical-align: middle;\n }\n .panebounds:before {\n padding: 1ch;\n }\n .panebounds.rotate:before {\n float: right;\n content: 'ROTATED';\n }\n .panebounds.main:before {\n float: left;\n content: 'MAIN';\n }\n </style>`);
|
|
2
|
-
map._container.insertAdjacentHTML("afterbegin",`<div class="crosshair c1"></div><div class="crosshair c2"></div>`);map._container.insertAdjacentHTML("afterend",`<hr>\n <table class="leaflet-rotate-info">\n <tr>\n <td>\n <button onclick="L.Rotate._map.setBearing(0);" title="map.setBearing(0);"> 0</button>\n <button onclick="L.Rotate._map.setBearing(15);" title="map.setBearing(15);">15</button>\n <button onclick="L.Rotate._map.setBearing(30);" title="map.setBearing(30);">30</button>\n <button onclick="L.Rotate._map.setBearing(45);" title="map.setBearing(45);">45</button>\n <button onclick="L.Rotate._map.setBearing(60);" title="map.setBearing(60);">60</button>\n <button onclick="L.Rotate._map.setBearing(75);" title="map.setBearing(75);">75</button>\n <button onclick="L.Rotate._map.setBearing(90);" title="map.setBearing(90);">90</button>\n <button onclick="L.Rotate._map.setBearing(180);" title="map.setBearing(180);">180</button>\n </td>\n <td>\n <input title="increase/decrease rotation angle" type="range" min="0" max="360" step="1" value="0" name="rho" id='rho_input' /><span id='rho'></span>\n </td>\n <td>\n <input title="increase/decrease padding bounds" type="range" min="-0.25" max="0" value="0" step="0.01" name="pad" id='pad_input' />\n </td>\n <td>\n <button onclick="L.Rotate.randomRotateMarkers(L.Rotate._map);" title="markers.setRotation(Math.random() * Math.PI / 30 + 0.1)">Rotate Markers</button>\n </td>\n </tr>\n <tr>\n <th>LatLng </th>\n <td id='llx'></td>\n <td id='lly'></td>\n <td class='long'>LatLng of mouse pointer</td>\n </tr>\n <tr>\n <th>Rel to pane </th>\n <td id='lyx'></td>\n <td id='lyy'></td>\n <td class='long'>Mouse pointer pixel coords relative to _rotatePane</td>\n </tr>\n <tr>\n <th>Rel to container</th>\n <td id='cnx'></td>\n <td id='cny'></td>\n <td class='long'>Mouse pointer coords relative to map <div></td>\n </tr>\n <tr>\n <th>Pivot </th>\n <td id='pvx'></td>\n <td id='pvy'></td>\n <td class='long'>Last _rotationPane pivot pixel coords relative to _rotationPane</td>\n </tr>\n <tr>\n <th>Pane offset </th>\n <td id='pox'></td>\n <td id='poy'></td>\n <td class='long'>Pixel offset of _mapPane</td>\n </tr>\n <tr>\n <th>Pixel origin </th>\n <td id='ogx'></td>\n <td id='ogy'></td>\n <td class='long'>Negative pixel coords of the (0,0) CRS point relative to _rotatePane</td>\n </tr>\n </table>`);
|
|
3
|
-
map.___rotatePixelOrigin=L.DomUtil.create("div","pixelorigin",map._rotatePane);map.___rotatePivotDot=L.DomUtil.create("div","pivot",map._mapPane);L.DomUtil.create("div","panebounds rotate",map._rotatePane);L.DomUtil.create("div","panebounds main",map._mapPane);var rhoInput=document.getElementById("rho_input");var padInput=document.getElementById("pad_input");rhoInput.addEventListener("change",L.Rotate.rotate.bind(this));rhoInput.addEventListener("mousemove",L.Rotate.rotate.bind(this));padInput.addEventListener("change",
|
|
4
|
-
L.Rotate.displayCenter.bind(this));padInput.addEventListener("mousemove",L.Rotate.displayCenter.bind(this));map.on("move rotate zoomend",this.updatePanePos);map.on("rotate zoomend load",this.updatePixelOrigin);map.on("moveend zoomend resetview rotate",this.displayCenter.bind(this));this.updatePixelOrigin.call(map);this.displayCenter.call(this);map.on("rotate",this.updatePivotDot);if(L.Browser.mobile)map.compassBearing.enable();map.on("mousemove",this.logMouse);map.on("locationfound",this.resetHeading);
|
|
5
|
-
if(options.log)map.on("click movestart move moveend zoomstart zoomend locationfound locationerror locationfound",this.logEvent)},logEvent:function(e){console.log(e,e.type)},logMouse:function(e){document.getElementById("llx").innerHTML=e.latlng.lng;document.getElementById("lly").innerHTML=e.latlng.lat;document.getElementById("lyx").innerHTML=e.layerPoint.x;document.getElementById("lyy").innerHTML=e.layerPoint.y;document.getElementById("cnx").innerHTML=e.containerPoint.x;document.getElementById("cny").innerHTML=
|
|
6
|
-
e.containerPoint.y},rotate:function(e){return e.buttons!==0&&this._map.setBearing(e.target.valueAsNumber)},updatePixelOrigin:function(){document.getElementById("ogx").innerHTML=this._pixelOrigin.x;document.getElementById("ogy").innerHTML=this._pixelOrigin.y;this.___rotatePixelOrigin.style.left=-this._pixelOrigin.x-1+"px";this.___rotatePixelOrigin.style.top=-this._pixelOrigin.y-1+"px"},updatePivotDot:function(){document.getElementById("pvx").innerHTML=this._pivot.x;document.getElementById("pvy").innerHTML=
|
|
7
|
-
this._pivot.y;this.___rotatePivotDot.style.left=this._pivot.x-1+"px";this.___rotatePivotDot.style.top=this._pivot.y-1+"px"},updatePanePos:function(){var panePos=this._getMapPanePos();document.getElementById("pox").innerHTML=panePos.x;document.getElementById("poy").innerHTML=panePos.y},rotateOneDegree:function(){var angle=document.getElementById("rho_input").valueAsNumber++;this.setBearing(angle<360?angle:0)},randomRotateMarkers:function(map){var markers=[],steps=[];for(var i in map._layers)if(map._layers[i]instanceof
|
|
8
|
-
L.Marker){markers.push(map._layers[i]);steps.push(Math.random()*Math.PI/30+.1)}function stepOn(steps_left){for(var i=0;i<markers.length;i++)markers[i].setRotation(markers[i].options.rotation+steps[i]);if(--steps_left)setTimeout(stepOn.bind(null,steps_left),20)}stepOn(25)},displayCenter:function(){var map=this._map;if(this.___centerMarker)this.___centerMarker.remove();this.___centerMarker=L.circleMarker(map.getCenter(),{radius:0,color:"green"}).addTo(map);if(this.___bounds)this.___bounds.remove();
|
|
9
|
-
var padding=document.getElementById("pad_input").valueAsNumber;this.___bounds=L.rectangle(map.getBounds().pad(padding),{fill:false,lineCap:"square",color:"green",dashArray:"5, 10",weight:2}).addTo(map)},resetHeading:function(e){if(e.heading!==null)this.setBearing(e.heading)},locate:function(){this._map.locate({setView:true,enableHighAccuracy:true})}};
|
|
1
|
+
L.Rotate={debug:function(map,options={}){this._map=map,document.head.insertAdjacentHTML("beforeend","<style>\n .leaflet-rotate-info {\n width: 100%;\n }\n .leaflet-rotate-info td {\n /* width: 7em; */\n overflow: hidden;\n /* max-width: 7em; */\n text-overflow: ellipsis;\n /* white-space: nowrap; */\n }\n .leaflet-rotate-info td:nth-of-type(3) {\n font-family: Monospace;\n }\n .leaflet-rotate-info th {\n text-align: left;\n }\n div.crosshair {\n position:absolute;\n width:1px;\n height:1px;\n border: 1px solid green;\n z-index: 100;\n left: 50%;\n right: 50%;\n }\n div.pivot {\n position:absolute;\n width:1px;\n height:1px;\n border: 5px solid yellow;\n border-radius: 100%;\n z-index: 1000;\n }\n div.pixelorigin {\n position: absolute;\n width: 1px;\n height: 1px;\n border: 5px solid yellow;\n border-radius: 100%;\n z-index: 1000;\n }\n div.pivot:before {\n left: -1.5em;\n bottom: -2em;\n position: absolute;\n content: 'PIVOT';\n color: yellow;\n }\n div.pixelorigin:before {\n left: -1.75em;\n top: -2em;\n position: absolute;\n content: 'ORIGIN';\n color: yellow;\n }\n div.panebounds.main {\n position:absolute;\n width:800px;\n height:600px;\n border: 1px solid red;\n border-bottom: 1px red dashed;\n border-right: 1px red dashed;\n z-index: 100;\n }\n div.panebounds.rotate {\n position:absolute;\n width:800px;\n height:600px;\n border: 1px solid purple;\n border-bottom: 1px purple dashed;\n border-right: 1px purple dashed;\n z-index: 100;\n }\n div.crosshair.c1 {\n left:calc(50% - 5px);\n top:50%;\n height: 0;\n width: 10px;\n }\n div.crosshair.c2 {\n left:50%;\n top:calc(50% - 5px);\n width: 0;\n height: 10px;\n }\n #rho_input {\n vertical-align: middle;\n }\n .panebounds:before {\n padding: 1ch;\n }\n .panebounds.rotate:before {\n float: right;\n content: 'ROTATED';\n }\n .panebounds.main:before {\n float: left;\n content: 'MAIN';\n }\n </style>"),map._container.insertAdjacentHTML("afterbegin",'<div class="crosshair c1"></div><div class="crosshair c2"></div>'),map._container.insertAdjacentHTML("afterend",'<hr>\n <table class="leaflet-rotate-info">\n <tr>\n <td>\n <button onclick="L.Rotate._map.setBearing(0);" title="map.setBearing(0);"> 0</button>\n <button onclick="L.Rotate._map.setBearing(15);" title="map.setBearing(15);">15</button>\n <button onclick="L.Rotate._map.setBearing(30);" title="map.setBearing(30);">30</button>\n <button onclick="L.Rotate._map.setBearing(45);" title="map.setBearing(45);">45</button>\n <button onclick="L.Rotate._map.setBearing(60);" title="map.setBearing(60);">60</button>\n <button onclick="L.Rotate._map.setBearing(75);" title="map.setBearing(75);">75</button>\n <button onclick="L.Rotate._map.setBearing(90);" title="map.setBearing(90);">90</button>\n <button onclick="L.Rotate._map.setBearing(180);" title="map.setBearing(180);">180</button>\n </td>\n <td>\n <input title="increase/decrease rotation angle" type="range" min="0" max="360" step="1" value="0" name="rho" id=\'rho_input\' /><span id=\'rho\'></span>\n </td>\n <td>\n <input title="increase/decrease padding bounds" type="range" min="-0.25" max="0" value="0" step="0.01" name="pad" id=\'pad_input\' />\n </td>\n <td>\n <button onclick="L.Rotate.randomRotateMarkers(L.Rotate._map);" title="markers.setRotation(Math.random() * Math.PI / 30 + 0.1)">Rotate Markers</button>\n <button onclick="L.Rotate.randomMarkers(L.Rotate._map, 100);" title="add 100 random markers to map">Add Markers</button>\n </td>\n </tr>\n <tr>\n <th>LatLng </th>\n <td id=\'llx\'></td>\n <td id=\'lly\'></td>\n <td class=\'long\'>LatLng of mouse pointer</td>\n </tr>\n <tr>\n <th>Rel to pane </th>\n <td id=\'lyx\'></td>\n <td id=\'lyy\'></td>\n <td class=\'long\'>Mouse pointer pixel coords relative to _rotatePane</td>\n </tr>\n <tr>\n <th>Rel to container</th>\n <td id=\'cnx\'></td>\n <td id=\'cny\'></td>\n <td class=\'long\'>Mouse pointer coords relative to map <div></td>\n </tr>\n <tr>\n <th>Pivot </th>\n <td id=\'pvx\'></td>\n <td id=\'pvy\'></td>\n <td class=\'long\'>Last _rotationPane pivot pixel coords relative to _rotationPane</td>\n </tr>\n <tr>\n <th>Pane offset </th>\n <td id=\'pox\'></td>\n <td id=\'poy\'></td>\n <td class=\'long\'>Pixel offset of _mapPane</td>\n </tr>\n <tr>\n <th>Pixel origin </th>\n <td id=\'ogx\'></td>\n <td id=\'ogy\'></td>\n <td class=\'long\'>Negative pixel coords of the (0,0) CRS point relative to _rotatePane</td>\n </tr>\n <tr>\n <th>Pixel bounds </th>\n <td id=\'ogbx\'></td>\n <td id=\'ogby\'></td>\n <td class=\'long\'>Bounds of the current map view in projected pixel coordinates {min, max}.</td>\n </tr>\n </table>'),map.___rotatePixelOrigin=L.DomUtil.create("div","pixelorigin",map._rotatePane),map.___rotatePivotDot=L.DomUtil.create("div","pivot",map._mapPane),L.DomUtil.create("div","panebounds rotate",map._rotatePane),L.DomUtil.create("div","panebounds main",map._mapPane);var rhoInput=document.getElementById("rho_input"),padInput=document.getElementById("pad_input");rhoInput.addEventListener("change",L.Rotate.rotate.bind(this)),rhoInput.addEventListener("mousemove",L.Rotate.rotate.bind(this)),padInput.addEventListener("change",L.Rotate.displayCenter.bind(this)),padInput.addEventListener("mousemove",L.Rotate.displayCenter.bind(this)),padInput.addEventListener("change",L.Rotate.displayBounds.bind(this)),padInput.addEventListener("mousemove",L.Rotate.displayBounds.bind(this)),padInput.addEventListener("change",L.Rotate.displayPixelBounds.bind(this)),padInput.addEventListener("mousemove",L.Rotate.displayPixelBounds.bind(this)),map.on("move rotate zoomend",this.updatePanePos),map.on("rotate zoomend load",this.updatePixelOrigin),map.on("rotate",this.updateRhoInput),map.on("rotate",this.updatePivotDot),map.on("moveend zoomend resetview rotate",this.displayCenter.bind(this)),map.on("moveend zoomend resetview rotate",this.displayBounds.bind(this)),map.on("moveend zoomend resetview rotate",this.displayPixelBounds.bind(this)),this.updatePixelOrigin.call(map),this.updateRhoInput.call(map),this.updatePivotDot.call(map),this.displayCenter.call(this),this.displayBounds.call(this),this.displayPixelBounds.call(this),L.Browser.mobile&&map.compassBearing.enable(),map.on("mousemove",this.logMouse),map.on("locationfound",this.resetHeading),options.log&&map.on("click movestart move moveend zoomstart zoomend locationfound locationerror locationfound",this.logEvent)},logEvent:function(e){console.log(e,e.type)},logMouse:function(e){document.getElementById("llx").innerHTML=e.latlng.lng,document.getElementById("lly").innerHTML=e.latlng.lat,document.getElementById("lyx").innerHTML=e.layerPoint.x,document.getElementById("lyy").innerHTML=e.layerPoint.y,document.getElementById("cnx").innerHTML=e.containerPoint.x,document.getElementById("cny").innerHTML=e.containerPoint.y},rotate:function(e){return 0!==e.buttons&&this._map.setBearing(e.target.valueAsNumber)},updatePixelOrigin:function(){document.getElementById("ogx").innerHTML=this._pixelOrigin.x,document.getElementById("ogy").innerHTML=this._pixelOrigin.y,this.___rotatePixelOrigin.style.left=-this._pixelOrigin.x-1+"px",this.___rotatePixelOrigin.style.top=-this._pixelOrigin.y-1+"px"},updatePivotDot:function(){document.getElementById("pvx").innerHTML=this._pivot.x,document.getElementById("pvy").innerHTML=this._pivot.y,this.___rotatePivotDot.style.left=this._pivot.x-1+"px",this.___rotatePivotDot.style.top=this._pivot.y-1+"px"},updatePanePos:function(){var panePos=this._getMapPanePos();document.getElementById("pox").innerHTML=panePos.x,document.getElementById("poy").innerHTML=panePos.y},updateRhoInput:function(){document.getElementById("rho_input").value=this.getBearing()},rotateOneDegree:function(){var angle=document.getElementById("rho_input").valueAsNumber++;this.setBearing(angle<360?angle:0)},randomRotateMarkers:function(map){var markers=[],steps=[];for(var i in map._layers)map._layers[i]instanceof L.Marker&&(markers.push(map._layers[i]),steps.push(Math.random()*Math.PI/30+.1));function stepOn(steps_left){for(var i=0;i<markers.length;i++)markers[i].setRotation(markers[i].options.rotation+steps[i]);--steps_left&&setTimeout(stepOn.bind(null,steps_left),20)}stepOn(25)},randomMarkers:function(map,number){var map=this._map,populate=function(){for(var i=0;i<number;i++){var bounds=map.getBounds(),southWest=bounds.getSouthWest(),northEast=bounds.getNorthEast(),lngSpan=northEast.lng-southWest.lng,latSpan=northEast.lat-southWest.lat,m=L.marker(L.latLng(southWest.lat+latSpan*Math.random(),southWest.lng+lngSpan*Math.random()));m.addTo(L.Rotate._map),L.Rotate.___cluster.addLayer(m)}};this.___cluster?"function"==typeof L.markerClusterGroup&&populate():this.___cluster=import("https://unpkg.com/leaflet.markercluster@1.4.1/src/index.js").then(m=>{document.head.insertAdjacentHTML("beforeend",'\n \x3c!-- Leaflet-MarkerCluster --\x3e\n <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css">\n <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css">\n '),Object.assign(globalThis.L,m),this.___cluster=L.markerClusterGroup({spiderfyOnMaxZoom:!1,showCoverageOnHover:!1,zoomToBoundsOnClick:!1}).on("clusterclick",a=>a.layer.spiderfy()).addTo(map),populate()})},displayCenter:function(){var map=this._map;this.___centerMarker&&this.___centerMarker.remove(),this.___centerMarker=L.circleMarker(map.getCenter(),{radius:3,color:"red"}).addTo(map).bindTooltip("<b>center</b>",{direction:"right",permanent:!0}),this.___centerMarker.getTooltip().getElement().setAttribute("tabindex","-1")},displayBounds:function(){var map=this._map;this.___bounds&&this.___bounds.remove();var padding=document.getElementById("pad_input").valueAsNumber,latLngBounds=map.getBounds().pad(padding);this.___bounds=L.rectangle(latLngBounds,{fill:!1,lineCap:"square",color:"yellow",dashArray:"5, 10",weight:2}).addTo(map)},displayPixelBounds:function(){var map=this._map;this.___corners&&this.___corners.remove(),this.___pixelbounds&&this.___pixelbounds.remove();const size=map.getSize(),rect=map._container.getBoundingClientRect(),pixelBounds=map.getPixelBounds(),TL=L.point(rect),TR=L.point(rect).add(L.point(rect.width,0)),BR=L.point(rect).add(L.point(rect.width,rect.height)),BL=L.point(rect).add(L.point(0,rect.height)),topLeft=L.marker(map.containerPointToLatLng(TL),{title:"Top Left corner",rotation:135*L.DomUtil.DEG_TO_RAD}),topRight=L.marker(map.containerPointToLatLng(TR),{title:"Top Right corner",rotation:-135*L.DomUtil.DEG_TO_RAD}),bottomRight=L.marker(map.containerPointToLatLng(BR),{title:"Bottom Right corner",rotation:-45*L.DomUtil.DEG_TO_RAD}),bottomLeft=L.marker(map.containerPointToLatLng(BL),{title:"Bottom Left corner",rotation:-135*L.DomUtil.DEG_TO_RAD});this.___corners=L.featureGroup([topLeft,topRight,bottomRight,bottomLeft]).addTo(map).eachLayer(marker=>marker.getElement().style.filter="hue-rotate(150deg)"),document.getElementById("ogbx").innerHTML=JSON.stringify(pixelBounds.min),document.getElementById("ogby").innerHTML=JSON.stringify(pixelBounds.max)},resetHeading:function(e){null!==e.heading&&this.setBearing(e.heading)},locate:function(){this._map.locate({setView:!0,enableHighAccuracy:!0})}};
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leaflet-rotate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A Leaflet plugin that allows to add rotation functionality to map tiles",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/leaflet-rotate.js",
|
|
7
|
+
"browser": "dist/leaflet-rotate.js",
|
|
6
8
|
"module": "src/index.js",
|
|
7
9
|
"scripts": {
|
|
8
10
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
11
|
"build": "rollup -c build/rollup.config.js",
|
|
10
|
-
"
|
|
12
|
+
"dev": "rollup -c build/rollup.config.js --watch",
|
|
13
|
+
"watch": "npm run dev",
|
|
11
14
|
"version": "npm run build && git add -A dist"
|
|
12
15
|
},
|
|
13
16
|
"repository": {
|
|
@@ -45,12 +48,12 @@
|
|
|
45
48
|
},
|
|
46
49
|
"homepage": "https://github.com/Raruto/leaflet-rotate#readme",
|
|
47
50
|
"devDependencies": {
|
|
48
|
-
"rollup": "^
|
|
49
|
-
"rollup
|
|
50
|
-
"rollup
|
|
51
|
-
"rollup
|
|
51
|
+
"rollup": "^3.10.0",
|
|
52
|
+
"@rollup/plugin-commonjs": "^24.0.0",
|
|
53
|
+
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
54
|
+
"@rollup/plugin-terser": "^0.3.0"
|
|
52
55
|
},
|
|
53
56
|
"peerDependencies": {
|
|
54
|
-
"leaflet": "^1.
|
|
57
|
+
"leaflet": "^1.9.3"
|
|
55
58
|
}
|
|
56
59
|
}
|
package/src/control/Rotate.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* A tri-state control for map rotation, states are:
|
|
3
|
+
*
|
|
4
|
+
* - Locked (default)
|
|
5
|
+
* - Unlocked (user can pinch-rotate)
|
|
6
|
+
* - Follow (rotation follows device orientation, if available)
|
|
7
|
+
*
|
|
8
|
+
* @typedef L.Control.Rotate
|
|
3
9
|
*/
|
|
4
10
|
|
|
5
|
-
// A tri-state control for map rotation. States are:
|
|
6
|
-
// Locked (default)
|
|
7
|
-
// Unlocked (user can pinch-rotate)
|
|
8
|
-
// Follow (rotation follows device orientation, if available)
|
|
9
11
|
L.Control.Rotate = L.Control.extend({
|
|
10
12
|
|
|
11
13
|
options: {
|
|
@@ -35,6 +37,7 @@ L.Control.Rotate = L.Control.extend({
|
|
|
35
37
|
link.appendChild(arrow);
|
|
36
38
|
link.href = '#';
|
|
37
39
|
link.title = 'Rotate map';
|
|
40
|
+
// link.draggable = false;
|
|
38
41
|
|
|
39
42
|
L.DomEvent
|
|
40
43
|
.on(link, 'dblclick', L.DomEvent.stopPropagation)
|
|
@@ -63,7 +66,7 @@ L.Control.Rotate = L.Control.extend({
|
|
|
63
66
|
},
|
|
64
67
|
|
|
65
68
|
_handleMouseDown: function(e) {
|
|
66
|
-
L.DomEvent.stopPropagation(e);
|
|
69
|
+
L.DomEvent.stop(e); // L.DomEvent.stopPropagation(e);
|
|
67
70
|
this.dragging = true;
|
|
68
71
|
this.dragstartX = e.pageX;
|
|
69
72
|
this.dragstartY = e.pageY;
|
|
@@ -73,7 +76,7 @@ L.Control.Rotate = L.Control.extend({
|
|
|
73
76
|
},
|
|
74
77
|
|
|
75
78
|
_handleMouseUp: function(e) {
|
|
76
|
-
L.DomEvent.stopPropagation(e);
|
|
79
|
+
L.DomEvent.stop(e); // L.DomEvent.stopPropagation(e);
|
|
77
80
|
this.dragging = false;
|
|
78
81
|
|
|
79
82
|
L.DomEvent
|
package/src/dom/DomUtil.js
CHANGED
package/src/dom/Draggable.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* L.Draggable
|
|
2
|
+
* @external L.Draggable
|
|
3
|
+
*
|
|
4
|
+
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/dom/Draggable.js
|
|
3
5
|
*/
|
|
6
|
+
|
|
4
7
|
L.Draggable.include({
|
|
5
8
|
|
|
6
|
-
updateMapBearing: function(mapBearing) {
|
|
7
|
-
|
|
8
|
-
},
|
|
9
|
+
// updateMapBearing: function(mapBearing) {
|
|
10
|
+
// this._mapBearing = mapBearing;
|
|
11
|
+
// },
|
|
9
12
|
|
|
10
|
-
});
|
|
13
|
+
});
|
package/src/geometry/Point.js
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* L.Point
|
|
2
|
+
* @external L.Point
|
|
3
|
+
*
|
|
4
|
+
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/geometry/Point.js
|
|
3
5
|
*/
|
|
6
|
+
|
|
4
7
|
L.extend(L.Point.prototype, {
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Rotate around (0,0) by applying the 2D rotation matrix:
|
|
11
|
+
*
|
|
12
|
+
* ⎡ x' ⎤ = ⎡ cos θ -sin θ ⎤ ⎡ x ⎤
|
|
13
|
+
* ⎣ y' ⎦ ⎣ sin θ cos θ ⎦ ⎣ y ⎦
|
|
14
|
+
*
|
|
15
|
+
* @param theta must be given in radians.
|
|
16
|
+
*/
|
|
10
17
|
rotate: function(theta) {
|
|
11
|
-
|
|
12
|
-
var sinTheta = Math.sin(theta);
|
|
13
|
-
var cosTheta = Math.cos(theta);
|
|
14
|
-
|
|
15
|
-
return new L.Point(
|
|
16
|
-
this.x * cosTheta - this.y * sinTheta,
|
|
17
|
-
this.x * sinTheta + this.y * cosTheta
|
|
18
|
-
);
|
|
18
|
+
return this.rotateFrom(theta, new L.Point(0,0))
|
|
19
19
|
},
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Rotate around (pivot.x, pivot.y) by:
|
|
23
|
+
*
|
|
24
|
+
* 1. subtract (pivot.x, pivot.y)
|
|
25
|
+
* 2. rotate around (0, 0)
|
|
26
|
+
* 3. add (pivot.x, pivot.y) back
|
|
27
|
+
*
|
|
28
|
+
* same as `this.subtract(pivot).rotate(theta).add(pivot)`
|
|
29
|
+
*/
|
|
26
30
|
rotateFrom: function(theta, pivot) {
|
|
27
31
|
if (!theta) { return this; }
|
|
28
32
|
var sinTheta = Math.sin(theta);
|
package/src/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* @external L
|
|
3
3
|
*
|
|
4
|
-
* @see https://github.com/Leaflet/Leaflet/
|
|
4
|
+
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/Leaflet.js
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// import {version} from '../package.json';
|
|
8
8
|
// export {version};
|
|
9
9
|
|
|
10
|
+
// control
|
|
11
|
+
// export * from './core/index';
|
|
10
12
|
|
|
11
13
|
// core
|
|
12
14
|
// export * from './core/index';
|
|
@@ -41,5 +43,5 @@ export * from './map/handler/TouchRotate';
|
|
|
41
43
|
export * from './map/handler/ShiftKeyRotate';
|
|
42
44
|
export * from './map/handler/TouchZoom';
|
|
43
45
|
|
|
44
|
-
//
|
|
46
|
+
// custom controls
|
|
45
47
|
export * from './control/Rotate';
|
package/src/layer/DivOverlay.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* L.DivOverlay
|
|
2
|
+
* @external L.DivOverlay
|
|
3
|
+
*
|
|
4
|
+
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/DivOverlay.js
|
|
3
5
|
*/
|
|
6
|
+
|
|
4
7
|
const divOverlayProto = L.extend({}, L.DivOverlay.prototype);
|
|
5
8
|
|
|
6
9
|
L.DivOverlay.include({
|
|
@@ -10,28 +13,17 @@ L.DivOverlay.include({
|
|
|
10
13
|
},
|
|
11
14
|
|
|
12
15
|
_updatePosition: function() {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
pos = this._map.rotatedPointToMapPanePoint(pos);
|
|
23
|
-
}
|
|
24
|
-
L.DomUtil.setPosition(this._container, pos.add(anchor));
|
|
25
|
-
} else {
|
|
26
|
-
offset = offset.add(pos).add(anchor);
|
|
16
|
+
// 0. update anchor (leaflet v1.9.3)
|
|
17
|
+
divOverlayProto._updatePosition.call(this);
|
|
18
|
+
// 1. subtract anchor
|
|
19
|
+
// 2. rotate element
|
|
20
|
+
// 3. restore anchor
|
|
21
|
+
if (this._map && this._map._rotate && this._zoomAnimated) {
|
|
22
|
+
var anchor = this._getAnchor();
|
|
23
|
+
var pos = L.DomUtil.getPosition(this._container).subtract(anchor);
|
|
24
|
+
L.DomUtil.setPosition(this._container, this._map.rotatedPointToMapPanePoint(pos).add(anchor));
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
var bottom = this._containerBottom = -offset.y,
|
|
30
|
-
left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x;
|
|
31
|
-
|
|
32
|
-
// bottom position the popup in case the height of the popup changes (images loading etc)
|
|
33
|
-
this._container.style.bottom = bottom + 'px';
|
|
34
|
-
this._container.style.left = left + 'px';
|
|
35
27
|
},
|
|
36
28
|
|
|
37
29
|
});
|