leaflet-rotate 0.4.0 → 0.5.1
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 +85 -5
- package/dist/leaflet-rotate-src.js +1325 -254
- package/dist/leaflet-rotate-src.js.map +4 -4
- package/dist/leaflet-rotate.js +1 -1
- package/dist/leaflet-rotate.js.map +4 -4
- package/lib/debug.js +62 -88
- package/lib/debug.min.js +16 -1
- package/misc/leaflet-heat-rotate.js +7 -0
- package/package.json +1 -1
- package/src/control/Rotate.js +160 -103
- package/src/dom/DomUtil.js +23 -12
- package/src/dom/Draggable.js +5 -0
- package/src/geo/LatLngBounds.js +5 -0
- package/src/geometry/Bounds.js +5 -0
- package/src/geometry/Point.js +17 -3
- package/src/index.js +4 -1
- package/src/layer/DivOverlay.js +34 -5
- package/src/layer/Popup.js +14 -3
- package/src/layer/Tooltip.js +16 -0
- package/src/layer/marker/Icon.js +12 -0
- package/src/layer/marker/Marker.js +86 -7
- package/src/layer/tile/GridLayer.js +38 -3
- package/src/layer/vector/Renderer.js +88 -34
- package/src/map/Map.js +578 -116
- package/src/map/handler/CompassBearing.js +34 -1
- package/src/map/handler/ContainerMutation.js +18 -1
- package/src/map/handler/ShiftKeyRotate.js +204 -13
- package/src/map/handler/TouchGestures.js +108 -10
- package/src/map/handler/TouchPitch.js +53 -0
- package/src/map/handler/TouchRotate.js +18 -1
- package/src/map/handler/TouchZoom.js +21 -1
- package/test/features/example.feature +8 -4
- package/test/features/gestures.feature +4 -0
- package/test/features/rotation.feature +60 -0
- package/test/index.html +342 -186
- package/test/steps/bearing.steps.js +535 -0
- package/test/steps/example.steps.js +56 -29
- package/test/steps/gestures.steps.js +55 -0
- package/test/support/hooks.js +4 -16
package/src/dom/DomUtil.js
CHANGED
|
@@ -11,11 +11,15 @@ Object.assign(L.DomUtil, {
|
|
|
11
11
|
* Resets the 3D CSS transform of `el` so it is translated by `offset` pixels,
|
|
12
12
|
* optionally scaled by `scale`, and rotated around `pivot` when `bearing` is set.
|
|
13
13
|
*
|
|
14
|
-
* @param {HTMLElement} el
|
|
15
|
-
* @param {L.Point} offset
|
|
16
|
-
* @param {
|
|
17
|
-
* @param {
|
|
18
|
-
* @param {L.Point} pivot
|
|
14
|
+
* @param {HTMLElement} el Element to transform.
|
|
15
|
+
* @param {L.Point} [offset] Translation in pixels; defaults to the origin.
|
|
16
|
+
* @param {number} [scale] Optional scale factor.
|
|
17
|
+
* @param {number} [bearing] Optional rotation in radians.
|
|
18
|
+
* @param {L.Point} [pivot] Point in pixels around which to rotate.
|
|
19
|
+
*
|
|
20
|
+
* @returns {void}
|
|
21
|
+
*
|
|
22
|
+
* @since leaflet-rotate (v0.1.0)
|
|
19
23
|
*/
|
|
20
24
|
setTransform(el, offset, scale, bearing, pivot) {
|
|
21
25
|
let pos = offset || new L.Point(0, 0);
|
|
@@ -35,11 +39,15 @@ Object.assign(L.DomUtil, {
|
|
|
35
39
|
* Sets the position of `el` to `point`, using CSS transforms or top/left positioning
|
|
36
40
|
* depending on browser support, and optionally rotating it around `pivot`.
|
|
37
41
|
*
|
|
38
|
-
* @param {HTMLElement} el
|
|
39
|
-
* @param {L.Point} point
|
|
40
|
-
* @param {
|
|
41
|
-
* @param {L.Point} pivot
|
|
42
|
-
* @param {
|
|
42
|
+
* @param {HTMLElement} el Element to position.
|
|
43
|
+
* @param {L.Point} point Position in pixels.
|
|
44
|
+
* @param {number} [bearing] Rotation in radians; zero or omitted uses Leaflet positioning.
|
|
45
|
+
* @param {L.Point} [pivot] Point in pixels around which to rotate.
|
|
46
|
+
* @param {number} [scale] Optional scale factor.
|
|
47
|
+
*
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*
|
|
50
|
+
* @since leaflet-rotate (v0.1.0)
|
|
43
51
|
*/
|
|
44
52
|
setPosition(el, point, bearing, pivot, scale) {
|
|
45
53
|
if (!bearing) {
|
|
@@ -53,8 +61,11 @@ Object.assign(L.DomUtil, {
|
|
|
53
61
|
/**
|
|
54
62
|
* Returns the position assigned to `el`.
|
|
55
63
|
*
|
|
56
|
-
* @param {HTMLElement} el
|
|
57
|
-
*
|
|
64
|
+
* @param {HTMLElement} el Element whose Leaflet position is requested.
|
|
65
|
+
*
|
|
66
|
+
* @returns {L.Point} Stored Leaflet position, or the position measured by Leaflet.
|
|
67
|
+
*
|
|
68
|
+
* @since leaflet-rotate (v0.1.0)
|
|
58
69
|
*/
|
|
59
70
|
getPosition(el) {
|
|
60
71
|
return el._leaflet_pos || domUtilProto.getPosition(el);
|
package/src/dom/Draggable.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* This plugin does not modify the `L.Draggable` API; it adapts marker drag
|
|
3
|
+
* coordinates in `L.Marker` when rotation or pitch is enabled.
|
|
4
|
+
*
|
|
2
5
|
* @external L.Draggable
|
|
3
6
|
*
|
|
4
7
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/dom/Draggable.js
|
|
@@ -8,6 +11,8 @@
|
|
|
8
11
|
* A class for making DOM elements draggable (including touch support).
|
|
9
12
|
* Used internally for map and marker dragging. Only works for elements
|
|
10
13
|
* that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).
|
|
14
|
+
*
|
|
15
|
+
* @since leaflet-rotate (v0.1.0)
|
|
11
16
|
*/
|
|
12
17
|
|
|
13
18
|
L.Draggable.include({
|
package/src/geo/LatLngBounds.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Leaflet's `L.LatLngBounds` is not overridden by this plugin. Map methods
|
|
3
|
+
* such as `getBounds()` return standard Leaflet bounds containing the viewport.
|
|
4
|
+
*
|
|
5
|
+
* @since leaflet-rotate (v0.1.0)
|
|
6
|
+
*
|
|
2
7
|
* @external L.LatLngBounds
|
|
3
8
|
*
|
|
4
9
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/geo/LatLngBounds.js
|
package/src/geometry/Bounds.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Leaflet's `L.Bounds` is not overridden by this plugin. Rotation-aware
|
|
3
|
+
* pixel bounds are calculated by the map and renderer extensions.
|
|
4
|
+
*
|
|
5
|
+
* @since leaflet-rotate (v0.1.0)
|
|
6
|
+
*
|
|
2
7
|
* @external L.Bounds
|
|
3
8
|
*
|
|
4
9
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/geometry/Bounds.js
|
package/src/geometry/Point.js
CHANGED
|
@@ -12,7 +12,10 @@ Object.assign(L.Point.prototype, {
|
|
|
12
12
|
* ⎡ x' ⎤ = ⎡ cos θ -sin θ ⎤ ⎡ x ⎤
|
|
13
13
|
* ⎣ y' ⎦ ⎣ sin θ cos θ ⎦ ⎣ y ⎦
|
|
14
14
|
*
|
|
15
|
-
* @param theta
|
|
15
|
+
* @param {number} theta Rotation angle in radians, counterclockwise.
|
|
16
|
+
* @returns {L.Point} Rotated point (or this point when theta is zero).
|
|
17
|
+
*
|
|
18
|
+
* @since leaflet-rotate (v0.1.0)
|
|
16
19
|
*/
|
|
17
20
|
rotate(theta) {
|
|
18
21
|
return this.rotateFrom(theta, new L.Point(0,0))
|
|
@@ -27,10 +30,12 @@ Object.assign(L.Point.prototype, {
|
|
|
27
30
|
*
|
|
28
31
|
* same as `this.subtract(pivot).rotate(theta).add(pivot)`
|
|
29
32
|
*
|
|
30
|
-
* @param {
|
|
31
|
-
* @param {L.Point} pivot
|
|
33
|
+
* @param {number} theta Rotation angle in radians, counterclockwise.
|
|
34
|
+
* @param {L.Point} pivot Point to rotate around.
|
|
32
35
|
*
|
|
33
36
|
* @returns {L.Point}
|
|
37
|
+
*
|
|
38
|
+
* @since leaflet-rotate (v0.1.0)
|
|
34
39
|
*/
|
|
35
40
|
rotateFrom(theta, pivot) {
|
|
36
41
|
if (!theta) { return this; }
|
|
@@ -49,6 +54,15 @@ Object.assign(L.Point.prototype, {
|
|
|
49
54
|
|
|
50
55
|
});
|
|
51
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Convert an array or point-like object to an `L.Point`.
|
|
59
|
+
*
|
|
60
|
+
* @param {L.Point|number[]|{x:number,y:number}|null} point Coordinate to convert.
|
|
61
|
+
*
|
|
62
|
+
* @returns {L.Point|null} Existing point, converted point, or `null` for a null input.
|
|
63
|
+
*
|
|
64
|
+
* @since leaflet-rotate (v0.1.0)
|
|
65
|
+
*/
|
|
52
66
|
export function toPoint(point) {
|
|
53
67
|
if (point == null || point instanceof L.Point) {
|
|
54
68
|
return point;
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Export Leaflet classes in the same order as the core library
|
|
2
|
+
* Export Leaflet classes in the same order as the core library.
|
|
3
|
+
*
|
|
4
|
+
* @since leaflet-rotate (v0.1.0)
|
|
3
5
|
*
|
|
4
6
|
* @external L
|
|
5
7
|
*
|
|
@@ -53,6 +55,7 @@ export * from './map/handler/CompassBearing';
|
|
|
53
55
|
export * from './map/handler/ContainerMutation';
|
|
54
56
|
export * from './map/handler/TouchGestures';
|
|
55
57
|
export * from './map/handler/TouchRotate';
|
|
58
|
+
export * from './map/handler/TouchPitch';
|
|
56
59
|
export * from './map/handler/ShiftKeyRotate';
|
|
57
60
|
export * from './map/handler/TouchZoom';
|
|
58
61
|
|
package/src/layer/DivOverlay.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Keeps popup and tooltip screen positions aligned with rotated and pitched maps.
|
|
3
|
+
*
|
|
2
4
|
* @external L.DivOverlay
|
|
3
5
|
*
|
|
4
6
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/DivOverlay.js
|
|
7
|
+
*
|
|
8
|
+
* @since leaflet-rotate (v0.1.0)
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
11
|
import { toPoint } from '../geometry/Point';
|
|
@@ -11,18 +15,43 @@ const divOverlayProto = Object.defineProperties({}, Object.getOwnPropertyDescrip
|
|
|
11
15
|
L.DivOverlay.include({
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
* the map is moved by calling `map.setBearing(theta)`
|
|
18
|
+
* Extend overlay event subscriptions to refresh position after map rotation and pitch.
|
|
16
19
|
*
|
|
17
20
|
* @listens L.Map~rotate
|
|
21
|
+
* @listens L.Map~pitch
|
|
22
|
+
*
|
|
23
|
+
* @returns {Object} Leaflet event map for the overlay.
|
|
24
|
+
*
|
|
25
|
+
* @since leaflet-rotate (v0.1.0)
|
|
18
26
|
*/
|
|
19
27
|
getEvents() {
|
|
20
|
-
|
|
28
|
+
const events = Object.assign(divOverlayProto.getEvents.apply(this, arguments), {
|
|
29
|
+
rotate: this._updatePosition,
|
|
30
|
+
pitch: this._updatePitchEvents,
|
|
31
|
+
});
|
|
32
|
+
if (this._map && this._map._pitch) {
|
|
33
|
+
events.move = this._updatePosition;
|
|
34
|
+
}
|
|
35
|
+
return events;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Listen to map movement only while pitch is non-zero.
|
|
40
|
+
*
|
|
41
|
+
* @since leaflet-rotate (0.5.0)
|
|
42
|
+
*/
|
|
43
|
+
_updatePitchEvents() {
|
|
44
|
+
if (this._map._pitch) {
|
|
45
|
+
this._map.on('move', this._updatePosition, this);
|
|
46
|
+
} else {
|
|
47
|
+
this._map.off('move', this._updatePosition, this);
|
|
48
|
+
}
|
|
21
49
|
},
|
|
22
50
|
|
|
23
51
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
52
|
+
* Reposition the overlay after map movement, applying rotation/pitch-aware coordinates.
|
|
53
|
+
*
|
|
54
|
+
* @since leaflet-rotate (v0.1.0)
|
|
26
55
|
*/
|
|
27
56
|
_updatePosition() {
|
|
28
57
|
if (!this._map) { return; }
|
package/src/layer/Popup.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Preserves popup positioning and auto-pan behavior on rotated maps.
|
|
3
|
+
*
|
|
2
4
|
* @external L.Popup
|
|
3
5
|
*
|
|
4
6
|
* @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/Popup.js
|
|
7
|
+
*
|
|
8
|
+
* @since leaflet-rotate (v0.1.0)
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
11
|
import { toPoint } from '../geometry/Point';
|
|
@@ -11,8 +15,11 @@ const popupProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(
|
|
|
11
15
|
L.Popup.include({
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
18
|
+
* Update the popup position during zoom animation and transform it into map-pane coordinates.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} e Zoom animation event.
|
|
21
|
+
*
|
|
22
|
+
* @since leaflet-rotate (v0.1.0)
|
|
16
23
|
*/
|
|
17
24
|
_animateZoom(e) {
|
|
18
25
|
popupProto._animateZoom.apply(this, arguments);
|
|
@@ -24,9 +31,13 @@ L.Popup.include({
|
|
|
24
31
|
},
|
|
25
32
|
|
|
26
33
|
/**
|
|
27
|
-
*
|
|
34
|
+
* Pan the map when a popup with auto-pan enabled would extend beyond the viewport.
|
|
28
35
|
*
|
|
29
36
|
* @see https://github.com/fnicollet/Leaflet/pull/21
|
|
37
|
+
*
|
|
38
|
+
* @fires L.Map#autopanstart
|
|
39
|
+
*
|
|
40
|
+
* @since leaflet-rotate (v0.1.0)
|
|
30
41
|
*/
|
|
31
42
|
_adjustPan() {
|
|
32
43
|
if (!this.options.autoPan || (this._map._panAnim && this._map._panAnim._inProgress)) { return; }
|
package/src/layer/Tooltip.js
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
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
11
|
const tooltipProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Tooltip.prototype));
|
|
8
12
|
|
|
9
13
|
L.Tooltip.include({
|
|
10
14
|
|
|
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
|
+
*/
|
|
11
22
|
_animateZoom(e) {
|
|
12
23
|
if (!this._map._rotate) {
|
|
13
24
|
return tooltipProto._animateZoom.apply(this, arguments);
|
|
@@ -18,6 +29,11 @@ L.Tooltip.include({
|
|
|
18
29
|
this._setPosition(pos);
|
|
19
30
|
},
|
|
20
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Recompute tooltip screen position after map movement.
|
|
34
|
+
*
|
|
35
|
+
* @since leaflet-rotate (v0.1.0)
|
|
36
|
+
*/
|
|
21
37
|
_updatePosition() {
|
|
22
38
|
if (!this._map._rotate) {
|
|
23
39
|
return tooltipProto._updatePosition.apply(this, arguments);
|
package/src/layer/marker/Icon.js
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
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
11
|
const iconProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Icon.prototype));
|
|
8
12
|
|
|
9
13
|
L.Icon.include({
|
|
10
14
|
|
|
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
|
+
*/
|
|
11
23
|
_setIconStyles(img, name) {
|
|
12
24
|
const options = this.options;
|
|
13
25
|
let sizeOption = options[name + 'Size'];
|
|
@@ -1,7 +1,16 @@
|
|
|
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
|
|
@@ -12,30 +21,41 @@ const markerProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors
|
|
|
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
|
|
|
@@ -52,6 +72,13 @@ const MarkerDrag = {
|
|
|
52
72
|
// this._draggable.updateMapBearing(this._marker._map._bearing);
|
|
53
73
|
// },
|
|
54
74
|
|
|
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
|
+
*/
|
|
55
82
|
_onDrag(e) {
|
|
56
83
|
const marker = this._marker,
|
|
57
84
|
/** @TODO use markerDragProto._onDrag */
|
|
@@ -86,6 +113,13 @@ const MarkerDrag = {
|
|
|
86
113
|
.fire('drag', e);
|
|
87
114
|
},
|
|
88
115
|
|
|
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
|
+
*/
|
|
89
123
|
_onDragEnd(e) {
|
|
90
124
|
if (this._marker._map._rotate) {
|
|
91
125
|
this._marker.update();
|
|
@@ -98,15 +132,44 @@ const 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)
|
|
105
143
|
*/
|
|
106
144
|
getEvents() {
|
|
107
|
-
|
|
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;
|
|
108
153
|
},
|
|
109
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Subscribe to map movement while pitch is active to keep the icon aligned.
|
|
157
|
+
*
|
|
158
|
+
* @since leaflet-rotate (0.5.0)
|
|
159
|
+
*/
|
|
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
|
+
}
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Install rotation-aware drag callbacks when marker dragging is enabled.
|
|
170
|
+
*
|
|
171
|
+
* @since leaflet-rotate (v0.1.0)
|
|
172
|
+
*/
|
|
110
173
|
_initInteraction() {
|
|
111
174
|
const ret = markerProto._initInteraction.apply(this, arguments);
|
|
112
175
|
if (this.dragging && this.dragging.enabled() && this._map && this._map._rotate) {
|
|
@@ -123,6 +186,13 @@ L.Marker.include({
|
|
|
123
186
|
return ret;
|
|
124
187
|
},
|
|
125
188
|
|
|
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
|
+
*/
|
|
126
196
|
_setPos(pos) {
|
|
127
197
|
|
|
128
198
|
/** @TODO use markerProto._setPos */
|
|
@@ -165,6 +235,15 @@ L.Marker.include({
|
|
|
165
235
|
// this._icon.style.zIndex = Math.round(this._zIndex + offset);
|
|
166
236
|
// },
|
|
167
237
|
|
|
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
|
+
*/
|
|
168
247
|
setRotation(rotation) {
|
|
169
248
|
this.options.rotation = rotation;
|
|
170
249
|
this.update();
|
|
@@ -1,7 +1,11 @@
|
|
|
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
11
|
const gridLayerProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.GridLayer.prototype));
|
|
@@ -9,10 +13,13 @@ const gridLayerProto = Object.defineProperties({}, Object.getOwnPropertyDescript
|
|
|
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
24
|
getEvents() {
|
|
18
25
|
const events = gridLayerProto.getEvents.apply(this, arguments);
|
|
@@ -20,11 +27,39 @@ L.GridLayer.include({
|
|
|
20
27
|
if (!this._onRotate) {
|
|
21
28
|
this._onRotate = L.Util.throttle(this._onMoveEnd, this.options.updateInterval, this);
|
|
22
29
|
}
|
|
23
|
-
events.rotate = this.
|
|
30
|
+
events.rotate = this._onRotateEvent;
|
|
24
31
|
}
|
|
25
32
|
return events;
|
|
26
33
|
},
|
|
27
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Keep tile levels aligned when a bearing/pitch change shifts the pixel origin
|
|
37
|
+
* (eg. when the rotation pivot is not the view center), then refresh tiles (throttled).
|
|
38
|
+
*
|
|
39
|
+
* @listens L.Map~rotate
|
|
40
|
+
*
|
|
41
|
+
* @since leaflet-rotate (0.5.1)
|
|
42
|
+
*/
|
|
43
|
+
_onRotateEvent() {
|
|
44
|
+
const map = this._map;
|
|
45
|
+
if (!map) { return; }
|
|
46
|
+
const origin = map.getPixelOrigin();
|
|
47
|
+
if (this._rotateOrigin && !this._rotateOrigin.equals(origin) && !map._animatingZoom && this._levels) {
|
|
48
|
+
this._setZoomTransforms(map.getCenter(), map.getZoom());
|
|
49
|
+
}
|
|
50
|
+
this._rotateOrigin = origin;
|
|
51
|
+
this._onRotate();
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Return tile pixel bounds that cover the rotated viewport.
|
|
56
|
+
*
|
|
57
|
+
* @param {L.LatLng} center View center used to calculate bounds.
|
|
58
|
+
*
|
|
59
|
+
* @returns {L.Bounds} Pixel bounds covered by the layer's tiles.
|
|
60
|
+
*
|
|
61
|
+
* @since leaflet-rotate (v0.1.0)
|
|
62
|
+
*/
|
|
28
63
|
_getTiledPixelBounds(center) {
|
|
29
64
|
if (!this._map._rotate) {
|
|
30
65
|
return gridLayerProto._getTiledPixelBounds.apply(this, arguments);
|