leaflet-rotate 0.3.0 → 0.5.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 +74 -5
- package/build/test.js +18 -0
- package/dist/leaflet-rotate-src.js +1081 -303
- package/dist/leaflet-rotate-src.js.map +3 -3
- package/dist/leaflet-rotate.js +1 -1
- package/dist/leaflet-rotate.js.map +3 -3
- package/lib/debug.js +84 -66
- package/lib/debug.min.js +1 -1
- package/misc/leaflet-heat-rotate.js +14 -7
- package/misc/loremIpsum.js +1 -1
- package/misc/places.js +1 -1
- package/misc/route.js +1 -1
- package/package.json +5 -5
- package/src/control/Rotate.js +98 -29
- package/src/dom/DomUtil.js +42 -47
- package/src/dom/Draggable.js +6 -1
- package/src/geo/LatLngBounds.js +5 -0
- package/src/geometry/Bounds.js +5 -0
- package/src/geometry/Point.js +33 -10
- package/src/index.js +3 -1
- package/src/layer/DivOverlay.js +43 -12
- package/src/layer/Popup.js +29 -16
- package/src/layer/Tooltip.js +21 -5
- package/src/layer/marker/Icon.js +20 -8
- package/src/layer/marker/Marker.js +103 -24
- package/src/layer/tile/GridLayer.js +22 -6
- package/src/layer/vector/Renderer.js +102 -11
- package/src/map/Map.js +408 -121
- package/src/map/handler/CompassBearing.js +33 -7
- package/src/map/handler/ContainerMutation.js +20 -3
- package/src/map/handler/ShiftKeyRotate.js +156 -16
- package/src/map/handler/TouchGestures.js +91 -29
- package/src/map/handler/TouchRotate.js +20 -3
- package/src/map/handler/TouchZoom.js +25 -5
- package/test/features/example.feature +5 -0
- package/test/features/rotation.feature +30 -0
- package/test/index.html +60 -22
- package/test/steps/bearing.steps.js +345 -3
- package/test/steps/example.steps.js +72 -11
- package/test/steps/gestures.steps.js +4 -4
- package/test/steps/overlays.steps.js +32 -32
- package/test/support/hooks.js +38 -2
package/src/layer/Tooltip.js
CHANGED
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Keeps tooltips positioned correctly when the map is rotated or pitched.
|
|
3
|
+
*
|
|
2
4
|
* @external L.Tooltip
|
|
3
5
|
*
|
|
4
6
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/Tooltip.js
|
|
7
|
+
*
|
|
8
|
+
* @since leaflet-rotate (v0.1.0)
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
|
-
const tooltipProto =
|
|
11
|
+
const tooltipProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Tooltip.prototype));
|
|
8
12
|
|
|
9
13
|
L.Tooltip.include({
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Reposition the tooltip during zoom animation using transformed map coordinates.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} e Zoom animation event.
|
|
19
|
+
*
|
|
20
|
+
* @since leaflet-rotate (v0.1.0)
|
|
21
|
+
*/
|
|
22
|
+
_animateZoom(e) {
|
|
12
23
|
if (!this._map._rotate) {
|
|
13
24
|
return tooltipProto._animateZoom.apply(this, arguments);
|
|
14
25
|
}
|
|
15
|
-
|
|
26
|
+
let pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
|
|
16
27
|
|
|
17
28
|
pos = this._map.rotatedPointToMapPanePoint(pos);
|
|
18
29
|
this._setPosition(pos);
|
|
19
30
|
},
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Recompute tooltip screen position after map movement.
|
|
34
|
+
*
|
|
35
|
+
* @since leaflet-rotate (v0.1.0)
|
|
36
|
+
*/
|
|
37
|
+
_updatePosition() {
|
|
22
38
|
if (!this._map._rotate) {
|
|
23
39
|
return tooltipProto._updatePosition.apply(this, arguments);
|
|
24
40
|
}
|
|
25
|
-
|
|
41
|
+
let pos = this._map.latLngToLayerPoint(this._latlng);
|
|
26
42
|
|
|
27
43
|
pos = this._map.rotatedPointToMapPanePoint(pos);
|
|
28
44
|
this._setPosition(pos);
|
package/src/layer/marker/Icon.js
CHANGED
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Applies icon-anchor transform origins so marker rotation pivots around its anchor.
|
|
3
|
+
*
|
|
2
4
|
* @external L.Icon
|
|
3
5
|
*
|
|
4
6
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/marker/Icon.js
|
|
7
|
+
*
|
|
8
|
+
* @since leaflet-rotate (v0.1.0)
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
|
-
const iconProto =
|
|
11
|
+
const iconProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Icon.prototype));
|
|
8
12
|
|
|
9
13
|
L.Icon.include({
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Set marker icon dimensions and anchor styles, including the rotation origin.
|
|
17
|
+
*
|
|
18
|
+
* @param {HTMLImageElement} img Icon or shadow element.
|
|
19
|
+
* @param {string} name Icon style key (`icon` or `shadow`).
|
|
20
|
+
*
|
|
21
|
+
* @since leaflet-rotate (v0.1.0)
|
|
22
|
+
*/
|
|
23
|
+
_setIconStyles(img, name) {
|
|
24
|
+
const options = this.options;
|
|
25
|
+
let sizeOption = options[name + 'Size'];
|
|
14
26
|
|
|
15
27
|
if (typeof sizeOption === 'number') {
|
|
16
28
|
sizeOption = [sizeOption, sizeOption];
|
|
17
29
|
}
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
const size = sizeOption ? new L.Point(...(Array.isArray(sizeOption) ? sizeOption : [sizeOption.x, sizeOption.y])) : null,
|
|
32
|
+
anchorOption = name === 'shadow' && options.shadowAnchor || options.iconAnchor || size && size.divideBy(2, true),
|
|
33
|
+
anchor = anchorOption ? new L.Point(...(Array.isArray(anchorOption) ? anchorOption : [anchorOption.x, anchorOption.y])) : null;
|
|
22
34
|
|
|
23
35
|
img.className = 'leaflet-marker-' + name + ' ' + (options.className || '');
|
|
24
36
|
|
|
@@ -26,7 +38,7 @@ L.Icon.include({
|
|
|
26
38
|
img.style.marginLeft = (-anchor.x) + 'px';
|
|
27
39
|
img.style.marginTop = (-anchor.y) + 'px';
|
|
28
40
|
/** @TODO use iconProto._setIconStyles */
|
|
29
|
-
img.style
|
|
41
|
+
img.style.transformOrigin = anchor.x + "px " + anchor.y + "px 0px";
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
if (size) {
|
|
@@ -1,63 +1,90 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Adds rotation and pitch-aware positioning to Leaflet markers.
|
|
3
|
+
*
|
|
2
4
|
* @external L.Marker
|
|
3
5
|
* @external L.Handler.MarkerDrag
|
|
4
6
|
*
|
|
7
|
+
* @property {number} [rotation=0] Marker icon rotation in radians.
|
|
8
|
+
* @property {boolean} [rotateWithView=false] Rotate the icon with the map bearing.
|
|
9
|
+
* @property {boolean} [keepUpright=false] Flip a map-aligned icon to keep it upright.
|
|
10
|
+
* @property {number} [scale] Optional scale applied to the icon and shadow.
|
|
11
|
+
*
|
|
12
|
+
* @since leaflet-rotate (v0.1.0)
|
|
13
|
+
*
|
|
5
14
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/marker/Marker.js
|
|
6
15
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/marker/Marker.Drag.js
|
|
7
16
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/dom/Draggable.js
|
|
8
17
|
*/
|
|
9
18
|
|
|
10
|
-
const markerProto =
|
|
19
|
+
const markerProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Marker.prototype));
|
|
11
20
|
|
|
12
21
|
L.Marker.mergeOptions({
|
|
13
22
|
|
|
14
23
|
/**
|
|
15
|
-
* Rotation of
|
|
24
|
+
* Rotation of the marker icon in radians.
|
|
16
25
|
*
|
|
17
26
|
* @type {Number}
|
|
27
|
+
*
|
|
28
|
+
* @since leaflet-rotate (v0.1.0)
|
|
18
29
|
*/
|
|
19
30
|
rotation: 0,
|
|
20
31
|
|
|
21
32
|
/**
|
|
22
|
-
* Rotate
|
|
33
|
+
* Rotate the marker icon when the map bearing changes.
|
|
34
|
+
*
|
|
35
|
+
* Combine with `keepUpright: true` to keep the marker readable while
|
|
36
|
+
* preserving its line alignment.
|
|
23
37
|
*
|
|
24
38
|
* @type {Boolean}
|
|
39
|
+
*
|
|
40
|
+
* @since leaflet-rotate (v0.1.0)
|
|
25
41
|
*/
|
|
26
42
|
rotateWithView: false,
|
|
27
43
|
|
|
28
44
|
/**
|
|
29
|
-
* Flip
|
|
45
|
+
* Flip the icon when needed to keep it upright while map-aligned.
|
|
30
46
|
*
|
|
31
47
|
* @type {Boolean}
|
|
48
|
+
*
|
|
49
|
+
* @since leaflet-rotate (v0.1.0)
|
|
32
50
|
*/
|
|
33
51
|
keepUpright: false,
|
|
34
52
|
|
|
35
53
|
/**
|
|
36
|
-
*
|
|
54
|
+
* Optional scale of the marker icon and shadow.
|
|
37
55
|
*
|
|
38
56
|
* @type {Number}
|
|
57
|
+
*
|
|
58
|
+
* @since leaflet-rotate (v0.1.0)
|
|
39
59
|
*/
|
|
40
60
|
scale: undefined,
|
|
41
61
|
|
|
42
62
|
});
|
|
43
63
|
|
|
44
|
-
|
|
64
|
+
let markerDragProto; // retrived at runtime (see below: L.Marker::_initInteraction())
|
|
45
65
|
|
|
46
|
-
|
|
66
|
+
const MarkerDrag = {
|
|
47
67
|
|
|
48
|
-
// _onDragStart
|
|
68
|
+
// _onDragStart() {
|
|
49
69
|
// if (!this._marker._map._rotate) {
|
|
50
70
|
// return markerDragProto._onDragStart.apply(this, arguments);
|
|
51
71
|
// }
|
|
52
72
|
// this._draggable.updateMapBearing(this._marker._map._bearing);
|
|
53
73
|
// },
|
|
54
74
|
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Update a dragged marker's geographic position from its transformed icon position.
|
|
77
|
+
*
|
|
78
|
+
* @param {Object} e Marker drag event with `latlng` and `oldLatLng` fields.
|
|
79
|
+
*
|
|
80
|
+
* @since leaflet-rotate (v0.1.0)
|
|
81
|
+
*/
|
|
82
|
+
_onDrag(e) {
|
|
83
|
+
const marker = this._marker,
|
|
57
84
|
/** @TODO use markerDragProto._onDrag */
|
|
58
85
|
rotated_marker = marker.options.rotation || marker.options.rotateWithView,
|
|
59
|
-
shadow = marker._shadow
|
|
60
|
-
|
|
86
|
+
shadow = marker._shadow;
|
|
87
|
+
let iconPos = L.DomUtil.getPosition(marker._icon);
|
|
61
88
|
|
|
62
89
|
/** @TODO use markerDragProto._onDrag */
|
|
63
90
|
// update shadow position
|
|
@@ -70,7 +97,7 @@ var MarkerDrag = {
|
|
|
70
97
|
// Reverse calculation from mapPane coordinates to rotatePane coordinates
|
|
71
98
|
iconPos = marker._map.mapPanePointToRotatedPoint(iconPos);
|
|
72
99
|
}
|
|
73
|
-
|
|
100
|
+
const latlng = marker._map.layerPointToLatLng(iconPos);
|
|
74
101
|
|
|
75
102
|
marker._latlng = latlng;
|
|
76
103
|
e.latlng = latlng;
|
|
@@ -86,7 +113,14 @@ var MarkerDrag = {
|
|
|
86
113
|
.fire('drag', e);
|
|
87
114
|
},
|
|
88
115
|
|
|
89
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Reposition the marker after a drag ends, then run Leaflet's drag-end logic.
|
|
118
|
+
*
|
|
119
|
+
* @param {Object} e Marker drag-end event.
|
|
120
|
+
*
|
|
121
|
+
* @since leaflet-rotate (v0.1.0)
|
|
122
|
+
*/
|
|
123
|
+
_onDragEnd(e) {
|
|
90
124
|
if (this._marker._map._rotate) {
|
|
91
125
|
this._marker.update();
|
|
92
126
|
}
|
|
@@ -98,17 +132,46 @@ var MarkerDrag = {
|
|
|
98
132
|
L.Marker.include({
|
|
99
133
|
|
|
100
134
|
/**
|
|
101
|
-
*
|
|
102
|
-
* is moved by calling `map.setBearing(theta)`
|
|
135
|
+
* Extend marker event subscriptions to reposition its icon after bearing or pitch changes.
|
|
103
136
|
*
|
|
104
137
|
* @listens L.Map~rotate
|
|
138
|
+
* @listens L.Map~pitch
|
|
139
|
+
*
|
|
140
|
+
* @returns {Object} Leaflet event map for the marker.
|
|
141
|
+
*
|
|
142
|
+
* @since leaflet-rotate (v0.1.0)
|
|
143
|
+
*/
|
|
144
|
+
getEvents() {
|
|
145
|
+
const events = Object.assign(markerProto.getEvents.apply(this, arguments), {
|
|
146
|
+
rotate: this.update,
|
|
147
|
+
pitch: this._updatePitchEvents,
|
|
148
|
+
});
|
|
149
|
+
if (this._map && this._map._pitch) {
|
|
150
|
+
events.move = this.update;
|
|
151
|
+
}
|
|
152
|
+
return events;
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Subscribe to map movement while pitch is active to keep the icon aligned.
|
|
157
|
+
*
|
|
158
|
+
* @since leaflet-rotate (0.5.0)
|
|
105
159
|
*/
|
|
106
|
-
|
|
107
|
-
|
|
160
|
+
_updatePitchEvents() {
|
|
161
|
+
if (this._map._pitch) {
|
|
162
|
+
this._map.on('move', this.update, this);
|
|
163
|
+
} else {
|
|
164
|
+
this._map.off('move', this.update, this);
|
|
165
|
+
}
|
|
108
166
|
},
|
|
109
167
|
|
|
110
|
-
|
|
111
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Install rotation-aware drag callbacks when marker dragging is enabled.
|
|
170
|
+
*
|
|
171
|
+
* @since leaflet-rotate (v0.1.0)
|
|
172
|
+
*/
|
|
173
|
+
_initInteraction() {
|
|
174
|
+
const ret = markerProto._initInteraction.apply(this, arguments);
|
|
112
175
|
if (this.dragging && this.dragging.enabled() && this._map && this._map._rotate) {
|
|
113
176
|
// L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable
|
|
114
177
|
markerDragProto = markerDragProto || Object.getPrototypeOf(this.dragging);
|
|
@@ -123,7 +186,14 @@ L.Marker.include({
|
|
|
123
186
|
return ret;
|
|
124
187
|
},
|
|
125
188
|
|
|
126
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Position and rotate the marker icon and shadow in map-pane coordinates.
|
|
191
|
+
*
|
|
192
|
+
* @param {L.Point} pos Marker anchor in layer-point coordinates.
|
|
193
|
+
*
|
|
194
|
+
* @since leaflet-rotate (v0.1.0)
|
|
195
|
+
*/
|
|
196
|
+
_setPos(pos) {
|
|
127
197
|
|
|
128
198
|
/** @TODO use markerProto._setPos */
|
|
129
199
|
if (this._map._rotate) {
|
|
@@ -131,7 +201,7 @@ L.Marker.include({
|
|
|
131
201
|
}
|
|
132
202
|
|
|
133
203
|
/** @TODO use markerProto._setPos */
|
|
134
|
-
|
|
204
|
+
let bearing = this.options.rotation || 0;
|
|
135
205
|
if (this.options.rotateWithView) {
|
|
136
206
|
bearing += this._map._bearing;
|
|
137
207
|
}
|
|
@@ -158,14 +228,23 @@ L.Marker.include({
|
|
|
158
228
|
this._resetZIndex();
|
|
159
229
|
},
|
|
160
230
|
|
|
161
|
-
// _updateZIndex
|
|
231
|
+
// _updateZIndex(offset) {
|
|
162
232
|
// if (!this._map._rotate) {
|
|
163
233
|
// return markerProto._updateZIndex.apply(this, arguments);
|
|
164
234
|
// }
|
|
165
235
|
// this._icon.style.zIndex = Math.round(this._zIndex + offset);
|
|
166
236
|
// },
|
|
167
237
|
|
|
168
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Set the marker icon's rotation and redraw it.
|
|
240
|
+
*
|
|
241
|
+
* @param {number} rotation Angle in radians.
|
|
242
|
+
*
|
|
243
|
+
* @returns {void}
|
|
244
|
+
*
|
|
245
|
+
* @since leaflet-rotate (v0.1.0)
|
|
246
|
+
*/
|
|
247
|
+
setRotation(rotation) {
|
|
169
248
|
this.options.rotation = rotation;
|
|
170
249
|
this.update();
|
|
171
250
|
},
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Updates tile coverage for rotated map bounds.
|
|
3
|
+
*
|
|
2
4
|
* @external L.GridLayer
|
|
3
5
|
*
|
|
4
6
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/tile/GridLayer.js
|
|
7
|
+
*
|
|
8
|
+
* @since leaflet-rotate (v0.1.0)
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
|
-
const gridLayerProto =
|
|
11
|
+
const gridLayerProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.GridLayer.prototype));
|
|
8
12
|
|
|
9
13
|
L.GridLayer.include({
|
|
10
14
|
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
13
|
-
* moved by just calling `map.setBearing(theta)`
|
|
16
|
+
* Add a throttled tile refresh after map bearing changes.
|
|
14
17
|
*
|
|
15
18
|
* @listens L.Map~rotate
|
|
19
|
+
*
|
|
20
|
+
* @returns {Object} Leaflet event map for the grid layer.
|
|
21
|
+
*
|
|
22
|
+
* @since leaflet-rotate (v0.1.0)
|
|
16
23
|
*/
|
|
17
|
-
getEvents
|
|
18
|
-
|
|
24
|
+
getEvents() {
|
|
25
|
+
const events = gridLayerProto.getEvents.apply(this, arguments);
|
|
19
26
|
if (this._map._rotate && !this.options.updateWhenIdle) {
|
|
20
27
|
if (!this._onRotate) {
|
|
21
28
|
this._onRotate = L.Util.throttle(this._onMoveEnd, this.options.updateInterval, this);
|
|
@@ -25,7 +32,16 @@ L.GridLayer.include({
|
|
|
25
32
|
return events;
|
|
26
33
|
},
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Return tile pixel bounds that cover the rotated viewport.
|
|
37
|
+
*
|
|
38
|
+
* @param {L.LatLng} center View center used to calculate bounds.
|
|
39
|
+
*
|
|
40
|
+
* @returns {L.Bounds} Pixel bounds covered by the layer's tiles.
|
|
41
|
+
*
|
|
42
|
+
* @since leaflet-rotate (v0.1.0)
|
|
43
|
+
*/
|
|
44
|
+
_getTiledPixelBounds(center) {
|
|
29
45
|
if (!this._map._rotate) {
|
|
30
46
|
return gridLayerProto._getTiledPixelBounds.apply(this, arguments);
|
|
31
47
|
}
|
|
@@ -1,29 +1,59 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Recalculates vector renderer bounds and transforms for rotated and pitched maps.
|
|
3
|
+
*
|
|
2
4
|
* @external L.Renderer
|
|
3
5
|
*
|
|
4
6
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/vector/Renderer.js
|
|
7
|
+
*
|
|
8
|
+
* @since leaflet-rotate (v0.1.0)
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
|
-
const rendererProto =
|
|
11
|
+
const rendererProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Renderer.prototype));
|
|
12
|
+
const rendererBase = Object.getPrototypeOf(L.Renderer.prototype);
|
|
13
|
+
const rendererGetEvents = rendererProto.getEvents || rendererBase.getEvents;
|
|
14
|
+
const rendererOnMoveEnd = rendererProto._onMoveEnd || rendererBase._onMoveEnd;
|
|
8
15
|
|
|
9
16
|
L.Renderer.include({
|
|
10
17
|
|
|
11
18
|
/**
|
|
12
|
-
*
|
|
13
|
-
* map is moved by just calling `map.setBearing(theta)`
|
|
19
|
+
* Subscribe the renderer to map rotation so its visible bounds are recalculated.
|
|
14
20
|
*
|
|
15
21
|
* @listens L.Map~rotate
|
|
22
|
+
*
|
|
23
|
+
* @returns {Object} Leaflet event map for the renderer.
|
|
24
|
+
*
|
|
25
|
+
* @since leaflet-rotate (v0.1.0)
|
|
16
26
|
*/
|
|
17
|
-
getEvents
|
|
18
|
-
|
|
27
|
+
getEvents() {
|
|
28
|
+
const events = rendererGetEvents.apply(this, arguments);
|
|
29
|
+
return Object.assign(events, { rotate: this._onRotate });
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reproject vector paths and refresh renderer bounds after bearing changes.
|
|
34
|
+
*
|
|
35
|
+
* @since leaflet-rotate (v0.1.0)
|
|
36
|
+
*/
|
|
37
|
+
_onRotate() {
|
|
38
|
+
if (!this._map._rotate) { return; }
|
|
39
|
+
this._onZoomEnd();
|
|
40
|
+
if (L.version.startsWith('2.')) {
|
|
41
|
+
this._onMoveEnd();
|
|
42
|
+
} else {
|
|
43
|
+
this._update();
|
|
44
|
+
}
|
|
19
45
|
},
|
|
20
46
|
|
|
21
47
|
/**
|
|
22
|
-
*
|
|
48
|
+
* Add the zoom-animation class needed for correct renderer transforms in Leaflet 1.
|
|
49
|
+
*
|
|
50
|
+
* Fixes `map.flyTo()` when `map.options.zoomAnimation` is false.
|
|
23
51
|
*
|
|
24
52
|
* @see https://github.com/Leaflet/Leaflet/pull/8794
|
|
53
|
+
*
|
|
54
|
+
* @since leaflet-rotate (v0.2.0)
|
|
25
55
|
*/
|
|
26
|
-
onAdd
|
|
56
|
+
onAdd() {
|
|
27
57
|
rendererProto.onAdd.apply(this, arguments);
|
|
28
58
|
if (L.version <= "1.9.3") {
|
|
29
59
|
// always keep transform-origin as 0 0
|
|
@@ -32,6 +62,8 @@ L.Renderer.include({
|
|
|
32
62
|
},
|
|
33
63
|
|
|
34
64
|
/**
|
|
65
|
+
* Update the renderer transform during zoom animation, accounting for rotated coordinates.
|
|
66
|
+
*
|
|
35
67
|
* @FIXME layer drifts on `map.setZoom()` (eg. zoom during animation)
|
|
36
68
|
*
|
|
37
69
|
* the main cause seems to be related to `this._updateTransform(path._center, path._zoom))`
|
|
@@ -46,11 +78,27 @@ L.Renderer.include({
|
|
|
46
78
|
* @see https://github.com/Leaflet/Leaflet/pull/8103
|
|
47
79
|
* @see https://github.com/Leaflet/Leaflet/issues/7466
|
|
48
80
|
*
|
|
49
|
-
* @TODO
|
|
81
|
+
* @TODO recheck these changes against leaflet@v1.9.3
|
|
50
82
|
*
|
|
51
83
|
* @see https://github.com/Leaflet/Leaflet/compare/v1.7.0...v1.9.3
|
|
84
|
+
*
|
|
85
|
+
* @param {L.LatLng} center Target map center.
|
|
86
|
+
* @param {number} zoom Target zoom level.
|
|
87
|
+
*
|
|
88
|
+
* @since leaflet-rotate (v0.1.0)
|
|
52
89
|
*/
|
|
53
|
-
_updateTransform
|
|
90
|
+
_updateTransform(center, zoom) {
|
|
91
|
+
if (L.version.startsWith('2.')) {
|
|
92
|
+
if (this._map._rotate) {
|
|
93
|
+
const scale = this._map.getZoomScale(zoom, this._zoom),
|
|
94
|
+
offset = this._topLeftPoint.multiplyBy(scale)
|
|
95
|
+
.subtract(this._map._getNewPixelOrigin(center, zoom));
|
|
96
|
+
|
|
97
|
+
L.DomUtil.setTransform(this._container, offset, scale);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
return rendererBase._updateTransform.apply(this, arguments);
|
|
101
|
+
}
|
|
54
102
|
if (!this._map._rotate) {
|
|
55
103
|
return rendererProto._updateTransform.apply(this, arguments);
|
|
56
104
|
}
|
|
@@ -61,13 +109,51 @@ L.Renderer.include({
|
|
|
61
109
|
/**
|
|
62
110
|
* @FIXME see path._renderer._reset();
|
|
63
111
|
*/
|
|
64
|
-
|
|
112
|
+
const scale = this._map.getZoomScale(zoom, this._zoom),
|
|
65
113
|
offset = this._map._latLngToNewLayerPoint(this._topLeft, zoom, center);
|
|
66
114
|
|
|
67
115
|
L.DomUtil.setTransform(this._container, offset, scale);
|
|
68
116
|
|
|
69
117
|
},
|
|
70
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Recalculate bounds and finish renderer updates after movement on Leaflet 2.
|
|
121
|
+
*
|
|
122
|
+
* @param {Object} ev Map movement event.
|
|
123
|
+
*
|
|
124
|
+
* @since leaflet-rotate (v0.4.0)
|
|
125
|
+
*/
|
|
126
|
+
_onMoveEnd(ev) {
|
|
127
|
+
if (!L.version.startsWith('2.') || !this._map._rotate) {
|
|
128
|
+
return rendererOnMoveEnd.apply(this, arguments);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
this._bounds = this._map._getPaddedPixelBounds(this.options.padding);
|
|
132
|
+
this._topLeft = this._map.layerPointToLatLng(this._bounds.min);
|
|
133
|
+
this._center = this._map.getCenter();
|
|
134
|
+
this._zoom = this._map.getZoom();
|
|
135
|
+
this._topLeftPoint = this._map._getNewPixelOrigin(this._center, this._zoom).add(this._bounds.min);
|
|
136
|
+
this._updateTransform(this._center, this._zoom);
|
|
137
|
+
this._resizeContainer();
|
|
138
|
+
this._onSettled(ev);
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Resize the renderer container to cover the pitch-aware map bounds.
|
|
143
|
+
*
|
|
144
|
+
* @since leaflet-rotate (v0.4.0)
|
|
145
|
+
*/
|
|
146
|
+
_resizeContainer() {
|
|
147
|
+
if (!L.version.startsWith('2.') || !this._map._rotate || !this._bounds) {
|
|
148
|
+
return rendererBase._resizeContainer.apply(this, arguments);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const size = this._bounds.getSize();
|
|
152
|
+
this._container.style.width = size.x + 'px';
|
|
153
|
+
this._container.style.height = size.y + 'px';
|
|
154
|
+
return size;
|
|
155
|
+
},
|
|
156
|
+
|
|
71
157
|
// getEvents() {
|
|
72
158
|
// const events = {
|
|
73
159
|
// viewreset: this._reset,
|
|
@@ -110,7 +196,12 @@ L.Renderer.include({
|
|
|
110
196
|
// }
|
|
111
197
|
// },
|
|
112
198
|
|
|
113
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Recalculate renderer bounds and cached view state.
|
|
201
|
+
*
|
|
202
|
+
* @since leaflet-rotate (v0.1.0)
|
|
203
|
+
*/
|
|
204
|
+
_update() {
|
|
114
205
|
if (!this._map._rotate) {
|
|
115
206
|
return rendererProto._update.apply(this, arguments);
|
|
116
207
|
}
|