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.
@@ -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.bind(this));
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); // L.DomEvent.stopPropagation(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); // L.DomEvent.stopPropagation(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
- var map = this._map;
95
+ if (!this._map) {
96
+ return;
97
+ }
95
98
 
96
- if (!map) { return; }
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
- // console.log('state is now: touch rotate');
103
- } else {
104
-
105
- if (!map.compassBearing.enabled()) {
106
- // Go from touch to compass
107
- map.touchRotate.disable();
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
- if (this.options.closeOnZeroBearing && bearing) {
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
- var cssTransform = 'rotate(' + bearing + 'deg)';
138
- this._arrow.style.transform = cssTransform;
139
-
136
+ // Compass mode
140
137
  if (map.compassBearing.enabled()) {
141
138
  this._link.style.backgroundColor = 'orange';
142
- } else if (map.touchRotate.enabled()) {
139
+ }
140
+
141
+ // Touch mode
142
+ else if (map.touchRotate.enabled()) {
143
143
  this._link.style.backgroundColor = null;
144
- } else {
144
+ }
145
+
146
+ // Locked mode
147
+ else {
145
148
  this._link.style.backgroundColor = 'grey';
146
- if (this.options.closeOnZeroBearing && map.getBearing() === 0) {
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
- if (L.Browser.any3d) {
33
- L.DomUtil.setTransform(this._container, offset, scale);
34
- } else {
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
- const nw = this.latLngToContainerPoint(bounds.getNorthWest()),
114
- ne = this.latLngToContainerPoint(bounds.getNorthEast()),
115
- sw = this.latLngToContainerPoint(bounds.getSouthWest()),
116
- se = this.latLngToContainerPoint(bounds.getSouthEast());
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
- this._throttled = L.Util.throttle(this._onDeviceOrientation, 1000, this);
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 && window.DeviceOrientationEvent) {
16
- L.DomEvent.on(window, 'deviceorientation', this._throttled, this);
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 && window.DeviceOrientationEvent) {
22
- L.DomEvent.off(window, 'deviceorientation', this._throttled, this);
31
+ if (this._map._rotate && this.__deviceOrientationEvent) {
32
+ L.DomEvent.off(window, this.__deviceOrientationEvent, this._throttled, this);
23
33
  }
24
34
  },
25
35
 
26
- _onDeviceOrientation: function(event) {
27
- if (event.alpha !== null && window.orientation !== undefined) {
28
- this._map.setBearing(event.alpha - window.orientation);
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
  });
@@ -19,10 +19,6 @@ L.Map.mergeOptions({
19
19
  */
20
20
  touchZoom: L.Browser.touch,
21
21
 
22
- /**
23
- *
24
- */
25
-
26
22
  /**
27
23
  * @TODO check if this is a duplicate of `L.Map.TouchGestures::bounceAtZoomLimits`
28
24
  *
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
- // compassBearing: false,
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"