leaflet-rotate 0.2.2 → 0.2.4
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/dist/leaflet-rotate-src.js +185 -63
- package/dist/leaflet-rotate-src.js.map +1 -1
- package/dist/leaflet-rotate.js +185 -63
- package/dist/leaflet-rotate.js.map +1 -1
- package/package.json +1 -1
- package/src/control/Rotate.js +42 -41
- package/src/layer/vector/Renderer.js +75 -5
- package/src/map/Map.js +21 -5
- package/src/map/handler/CompassBearing.js +47 -8
- package/src/map/handler/TouchZoom.js +0 -4
- package/test/index.html +14 -1
package/src/control/Rotate.js
CHANGED
|
@@ -16,8 +16,6 @@ L.Control.Rotate = L.Control.extend({
|
|
|
16
16
|
},
|
|
17
17
|
|
|
18
18
|
onAdd: function(map) {
|
|
19
|
-
this._onDeviceOrientation = L.Util.throttle(this._unthrottledOnDeviceOrientation, 100, this);
|
|
20
|
-
|
|
21
19
|
var container = this._container = L.DomUtil.create('div', 'leaflet-control-rotate leaflet-bar');
|
|
22
20
|
|
|
23
21
|
// this.button = L.Control.Zoom.prototype._createButton.call(this, 'R', 'leaflet-control-rotate', 'leaflet-control-rotate', container, this._toggleLock);
|
|
@@ -37,7 +35,6 @@ L.Control.Rotate = L.Control.extend({
|
|
|
37
35
|
link.appendChild(arrow);
|
|
38
36
|
link.href = '#';
|
|
39
37
|
link.title = 'Rotate map';
|
|
40
|
-
// link.draggable = false;
|
|
41
38
|
|
|
42
39
|
L.DomEvent
|
|
43
40
|
.on(link, 'dblclick', L.DomEvent.stopPropagation)
|
|
@@ -52,7 +49,7 @@ L.Control.Rotate = L.Control.extend({
|
|
|
52
49
|
|
|
53
50
|
this._restyle();
|
|
54
51
|
|
|
55
|
-
map.on('rotate', this._restyle
|
|
52
|
+
map.on('rotate', this._restyle, this);
|
|
56
53
|
|
|
57
54
|
// State flag
|
|
58
55
|
this._follow = false;
|
|
@@ -64,9 +61,13 @@ L.Control.Rotate = L.Control.extend({
|
|
|
64
61
|
|
|
65
62
|
return container;
|
|
66
63
|
},
|
|
64
|
+
|
|
65
|
+
onRemove: function(map) {
|
|
66
|
+
map.off('rotate', this._restyle, this);
|
|
67
|
+
},
|
|
67
68
|
|
|
68
69
|
_handleMouseDown: function(e) {
|
|
69
|
-
L.DomEvent.stop(e);
|
|
70
|
+
L.DomEvent.stop(e);
|
|
70
71
|
this.dragging = true;
|
|
71
72
|
this.dragstartX = e.pageX;
|
|
72
73
|
this.dragstartY = e.pageY;
|
|
@@ -76,7 +77,7 @@ L.Control.Rotate = L.Control.extend({
|
|
|
76
77
|
},
|
|
77
78
|
|
|
78
79
|
_handleMouseUp: function(e) {
|
|
79
|
-
L.DomEvent.stop(e);
|
|
80
|
+
L.DomEvent.stop(e);
|
|
80
81
|
this.dragging = false;
|
|
81
82
|
|
|
82
83
|
L.DomEvent
|
|
@@ -91,64 +92,64 @@ L.Control.Rotate = L.Control.extend({
|
|
|
91
92
|
},
|
|
92
93
|
|
|
93
94
|
_cycleState: function(ev) {
|
|
94
|
-
|
|
95
|
+
if (!this._map) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
95
98
|
|
|
96
|
-
|
|
99
|
+
var map = this._map;
|
|
97
100
|
|
|
101
|
+
// Touch mode
|
|
98
102
|
if (!map.touchRotate.enabled() && !map.compassBearing.enabled()) {
|
|
99
|
-
// Go from disabled to touch
|
|
100
103
|
map.touchRotate.enable();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Compass mode
|
|
107
|
+
else if (!map.compassBearing.enabled()) {
|
|
108
|
+
map.touchRotate.disable();
|
|
109
|
+
map.compassBearing.enable();
|
|
110
|
+
}
|
|
101
111
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
map.touchRotate.
|
|
108
|
-
map.compassBearing.enable();
|
|
109
|
-
|
|
110
|
-
// console.log('state is now: compass');
|
|
111
|
-
|
|
112
|
-
// It is possible that compass is not supported. If so,
|
|
113
|
-
// the hangler will automatically go from compass to disabled.
|
|
114
|
-
} else {
|
|
115
|
-
// Go from compass to disabled
|
|
116
|
-
map.compassBearing.disable();
|
|
117
|
-
|
|
118
|
-
// console.log('state is now: locked');
|
|
119
|
-
|
|
120
|
-
map.setBearing(0);
|
|
121
|
-
if (this.options.closeOnZeroBearing) {
|
|
122
|
-
map.touchRotate.enable();
|
|
123
|
-
}
|
|
112
|
+
// Locked mode
|
|
113
|
+
else {
|
|
114
|
+
map.compassBearing.disable();
|
|
115
|
+
map.setBearing(0);
|
|
116
|
+
if (this.options.closeOnZeroBearing) {
|
|
117
|
+
map.touchRotate.enable();
|
|
124
118
|
}
|
|
125
119
|
}
|
|
126
120
|
this._restyle();
|
|
127
121
|
},
|
|
128
122
|
|
|
129
123
|
_restyle: function() {
|
|
130
|
-
if (this._map.options.rotate) {
|
|
124
|
+
if (!this._map.options.rotate) {
|
|
125
|
+
L.DomUtil.addClass(this._link, 'leaflet-disabled');
|
|
126
|
+
} else {
|
|
131
127
|
var map = this._map;
|
|
132
128
|
var bearing = map.getBearing();
|
|
133
|
-
|
|
129
|
+
|
|
130
|
+
this._arrow.style.transform = 'rotate(' + bearing + 'deg)';
|
|
131
|
+
|
|
132
|
+
if (bearing && this.options.closeOnZeroBearing) {
|
|
134
133
|
this._container.style.display = 'block';
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
|
|
138
|
-
this._arrow.style.transform = cssTransform;
|
|
139
|
-
|
|
136
|
+
// Compass mode
|
|
140
137
|
if (map.compassBearing.enabled()) {
|
|
141
138
|
this._link.style.backgroundColor = 'orange';
|
|
142
|
-
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Touch mode
|
|
142
|
+
else if (map.touchRotate.enabled()) {
|
|
143
143
|
this._link.style.backgroundColor = null;
|
|
144
|
-
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Locked mode
|
|
147
|
+
else {
|
|
145
148
|
this._link.style.backgroundColor = 'grey';
|
|
146
|
-
if (this.options.closeOnZeroBearing
|
|
149
|
+
if (0 === bearing && this.options.closeOnZeroBearing) {
|
|
147
150
|
this._container.style.display = 'none';
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
|
-
} else {
|
|
151
|
-
L.DomUtil.addClass(this._link, 'leaflet-disabled');
|
|
152
153
|
}
|
|
153
154
|
},
|
|
154
155
|
|
|
@@ -19,6 +19,33 @@ L.Renderer.include({
|
|
|
19
19
|
},
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
+
* Fix for `map.flyTo()` when `false === map.options.zoomAnimation`
|
|
23
|
+
*
|
|
24
|
+
* @see https://github.com/Leaflet/Leaflet/pull/8794
|
|
25
|
+
*/
|
|
26
|
+
onAdd: function() {
|
|
27
|
+
rendererProto.onAdd.apply(this, arguments);
|
|
28
|
+
if (L.version <= "1.9.3") {
|
|
29
|
+
// always keep transform-origin as 0 0
|
|
30
|
+
this._container.classList.add('leaflet-zoom-animated');
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @FIXME layer drifts on `map.setZoom()` (eg. zoom during animation)
|
|
36
|
+
*
|
|
37
|
+
* the main cause seems to be related to `this._updateTransform(path._center, path._zoom))`
|
|
38
|
+
* and `this._topLeft = this._map.layerPointToLatLng(this._bounds.min);`
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* map.setZoom(2);
|
|
42
|
+
* path._renderer._update();
|
|
43
|
+
* path._renderer._updateTransform(path._renderer._center, path._renderer._zoom);
|
|
44
|
+
*
|
|
45
|
+
* @see https://github.com/Leaflet/Leaflet/pull/8794
|
|
46
|
+
* @see https://github.com/Leaflet/Leaflet/pull/8103
|
|
47
|
+
* @see https://github.com/Leaflet/Leaflet/issues/7466
|
|
48
|
+
*
|
|
22
49
|
* @TODO rechek this changes from leaflet@v1.9.3
|
|
23
50
|
*
|
|
24
51
|
* @see https://github.com/Leaflet/Leaflet/compare/v1.7.0...v1.9.3
|
|
@@ -27,15 +54,58 @@ L.Renderer.include({
|
|
|
27
54
|
if (!this._map._rotate) {
|
|
28
55
|
return rendererProto._updateTransform.apply(this, arguments);
|
|
29
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* @FIXME see path._renderer._reset();
|
|
59
|
+
*/
|
|
30
60
|
var scale = this._map.getZoomScale(zoom, this._zoom),
|
|
31
61
|
offset = this._map._latLngToNewLayerPoint(this._topLeft, zoom, center);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
L.DomUtil.setPosition(this._container, offset);
|
|
36
|
-
}
|
|
62
|
+
|
|
63
|
+
L.DomUtil.setTransform(this._container, offset, scale);
|
|
64
|
+
|
|
37
65
|
},
|
|
38
66
|
|
|
67
|
+
// getEvents() {
|
|
68
|
+
// const events = {
|
|
69
|
+
// viewreset: this._reset,
|
|
70
|
+
// zoom: this._onZoom,
|
|
71
|
+
// moveend: this._update,
|
|
72
|
+
// zoomend: this._onZoomEnd
|
|
73
|
+
// };
|
|
74
|
+
// if (this._zoomAnimated) {
|
|
75
|
+
// events.zoomanim = this._onAnimZoom;
|
|
76
|
+
// }
|
|
77
|
+
// return events;
|
|
78
|
+
// },
|
|
79
|
+
|
|
80
|
+
// _onAnimZoom(ev) {
|
|
81
|
+
// this._updateTransform(ev.center, ev.zoom);
|
|
82
|
+
// },
|
|
83
|
+
|
|
84
|
+
// _onZoom() {
|
|
85
|
+
// this._updateTransform(this._map.getCenter(), this._map.getZoom());
|
|
86
|
+
// },
|
|
87
|
+
|
|
88
|
+
// _onZoomEnd() {
|
|
89
|
+
// for (const id in this._layers) {
|
|
90
|
+
// this._layers[id]._project();
|
|
91
|
+
// }
|
|
92
|
+
// },
|
|
93
|
+
|
|
94
|
+
// _reset() {
|
|
95
|
+
// this._update();
|
|
96
|
+
// this._updateTransform(this._center, this._zoom);
|
|
97
|
+
|
|
98
|
+
// for (const id in this._layers) {
|
|
99
|
+
// this._layers[id]._reset();
|
|
100
|
+
// }
|
|
101
|
+
// },
|
|
102
|
+
|
|
103
|
+
// _updatePaths() {
|
|
104
|
+
// for (const id in this._layers) {
|
|
105
|
+
// this._layers[id]._update();
|
|
106
|
+
// }
|
|
107
|
+
// },
|
|
108
|
+
|
|
39
109
|
_update: function() {
|
|
40
110
|
if (!this._map._rotate) {
|
|
41
111
|
return rendererProto._update.apply(this, arguments);
|
package/src/map/Map.js
CHANGED
|
@@ -95,6 +95,15 @@ L.Map.include({
|
|
|
95
95
|
.rotate(-this._bearing);
|
|
96
96
|
},
|
|
97
97
|
|
|
98
|
+
// latLngToLayerPoint: function (latlng) {
|
|
99
|
+
// var projectedPoint = this.project(L.latLng(latlng))._round();
|
|
100
|
+
// return projectedPoint._subtract(this.getPixelOrigin());
|
|
101
|
+
// },
|
|
102
|
+
|
|
103
|
+
// latLngToContainerPoint: function (latlng) {
|
|
104
|
+
// return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng)));
|
|
105
|
+
// },
|
|
106
|
+
|
|
98
107
|
/**
|
|
99
108
|
* Given latlng bounds, returns the bounds in projected pixel
|
|
100
109
|
* relative to the map container.
|
|
@@ -110,10 +119,12 @@ L.Map.include({
|
|
|
110
119
|
if (!this._rotate && mapProto.mapBoundsToContainerBounds) {
|
|
111
120
|
return mapProto.mapBoundsToContainerBounds.apply(this, arguments);
|
|
112
121
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
// same as `this.latLngToContainerPoint(latlng)` but with floating point precision
|
|
123
|
+
const origin = this.getPixelOrigin().add(this._getMapPanePos());
|
|
124
|
+
const nw = this.project(bounds.getNorthWest())._subtract(origin),
|
|
125
|
+
ne = this.project(bounds.getNorthEast())._subtract(origin),
|
|
126
|
+
sw = this.project(bounds.getSouthWest())._subtract(origin),
|
|
127
|
+
se = this.project(bounds.getSouthEast())._subtract(origin);
|
|
117
128
|
return L.bounds([
|
|
118
129
|
L.point(Math.min(nw.x, ne.x, se.x, sw.x), Math.min(nw.y, ne.y, se.y, sw.y)), // [ minX, minY ]
|
|
119
130
|
L.point(Math.max(nw.x, ne.x, se.x, sw.x), Math.max(nw.y, ne.y, se.y, sw.y)) // [ maxX, maxY ]
|
|
@@ -473,11 +484,16 @@ L.Map.include({
|
|
|
473
484
|
// return L.DomUtil.getPosition(this._rotatePane) || new L.Point(0, 0);
|
|
474
485
|
},
|
|
475
486
|
|
|
487
|
+
// _latLngToNewLayerPoint(latlng, zoom, center) {
|
|
488
|
+
// const topLeft = this._getNewPixelOrigin(center, zoom);
|
|
489
|
+
// return this.project(latlng, zoom)._subtract(topLeft);
|
|
490
|
+
//},
|
|
491
|
+
|
|
476
492
|
_getNewPixelOrigin: function(center, zoom) {
|
|
477
|
-
var viewHalf = this.getSize()._divideBy(2);
|
|
478
493
|
if (!this._rotate) {
|
|
479
494
|
return mapProto._getNewPixelOrigin.apply(this, arguments);
|
|
480
495
|
}
|
|
496
|
+
var viewHalf = this.getSize()._divideBy(2);
|
|
481
497
|
return this.project(center, zoom)
|
|
482
498
|
.rotate(this._bearing)
|
|
483
499
|
._subtract(viewHalf)
|
|
@@ -8,25 +8,64 @@ L.Map.CompassBearing = L.Handler.extend({
|
|
|
8
8
|
|
|
9
9
|
initialize: function(map) {
|
|
10
10
|
this._map = map;
|
|
11
|
-
|
|
11
|
+
/** @see https://caniuse.com/?search=DeviceOrientation */
|
|
12
|
+
if ('ondeviceorientationabsolute' in window) {
|
|
13
|
+
this.__deviceOrientationEvent = 'deviceorientationabsolute';
|
|
14
|
+
} else if('ondeviceorientation' in window) {
|
|
15
|
+
this.__deviceOrientationEvent = 'deviceorientation';
|
|
16
|
+
}
|
|
17
|
+
this._throttled = L.Util.throttle(this._onDeviceOrientation, 100, this);
|
|
12
18
|
},
|
|
13
19
|
|
|
14
20
|
addHooks: function() {
|
|
15
|
-
if (this._map._rotate &&
|
|
16
|
-
L.DomEvent.on(window,
|
|
21
|
+
if (this._map._rotate && this.__deviceOrientationEvent) {
|
|
22
|
+
L.DomEvent.on(window, this.__deviceOrientationEvent, this._throttled, this);
|
|
23
|
+
} else {
|
|
24
|
+
// L.Map.CompassBearing handler will be automatically
|
|
25
|
+
// disabled if device orientation is not supported.
|
|
26
|
+
this.disable();
|
|
17
27
|
}
|
|
18
28
|
},
|
|
19
29
|
|
|
20
30
|
removeHooks: function() {
|
|
21
|
-
if (this._map._rotate &&
|
|
22
|
-
L.DomEvent.off(window,
|
|
31
|
+
if (this._map._rotate && this.__deviceOrientationEvent) {
|
|
32
|
+
L.DomEvent.off(window, this.__deviceOrientationEvent, this._throttled, this);
|
|
23
33
|
}
|
|
24
34
|
},
|
|
25
35
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
/**
|
|
37
|
+
* `DeviceOrientationEvent.absolute` - Indicates whether the device is providing absolute
|
|
38
|
+
* orientation values (relatives to Magnetic North) or
|
|
39
|
+
* using some arbitrary frame determined by the device.
|
|
40
|
+
*
|
|
41
|
+
* `DeviceOrientationEvent.alpha` - Returns the rotation of the device around the Z axis;
|
|
42
|
+
* that is, the number of degrees by which the device is
|
|
43
|
+
* being twisted around the center of the screen.
|
|
44
|
+
*
|
|
45
|
+
* `window.orientation` - Returns the screen orientation in degrees (in 90-degree increments)
|
|
46
|
+
* of the viewport relative to the device's natural orientation.
|
|
47
|
+
* Its only possible values are -90, 0, 90, and 180. Positive
|
|
48
|
+
* values are counterclockwise; negative values are clockwise.
|
|
49
|
+
*
|
|
50
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/absolute
|
|
51
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/alpha
|
|
52
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation
|
|
53
|
+
*/
|
|
54
|
+
_onDeviceOrientation: function(e) {
|
|
55
|
+
var angle = e.webkitCompassHeading || e.alpha;
|
|
56
|
+
var deviceOrientation = 0;
|
|
57
|
+
|
|
58
|
+
// Safari iOS
|
|
59
|
+
if (!e.absolute && e.webkitCompassHeading) {
|
|
60
|
+
angle = 360 - angle;
|
|
29
61
|
}
|
|
62
|
+
|
|
63
|
+
// Older browsers
|
|
64
|
+
if (!e.absolute && 'undefined' !== typeof window.orientation) {
|
|
65
|
+
deviceOrientation = window.orientation;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this._map.setBearing(angle - deviceOrientation);
|
|
30
69
|
},
|
|
31
70
|
|
|
32
71
|
});
|
package/test/index.html
CHANGED
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
<button onclick="map.flyTo(places['Washington'], 10);">Washington</button>
|
|
56
56
|
<button onclick="map.flyTo(places['Trondheim'], 10);">Trondheim</button>
|
|
57
57
|
</p>
|
|
58
|
+
<p>
|
|
59
|
+
<strong>Fit bounds (z = 0): </strong>
|
|
60
|
+
<button onclick="map.setZoom(0, {animate: false}) && setTimeout(() => map.fitBounds(rectangle.getBounds(), { animate: false }), 1000);" title="DEBUG: map.setZoom(0) && map.getBoundsZoom(rectangle.getBounds())">RECTANGLE</button>
|
|
61
|
+
</p>
|
|
58
62
|
</div>
|
|
59
63
|
|
|
60
64
|
<script>
|
|
@@ -79,6 +83,7 @@
|
|
|
79
83
|
layers: [esri],
|
|
80
84
|
// worldCopyJump: true,
|
|
81
85
|
// preferCanvas: false,
|
|
86
|
+
zoomAnimation: false, /* DEBUG: L.Renderer._updateTransform() */
|
|
82
87
|
rotate: true,
|
|
83
88
|
rotateControl: {
|
|
84
89
|
closeOnZeroBearing: false,
|
|
@@ -87,7 +92,7 @@
|
|
|
87
92
|
bearing: 30,
|
|
88
93
|
// attributionControl: false,
|
|
89
94
|
// zoomControl: false,
|
|
90
|
-
|
|
95
|
+
compassBearing: true,
|
|
91
96
|
// trackContainerMutation: false,
|
|
92
97
|
// shiftKeyRotate: false,
|
|
93
98
|
// touchGestures: true,
|
|
@@ -142,8 +147,16 @@
|
|
|
142
147
|
[52, 4]
|
|
143
148
|
]).addTo(map);
|
|
144
149
|
|
|
150
|
+
const rectangle = L.rectangle([
|
|
151
|
+
[60.81123, 25.71632],
|
|
152
|
+
[60.81028, 25.73166],
|
|
153
|
+
[60.7997, 25.72892],
|
|
154
|
+
[60.80061, 25.71362]
|
|
155
|
+
]).addTo(map);
|
|
156
|
+
|
|
145
157
|
// Display some debug info
|
|
146
158
|
L.Rotate.debug(map);
|
|
159
|
+
|
|
147
160
|
</script>
|
|
148
161
|
|
|
149
162
|
<a href="https://github.com/Raruto/leaflet-rotate" class="view-on-github" style="position: fixed;bottom: 10px;left: calc(50% - 60px);z-index: 9999;"> <img alt="View on Github" src="https://raruto.github.io/img/view-on-github.png" title="View on Github"
|