@tomickigrzegorz/leaflet-rotate 0.2.2 → 0.2.3

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 CHANGED
@@ -57,7 +57,7 @@ jsDelivr equivalent:
57
57
  <script src="https://cdn.jsdelivr.net/npm/@tomickigrzegorz/leaflet-rotate/dist/leaflet-rotate.umd.min.js"></script>
58
58
  ```
59
59
 
60
- Pin a version for production by appending `@x.y.z` to the package name, e.g. `@tomickigrzegorz/leaflet-rotate@0.2.2`. The `leaflet-rotate.css` is only needed if you use the rotate/compass control.
60
+ Pin a version for production by appending `@x.y.z` to the package name, e.g. `@tomickigrzegorz/leaflet-rotate@0.2.3`. The `leaflet-rotate.css` is only needed if you use the rotate/compass control.
61
61
 
62
62
  ---
63
63
 
@@ -1,4 +1,4 @@
1
- /*! @tomickigrzegorz/leaflet-rotate v0.2.2 | MIT */
1
+ /*! @tomickigrzegorz/leaflet-rotate v0.2.3 | MIT */
2
2
  import L from 'leaflet';
3
3
 
4
4
  // =====================================================================
@@ -48,7 +48,30 @@ import L from 'leaflet';
48
48
  };
49
49
 
50
50
  const DEG_TO_RAD = Math.PI / 180;
51
- const RAD_TO_DEG = 180 / Math.PI;
51
+ const RAD_TO_DEG = 180 / Math.PI;
52
+
53
+ // Normalize degrees to [0, 360)
54
+ function normalizeDeg(deg) {
55
+ return ((deg % 360) + 360) % 360;
56
+ }
57
+
58
+ // Wrap a degree delta to [-180, 180)
59
+ function wrapDeg(deg) {
60
+ return normalizeDeg(deg + 180) - 180;
61
+ }
62
+
63
+ // Wrap a radian delta to [-PI, PI)
64
+ function wrapRad(rad) {
65
+ var twoPi = 2 * Math.PI;
66
+ return ((((rad + Math.PI) % twoPi) + twoPi) % twoPi) - Math.PI;
67
+ }
68
+
69
+ // Monotonic-ish timestamp; performance.now is missing in some old WebViews
70
+ function now() {
71
+ return typeof performance !== "undefined" && performance.now
72
+ ? performance.now()
73
+ : Date.now();
74
+ }
52
75
 
53
76
  // =====================================================================
54
77
  // 3. L.Map — core rotation
@@ -106,9 +129,10 @@ const RAD_TO_DEG = 180 / Math.PI;
106
129
  // --- setBearing / getBearing ---
107
130
  _mapProto$1.setBearing = function (theta) {
108
131
  if (!this._rotate) return;
109
- this._commitRotatePan();
110
132
  var prev = this._bearing || 0;
111
- var bearing = ((theta % 360) + 360) % 360;
133
+ var bearing = normalizeDeg(theta);
134
+ if (bearing === prev) return;
135
+ this._commitRotatePan();
112
136
  this._bearing = bearing;
113
137
  this._bearingRad = bearing * DEG_TO_RAD;
114
138
  this._updateRotatePaneTransform();
@@ -429,7 +453,7 @@ const _mapProto = L.Map.prototype;
429
453
  this._headingDeadzone =
430
454
  options.deadzone != null ? options.deadzone : 0.5;
431
455
  // Heading direction must point to the top of the screen: bearing = -heading.
432
- this._headingTarget = (((-deg % 360) + 360) % 360);
456
+ this._headingTarget = normalizeDeg(-deg);
433
457
  this._startHeadingAnim();
434
458
  return this;
435
459
  };
@@ -456,9 +480,7 @@ const _mapProto = L.Map.prototype;
456
480
  this._headingRAF = null;
457
481
  if (!this._headingUp) return;
458
482
  var current = this.getBearing();
459
- var diff = this._headingTarget - current;
460
- while (diff > 180) diff -= 360;
461
- while (diff < -180) diff += 360;
483
+ var diff = wrapDeg(this._headingTarget - current);
462
484
  if (Math.abs(diff) < this._headingDeadzone) {
463
485
  if (Math.abs(diff) > 0.001) this.setBearing(this._headingTarget);
464
486
  return; // settled; loop restarts on next setHeading
@@ -503,25 +525,31 @@ const _mapProto = L.Map.prototype;
503
525
  this._resetZIndex();
504
526
  };
505
527
 
528
+ // Shared by update() and _rotateReposition: apply the marker's own
529
+ // rotation/scale on top of the position transform.
530
+ function _applyIconTransform(marker, map) {
531
+ var rotation = marker.options.rotation || 0;
532
+ if (marker.options.rotateWithView) {
533
+ rotation += map._bearing || 0;
534
+ }
535
+ if (rotation || marker.options.scale) {
536
+ var pos = L.DomUtil.getPosition(marker._icon) || new L.Point(0, 0);
537
+ var transform = "translate3d(" + pos.x + "px," + pos.y + "px,0)";
538
+ if (rotation) {
539
+ transform += " rotate(" + rotation + "deg)";
540
+ }
541
+ if (marker.options.scale) {
542
+ transform += " scale(" + marker.options.scale + ")";
543
+ }
544
+ marker._icon.style[L.DomUtil.TRANSFORM] = transform;
545
+ }
546
+ }
547
+
506
548
  var _markerUpdate = L.Marker.prototype.update;
507
549
  L.Marker.prototype.update = function () {
508
550
  var result = _markerUpdate.call(this);
509
551
  if (this._icon && this._map) {
510
- var rotation = this.options.rotation || 0;
511
- if (this.options.rotateWithView) {
512
- rotation += this._map._bearing;
513
- }
514
- if (rotation || this.options.scale) {
515
- var pos = L.DomUtil.getPosition(this._icon) || new L.Point(0, 0);
516
- var transform = "translate3d(" + pos.x + "px," + pos.y + "px,0)";
517
- if (rotation) {
518
- transform += " rotate(" + rotation + "deg)";
519
- }
520
- if (this.options.scale) {
521
- transform += " scale(" + this.options.scale + ")";
522
- }
523
- this._icon.style[L.DomUtil.TRANSFORM] = transform;
524
- }
552
+ _applyIconTransform(this, this._map);
525
553
  }
526
554
  return result;
527
555
  };
@@ -540,21 +568,7 @@ const _mapProto = L.Map.prototype;
540
568
  if (map._rotInertia) this._rotLayerPt = lp;
541
569
  }
542
570
  this._setPos(lp);
543
- var rotation = this.options.rotation || 0;
544
- if (this.options.rotateWithView) {
545
- rotation += map._bearing;
546
- }
547
- if (rotation || this.options.scale) {
548
- var pos = L.DomUtil.getPosition(this._icon) || new L.Point(0, 0);
549
- var transform = "translate3d(" + pos.x + "px," + pos.y + "px,0)";
550
- if (rotation) {
551
- transform += " rotate(" + rotation + "deg)";
552
- }
553
- if (this.options.scale) {
554
- transform += " scale(" + this.options.scale + ")";
555
- }
556
- this._icon.style[L.DomUtil.TRANSFORM] = transform;
557
- }
571
+ _applyIconTransform(this, map);
558
572
  };
559
573
 
560
574
  // Rotation session ended: drop the cache and do a full update (which now
@@ -811,9 +825,7 @@ const _mapProto = L.Map.prototype;
811
825
  var scale = dist / this._startDist;
812
826
  var scaleDelta = Math.abs(scale - 1);
813
827
 
814
- var angleDelta = angle - this._startAngle;
815
- while (angleDelta > Math.PI) angleDelta -= 2 * Math.PI;
816
- while (angleDelta < -Math.PI) angleDelta += 2 * Math.PI;
828
+ var angleDelta = wrapRad(angle - this._startAngle);
817
829
 
818
830
  var rotationBeyond =
819
831
  map.options.touchRotate &&
@@ -873,33 +885,26 @@ const _mapProto = L.Map.prototype;
873
885
  }
874
886
  }
875
887
  if (this._rotationActive) {
876
- var rotDelta = angle - this._rotRefAngle;
877
- while (rotDelta > Math.PI) rotDelta -= 2 * Math.PI;
878
- while (rotDelta < -Math.PI) rotDelta += 2 * Math.PI;
888
+ var rotDelta = wrapRad(angle - this._rotRefAngle);
879
889
  var dir = map.options.rotateClockwise === false ? -1 : 1;
880
- var newBearing = this._startBearing + dir * rotDelta * RAD_TO_DEG;
881
- newBearing = ((newBearing % 360) + 360) % 360;
890
+ var newBearing = normalizeDeg(
891
+ this._startBearing + dir * rotDelta * RAD_TO_DEG,
892
+ );
882
893
  map.setBearing(newBearing);
883
894
  newBearingRad = map._bearingRad || 0;
884
895
 
885
896
  // Track angular velocity (deg/ms) for release inertia
886
- var now =
887
- (typeof performance !== "undefined" && performance.now
888
- ? performance.now()
889
- : Date.now());
897
+ var t = now();
890
898
  if (this._lastRotTime) {
891
- var dtRot = now - this._lastRotTime;
899
+ var dtRot = t - this._lastRotTime;
892
900
  if (dtRot > 0) {
893
- var db = newBearing - this._lastRotBearing;
894
- while (db > 180) db -= 360;
895
- while (db < -180) db += 360;
896
- var sample = db / dtRot;
901
+ var sample = wrapDeg(newBearing - this._lastRotBearing) / dtRot;
897
902
  var w = this._ROT_VELOCITY_SMOOTH;
898
903
  this._rotVelocity =
899
904
  (1 - w) * (this._rotVelocity || 0) + w * sample;
900
905
  }
901
906
  }
902
- this._lastRotTime = now;
907
+ this._lastRotTime = t;
903
908
  this._lastRotBearing = newBearing;
904
909
  }
905
910
  }
@@ -1004,14 +1009,11 @@ const _mapProto = L.Map.prototype;
1004
1009
  var map = this._map;
1005
1010
  if (!this._ROT_INERTIA) return false;
1006
1011
 
1007
- var now =
1008
- (typeof performance !== "undefined" && performance.now
1009
- ? performance.now()
1010
- : Date.now());
1012
+ var t0 = now();
1011
1013
  // Stale: finger held still before lifting → no fling
1012
1014
  if (
1013
1015
  !this._lastRotTime ||
1014
- now - this._lastRotTime > this._ROT_STALE_MS ||
1016
+ t0 - this._lastRotTime > this._ROT_STALE_MS ||
1015
1017
  Math.abs(this._rotVelocity || 0) < this._ROT_MIN_VELOCITY
1016
1018
  ) {
1017
1019
  return false;
@@ -1024,16 +1026,13 @@ const _mapProto = L.Map.prototype;
1024
1026
 
1025
1027
  var decay = this._ROT_DECAY;
1026
1028
  var minV = this._ROT_MIN_VELOCITY;
1027
- var last = now;
1029
+ var last = t0;
1028
1030
  var self = this;
1029
1031
 
1030
1032
  map._rotInertia = true;
1031
1033
  map.fire("rotatestart");
1032
1034
  var step = function () {
1033
- var t =
1034
- (typeof performance !== "undefined" && performance.now
1035
- ? performance.now()
1036
- : Date.now());
1035
+ var t = now();
1037
1036
  var dt = t - last;
1038
1037
  last = t;
1039
1038
  if (dt <= 0) dt = 16;
@@ -1046,9 +1045,7 @@ const _mapProto = L.Map.prototype;
1046
1045
  map.fire("rotateend");
1047
1046
  return;
1048
1047
  }
1049
- var b = map.getBearing() + v * dt;
1050
- b = ((b % 360) + 360) % 360;
1051
- map.setBearing(b);
1048
+ map.setBearing(map.getBearing() + v * dt);
1052
1049
  self._rotInertiaReq = L.Util.requestAnimFrame(step, self);
1053
1050
  };
1054
1051
  this._rotInertiaReq = L.Util.requestAnimFrame(step, this);
@@ -1084,11 +1081,15 @@ const _mapProto = L.Map.prototype;
1084
1081
  L.DomEvent.stop(e);
1085
1082
  var map = this._map;
1086
1083
  map.stopHeadingUp();
1087
- if (!this._animating) map.fire("rotatestart");
1084
+ if (!this._animating) {
1085
+ map._rotating = true;
1086
+ map.fire("rotatestart");
1087
+ }
1088
1088
  var delta = L.DomEvent.getWheelDelta(e);
1089
1089
  var dir = map.options.rotateClockwise === false ? -1 : 1;
1090
- var next = map.getBearing() - dir * delta * this._ROTATE_STEP;
1091
- this._targetBearing = ((next % 360) + 360) % 360;
1090
+ this._targetBearing = normalizeDeg(
1091
+ map.getBearing() - dir * delta * this._ROTATE_STEP,
1092
+ );
1092
1093
  if (!this._animating) {
1093
1094
  this._startAnim();
1094
1095
  }
@@ -1105,7 +1106,11 @@ const _mapProto = L.Map.prototype;
1105
1106
  L.Util.cancelAnimFrame(this._animRequest);
1106
1107
  this._animRequest = null;
1107
1108
  }
1108
- this._animating = false;
1109
+ if (this._animating) {
1110
+ this._animating = false;
1111
+ this._map._rotating = false;
1112
+ this._map.fire("rotateend");
1113
+ }
1109
1114
  },
1110
1115
 
1111
1116
  _animate: function () {
@@ -1117,9 +1122,7 @@ const _mapProto = L.Map.prototype;
1117
1122
 
1118
1123
  var map = this._map;
1119
1124
  var current = map.getBearing();
1120
- var diff = this._targetBearing - current;
1121
- if (diff > 180) diff -= 360;
1122
- if (diff < -180) diff += 360;
1125
+ var diff = wrapDeg(this._targetBearing - current);
1123
1126
 
1124
1127
  if (Math.abs(diff) < 0.1) {
1125
1128
  map.setBearing(this._targetBearing);
@@ -1199,25 +1202,33 @@ const _mapProto = L.Map.prototype;
1199
1202
  _onMove: function (e) {
1200
1203
  var dx = e.clientX - this._startX;
1201
1204
  if (!this._moved && Math.abs(dx) < 2) return;
1202
- if (!this._moved) this._map.fire("rotatestart");
1203
- this._moved = true;
1205
+ if (!this._moved) {
1206
+ this._moved = true;
1207
+ this._map._rotating = true;
1208
+ this._map.fire("rotatestart");
1209
+ }
1204
1210
  this._map.stopHeadingUp();
1205
1211
  var dir = this._map.options.rotateClockwise === false ? -1 : 1;
1206
1212
  this._map.setBearing(this._startBearing + dir * dx * this._SENSITIVITY);
1207
1213
  },
1208
1214
  _onUp: function (e) {
1215
+ var moved = this._moved;
1209
1216
  this._cleanup();
1210
1217
  if (this._draggingWasEnabled && this._map.dragging) {
1211
1218
  this._map.dragging.enable();
1212
1219
  }
1213
- if (this._moved) {
1214
- L.DomEvent.preventDefault(e);
1215
- this._map.fire("rotate");
1216
- }
1220
+ if (moved) L.DomEvent.preventDefault(e);
1217
1221
  },
1222
+ // Also runs on removeHooks: close a live rotation session so _rotating
1223
+ // never sticks and rotatestart/rotateend stay balanced.
1218
1224
  _cleanup: function () {
1219
1225
  L.DomEvent.off(document, "mousemove", this._onMove, this);
1220
1226
  L.DomEvent.off(document, "mouseup", this._onUp, this);
1227
+ if (this._moved) {
1228
+ this._moved = false;
1229
+ this._map._rotating = false;
1230
+ this._map.fire("rotateend");
1231
+ }
1221
1232
  },
1222
1233
  });
1223
1234
 
@@ -1434,9 +1445,14 @@ const _mapProto = L.Map.prototype;
1434
1445
 
1435
1446
  // Injects ONLY the structural pane CSS (required for rotation to work).
1436
1447
  // Control styling lives in dist/leaflet-rotate.css (optional import).
1437
- const style = document.createElement("style");
1438
- style.textContent = [
1439
- ".leaflet-rotate-pane { position: absolute; top: 0; left: 0; will-change: transform; }",
1440
- ".leaflet-norotate-pane { position: absolute; top: 0; left: 0; z-index: 600; }",
1441
- ].join("\n");
1442
- document.head.appendChild(style);
1448
+ // Guarded for SSR (no document) and double injection (ESM + UMD, HMR).
1449
+ const STYLE_ID = "leaflet-rotate-panes";
1450
+ if (typeof document !== "undefined" && !document.getElementById(STYLE_ID)) {
1451
+ const style = document.createElement("style");
1452
+ style.id = STYLE_ID;
1453
+ style.textContent = [
1454
+ ".leaflet-rotate-pane { position: absolute; top: 0; left: 0; will-change: transform; }",
1455
+ ".leaflet-norotate-pane { position: absolute; top: 0; left: 0; z-index: 600; }",
1456
+ ].join("\n");
1457
+ document.head.appendChild(style);
1458
+ }
@@ -1,4 +1,4 @@
1
- /*! @tomickigrzegorz/leaflet-rotate v0.2.2 | MIT */
1
+ /*! @tomickigrzegorz/leaflet-rotate v0.2.3 | MIT */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('leaflet')) :
4
4
  typeof define === 'function' && define.amd ? define(['leaflet'], factory) :
@@ -52,7 +52,30 @@
52
52
  };
53
53
 
54
54
  const DEG_TO_RAD = Math.PI / 180;
55
- const RAD_TO_DEG = 180 / Math.PI;
55
+ const RAD_TO_DEG = 180 / Math.PI;
56
+
57
+ // Normalize degrees to [0, 360)
58
+ function normalizeDeg(deg) {
59
+ return ((deg % 360) + 360) % 360;
60
+ }
61
+
62
+ // Wrap a degree delta to [-180, 180)
63
+ function wrapDeg(deg) {
64
+ return normalizeDeg(deg + 180) - 180;
65
+ }
66
+
67
+ // Wrap a radian delta to [-PI, PI)
68
+ function wrapRad(rad) {
69
+ var twoPi = 2 * Math.PI;
70
+ return ((((rad + Math.PI) % twoPi) + twoPi) % twoPi) - Math.PI;
71
+ }
72
+
73
+ // Monotonic-ish timestamp; performance.now is missing in some old WebViews
74
+ function now() {
75
+ return typeof performance !== "undefined" && performance.now
76
+ ? performance.now()
77
+ : Date.now();
78
+ }
56
79
 
57
80
  // =====================================================================
58
81
  // 3. L.Map — core rotation
@@ -110,9 +133,10 @@
110
133
  // --- setBearing / getBearing ---
111
134
  _mapProto$1.setBearing = function (theta) {
112
135
  if (!this._rotate) return;
113
- this._commitRotatePan();
114
136
  var prev = this._bearing || 0;
115
- var bearing = ((theta % 360) + 360) % 360;
137
+ var bearing = normalizeDeg(theta);
138
+ if (bearing === prev) return;
139
+ this._commitRotatePan();
116
140
  this._bearing = bearing;
117
141
  this._bearingRad = bearing * DEG_TO_RAD;
118
142
  this._updateRotatePaneTransform();
@@ -433,7 +457,7 @@
433
457
  this._headingDeadzone =
434
458
  options.deadzone != null ? options.deadzone : 0.5;
435
459
  // Heading direction must point to the top of the screen: bearing = -heading.
436
- this._headingTarget = (((-deg % 360) + 360) % 360);
460
+ this._headingTarget = normalizeDeg(-deg);
437
461
  this._startHeadingAnim();
438
462
  return this;
439
463
  };
@@ -460,9 +484,7 @@
460
484
  this._headingRAF = null;
461
485
  if (!this._headingUp) return;
462
486
  var current = this.getBearing();
463
- var diff = this._headingTarget - current;
464
- while (diff > 180) diff -= 360;
465
- while (diff < -180) diff += 360;
487
+ var diff = wrapDeg(this._headingTarget - current);
466
488
  if (Math.abs(diff) < this._headingDeadzone) {
467
489
  if (Math.abs(diff) > 0.001) this.setBearing(this._headingTarget);
468
490
  return; // settled; loop restarts on next setHeading
@@ -507,25 +529,31 @@
507
529
  this._resetZIndex();
508
530
  };
509
531
 
532
+ // Shared by update() and _rotateReposition: apply the marker's own
533
+ // rotation/scale on top of the position transform.
534
+ function _applyIconTransform(marker, map) {
535
+ var rotation = marker.options.rotation || 0;
536
+ if (marker.options.rotateWithView) {
537
+ rotation += map._bearing || 0;
538
+ }
539
+ if (rotation || marker.options.scale) {
540
+ var pos = L.DomUtil.getPosition(marker._icon) || new L.Point(0, 0);
541
+ var transform = "translate3d(" + pos.x + "px," + pos.y + "px,0)";
542
+ if (rotation) {
543
+ transform += " rotate(" + rotation + "deg)";
544
+ }
545
+ if (marker.options.scale) {
546
+ transform += " scale(" + marker.options.scale + ")";
547
+ }
548
+ marker._icon.style[L.DomUtil.TRANSFORM] = transform;
549
+ }
550
+ }
551
+
510
552
  var _markerUpdate = L.Marker.prototype.update;
511
553
  L.Marker.prototype.update = function () {
512
554
  var result = _markerUpdate.call(this);
513
555
  if (this._icon && this._map) {
514
- var rotation = this.options.rotation || 0;
515
- if (this.options.rotateWithView) {
516
- rotation += this._map._bearing;
517
- }
518
- if (rotation || this.options.scale) {
519
- var pos = L.DomUtil.getPosition(this._icon) || new L.Point(0, 0);
520
- var transform = "translate3d(" + pos.x + "px," + pos.y + "px,0)";
521
- if (rotation) {
522
- transform += " rotate(" + rotation + "deg)";
523
- }
524
- if (this.options.scale) {
525
- transform += " scale(" + this.options.scale + ")";
526
- }
527
- this._icon.style[L.DomUtil.TRANSFORM] = transform;
528
- }
556
+ _applyIconTransform(this, this._map);
529
557
  }
530
558
  return result;
531
559
  };
@@ -544,21 +572,7 @@
544
572
  if (map._rotInertia) this._rotLayerPt = lp;
545
573
  }
546
574
  this._setPos(lp);
547
- var rotation = this.options.rotation || 0;
548
- if (this.options.rotateWithView) {
549
- rotation += map._bearing;
550
- }
551
- if (rotation || this.options.scale) {
552
- var pos = L.DomUtil.getPosition(this._icon) || new L.Point(0, 0);
553
- var transform = "translate3d(" + pos.x + "px," + pos.y + "px,0)";
554
- if (rotation) {
555
- transform += " rotate(" + rotation + "deg)";
556
- }
557
- if (this.options.scale) {
558
- transform += " scale(" + this.options.scale + ")";
559
- }
560
- this._icon.style[L.DomUtil.TRANSFORM] = transform;
561
- }
575
+ _applyIconTransform(this, map);
562
576
  };
563
577
 
564
578
  // Rotation session ended: drop the cache and do a full update (which now
@@ -815,9 +829,7 @@
815
829
  var scale = dist / this._startDist;
816
830
  var scaleDelta = Math.abs(scale - 1);
817
831
 
818
- var angleDelta = angle - this._startAngle;
819
- while (angleDelta > Math.PI) angleDelta -= 2 * Math.PI;
820
- while (angleDelta < -Math.PI) angleDelta += 2 * Math.PI;
832
+ var angleDelta = wrapRad(angle - this._startAngle);
821
833
 
822
834
  var rotationBeyond =
823
835
  map.options.touchRotate &&
@@ -877,33 +889,26 @@
877
889
  }
878
890
  }
879
891
  if (this._rotationActive) {
880
- var rotDelta = angle - this._rotRefAngle;
881
- while (rotDelta > Math.PI) rotDelta -= 2 * Math.PI;
882
- while (rotDelta < -Math.PI) rotDelta += 2 * Math.PI;
892
+ var rotDelta = wrapRad(angle - this._rotRefAngle);
883
893
  var dir = map.options.rotateClockwise === false ? -1 : 1;
884
- var newBearing = this._startBearing + dir * rotDelta * RAD_TO_DEG;
885
- newBearing = ((newBearing % 360) + 360) % 360;
894
+ var newBearing = normalizeDeg(
895
+ this._startBearing + dir * rotDelta * RAD_TO_DEG,
896
+ );
886
897
  map.setBearing(newBearing);
887
898
  newBearingRad = map._bearingRad || 0;
888
899
 
889
900
  // Track angular velocity (deg/ms) for release inertia
890
- var now =
891
- (typeof performance !== "undefined" && performance.now
892
- ? performance.now()
893
- : Date.now());
901
+ var t = now();
894
902
  if (this._lastRotTime) {
895
- var dtRot = now - this._lastRotTime;
903
+ var dtRot = t - this._lastRotTime;
896
904
  if (dtRot > 0) {
897
- var db = newBearing - this._lastRotBearing;
898
- while (db > 180) db -= 360;
899
- while (db < -180) db += 360;
900
- var sample = db / dtRot;
905
+ var sample = wrapDeg(newBearing - this._lastRotBearing) / dtRot;
901
906
  var w = this._ROT_VELOCITY_SMOOTH;
902
907
  this._rotVelocity =
903
908
  (1 - w) * (this._rotVelocity || 0) + w * sample;
904
909
  }
905
910
  }
906
- this._lastRotTime = now;
911
+ this._lastRotTime = t;
907
912
  this._lastRotBearing = newBearing;
908
913
  }
909
914
  }
@@ -1008,14 +1013,11 @@
1008
1013
  var map = this._map;
1009
1014
  if (!this._ROT_INERTIA) return false;
1010
1015
 
1011
- var now =
1012
- (typeof performance !== "undefined" && performance.now
1013
- ? performance.now()
1014
- : Date.now());
1016
+ var t0 = now();
1015
1017
  // Stale: finger held still before lifting → no fling
1016
1018
  if (
1017
1019
  !this._lastRotTime ||
1018
- now - this._lastRotTime > this._ROT_STALE_MS ||
1020
+ t0 - this._lastRotTime > this._ROT_STALE_MS ||
1019
1021
  Math.abs(this._rotVelocity || 0) < this._ROT_MIN_VELOCITY
1020
1022
  ) {
1021
1023
  return false;
@@ -1028,16 +1030,13 @@
1028
1030
 
1029
1031
  var decay = this._ROT_DECAY;
1030
1032
  var minV = this._ROT_MIN_VELOCITY;
1031
- var last = now;
1033
+ var last = t0;
1032
1034
  var self = this;
1033
1035
 
1034
1036
  map._rotInertia = true;
1035
1037
  map.fire("rotatestart");
1036
1038
  var step = function () {
1037
- var t =
1038
- (typeof performance !== "undefined" && performance.now
1039
- ? performance.now()
1040
- : Date.now());
1039
+ var t = now();
1041
1040
  var dt = t - last;
1042
1041
  last = t;
1043
1042
  if (dt <= 0) dt = 16;
@@ -1050,9 +1049,7 @@
1050
1049
  map.fire("rotateend");
1051
1050
  return;
1052
1051
  }
1053
- var b = map.getBearing() + v * dt;
1054
- b = ((b % 360) + 360) % 360;
1055
- map.setBearing(b);
1052
+ map.setBearing(map.getBearing() + v * dt);
1056
1053
  self._rotInertiaReq = L.Util.requestAnimFrame(step, self);
1057
1054
  };
1058
1055
  this._rotInertiaReq = L.Util.requestAnimFrame(step, this);
@@ -1088,11 +1085,15 @@
1088
1085
  L.DomEvent.stop(e);
1089
1086
  var map = this._map;
1090
1087
  map.stopHeadingUp();
1091
- if (!this._animating) map.fire("rotatestart");
1088
+ if (!this._animating) {
1089
+ map._rotating = true;
1090
+ map.fire("rotatestart");
1091
+ }
1092
1092
  var delta = L.DomEvent.getWheelDelta(e);
1093
1093
  var dir = map.options.rotateClockwise === false ? -1 : 1;
1094
- var next = map.getBearing() - dir * delta * this._ROTATE_STEP;
1095
- this._targetBearing = ((next % 360) + 360) % 360;
1094
+ this._targetBearing = normalizeDeg(
1095
+ map.getBearing() - dir * delta * this._ROTATE_STEP,
1096
+ );
1096
1097
  if (!this._animating) {
1097
1098
  this._startAnim();
1098
1099
  }
@@ -1109,7 +1110,11 @@
1109
1110
  L.Util.cancelAnimFrame(this._animRequest);
1110
1111
  this._animRequest = null;
1111
1112
  }
1112
- this._animating = false;
1113
+ if (this._animating) {
1114
+ this._animating = false;
1115
+ this._map._rotating = false;
1116
+ this._map.fire("rotateend");
1117
+ }
1113
1118
  },
1114
1119
 
1115
1120
  _animate: function () {
@@ -1121,9 +1126,7 @@
1121
1126
 
1122
1127
  var map = this._map;
1123
1128
  var current = map.getBearing();
1124
- var diff = this._targetBearing - current;
1125
- if (diff > 180) diff -= 360;
1126
- if (diff < -180) diff += 360;
1129
+ var diff = wrapDeg(this._targetBearing - current);
1127
1130
 
1128
1131
  if (Math.abs(diff) < 0.1) {
1129
1132
  map.setBearing(this._targetBearing);
@@ -1203,25 +1206,33 @@
1203
1206
  _onMove: function (e) {
1204
1207
  var dx = e.clientX - this._startX;
1205
1208
  if (!this._moved && Math.abs(dx) < 2) return;
1206
- if (!this._moved) this._map.fire("rotatestart");
1207
- this._moved = true;
1209
+ if (!this._moved) {
1210
+ this._moved = true;
1211
+ this._map._rotating = true;
1212
+ this._map.fire("rotatestart");
1213
+ }
1208
1214
  this._map.stopHeadingUp();
1209
1215
  var dir = this._map.options.rotateClockwise === false ? -1 : 1;
1210
1216
  this._map.setBearing(this._startBearing + dir * dx * this._SENSITIVITY);
1211
1217
  },
1212
1218
  _onUp: function (e) {
1219
+ var moved = this._moved;
1213
1220
  this._cleanup();
1214
1221
  if (this._draggingWasEnabled && this._map.dragging) {
1215
1222
  this._map.dragging.enable();
1216
1223
  }
1217
- if (this._moved) {
1218
- L.DomEvent.preventDefault(e);
1219
- this._map.fire("rotate");
1220
- }
1224
+ if (moved) L.DomEvent.preventDefault(e);
1221
1225
  },
1226
+ // Also runs on removeHooks: close a live rotation session so _rotating
1227
+ // never sticks and rotatestart/rotateend stay balanced.
1222
1228
  _cleanup: function () {
1223
1229
  L.DomEvent.off(document, "mousemove", this._onMove, this);
1224
1230
  L.DomEvent.off(document, "mouseup", this._onUp, this);
1231
+ if (this._moved) {
1232
+ this._moved = false;
1233
+ this._map._rotating = false;
1234
+ this._map.fire("rotateend");
1235
+ }
1225
1236
  },
1226
1237
  });
1227
1238
 
@@ -1438,11 +1449,16 @@
1438
1449
 
1439
1450
  // Injects ONLY the structural pane CSS (required for rotation to work).
1440
1451
  // Control styling lives in dist/leaflet-rotate.css (optional import).
1441
- const style = document.createElement("style");
1442
- style.textContent = [
1443
- ".leaflet-rotate-pane { position: absolute; top: 0; left: 0; will-change: transform; }",
1444
- ".leaflet-norotate-pane { position: absolute; top: 0; left: 0; z-index: 600; }",
1445
- ].join("\n");
1446
- document.head.appendChild(style);
1452
+ // Guarded for SSR (no document) and double injection (ESM + UMD, HMR).
1453
+ const STYLE_ID = "leaflet-rotate-panes";
1454
+ if (typeof document !== "undefined" && !document.getElementById(STYLE_ID)) {
1455
+ const style = document.createElement("style");
1456
+ style.id = STYLE_ID;
1457
+ style.textContent = [
1458
+ ".leaflet-rotate-pane { position: absolute; top: 0; left: 0; will-change: transform; }",
1459
+ ".leaflet-norotate-pane { position: absolute; top: 0; left: 0; z-index: 600; }",
1460
+ ].join("\n");
1461
+ document.head.appendChild(style);
1462
+ }
1447
1463
 
1448
1464
  }));
@@ -1,2 +1,2 @@
1
- /*! @tomickigrzegorz/leaflet-rotate v0.2.2 | MIT */
2
- !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("leaflet")):"function"==typeof define&&define.amd?define(["leaflet"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).L)}(this,function(t){"use strict";t.Point.prototype.rotate=function(i){var e=Math.cos(i),o=Math.sin(i);return new t.Point(this.x*e-this.y*o,this.x*o+this.y*e)},t.Point.prototype.rotateFrom=function(t,i){return i?this.subtract(i).rotate(t).add(i):this.rotate(t)},t.DomUtil.setTransform=function(i,e,o,a,n){var s=e||new t.Point(0,0),r="translate3d("+s.x+"px,"+s.y+"px,0)";null!=o&&(r+=" scale("+o+")"),a&&(r+=" rotate("+a+"rad)"),i.style[t.DomUtil.TRANSFORM]=r,n&&(i.style[t.DomUtil.TRANSFORM+"Origin"]=n.x+"px "+n.y+"px")},t.DomUtil.setPosition=function(i,e,o,a){i._leaflet_pos=e,t.Browser.any3d?t.DomUtil.setTransform(i,e,void 0,o,a):(i.style.left=e.x+"px",i.style.top=e.y+"px")};const i=Math.PI/180,e=180/Math.PI;var o=t.Map.prototype;t.Map.mergeOptions({rotate:!1,bearing:0,touchRotate:!1,shiftKeyRotate:!1,dragRotate:!0,rotateControl:!1,rotateClockwise:!0});var a=o.initialize;o.initialize=function(t,i){i&&i.rotate&&(this._rotate=!0,this._bearing=0,this._bearingRad=0),a.call(this,t,i),this._rotate&&this.setBearing(i.bearing||0)};var n=o._initPanes;o._initPanes=function(){if(n.call(this),this._rotate){var i=this._mapPane;this._rotatePane=t.DomUtil.create("div","leaflet-rotate-pane",i),this._norotatePane=t.DomUtil.create("div","leaflet-norotate-pane",i),this._rotatePane.appendChild(this._panes.tilePane),this._rotatePane.appendChild(this._panes.overlayPane),this._norotatePane.appendChild(this._panes.shadowPane),this._norotatePane.appendChild(this._panes.markerPane),this._norotatePane.appendChild(this._panes.tooltipPane),this._norotatePane.appendChild(this._panes.popupPane),t.DomUtil.addClass(this._rotatePane,"leaflet-proxy leaflet-zoom-animated")}},o.setBearing=function(e){if(this._rotate){this._commitRotatePan();var o=this._bearing||0,a=(e%360+360)%360;if(this._bearing=a,this._bearingRad=a*i,this._updateRotatePaneTransform(),0===o!=(0===a))for(var n in this._layers){var s=this._layers[n];s instanceof t.Renderer&&s._update()}this.fire("rotate")}},o.getBearing=function(){return this._bearing||0},o._updateRotatePaneTransform=function(){if(this._rotatePane){if(!this._bearing)return this._rotatePane.style[t.DomUtil.TRANSFORM]="",void(this._rotatePane.style[t.DomUtil.TRANSFORM+"Origin"]="");var i=this.getSize().divideBy(2);this._rotatePane.style[t.DomUtil.TRANSFORM+"Origin"]=i.x+"px "+i.y+"px",this._rotatePane.style[t.DomUtil.TRANSFORM]="rotate("+this._bearingRad+"rad)"}},o._commitRotatePan=function(){if(this._rotate&&!this._committingRotatePan){var t=this._getMapPanePos();!t||0===t.x&&0===t.y||(this._committingRotatePan=!0,this._resetView(this.getCenter(),this.getZoom(),!0),this._committingRotatePan=!1)}};var s=o.containerPointToLayerPoint;o.containerPointToLayerPoint=function(i){if(!this._rotate||!this._bearing)return s.call(this,i);var e=t.point(i),o=this._getMapPanePos(),a=this.getSize().divideBy(2);return e.subtract(o).subtract(a).rotate(-this._bearingRad).add(a)};var r=o.layerPointToContainerPoint;o.layerPointToContainerPoint=function(i){if(!this._rotate||!this._bearing)return r.call(this,i);var e=t.point(i),o=this._getMapPanePos(),a=this.getSize().divideBy(2);return e.subtract(a).rotate(this._bearingRad).add(a).add(o)},o.rotatedPointToMapPanePoint=function(i){if(!this._bearing)return t.point(i);var e=this.getSize().divideBy(2);return t.point(i).rotateFrom(this._bearingRad,e)},o.mapPanePointToRotatedPoint=function(i){if(!this._bearing)return t.point(i);var e=this.getSize().divideBy(2);return t.point(i).rotateFrom(-this._bearingRad,e)};var h=o._getCenterOffset;o._getCenterOffset=function(t){return this._rotate&&this._bearing?this.project(t).subtract(this.project(this.getCenter())).rotate(this._bearingRad):h.call(this,t)};var _=o.getBounds;o.getBounds=function(){if(!this._rotate||!this._bearing)return _.call(this);var i=this.getSize(),e=t.latLngBounds();return e.extend(this.containerPointToLatLng(t.point(0,0))),e.extend(this.containerPointToLatLng(t.point(i.x,0))),e.extend(this.containerPointToLatLng(t.point(i.x,i.y))),e.extend(this.containerPointToLatLng(t.point(0,i.y))),e},o.mapBoundsToContainerBounds=function(i){return t.bounds([this.latLngToContainerPoint(i.getNorthWest()),this.latLngToContainerPoint(i.getNorthEast()),this.latLngToContainerPoint(i.getSouthEast()),this.latLngToContainerPoint(i.getSouthWest())])};var p=o.getBoundsZoom;o.getBoundsZoom=function(i,e,o){if(!this._rotate||!this._bearing)return p.call(this,i,e,o);i=t.latLngBounds(i),o=t.point(o||[0,0]);var a=this.getZoom()||0,n=this.getMinZoom(),s=this.getMaxZoom(),r=this.getSize().subtract(o);if(r.x<=0||r.y<=0)return a;var h=this.mapBoundsToContainerBounds(i).getSize(),_=this.options.zoomSnap,l=r.x/h.x,m=r.y/h.y,d=e?Math.max(l,m):Math.min(l,m);return a=this.getScaleZoom(d,a),_&&(a=Math.round(a/_)*_),Math.max(n,Math.min(s,a))},o._animateZoomNoDelay=function(t,i,e){this._mapPane&&(e&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i),this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._onZoomTransitionEnd())};var l=o._tryAnimatedZoom;o._tryAnimatedZoom=function(t,i,e){if(this._rotate&&this._bearing&&!this._animatingZoom){var o=this._getMapPanePos();o&&(o.x||o.y)&&this._resetView(this.getCenter(),this.getZoom(),!0)}return l.call(this,t,i,e)},t.Map.addInitHook(function(){this._rotate&&this.on("resize",this._updateRotatePaneTransform,this)});var m=t.GridLayer.prototype.getEvents;t.GridLayer.prototype.getEvents=function(){var t=m.call(this);return this._map&&this._map._rotate&&(t.rotate=this._onRotate),t},t.GridLayer.prototype._onRotate=function(){this._update()};var d=t.GridLayer.prototype._invalidateAll;t.GridLayer.prototype._invalidateAll=function(){if(!this._map||!this._map._committingRotatePan)return d.call(this)};var c=t.GridLayer.prototype._getTiledPixelBounds;t.GridLayer.prototype._getTiledPixelBounds=function(i){if(!this._map._rotate||!this._map._bearing)return c.call(this,i);for(var e=this._map,o=e._animatingZoom?Math.max(e._animateToZoom,e.getZoom()):e.getZoom(),a=e.getZoomScale(o,this._tileZoom),n=e.project(i,this._tileZoom).floor(),s=e.getSize().divideBy(2*Math.min(a,1)).multiplyBy(1.25),r=new t.Bounds,h=[t.point(-s.x,-s.y),t.point(s.x,-s.y),t.point(s.x,s.y),t.point(-s.x,s.y)],_=0;_<4;_++)r.extend(n.add(h[_].rotate(-e._bearingRad)));return r};var u=t.Renderer.prototype.onAdd;t.Renderer.prototype.onAdd=function(i){u.call(this,i),i._rotate&&t.DomUtil.addClass(this._container,"leaflet-zoom-animated")};var g=t.Renderer.prototype._updateTransform;t.Renderer.prototype._updateTransform=function(i,e){if(!this._map||!this._map._rotate||!this._map._bearing)return g.call(this,i,e);if(this._bounds&&this._boundsMinLatLng){var o=this._map,a=o.getZoomScale(e,this._zoom),n=o._latLngToNewLayerPoint(this._boundsMinLatLng,e,i);t.DomUtil.setTransform(this._container,n,a)}};var f=t.Renderer.prototype._update;t.Renderer.prototype._update=function(){if(!this._map||!this._map._rotate||!this._map._bearing)return f.call(this);var i=Math.max(this.options.padding||0,1.5),e=this._map,o=e.getSize(),a=e.containerPointToLayerPoint(o.divideBy(2)),n=o.multiplyBy(.5+i),s=Math.ceil(Math.sqrt(n.x*n.x+n.y*n.y));this._bounds=new t.Bounds(a.subtract([s,s]).round(),a.add([s,s]).round()),this._center=e.getCenter(),this._zoom=e.getZoom(),this._boundsMinLatLng=e.layerPointToLatLng(this._bounds.min)};const v=t.Map.prototype;v.setHeading=function(t,i){return this._rotate?null==t||isNaN(t)?this.stopHeadingUp():(i=i||{},this._headingUp=!0,this._headingEase=null!=i.ease?i.ease:.2,this._headingDeadzone=null!=i.deadzone?i.deadzone:.5,this._headingTarget=(-t%360+360)%360,this._startHeadingAnim(),this):this},v.stopHeadingUp=function(){return this._headingUp=!1,this._headingRAF&&(t.Util.cancelAnimFrame(this._headingRAF),this._headingRAF=null),this},v.getHeadingUp=function(){return!!this._headingUp},v._startHeadingAnim=function(){this._headingRAF||(this._headingRAF=t.Util.requestAnimFrame(this._headingAnim,this))},v._headingAnim=function(){if(this._headingRAF=null,this._headingUp){for(var i=this.getBearing(),e=this._headingTarget-i;e>180;)e-=360;for(;e<-180;)e+=360;Math.abs(e)<this._headingDeadzone?Math.abs(e)>.001&&this.setBearing(this._headingTarget):(this.setBearing(i+e*this._headingEase),this._headingRAF=t.Util.requestAnimFrame(this._headingAnim,this))}},t.Marker.mergeOptions({rotation:0,rotateWithView:!1,scale:void 0});var y=t.Marker.prototype.getEvents;t.Marker.prototype.getEvents=function(){var t=y.call(this);return this._map&&this._map._rotate&&(t.rotate=this._rotateReposition,t.rotateend=this._rotateEnd),t};var P=t.Marker.prototype._setPos;t.Marker.prototype._setPos=function(i){this._map&&this._map._rotate&&this._map._bearing&&(i=this._map.rotatedPointToMapPanePoint(i)),P?P.call(this,i):(t.DomUtil.setPosition(this._icon,i),this._shadow&&t.DomUtil.setPosition(this._shadow,i),this._zIndex=i.y+this.options.zIndexOffset,this._resetZIndex())};var R=t.Marker.prototype.update;t.Marker.prototype.update=function(){var i=R.call(this);if(this._icon&&this._map){var e=this.options.rotation||0;if(this.options.rotateWithView&&(e+=this._map._bearing),e||this.options.scale){var o=t.DomUtil.getPosition(this._icon)||new t.Point(0,0),a="translate3d("+o.x+"px,"+o.y+"px,0)";e&&(a+=" rotate("+e+"deg)"),this.options.scale&&(a+=" scale("+this.options.scale+")"),this._icon.style[t.DomUtil.TRANSFORM]=a}}return i},t.Marker.prototype._rotateReposition=function(){var i=this._map;if(i&&this._icon){var e;i._rotInertia&&this._rotLayerPt?e=this._rotLayerPt:(e=i.latLngToLayerPoint(this._latlng),i._rotInertia&&(this._rotLayerPt=e)),this._setPos(e);var o=this.options.rotation||0;if(this.options.rotateWithView&&(o+=i._bearing),o||this.options.scale){var a=t.DomUtil.getPosition(this._icon)||new t.Point(0,0),n="translate3d("+a.x+"px,"+a.y+"px,0)";o&&(n+=" rotate("+o+"deg)"),this.options.scale&&(n+=" scale("+this.options.scale+")"),this._icon.style[t.DomUtil.TRANSFORM]=n}}},t.Marker.prototype._rotateEnd=function(){this._rotLayerPt=null,this.update()};var T=t.Marker.prototype._resetZIndex;t.Marker.prototype._resetZIndex=function(){if(!this._map||!this._map._rotating)return T.call(this)};var M=t.Icon.prototype._setIconStyles;if(t.Icon.prototype._setIconStyles=function(i,e){M.call(this,i,e);var o=this.options.iconAnchor||this.options.shadowAnchor;o&&(i.style[t.DomUtil.TRANSFORM+"Origin"]=o[0]+"px "+o[1]+"px")},t.DivOverlay){var b=t.DivOverlay.prototype.getEvents;t.DivOverlay.prototype.getEvents=function(){var t=b.call(this);return this._map&&this._map._rotate&&(t.rotate=this._updatePosition),t}}if(t.Popup){var D=t.Popup.prototype._updatePosition;t.Popup.prototype._updatePosition=function(){if(this._map){if(!this._map._rotate||!this._map._bearing)return D.call(this);var i=this._map.latLngToLayerPoint(this._latlng),e=this._map.rotatedPointToMapPanePoint(i),o=t.point(this.options.offset),a=this._getAnchor();t.DomUtil.setPosition(this._container,e.add(a)),this._containerBottom=-o.y,this._containerLeft=-Math.round(this._containerWidth/2)+o.x,this._container.style.bottom=this._containerBottom+"px",this._container.style.left=this._containerLeft+"px"}};var E=t.Popup.prototype._animateZoom;t.Popup.prototype._animateZoom=function(i){if(!this._map||!this._map._rotate||!this._map._bearing)return E?E.call(this,i):void 0;var e=this._map._latLngToNewLayerPoint(this._latlng,i.zoom,i.center);e=this._map.rotatedPointToMapPanePoint(e);var o=this._getAnchor();t.DomUtil.setPosition(this._container,e.add(o))};var A=t.Popup.prototype._adjustPan;t.Popup.prototype._adjustPan=function(){this._map&&this._map._rotate||A&&A.call(this)}}if(t.Tooltip){var L=t.Tooltip.prototype._updatePosition;t.Tooltip.prototype._updatePosition=function(){if(this._map){if(!this._map._rotate||!this._map._bearing)return L.call(this);var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(this._map.rotatedPointToMapPanePoint(t))}};var O=t.Tooltip.prototype._animateZoom;t.Tooltip.prototype._animateZoom=function(t){if(!this._map||!this._map._rotate||!this._map._bearing)return O?O.call(this,t):void 0;var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);this._setPosition(this._map.rotatedPointToMapPanePoint(i))}}if(t.Map.TouchGestures=t.Handler.extend({_ROTATION_THRESHOLD:30*i,_SCALE_THRESHOLD:.04,_SCALE_THRESHOLD_ROT:.12,_MOVE_THRESHOLD:4,_ZOOM_EPS:.01,_PAN_EPS:2,_ZOOM_SNAP_STEP:0,_ROT_INERTIA:!0,_ROT_DECAY:.0018,_ROT_MIN_VELOCITY:.004,_ROT_MAX_VELOCITY:1.2,_ROT_VELOCITY_SMOOTH:.4,_ROT_STALE_MS:80,addHooks:function(){t.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this),t.DomEvent.on(this._map._container,"touchmove",this._onTouchMove,this),t.DomEvent.on(this._map._container,"touchend touchcancel",this._onTouchEnd,this)},removeHooks:function(){t.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this),t.DomEvent.off(this._map._container,"touchmove",this._onTouchMove,this),t.DomEvent.off(this._map._container,"touchend touchcancel",this._onTouchEnd,this)},_onTouchStart:function(i){if(this._stopRotateInertia(),i.touches&&2===i.touches.length){var e=this._map;e.dragging&&e.dragging.enabled()&&(this._draggingWasEnabled=!0,e.dragging.disable()),e._stop&&e._stop(),this._rotVelocity=0,this._lastRotTime=0,this._lastRotBearing=0,e.stopHeadingUp(),e._commitRotatePan();var o=e.mouseEventToContainerPoint(i.touches[0]),a=e.mouseEventToContainerPoint(i.touches[1]);this._startDist=o.distanceTo(a),this._startDist<1?this._active=!1:(this._touchZoomCenter="center"===e.options.touchZoom,this._centerPoint=e.getSize().divideBy(2),this._startCenter=e.getCenter(),this._startMidpoint=this._touchZoomCenter?this._centerPoint:o.add(a).divideBy(2),this._startAngle=Math.atan2(a.y-o.y,a.x-o.x),this._startBearing=e.getBearing(),this._startBearingRad=e._bearingRad||0,this._startZoom=e.getZoom(),this._anchorLatLng=this._touchZoomCenter?this._startCenter:e.containerPointToLatLng(this._startMidpoint),this._moved=!1,this._active=!0,this._rotationActive=!1,this._scaleActive=!1,this.zoom=!1,this._lastMoveZoom=this._startZoom,this._lastMoveMidpoint=this._startMidpoint,t.DomEvent.preventDefault(i))}else this._active=!1},_onTouchMove:function(i){if(i.touches&&2===i.touches.length&&this._active){for(var o=this._map,a=o.mouseEventToContainerPoint(i.touches[0]),n=o.mouseEventToContainerPoint(i.touches[1]),s=this._touchZoomCenter?this._centerPoint:a.add(n).divideBy(2),r=a.distanceTo(n),h=Math.atan2(n.y-a.y,n.x-a.x),_=s.distanceTo(this._startMidpoint),p=r/this._startDist,l=Math.abs(p-1),m=h-this._startAngle;m>Math.PI;)m-=2*Math.PI;for(;m<-Math.PI;)m+=2*Math.PI;var d=o.options.touchRotate&&Math.abs(m)>this._ROTATION_THRESHOLD,c=l>(this._rotationActive?this._SCALE_THRESHOLD_ROT:this._SCALE_THRESHOLD),u=_>this._MOVE_THRESHOLD;if(!this._moved){if(!d&&!c&&!u)return void t.DomEvent.preventDefault(i);o._moveStart(!0,!1),this._moved=!0}var g=this._startZoom;!this._scaleActive&&c&&(this._scaleActive=!0),this._scaleActive&&(g=o.getScaleZoom(p,this._startZoom),!o.options.bounceAtZoomLimits&&(g<o.getMinZoom()&&p<1||g>o.getMaxZoom()&&p>1)&&(g=Math.max(o.getMinZoom(),Math.min(o.getMaxZoom(),g))),this._ZOOM_SNAP_STEP>0&&(g=Math.round(g/this._ZOOM_SNAP_STEP)*this._ZOOM_SNAP_STEP));var f=this._startBearingRad;if(o.options.touchRotate&&(this._rotationActive||Math.abs(m)>this._ROTATION_THRESHOLD&&(this._rotationActive=!0,this._rotRefAngle=h,o._rotating=!0,o.stopHeadingUp(),o.fire("rotatestart")),this._rotationActive)){for(var v=h-this._rotRefAngle;v>Math.PI;)v-=2*Math.PI;for(;v<-Math.PI;)v+=2*Math.PI;var y=!1===o.options.rotateClockwise?-1:1,P=this._startBearing+y*v*e;P=(P%360+360)%360,o.setBearing(P),f=o._bearingRad||0;var R="undefined"!=typeof performance&&performance.now?performance.now():Date.now();if(this._lastRotTime){var T=R-this._lastRotTime;if(T>0){for(var M=P-this._lastRotBearing;M>180;)M-=360;for(;M<-180;)M+=360;var b=M/T,D=this._ROT_VELOCITY_SMOOTH;this._rotVelocity=(1-D)*(this._rotVelocity||0)+D*b}}this._lastRotTime=R,this._lastRotBearing=P}var E=Math.abs(g-this._lastMoveZoom)>this._ZOOM_EPS,A=s.distanceTo(this._lastMoveMidpoint)>this._PAN_EPS;if(this._scaleActive&&(E||A)){var L=o.getSize().divideBy(2),O=s.subtract(L),S=o.project(this._anchorLatLng,g).subtract(O.rotate(-f)),x=o.unproject(S,g);this._center=x,this._zoom=g,this.zoom=!0,this._lastMoveZoom=g,this._lastMoveMidpoint=s,this._animRequest&&t.Util.cancelAnimFrame(this._animRequest);var C=t.Util.bind(o._move,o,x,g,{pinch:!0,round:!1},void 0);this._animRequest=t.Util.requestAnimFrame(C,this,!0)}else this._scaleActive||(this._center=this._startCenter,this._zoom=this._startZoom,this.zoom=!1,this._animRequest&&(t.Util.cancelAnimFrame(this._animRequest),this._animRequest=null));t.DomEvent.preventDefault(i)}},_onTouchEnd:function(i){var e=this._map;this._draggingWasEnabled&&e.dragging&&(e.dragging.enable(),this._draggingWasEnabled=!1),this._active&&(this._active=!1,this._moved&&(this._animRequest&&(t.Util.cancelAnimFrame(this._animRequest),this._animRequest=null),this.zoom&&(e.options.zoomAnimation?e._animateZoom(this._center,e._limitZoom(this._zoom),!0,e.options.zoomSnap):e._resetView(this._center,e._limitZoom(this._zoom))),this._rotationActive&&(this._startRotateInertia()||(e._rotating=!1,e.fire("rotateend"))),this.zoom=!1))},_stopRotateInertia:function(){this._rotInertiaReq&&(t.Util.cancelAnimFrame(this._rotInertiaReq),this._rotInertiaReq=null);var i=this._map;i&&i._rotating&&(i._rotating=!1,i._rotInertia=!1,i.fire("rotateend"))},_startRotateInertia:function(){var i=this._map;if(!this._ROT_INERTIA)return!1;var e="undefined"!=typeof performance&&performance.now?performance.now():Date.now();if(!this._lastRotTime||e-this._lastRotTime>this._ROT_STALE_MS||Math.abs(this._rotVelocity||0)<this._ROT_MIN_VELOCITY)return!1;var o=this._rotVelocity,a=this._ROT_MAX_VELOCITY;o>a&&(o=a),o<-a&&(o=-a);var n=this._ROT_DECAY,s=this._ROT_MIN_VELOCITY,r=e,h=this;i._rotInertia=!0,i.fire("rotatestart");var _=function(){var e="undefined"!=typeof performance&&performance.now?performance.now():Date.now(),a=e-r;if(r=e,a<=0&&(a=16),o*=Math.exp(-n*a),Math.abs(o)<s)return h._rotInertiaReq=null,i._rotating=!1,i._rotInertia=!1,void i.fire("rotateend");var p=i.getBearing()+o*a;p=(p%360+360)%360,i.setBearing(p),h._rotInertiaReq=t.Util.requestAnimFrame(_,h)};return this._rotInertiaReq=t.Util.requestAnimFrame(_,this),!0}}),t.Map.addInitHook("addHandler","touchGestures",t.Map.TouchGestures),t.Map.addInitHook(function(){this.options.rotate&&this.options.touchRotate&&(this.touchGestures&&this.touchGestures.enable(),this.touchZoom&&this.touchZoom.disable())}),t.Map.ShiftKeyRotate=t.Handler.extend({_ROTATE_STEP:5,_EASE:.2,addHooks:function(){t.DomEvent.on(this._map._container,"wheel",this._onWheel,this)},removeHooks:function(){t.DomEvent.off(this._map._container,"wheel",this._onWheel,this),this._stopAnim()},_onWheel:function(i){if(i.shiftKey){t.DomEvent.stop(i);var e=this._map;e.stopHeadingUp(),this._animating||e.fire("rotatestart");var o=t.DomEvent.getWheelDelta(i),a=!1===e.options.rotateClockwise?-1:1,n=e.getBearing()-a*o*this._ROTATE_STEP;this._targetBearing=(n%360+360)%360,this._animating||this._startAnim()}},_startAnim:function(){this._animating||(this._animating=!0,this._animRequest=t.Util.requestAnimFrame(this._animate,this,!0))},_stopAnim:function(){this._animRequest&&(t.Util.cancelAnimFrame(this._animRequest),this._animRequest=null),this._animating=!1},_animate:function(){if(this._animating)if(void 0!==this._targetBearing&&null!==this._targetBearing){var i=this._map,e=i.getBearing(),o=this._targetBearing-e;if(o>180&&(o-=360),o<-180&&(o+=360),Math.abs(o)<.1)return i.setBearing(this._targetBearing),void this._stopAnim();i.setBearing(e+o*this._EASE),this._animRequest=t.Util.requestAnimFrame(this._animate,this,!0)}else this._stopAnim()}}),t.Map.addInitHook("addHandler","shiftKeyRotate",t.Map.ShiftKeyRotate),t.Map.addInitHook(function(){this.options.rotate&&this.options.shiftKeyRotate&&this.shiftKeyRotate&&this.shiftKeyRotate.enable()}),t.Map.ScrollWheelZoom){var S=t.Map.ScrollWheelZoom.prototype._onWheelScroll;t.Map.ScrollWheelZoom.prototype._onWheelScroll=function(t){if(!(t.shiftKey&&this._map&&this._map._rotate&&this._map.options.shiftKeyRotate))return S.call(this,t)}}t.Map.DragRotate=t.Handler.extend({_SENSITIVITY:.5,addHooks:function(){t.DomEvent.on(this._map._container,"mousedown",this._onDown,this),t.DomEvent.on(this._map._container,"contextmenu",t.DomEvent.preventDefault)},removeHooks:function(){t.DomEvent.off(this._map._container,"mousedown",this._onDown,this),t.DomEvent.off(this._map._container,"contextmenu",t.DomEvent.preventDefault),this._cleanup()},_onDown:function(i){if(2===i.button){t.DomEvent.preventDefault(i),t.DomEvent.stopPropagation(i);var e=this._map;this._startX=i.clientX,this._startBearing=e.getBearing(),this._moved=!1,e.dragging&&e.dragging.enabled()?(this._draggingWasEnabled=!0,e.dragging.disable()):this._draggingWasEnabled=!1,t.DomEvent.on(document,"mousemove",this._onMove,this),t.DomEvent.on(document,"mouseup",this._onUp,this)}},_onMove:function(t){var i=t.clientX-this._startX;if(this._moved||!(Math.abs(i)<2)){this._moved||this._map.fire("rotatestart"),this._moved=!0,this._map.stopHeadingUp();var e=!1===this._map.options.rotateClockwise?-1:1;this._map.setBearing(this._startBearing+e*i*this._SENSITIVITY)}},_onUp:function(i){this._cleanup(),this._draggingWasEnabled&&this._map.dragging&&this._map.dragging.enable(),this._moved&&(t.DomEvent.preventDefault(i),this._map.fire("rotate"))},_cleanup:function(){t.DomEvent.off(document,"mousemove",this._onMove,this),t.DomEvent.off(document,"mouseup",this._onUp,this)}}),t.Map.addInitHook("addHandler","dragRotate",t.Map.DragRotate),t.Map.addInitHook(function(){this.options.rotate&&this.options.dragRotate&&this.dragRotate&&this.dragRotate.enable()});var x=t.Marker.prototype._initInteraction;t.Marker.prototype._initInteraction=function(){var i=x.call(this);if(this.dragging){var e=Object.getPrototypeOf(this.dragging);if(e&&e._onDrag&&!e._rotateOnDragPatched){e._rotateOnDragPatched=!0;var o=e._onDrag;e._onDrag=function(i){var e=this._marker,a=e._map;if(a&&a._rotate&&a._bearing){var n=t.DomUtil.getPosition(e._icon),s=a.mapPanePointToRotatedPoint(n),r=a.layerPointToLatLng(s);return e._shadow&&t.DomUtil.setPosition(e._shadow,n),e._latlng=r,i.latlng=r,i.oldLatLng=this._oldLatLng,void e.fire("move",i).fire("drag",i)}return o.call(this,i)}}}return i},t.Control.Rotate=t.Control.extend({options:{position:"topleft",behavior:"reset",closeOnZeroBearing:!0,enabled:!1},onAdd:function(i){this._map=i;var e=t.DomUtil.create("div","leaflet-control-rotate leaflet-bar"),o=t.DomUtil.create("a","leaflet-control-rotate-toggle",e);o.href="#",o.setAttribute("role","button");var a="toggle"===this.options.behavior?"Map rotation":"Reset rotation";return o.title=a,o.setAttribute("aria-label",a),o.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="22" height="22" fill-rule="evenodd" clip-rule="evenodd" style="display:block;transform-origin:center;transform-box:fill-box"><path fill="#ebebeb" stroke="#333" stroke-width=".6" d="m11.81.44 3.6 11.27h-7.2z"/><path fill="#b95358" stroke="#333" stroke-width=".6" d="m11.81 23.18-3.6-11.27h7.2z"/></svg>',this._needle=o.firstChild,this._link=o,this._container=e,t.DomEvent.disableClickPropagation(e),t.DomEvent.on(o,"click",this._onClick,this),i.on("rotate",this._updateDisplay,this),"toggle"===this.options.behavior?this.options.enabled?this._enableRotation():this._disableRotation():this._updateDisplay(),e},onRemove:function(i){i.off("rotate",this._updateDisplay,this),t.DomEvent.off(this._link,"click",this._onClick,this)},_onClick:function(i){t.DomEvent.stop(i),"toggle"===this.options.behavior?this._enabled?this._disableRotation():this._enableRotation():this._map.setBearing(0)},_disableRotation:function(){this._enabled=!1,this._map.dragRotate&&this._map.dragRotate.disable(),this._map.touchGestures&&this._map.touchGestures.disable(),this._map.touchZoom&&this._map.touchZoom.enable(),this._map.shiftKeyRotate&&this._map.shiftKeyRotate.disable(),this._map.setBearing(0),this._updateDisplay()},_enableRotation:function(){this._enabled=!0,this._map.dragRotate&&this._map.options.dragRotate&&this._map.dragRotate.enable(),this._map.touchGestures&&this._map.options.touchRotate&&(this._map.touchGestures.enable(),this._map.touchZoom&&this._map.touchZoom.disable()),this._map.shiftKeyRotate&&this._map.options.shiftKeyRotate&&this._map.shiftKeyRotate.enable(),this._updateDisplay()},_updateDisplay:function(){if(this._map&&this._link){var i=this._map.getBearing();this._needle&&(this._needle.style[t.DomUtil.TRANSFORM]="rotate("+-i+"deg)"),"toggle"===this.options.behavior?this._enabled?t.DomUtil.removeClass(this._container,"leaflet-control-rotate--inactive"):t.DomUtil.addClass(this._container,"leaflet-control-rotate--inactive"):this.options.closeOnZeroBearing&&(this._container.style.display=0===i?"none":"")}}}),t.control.rotate=function(i){return new t.Control.Rotate(i)},t.Map.addInitHook(function(){if(this.options.rotate&&this.options.rotateControl){var i=!0===this.options.rotateControl?{}:this.options.rotateControl;this.rotateControl=t.control.rotate(i),this.addControl(this.rotateControl)}}),t.Map.mergeOptions({preventPageGestures:!0}),t.Map.addInitHook(function(){if(this.options.preventPageGestures){var t=["gesturestart","gesturechange","gestureend"],i=function(t){t.preventDefault()};t.forEach(function(t){document.addEventListener(t,i,{passive:!1})}),this.on("unload",function(){t.forEach(function(t){document.removeEventListener(t,i,{passive:!1})})})}});const C=document.createElement("style");C.textContent=[".leaflet-rotate-pane { position: absolute; top: 0; left: 0; will-change: transform; }",".leaflet-norotate-pane { position: absolute; top: 0; left: 0; z-index: 600; }"].join("\n"),document.head.appendChild(C)});
1
+ /*! @tomickigrzegorz/leaflet-rotate v0.2.3 | MIT */
2
+ !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("leaflet")):"function"==typeof define&&define.amd?define(["leaflet"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).L)}(this,function(t){"use strict";t.Point.prototype.rotate=function(i){var e=Math.cos(i),o=Math.sin(i);return new t.Point(this.x*e-this.y*o,this.x*o+this.y*e)},t.Point.prototype.rotateFrom=function(t,i){return i?this.subtract(i).rotate(t).add(i):this.rotate(t)},t.DomUtil.setTransform=function(i,e,o,a,n){var s=e||new t.Point(0,0),r="translate3d("+s.x+"px,"+s.y+"px,0)";null!=o&&(r+=" scale("+o+")"),a&&(r+=" rotate("+a+"rad)"),i.style[t.DomUtil.TRANSFORM]=r,n&&(i.style[t.DomUtil.TRANSFORM+"Origin"]=n.x+"px "+n.y+"px")},t.DomUtil.setPosition=function(i,e,o,a){i._leaflet_pos=e,t.Browser.any3d?t.DomUtil.setTransform(i,e,void 0,o,a):(i.style.left=e.x+"px",i.style.top=e.y+"px")};const i=Math.PI/180,e=180/Math.PI;function o(t){return(t%360+360)%360}function a(t){return o(t+180)-180}function n(t){var i=2*Math.PI;return((t+Math.PI)%i+i)%i-Math.PI}function s(){return"undefined"!=typeof performance&&performance.now?performance.now():Date.now()}var r=t.Map.prototype;t.Map.mergeOptions({rotate:!1,bearing:0,touchRotate:!1,shiftKeyRotate:!1,dragRotate:!0,rotateControl:!1,rotateClockwise:!0});var h=r.initialize;r.initialize=function(t,i){i&&i.rotate&&(this._rotate=!0,this._bearing=0,this._bearingRad=0),h.call(this,t,i),this._rotate&&this.setBearing(i.bearing||0)};var _=r._initPanes;r._initPanes=function(){if(_.call(this),this._rotate){var i=this._mapPane;this._rotatePane=t.DomUtil.create("div","leaflet-rotate-pane",i),this._norotatePane=t.DomUtil.create("div","leaflet-norotate-pane",i),this._rotatePane.appendChild(this._panes.tilePane),this._rotatePane.appendChild(this._panes.overlayPane),this._norotatePane.appendChild(this._panes.shadowPane),this._norotatePane.appendChild(this._panes.markerPane),this._norotatePane.appendChild(this._panes.tooltipPane),this._norotatePane.appendChild(this._panes.popupPane),t.DomUtil.addClass(this._rotatePane,"leaflet-proxy leaflet-zoom-animated")}},r.setBearing=function(e){if(this._rotate){var a=this._bearing||0,n=o(e);if(n!==a){if(this._commitRotatePan(),this._bearing=n,this._bearingRad=n*i,this._updateRotatePaneTransform(),0===a!=(0===n))for(var s in this._layers){var r=this._layers[s];r instanceof t.Renderer&&r._update()}this.fire("rotate")}}},r.getBearing=function(){return this._bearing||0},r._updateRotatePaneTransform=function(){if(this._rotatePane){if(!this._bearing)return this._rotatePane.style[t.DomUtil.TRANSFORM]="",void(this._rotatePane.style[t.DomUtil.TRANSFORM+"Origin"]="");var i=this.getSize().divideBy(2);this._rotatePane.style[t.DomUtil.TRANSFORM+"Origin"]=i.x+"px "+i.y+"px",this._rotatePane.style[t.DomUtil.TRANSFORM]="rotate("+this._bearingRad+"rad)"}},r._commitRotatePan=function(){if(this._rotate&&!this._committingRotatePan){var t=this._getMapPanePos();!t||0===t.x&&0===t.y||(this._committingRotatePan=!0,this._resetView(this.getCenter(),this.getZoom(),!0),this._committingRotatePan=!1)}};var p=r.containerPointToLayerPoint;r.containerPointToLayerPoint=function(i){if(!this._rotate||!this._bearing)return p.call(this,i);var e=t.point(i),o=this._getMapPanePos(),a=this.getSize().divideBy(2);return e.subtract(o).subtract(a).rotate(-this._bearingRad).add(a)};var l=r.layerPointToContainerPoint;r.layerPointToContainerPoint=function(i){if(!this._rotate||!this._bearing)return l.call(this,i);var e=t.point(i),o=this._getMapPanePos(),a=this.getSize().divideBy(2);return e.subtract(a).rotate(this._bearingRad).add(a).add(o)},r.rotatedPointToMapPanePoint=function(i){if(!this._bearing)return t.point(i);var e=this.getSize().divideBy(2);return t.point(i).rotateFrom(this._bearingRad,e)},r.mapPanePointToRotatedPoint=function(i){if(!this._bearing)return t.point(i);var e=this.getSize().divideBy(2);return t.point(i).rotateFrom(-this._bearingRad,e)};var m=r._getCenterOffset;r._getCenterOffset=function(t){return this._rotate&&this._bearing?this.project(t).subtract(this.project(this.getCenter())).rotate(this._bearingRad):m.call(this,t)};var d=r.getBounds;r.getBounds=function(){if(!this._rotate||!this._bearing)return d.call(this);var i=this.getSize(),e=t.latLngBounds();return e.extend(this.containerPointToLatLng(t.point(0,0))),e.extend(this.containerPointToLatLng(t.point(i.x,0))),e.extend(this.containerPointToLatLng(t.point(i.x,i.y))),e.extend(this.containerPointToLatLng(t.point(0,i.y))),e},r.mapBoundsToContainerBounds=function(i){return t.bounds([this.latLngToContainerPoint(i.getNorthWest()),this.latLngToContainerPoint(i.getNorthEast()),this.latLngToContainerPoint(i.getSouthEast()),this.latLngToContainerPoint(i.getSouthWest())])};var c=r.getBoundsZoom;r.getBoundsZoom=function(i,e,o){if(!this._rotate||!this._bearing)return c.call(this,i,e,o);i=t.latLngBounds(i),o=t.point(o||[0,0]);var a=this.getZoom()||0,n=this.getMinZoom(),s=this.getMaxZoom(),r=this.getSize().subtract(o);if(r.x<=0||r.y<=0)return a;var h=this.mapBoundsToContainerBounds(i).getSize(),_=this.options.zoomSnap,p=r.x/h.x,l=r.y/h.y,m=e?Math.max(p,l):Math.min(p,l);return a=this.getScaleZoom(m,a),_&&(a=Math.round(a/_)*_),Math.max(n,Math.min(s,a))},r._animateZoomNoDelay=function(t,i,e){this._mapPane&&(e&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i),this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._onZoomTransitionEnd())};var u=r._tryAnimatedZoom;r._tryAnimatedZoom=function(t,i,e){if(this._rotate&&this._bearing&&!this._animatingZoom){var o=this._getMapPanePos();o&&(o.x||o.y)&&this._resetView(this.getCenter(),this.getZoom(),!0)}return u.call(this,t,i,e)},t.Map.addInitHook(function(){this._rotate&&this.on("resize",this._updateRotatePaneTransform,this)});var g=t.GridLayer.prototype.getEvents;t.GridLayer.prototype.getEvents=function(){var t=g.call(this);return this._map&&this._map._rotate&&(t.rotate=this._onRotate),t},t.GridLayer.prototype._onRotate=function(){this._update()};var f=t.GridLayer.prototype._invalidateAll;t.GridLayer.prototype._invalidateAll=function(){if(!this._map||!this._map._committingRotatePan)return f.call(this)};var v=t.GridLayer.prototype._getTiledPixelBounds;t.GridLayer.prototype._getTiledPixelBounds=function(i){if(!this._map._rotate||!this._map._bearing)return v.call(this,i);for(var e=this._map,o=e._animatingZoom?Math.max(e._animateToZoom,e.getZoom()):e.getZoom(),a=e.getZoomScale(o,this._tileZoom),n=e.project(i,this._tileZoom).floor(),s=e.getSize().divideBy(2*Math.min(a,1)).multiplyBy(1.25),r=new t.Bounds,h=[t.point(-s.x,-s.y),t.point(s.x,-s.y),t.point(s.x,s.y),t.point(-s.x,s.y)],_=0;_<4;_++)r.extend(n.add(h[_].rotate(-e._bearingRad)));return r};var y=t.Renderer.prototype.onAdd;t.Renderer.prototype.onAdd=function(i){y.call(this,i),i._rotate&&t.DomUtil.addClass(this._container,"leaflet-zoom-animated")};var R=t.Renderer.prototype._updateTransform;t.Renderer.prototype._updateTransform=function(i,e){if(!this._map||!this._map._rotate||!this._map._bearing)return R.call(this,i,e);if(this._bounds&&this._boundsMinLatLng){var o=this._map,a=o.getZoomScale(e,this._zoom),n=o._latLngToNewLayerPoint(this._boundsMinLatLng,e,i);t.DomUtil.setTransform(this._container,n,a)}};var P=t.Renderer.prototype._update;t.Renderer.prototype._update=function(){if(!this._map||!this._map._rotate||!this._map._bearing)return P.call(this);var i=Math.max(this.options.padding||0,1.5),e=this._map,o=e.getSize(),a=e.containerPointToLayerPoint(o.divideBy(2)),n=o.multiplyBy(.5+i),s=Math.ceil(Math.sqrt(n.x*n.x+n.y*n.y));this._bounds=new t.Bounds(a.subtract([s,s]).round(),a.add([s,s]).round()),this._center=e.getCenter(),this._zoom=e.getZoom(),this._boundsMinLatLng=e.layerPointToLatLng(this._bounds.min)};const T=t.Map.prototype;T.setHeading=function(t,i){return this._rotate?null==t||isNaN(t)?this.stopHeadingUp():(i=i||{},this._headingUp=!0,this._headingEase=null!=i.ease?i.ease:.2,this._headingDeadzone=null!=i.deadzone?i.deadzone:.5,this._headingTarget=o(-t),this._startHeadingAnim(),this):this},T.stopHeadingUp=function(){return this._headingUp=!1,this._headingRAF&&(t.Util.cancelAnimFrame(this._headingRAF),this._headingRAF=null),this},T.getHeadingUp=function(){return!!this._headingUp},T._startHeadingAnim=function(){this._headingRAF||(this._headingRAF=t.Util.requestAnimFrame(this._headingAnim,this))},T._headingAnim=function(){if(this._headingRAF=null,this._headingUp){var i=this.getBearing(),e=a(this._headingTarget-i);Math.abs(e)<this._headingDeadzone?Math.abs(e)>.001&&this.setBearing(this._headingTarget):(this.setBearing(i+e*this._headingEase),this._headingRAF=t.Util.requestAnimFrame(this._headingAnim,this))}},t.Marker.mergeOptions({rotation:0,rotateWithView:!1,scale:void 0});var M=t.Marker.prototype.getEvents;t.Marker.prototype.getEvents=function(){var t=M.call(this);return this._map&&this._map._rotate&&(t.rotate=this._rotateReposition,t.rotateend=this._rotateEnd),t};var b=t.Marker.prototype._setPos;function E(i,e){var o=i.options.rotation||0;if(i.options.rotateWithView&&(o+=e._bearing||0),o||i.options.scale){var a=t.DomUtil.getPosition(i._icon)||new t.Point(0,0),n="translate3d("+a.x+"px,"+a.y+"px,0)";o&&(n+=" rotate("+o+"deg)"),i.options.scale&&(n+=" scale("+i.options.scale+")"),i._icon.style[t.DomUtil.TRANSFORM]=n}}t.Marker.prototype._setPos=function(i){this._map&&this._map._rotate&&this._map._bearing&&(i=this._map.rotatedPointToMapPanePoint(i)),b?b.call(this,i):(t.DomUtil.setPosition(this._icon,i),this._shadow&&t.DomUtil.setPosition(this._shadow,i),this._zIndex=i.y+this.options.zIndexOffset,this._resetZIndex())};var D=t.Marker.prototype.update;t.Marker.prototype.update=function(){var t=D.call(this);return this._icon&&this._map&&E(this,this._map),t},t.Marker.prototype._rotateReposition=function(){var t,i=this._map;i&&this._icon&&(i._rotInertia&&this._rotLayerPt?t=this._rotLayerPt:(t=i.latLngToLayerPoint(this._latlng),i._rotInertia&&(this._rotLayerPt=t)),this._setPos(t),E(this,i))},t.Marker.prototype._rotateEnd=function(){this._rotLayerPt=null,this.update()};var A=t.Marker.prototype._resetZIndex;t.Marker.prototype._resetZIndex=function(){if(!this._map||!this._map._rotating)return A.call(this)};var L=t.Icon.prototype._setIconStyles;if(t.Icon.prototype._setIconStyles=function(i,e){L.call(this,i,e);var o=this.options.iconAnchor||this.options.shadowAnchor;o&&(i.style[t.DomUtil.TRANSFORM+"Origin"]=o[0]+"px "+o[1]+"px")},t.DivOverlay){var O=t.DivOverlay.prototype.getEvents;t.DivOverlay.prototype.getEvents=function(){var t=O.call(this);return this._map&&this._map._rotate&&(t.rotate=this._updatePosition),t}}if(t.Popup){var S=t.Popup.prototype._updatePosition;t.Popup.prototype._updatePosition=function(){if(this._map){if(!this._map._rotate||!this._map._bearing)return S.call(this);var i=this._map.latLngToLayerPoint(this._latlng),e=this._map.rotatedPointToMapPanePoint(i),o=t.point(this.options.offset),a=this._getAnchor();t.DomUtil.setPosition(this._container,e.add(a)),this._containerBottom=-o.y,this._containerLeft=-Math.round(this._containerWidth/2)+o.x,this._container.style.bottom=this._containerBottom+"px",this._container.style.left=this._containerLeft+"px"}};var x=t.Popup.prototype._animateZoom;t.Popup.prototype._animateZoom=function(i){if(!this._map||!this._map._rotate||!this._map._bearing)return x?x.call(this,i):void 0;var e=this._map._latLngToNewLayerPoint(this._latlng,i.zoom,i.center);e=this._map.rotatedPointToMapPanePoint(e);var o=this._getAnchor();t.DomUtil.setPosition(this._container,e.add(o))};var C=t.Popup.prototype._adjustPan;t.Popup.prototype._adjustPan=function(){this._map&&this._map._rotate||C&&C.call(this)}}if(t.Tooltip){var Z=t.Tooltip.prototype._updatePosition;t.Tooltip.prototype._updatePosition=function(){if(this._map){if(!this._map._rotate||!this._map._bearing)return Z.call(this);var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(this._map.rotatedPointToMapPanePoint(t))}};var B=t.Tooltip.prototype._animateZoom;t.Tooltip.prototype._animateZoom=function(t){if(!this._map||!this._map._rotate||!this._map._bearing)return B?B.call(this,t):void 0;var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);this._setPosition(this._map.rotatedPointToMapPanePoint(i))}}if(t.Map.TouchGestures=t.Handler.extend({_ROTATION_THRESHOLD:30*i,_SCALE_THRESHOLD:.04,_SCALE_THRESHOLD_ROT:.12,_MOVE_THRESHOLD:4,_ZOOM_EPS:.01,_PAN_EPS:2,_ZOOM_SNAP_STEP:0,_ROT_INERTIA:!0,_ROT_DECAY:.0018,_ROT_MIN_VELOCITY:.004,_ROT_MAX_VELOCITY:1.2,_ROT_VELOCITY_SMOOTH:.4,_ROT_STALE_MS:80,addHooks:function(){t.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this),t.DomEvent.on(this._map._container,"touchmove",this._onTouchMove,this),t.DomEvent.on(this._map._container,"touchend touchcancel",this._onTouchEnd,this)},removeHooks:function(){t.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this),t.DomEvent.off(this._map._container,"touchmove",this._onTouchMove,this),t.DomEvent.off(this._map._container,"touchend touchcancel",this._onTouchEnd,this)},_onTouchStart:function(i){if(this._stopRotateInertia(),i.touches&&2===i.touches.length){var e=this._map;e.dragging&&e.dragging.enabled()&&(this._draggingWasEnabled=!0,e.dragging.disable()),e._stop&&e._stop(),this._rotVelocity=0,this._lastRotTime=0,this._lastRotBearing=0,e.stopHeadingUp(),e._commitRotatePan();var o=e.mouseEventToContainerPoint(i.touches[0]),a=e.mouseEventToContainerPoint(i.touches[1]);this._startDist=o.distanceTo(a),this._startDist<1?this._active=!1:(this._touchZoomCenter="center"===e.options.touchZoom,this._centerPoint=e.getSize().divideBy(2),this._startCenter=e.getCenter(),this._startMidpoint=this._touchZoomCenter?this._centerPoint:o.add(a).divideBy(2),this._startAngle=Math.atan2(a.y-o.y,a.x-o.x),this._startBearing=e.getBearing(),this._startBearingRad=e._bearingRad||0,this._startZoom=e.getZoom(),this._anchorLatLng=this._touchZoomCenter?this._startCenter:e.containerPointToLatLng(this._startMidpoint),this._moved=!1,this._active=!0,this._rotationActive=!1,this._scaleActive=!1,this.zoom=!1,this._lastMoveZoom=this._startZoom,this._lastMoveMidpoint=this._startMidpoint,t.DomEvent.preventDefault(i))}else this._active=!1},_onTouchMove:function(i){if(i.touches&&2===i.touches.length&&this._active){var r=this._map,h=r.mouseEventToContainerPoint(i.touches[0]),_=r.mouseEventToContainerPoint(i.touches[1]),p=this._touchZoomCenter?this._centerPoint:h.add(_).divideBy(2),l=h.distanceTo(_),m=Math.atan2(_.y-h.y,_.x-h.x),d=p.distanceTo(this._startMidpoint),c=l/this._startDist,u=Math.abs(c-1),g=n(m-this._startAngle),f=r.options.touchRotate&&Math.abs(g)>this._ROTATION_THRESHOLD,v=u>(this._rotationActive?this._SCALE_THRESHOLD_ROT:this._SCALE_THRESHOLD),y=d>this._MOVE_THRESHOLD;if(!this._moved){if(!f&&!v&&!y)return void t.DomEvent.preventDefault(i);r._moveStart(!0,!1),this._moved=!0}var R=this._startZoom;!this._scaleActive&&v&&(this._scaleActive=!0),this._scaleActive&&(R=r.getScaleZoom(c,this._startZoom),!r.options.bounceAtZoomLimits&&(R<r.getMinZoom()&&c<1||R>r.getMaxZoom()&&c>1)&&(R=Math.max(r.getMinZoom(),Math.min(r.getMaxZoom(),R))),this._ZOOM_SNAP_STEP>0&&(R=Math.round(R/this._ZOOM_SNAP_STEP)*this._ZOOM_SNAP_STEP));var P=this._startBearingRad;if(r.options.touchRotate&&(this._rotationActive||Math.abs(g)>this._ROTATION_THRESHOLD&&(this._rotationActive=!0,this._rotRefAngle=m,r._rotating=!0,r.stopHeadingUp(),r.fire("rotatestart")),this._rotationActive)){var T=n(m-this._rotRefAngle),M=!1===r.options.rotateClockwise?-1:1,b=o(this._startBearing+M*T*e);r.setBearing(b),P=r._bearingRad||0;var E=s();if(this._lastRotTime){var D=E-this._lastRotTime;if(D>0){var A=a(b-this._lastRotBearing)/D,L=this._ROT_VELOCITY_SMOOTH;this._rotVelocity=(1-L)*(this._rotVelocity||0)+L*A}}this._lastRotTime=E,this._lastRotBearing=b}var O=Math.abs(R-this._lastMoveZoom)>this._ZOOM_EPS,S=p.distanceTo(this._lastMoveMidpoint)>this._PAN_EPS;if(this._scaleActive&&(O||S)){var x=r.getSize().divideBy(2),C=p.subtract(x),Z=r.project(this._anchorLatLng,R).subtract(C.rotate(-P)),B=r.unproject(Z,R);this._center=B,this._zoom=R,this.zoom=!0,this._lastMoveZoom=R,this._lastMoveMidpoint=p,this._animRequest&&t.Util.cancelAnimFrame(this._animRequest);var I=t.Util.bind(r._move,r,B,R,{pinch:!0,round:!1},void 0);this._animRequest=t.Util.requestAnimFrame(I,this,!0)}else this._scaleActive||(this._center=this._startCenter,this._zoom=this._startZoom,this.zoom=!1,this._animRequest&&(t.Util.cancelAnimFrame(this._animRequest),this._animRequest=null));t.DomEvent.preventDefault(i)}},_onTouchEnd:function(i){var e=this._map;this._draggingWasEnabled&&e.dragging&&(e.dragging.enable(),this._draggingWasEnabled=!1),this._active&&(this._active=!1,this._moved&&(this._animRequest&&(t.Util.cancelAnimFrame(this._animRequest),this._animRequest=null),this.zoom&&(e.options.zoomAnimation?e._animateZoom(this._center,e._limitZoom(this._zoom),!0,e.options.zoomSnap):e._resetView(this._center,e._limitZoom(this._zoom))),this._rotationActive&&(this._startRotateInertia()||(e._rotating=!1,e.fire("rotateend"))),this.zoom=!1))},_stopRotateInertia:function(){this._rotInertiaReq&&(t.Util.cancelAnimFrame(this._rotInertiaReq),this._rotInertiaReq=null);var i=this._map;i&&i._rotating&&(i._rotating=!1,i._rotInertia=!1,i.fire("rotateend"))},_startRotateInertia:function(){var i=this._map;if(!this._ROT_INERTIA)return!1;var e=s();if(!this._lastRotTime||e-this._lastRotTime>this._ROT_STALE_MS||Math.abs(this._rotVelocity||0)<this._ROT_MIN_VELOCITY)return!1;var o=this._rotVelocity,a=this._ROT_MAX_VELOCITY;o>a&&(o=a),o<-a&&(o=-a);var n=this._ROT_DECAY,r=this._ROT_MIN_VELOCITY,h=e,_=this;i._rotInertia=!0,i.fire("rotatestart");var p=function(){var e=s(),a=e-h;if(h=e,a<=0&&(a=16),o*=Math.exp(-n*a),Math.abs(o)<r)return _._rotInertiaReq=null,i._rotating=!1,i._rotInertia=!1,void i.fire("rotateend");i.setBearing(i.getBearing()+o*a),_._rotInertiaReq=t.Util.requestAnimFrame(p,_)};return this._rotInertiaReq=t.Util.requestAnimFrame(p,this),!0}}),t.Map.addInitHook("addHandler","touchGestures",t.Map.TouchGestures),t.Map.addInitHook(function(){this.options.rotate&&this.options.touchRotate&&(this.touchGestures&&this.touchGestures.enable(),this.touchZoom&&this.touchZoom.disable())}),t.Map.ShiftKeyRotate=t.Handler.extend({_ROTATE_STEP:5,_EASE:.2,addHooks:function(){t.DomEvent.on(this._map._container,"wheel",this._onWheel,this)},removeHooks:function(){t.DomEvent.off(this._map._container,"wheel",this._onWheel,this),this._stopAnim()},_onWheel:function(i){if(i.shiftKey){t.DomEvent.stop(i);var e=this._map;e.stopHeadingUp(),this._animating||(e._rotating=!0,e.fire("rotatestart"));var a=t.DomEvent.getWheelDelta(i),n=!1===e.options.rotateClockwise?-1:1;this._targetBearing=o(e.getBearing()-n*a*this._ROTATE_STEP),this._animating||this._startAnim()}},_startAnim:function(){this._animating||(this._animating=!0,this._animRequest=t.Util.requestAnimFrame(this._animate,this,!0))},_stopAnim:function(){this._animRequest&&(t.Util.cancelAnimFrame(this._animRequest),this._animRequest=null),this._animating&&(this._animating=!1,this._map._rotating=!1,this._map.fire("rotateend"))},_animate:function(){if(this._animating)if(void 0!==this._targetBearing&&null!==this._targetBearing){var i=this._map,e=i.getBearing(),o=a(this._targetBearing-e);if(Math.abs(o)<.1)return i.setBearing(this._targetBearing),void this._stopAnim();i.setBearing(e+o*this._EASE),this._animRequest=t.Util.requestAnimFrame(this._animate,this,!0)}else this._stopAnim()}}),t.Map.addInitHook("addHandler","shiftKeyRotate",t.Map.ShiftKeyRotate),t.Map.addInitHook(function(){this.options.rotate&&this.options.shiftKeyRotate&&this.shiftKeyRotate&&this.shiftKeyRotate.enable()}),t.Map.ScrollWheelZoom){var I=t.Map.ScrollWheelZoom.prototype._onWheelScroll;t.Map.ScrollWheelZoom.prototype._onWheelScroll=function(t){if(!(t.shiftKey&&this._map&&this._map._rotate&&this._map.options.shiftKeyRotate))return I.call(this,t)}}t.Map.DragRotate=t.Handler.extend({_SENSITIVITY:.5,addHooks:function(){t.DomEvent.on(this._map._container,"mousedown",this._onDown,this),t.DomEvent.on(this._map._container,"contextmenu",t.DomEvent.preventDefault)},removeHooks:function(){t.DomEvent.off(this._map._container,"mousedown",this._onDown,this),t.DomEvent.off(this._map._container,"contextmenu",t.DomEvent.preventDefault),this._cleanup()},_onDown:function(i){if(2===i.button){t.DomEvent.preventDefault(i),t.DomEvent.stopPropagation(i);var e=this._map;this._startX=i.clientX,this._startBearing=e.getBearing(),this._moved=!1,e.dragging&&e.dragging.enabled()?(this._draggingWasEnabled=!0,e.dragging.disable()):this._draggingWasEnabled=!1,t.DomEvent.on(document,"mousemove",this._onMove,this),t.DomEvent.on(document,"mouseup",this._onUp,this)}},_onMove:function(t){var i=t.clientX-this._startX;if(this._moved||!(Math.abs(i)<2)){this._moved||(this._moved=!0,this._map._rotating=!0,this._map.fire("rotatestart")),this._map.stopHeadingUp();var e=!1===this._map.options.rotateClockwise?-1:1;this._map.setBearing(this._startBearing+e*i*this._SENSITIVITY)}},_onUp:function(i){var e=this._moved;this._cleanup(),this._draggingWasEnabled&&this._map.dragging&&this._map.dragging.enable(),e&&t.DomEvent.preventDefault(i)},_cleanup:function(){t.DomEvent.off(document,"mousemove",this._onMove,this),t.DomEvent.off(document,"mouseup",this._onUp,this),this._moved&&(this._moved=!1,this._map._rotating=!1,this._map.fire("rotateend"))}}),t.Map.addInitHook("addHandler","dragRotate",t.Map.DragRotate),t.Map.addInitHook(function(){this.options.rotate&&this.options.dragRotate&&this.dragRotate&&this.dragRotate.enable()});var U=t.Marker.prototype._initInteraction;t.Marker.prototype._initInteraction=function(){var i=U.call(this);if(this.dragging){var e=Object.getPrototypeOf(this.dragging);if(e&&e._onDrag&&!e._rotateOnDragPatched){e._rotateOnDragPatched=!0;var o=e._onDrag;e._onDrag=function(i){var e=this._marker,a=e._map;if(a&&a._rotate&&a._bearing){var n=t.DomUtil.getPosition(e._icon),s=a.mapPanePointToRotatedPoint(n),r=a.layerPointToLatLng(s);return e._shadow&&t.DomUtil.setPosition(e._shadow,n),e._latlng=r,i.latlng=r,i.oldLatLng=this._oldLatLng,void e.fire("move",i).fire("drag",i)}return o.call(this,i)}}}return i},t.Control.Rotate=t.Control.extend({options:{position:"topleft",behavior:"reset",closeOnZeroBearing:!0,enabled:!1},onAdd:function(i){this._map=i;var e=t.DomUtil.create("div","leaflet-control-rotate leaflet-bar"),o=t.DomUtil.create("a","leaflet-control-rotate-toggle",e);o.href="#",o.setAttribute("role","button");var a="toggle"===this.options.behavior?"Map rotation":"Reset rotation";return o.title=a,o.setAttribute("aria-label",a),o.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="22" height="22" fill-rule="evenodd" clip-rule="evenodd" style="display:block;transform-origin:center;transform-box:fill-box"><path fill="#ebebeb" stroke="#333" stroke-width=".6" d="m11.81.44 3.6 11.27h-7.2z"/><path fill="#b95358" stroke="#333" stroke-width=".6" d="m11.81 23.18-3.6-11.27h7.2z"/></svg>',this._needle=o.firstChild,this._link=o,this._container=e,t.DomEvent.disableClickPropagation(e),t.DomEvent.on(o,"click",this._onClick,this),i.on("rotate",this._updateDisplay,this),"toggle"===this.options.behavior?this.options.enabled?this._enableRotation():this._disableRotation():this._updateDisplay(),e},onRemove:function(i){i.off("rotate",this._updateDisplay,this),t.DomEvent.off(this._link,"click",this._onClick,this)},_onClick:function(i){t.DomEvent.stop(i),"toggle"===this.options.behavior?this._enabled?this._disableRotation():this._enableRotation():this._map.setBearing(0)},_disableRotation:function(){this._enabled=!1,this._map.dragRotate&&this._map.dragRotate.disable(),this._map.touchGestures&&this._map.touchGestures.disable(),this._map.touchZoom&&this._map.touchZoom.enable(),this._map.shiftKeyRotate&&this._map.shiftKeyRotate.disable(),this._map.setBearing(0),this._updateDisplay()},_enableRotation:function(){this._enabled=!0,this._map.dragRotate&&this._map.options.dragRotate&&this._map.dragRotate.enable(),this._map.touchGestures&&this._map.options.touchRotate&&(this._map.touchGestures.enable(),this._map.touchZoom&&this._map.touchZoom.disable()),this._map.shiftKeyRotate&&this._map.options.shiftKeyRotate&&this._map.shiftKeyRotate.enable(),this._updateDisplay()},_updateDisplay:function(){if(this._map&&this._link){var i=this._map.getBearing();this._needle&&(this._needle.style[t.DomUtil.TRANSFORM]="rotate("+-i+"deg)"),"toggle"===this.options.behavior?this._enabled?t.DomUtil.removeClass(this._container,"leaflet-control-rotate--inactive"):t.DomUtil.addClass(this._container,"leaflet-control-rotate--inactive"):this.options.closeOnZeroBearing&&(this._container.style.display=0===i?"none":"")}}}),t.control.rotate=function(i){return new t.Control.Rotate(i)},t.Map.addInitHook(function(){if(this.options.rotate&&this.options.rotateControl){var i=!0===this.options.rotateControl?{}:this.options.rotateControl;this.rotateControl=t.control.rotate(i),this.addControl(this.rotateControl)}}),t.Map.mergeOptions({preventPageGestures:!0}),t.Map.addInitHook(function(){if(this.options.preventPageGestures){var t=["gesturestart","gesturechange","gestureend"],i=function(t){t.preventDefault()};t.forEach(function(t){document.addEventListener(t,i,{passive:!1})}),this.on("unload",function(){t.forEach(function(t){document.removeEventListener(t,i,{passive:!1})})})}});const H="leaflet-rotate-panes";if("undefined"!=typeof document&&!document.getElementById(H)){const t=document.createElement("style");t.id=H,t.textContent=[".leaflet-rotate-pane { position: absolute; top: 0; left: 0; will-change: transform; }",".leaflet-norotate-pane { position: absolute; top: 0; left: 0; z-index: 600; }"].join("\n"),document.head.appendChild(t)}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomickigrzegorz/leaflet-rotate",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Leaflet map rotation engine: bearing, heading-up, touch/drag/keyboard rotate, compass control.",
5
5
  "type": "module",
6
6
  "publishConfig": {