@deck.gl/widgets 9.3.0-beta.1 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dist.dev.js CHANGED
@@ -659,26 +659,65 @@ var __exports__ = (() => {
659
659
  ] });
660
660
  B(ui, rootElement);
661
661
  }
662
- handleZoom(viewId, nextZoom, delta) {
662
+ isOrthographicView(viewId) {
663
+ const deck = this.deck;
664
+ const view = deck?.isInitialized && deck.getView(viewId);
665
+ return view instanceof import_core2.OrthographicView;
666
+ }
667
+ handleZoom(viewId, delta) {
663
668
  const viewState = this.getViewState(viewId);
664
- if (viewState) {
665
- const { minZoom, maxZoom } = viewState;
666
- if (Number.isFinite(minZoom)) {
667
- nextZoom = Math.max(minZoom, nextZoom);
668
- }
669
- if (Number.isFinite(maxZoom)) {
670
- nextZoom = Math.min(maxZoom, nextZoom);
669
+ const newViewState = {};
670
+ if (this.isOrthographicView(viewId)) {
671
+ const { zoomAxis } = this.props;
672
+ const { zoomX, minZoomX, maxZoomX, zoomY, minZoomY, maxZoomY } = normalizeOrthographicViewState(
673
+ viewState
674
+ );
675
+ let nextZoom;
676
+ let nextZoomY;
677
+ if (zoomAxis === "X") {
678
+ nextZoom = clamp(zoomX + delta, minZoomX, maxZoomX);
679
+ nextZoomY = zoomY;
680
+ } else if (zoomAxis === "Y") {
681
+ nextZoom = zoomX;
682
+ nextZoomY = clamp(zoomY + delta, minZoomY, maxZoomY);
683
+ } else {
684
+ const clampedDelta = clamp(
685
+ delta,
686
+ Math.max(minZoomX - zoomX, minZoomY - zoomY),
687
+ Math.min(maxZoomX - zoomX, maxZoomY - zoomY)
688
+ );
689
+ nextZoom = zoomX + clampedDelta;
690
+ nextZoomY = zoomY + clampedDelta;
671
691
  }
692
+ newViewState.zoom = [nextZoom, nextZoomY];
693
+ newViewState.zoomX = nextZoom;
694
+ newViewState.zoomY = nextZoomY;
695
+ this.props.onZoom?.({
696
+ viewId,
697
+ delta,
698
+ // `zoom` will not match the new state if using 2D zoom. Deprecated behavior for backward compatibility.
699
+ zoom: zoomAxis === "Y" ? nextZoomY : nextZoom,
700
+ zoomX: nextZoom,
701
+ zoomY: nextZoomY
702
+ });
703
+ } else {
704
+ const { zoom = 0, minZoom, maxZoom } = viewState;
705
+ const nextZoom = clamp(zoom + delta, minZoom, maxZoom);
706
+ newViewState.zoom = nextZoom;
707
+ this.props.onZoom?.({
708
+ viewId,
709
+ delta,
710
+ zoom: nextZoom
711
+ });
672
712
  }
673
- this.props.onZoom?.({ viewId, delta, zoom: nextZoom });
674
713
  const nextViewState = {
675
714
  ...viewState,
676
- zoom: nextZoom
715
+ ...newViewState
677
716
  };
678
717
  if (this.props.transitionDuration > 0) {
679
718
  nextViewState.transitionDuration = this.props.transitionDuration;
680
719
  nextViewState.transitionInterpolator = "latitude" in nextViewState ? new import_core2.FlyToInterpolator() : new import_core2.LinearInterpolator({
681
- transitionProps: ["zoom"]
720
+ transitionProps: "zoomX" in newViewState ? ["zoomX", "zoomY"] : ["zoom"]
682
721
  });
683
722
  }
684
723
  this.setViewState(viewId, nextViewState);
@@ -686,15 +725,13 @@ var __exports__ = (() => {
686
725
  handleZoomIn() {
687
726
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v3) => v3.id) ?? [];
688
727
  for (const viewId of viewIds) {
689
- const viewState = this.getViewState(viewId);
690
- this.handleZoom(viewId, viewState.zoom + 1, 1);
728
+ this.handleZoom(viewId, 1);
691
729
  }
692
730
  }
693
731
  handleZoomOut() {
694
732
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v3) => v3.id) ?? [];
695
733
  for (const viewId of viewIds) {
696
- const viewState = this.getViewState(viewId);
697
- this.handleZoom(viewId, viewState.zoom - 1, -1);
734
+ this.handleZoom(viewId, -1);
698
735
  }
699
736
  }
700
737
  };
@@ -706,10 +743,29 @@ var __exports__ = (() => {
706
743
  transitionDuration: 200,
707
744
  zoomInLabel: "Zoom In",
708
745
  zoomOutLabel: "Zoom Out",
746
+ zoomAxis: "all",
709
747
  viewId: null,
710
748
  onZoom: () => {
711
749
  }
712
750
  };
751
+ function clamp(zoom, minZoom, maxZoom) {
752
+ return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
753
+ }
754
+ function normalizeOrthographicViewState({
755
+ zoom = 0,
756
+ zoomX,
757
+ zoomY,
758
+ minZoom = -Infinity,
759
+ maxZoom = Infinity,
760
+ minZoomX = minZoom,
761
+ maxZoomX = maxZoom,
762
+ minZoomY = minZoom,
763
+ maxZoomY = maxZoom
764
+ }) {
765
+ zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
766
+ zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
767
+ return { zoomX, zoomY, minZoomX, minZoomY, maxZoomX, maxZoomY };
768
+ }
713
769
 
714
770
  // src/reset-view-widget.tsx
715
771
  var import_core3 = __toESM(require_core(), 1);
@@ -1921,7 +1977,7 @@ var __exports__ = (() => {
1921
1977
  bottom: "top",
1922
1978
  top: "bottom"
1923
1979
  };
1924
- function clamp(start, value, end) {
1980
+ function clamp2(start, value, end) {
1925
1981
  return max(start, min(value, end));
1926
1982
  }
1927
1983
  function evaluate(value, param) {
@@ -2281,7 +2337,7 @@ var __exports__ = (() => {
2281
2337
  const min$1 = minPadding;
2282
2338
  const max2 = clientSize - arrowDimensions[length] - maxPadding;
2283
2339
  const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
2284
- const offset3 = clamp(min$1, center, max2);
2340
+ const offset3 = clamp2(min$1, center, max2);
2285
2341
  const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset3 && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
2286
2342
  const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max2 : 0;
2287
2343
  return {
@@ -2519,14 +2575,14 @@ var __exports__ = (() => {
2519
2575
  const maxSide = mainAxis === "y" ? "bottom" : "right";
2520
2576
  const min2 = mainAxisCoord + overflow[minSide];
2521
2577
  const max2 = mainAxisCoord - overflow[maxSide];
2522
- mainAxisCoord = clamp(min2, mainAxisCoord, max2);
2578
+ mainAxisCoord = clamp2(min2, mainAxisCoord, max2);
2523
2579
  }
2524
2580
  if (checkCrossAxis) {
2525
2581
  const minSide = crossAxis === "y" ? "top" : "left";
2526
2582
  const maxSide = crossAxis === "y" ? "bottom" : "right";
2527
2583
  const min2 = crossAxisCoord + overflow[minSide];
2528
2584
  const max2 = crossAxisCoord - overflow[maxSide];
2529
- crossAxisCoord = clamp(min2, crossAxisCoord, max2);
2585
+ crossAxisCoord = clamp2(min2, crossAxisCoord, max2);
2530
2586
  }
2531
2587
  const limitedCoords = limiter.fn({
2532
2588
  ...state,
@@ -3744,7 +3800,7 @@ var __exports__ = (() => {
3744
3800
 
3745
3801
  // src/lib/components/range-input.tsx
3746
3802
  var wheelListenerOptions = { passive: false };
3747
- var clamp2 = (value, min2, max2) => {
3803
+ var clamp3 = (value, min2, max2) => {
3748
3804
  if (value < min2) {
3749
3805
  return min2;
3750
3806
  }
@@ -3800,7 +3856,7 @@ var __exports__ = (() => {
3800
3856
  const range = max2 - min2;
3801
3857
  const rangeSize = Math.max(0, value[1] - value[0]);
3802
3858
  const maxStart = Math.max(0, range - rangeSize);
3803
- const clampedStart = clamp2(value[0], min2, min2 + maxStart);
3859
+ const clampedStart = clamp3(value[0], min2, min2 + maxStart);
3804
3860
  const { thumbLength, thumbOffset } = T2(() => {
3805
3861
  if (trackLength <= 0 || range <= 0) {
3806
3862
  return { thumbLength: 0, thumbOffset: 0 };
@@ -3810,7 +3866,7 @@ var __exports__ = (() => {
3810
3866
  }
3811
3867
  const nextThumbLength = rangeSize / range;
3812
3868
  const travel = Math.max(0, 1 - nextThumbLength);
3813
- const ratio = maxStart <= 0 ? 0 : clamp2((clampedStart - min2) / maxStart, 0, 1);
3869
+ const ratio = maxStart <= 0 ? 0 : clamp3((clampedStart - min2) / maxStart, 0, 1);
3814
3870
  return {
3815
3871
  thumbLength: Math.max(0, Math.min(nextThumbLength, 1)),
3816
3872
  thumbOffset: travel * ratio
@@ -3821,7 +3877,7 @@ var __exports__ = (() => {
3821
3877
  if (!onChange) {
3822
3878
  return;
3823
3879
  }
3824
- const clamped = clamp2(nextStart, min2, min2 + maxStart);
3880
+ const clamped = clamp3(nextStart, min2, min2 + maxStart);
3825
3881
  onChange([clamped, clamped + rangeSize]);
3826
3882
  },
3827
3883
  [onChange, min2, maxStart, rangeSize]
@@ -3859,7 +3915,7 @@ var __exports__ = (() => {
3859
3915
  const coordinate = vertical ? event.clientY - trackStart : event.clientX - trackStart;
3860
3916
  const span = Math.max(1, 1 - thumbLength) * trackLength;
3861
3917
  const thumbCenter = thumbLength / 2 * trackLength;
3862
- const ratio = span <= 0 ? 0 : clamp2((coordinate - thumbCenter) / span, 0, 1);
3918
+ const ratio = span <= 0 ? 0 : clamp3((coordinate - thumbCenter) / span, 0, 1);
3863
3919
  emitRange(min2 + ratio * maxStart);
3864
3920
  },
3865
3921
  [vertical, trackLength, thumbLength, emitRange, min2, maxStart]
@@ -3894,7 +3950,7 @@ var __exports__ = (() => {
3894
3950
  const coordinate = vertical ? event.clientY : event.clientX;
3895
3951
  const delta = coordinate - state.startCoord;
3896
3952
  const ratio = state.startRatio + delta / trackLength2;
3897
- const nextStart = clamp2(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
3953
+ const nextStart = clamp3(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
3898
3954
  emitRange(nextStart);
3899
3955
  event.preventDefault();
3900
3956
  },
@@ -4084,7 +4140,7 @@ var __exports__ = (() => {
4084
4140
  }
4085
4141
 
4086
4142
  // src/scrollbar-widget.tsx
4087
- var clamp3 = (value, min2, max2) => {
4143
+ var clamp4 = (value, min2, max2) => {
4088
4144
  if (value < min2) {
4089
4145
  return min2;
4090
4146
  }
@@ -4213,7 +4269,7 @@ var __exports__ = (() => {
4213
4269
  }
4214
4270
  getClampedOffset() {
4215
4271
  const maxScroll = this.getMaxScroll();
4216
- return clamp3(this.scrollOffset, 0, maxScroll);
4272
+ return clamp4(this.scrollOffset, 0, maxScroll);
4217
4273
  }
4218
4274
  isVertical() {
4219
4275
  return this.props.orientation !== "horizontal";
@@ -4232,7 +4288,7 @@ var __exports__ = (() => {
4232
4288
  }
4233
4289
  emitScroll(next) {
4234
4290
  const maxScroll = this.getMaxScroll();
4235
- const target = clamp3(Math.round(next), 0, maxScroll);
4291
+ const target = clamp4(Math.round(next), 0, maxScroll);
4236
4292
  const viewport = this.viewport;
4237
4293
  if (viewport && target !== this.getClampedOffset()) {
4238
4294
  const pixel = viewport.project(viewport.position);
package/dist/index.cjs CHANGED
@@ -110,27 +110,60 @@ var ZoomWidget = class extends import_core.Widget {
110
110
  const ui = (0, import_jsx_runtime3.jsxs)(ButtonGroup, { orientation: this.props.orientation, children: [(0, import_jsx_runtime3.jsx)(IconButton, { onClick: () => this.handleZoomIn(), label: this.props.zoomInLabel, className: "deck-widget-zoom-in" }), (0, import_jsx_runtime3.jsx)(IconButton, { onClick: () => this.handleZoomOut(), label: this.props.zoomOutLabel, className: "deck-widget-zoom-out" })] });
111
111
  (0, import_preact.render)(ui, rootElement);
112
112
  }
113
- handleZoom(viewId, nextZoom, delta) {
114
- var _a, _b;
113
+ isOrthographicView(viewId) {
114
+ const deck = this.deck;
115
+ const view = (deck == null ? void 0 : deck.isInitialized) && deck.getView(viewId);
116
+ return view instanceof import_core.OrthographicView;
117
+ }
118
+ handleZoom(viewId, delta) {
119
+ var _a, _b, _c, _d;
115
120
  const viewState = this.getViewState(viewId);
116
- if (viewState) {
117
- const { minZoom, maxZoom } = viewState;
118
- if (Number.isFinite(minZoom)) {
119
- nextZoom = Math.max(minZoom, nextZoom);
120
- }
121
- if (Number.isFinite(maxZoom)) {
122
- nextZoom = Math.min(maxZoom, nextZoom);
121
+ const newViewState = {};
122
+ if (this.isOrthographicView(viewId)) {
123
+ const { zoomAxis } = this.props;
124
+ const { zoomX, minZoomX, maxZoomX, zoomY, minZoomY, maxZoomY } = normalizeOrthographicViewState(viewState);
125
+ let nextZoom;
126
+ let nextZoomY;
127
+ if (zoomAxis === "X") {
128
+ nextZoom = clamp(zoomX + delta, minZoomX, maxZoomX);
129
+ nextZoomY = zoomY;
130
+ } else if (zoomAxis === "Y") {
131
+ nextZoom = zoomX;
132
+ nextZoomY = clamp(zoomY + delta, minZoomY, maxZoomY);
133
+ } else {
134
+ const clampedDelta = clamp(delta, Math.max(minZoomX - zoomX, minZoomY - zoomY), Math.min(maxZoomX - zoomX, maxZoomY - zoomY));
135
+ nextZoom = zoomX + clampedDelta;
136
+ nextZoomY = zoomY + clampedDelta;
123
137
  }
138
+ newViewState.zoom = [nextZoom, nextZoomY];
139
+ newViewState.zoomX = nextZoom;
140
+ newViewState.zoomY = nextZoomY;
141
+ (_b = (_a = this.props).onZoom) == null ? void 0 : _b.call(_a, {
142
+ viewId,
143
+ delta,
144
+ // `zoom` will not match the new state if using 2D zoom. Deprecated behavior for backward compatibility.
145
+ zoom: zoomAxis === "Y" ? nextZoomY : nextZoom,
146
+ zoomX: nextZoom,
147
+ zoomY: nextZoomY
148
+ });
149
+ } else {
150
+ const { zoom = 0, minZoom, maxZoom } = viewState;
151
+ const nextZoom = clamp(zoom + delta, minZoom, maxZoom);
152
+ newViewState.zoom = nextZoom;
153
+ (_d = (_c = this.props).onZoom) == null ? void 0 : _d.call(_c, {
154
+ viewId,
155
+ delta,
156
+ zoom: nextZoom
157
+ });
124
158
  }
125
- (_b = (_a = this.props).onZoom) == null ? void 0 : _b.call(_a, { viewId, delta, zoom: nextZoom });
126
159
  const nextViewState = {
127
160
  ...viewState,
128
- zoom: nextZoom
161
+ ...newViewState
129
162
  };
130
163
  if (this.props.transitionDuration > 0) {
131
164
  nextViewState.transitionDuration = this.props.transitionDuration;
132
165
  nextViewState.transitionInterpolator = "latitude" in nextViewState ? new import_core.FlyToInterpolator() : new import_core.LinearInterpolator({
133
- transitionProps: ["zoom"]
166
+ transitionProps: "zoomX" in newViewState ? ["zoomX", "zoomY"] : ["zoom"]
134
167
  });
135
168
  }
136
169
  this.setViewState(viewId, nextViewState);
@@ -139,16 +172,14 @@ var ZoomWidget = class extends import_core.Widget {
139
172
  var _a;
140
173
  const viewIds = this.viewId ? [this.viewId] : ((_a = this.deck) == null ? void 0 : _a.getViews().map((v) => v.id)) ?? [];
141
174
  for (const viewId of viewIds) {
142
- const viewState = this.getViewState(viewId);
143
- this.handleZoom(viewId, viewState.zoom + 1, 1);
175
+ this.handleZoom(viewId, 1);
144
176
  }
145
177
  }
146
178
  handleZoomOut() {
147
179
  var _a;
148
180
  const viewIds = this.viewId ? [this.viewId] : ((_a = this.deck) == null ? void 0 : _a.getViews().map((v) => v.id)) ?? [];
149
181
  for (const viewId of viewIds) {
150
- const viewState = this.getViewState(viewId);
151
- this.handleZoom(viewId, viewState.zoom - 1, -1);
182
+ this.handleZoom(viewId, -1);
152
183
  }
153
184
  }
154
185
  };
@@ -160,10 +191,19 @@ ZoomWidget.defaultProps = {
160
191
  transitionDuration: 200,
161
192
  zoomInLabel: "Zoom In",
162
193
  zoomOutLabel: "Zoom Out",
194
+ zoomAxis: "all",
163
195
  viewId: null,
164
196
  onZoom: () => {
165
197
  }
166
198
  };
199
+ function clamp(zoom, minZoom, maxZoom) {
200
+ return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
201
+ }
202
+ function normalizeOrthographicViewState({ zoom = 0, zoomX, zoomY, minZoom = -Infinity, maxZoom = Infinity, minZoomX = minZoom, maxZoomX = maxZoom, minZoomY = minZoom, maxZoomY = maxZoom }) {
203
+ zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
204
+ zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
205
+ return { zoomX, zoomY, minZoomX, minZoomY, maxZoomX, maxZoomY };
206
+ }
167
207
 
168
208
  // dist/reset-view-widget.js
169
209
  var import_jsx_runtime4 = require("preact/jsx-runtime");
@@ -1500,7 +1540,7 @@ var import_preact12 = require("preact");
1500
1540
  var import_jsx_runtime17 = require("preact/jsx-runtime");
1501
1541
  var import_hooks6 = require("preact/hooks");
1502
1542
  var wheelListenerOptions = { passive: false };
1503
- var clamp = (value, min, max) => {
1543
+ var clamp2 = (value, min, max) => {
1504
1544
  if (value < min) {
1505
1545
  return min;
1506
1546
  }
@@ -1542,7 +1582,7 @@ function RangeInput(props) {
1542
1582
  const range = max - min;
1543
1583
  const rangeSize = Math.max(0, value[1] - value[0]);
1544
1584
  const maxStart = Math.max(0, range - rangeSize);
1545
- const clampedStart = clamp(value[0], min, min + maxStart);
1585
+ const clampedStart = clamp2(value[0], min, min + maxStart);
1546
1586
  const { thumbLength, thumbOffset } = (0, import_hooks6.useMemo)(() => {
1547
1587
  if (trackLength <= 0 || range <= 0) {
1548
1588
  return { thumbLength: 0, thumbOffset: 0 };
@@ -1552,7 +1592,7 @@ function RangeInput(props) {
1552
1592
  }
1553
1593
  const nextThumbLength = rangeSize / range;
1554
1594
  const travel = Math.max(0, 1 - nextThumbLength);
1555
- const ratio = maxStart <= 0 ? 0 : clamp((clampedStart - min) / maxStart, 0, 1);
1595
+ const ratio = maxStart <= 0 ? 0 : clamp2((clampedStart - min) / maxStart, 0, 1);
1556
1596
  return {
1557
1597
  thumbLength: Math.max(0, Math.min(nextThumbLength, 1)),
1558
1598
  thumbOffset: travel * ratio
@@ -1562,7 +1602,7 @@ function RangeInput(props) {
1562
1602
  if (!onChange) {
1563
1603
  return;
1564
1604
  }
1565
- const clamped = clamp(nextStart, min, min + maxStart);
1605
+ const clamped = clamp2(nextStart, min, min + maxStart);
1566
1606
  onChange([clamped, clamped + rangeSize]);
1567
1607
  }, [onChange, min, maxStart, rangeSize]);
1568
1608
  const handleStepNegative = (0, import_hooks6.useCallback)((event) => {
@@ -1591,7 +1631,7 @@ function RangeInput(props) {
1591
1631
  const coordinate = vertical ? event.clientY - trackStart : event.clientX - trackStart;
1592
1632
  const span = Math.max(1, 1 - thumbLength) * trackLength;
1593
1633
  const thumbCenter = thumbLength / 2 * trackLength;
1594
- const ratio = span <= 0 ? 0 : clamp((coordinate - thumbCenter) / span, 0, 1);
1634
+ const ratio = span <= 0 ? 0 : clamp2((coordinate - thumbCenter) / span, 0, 1);
1595
1635
  emitRange(min + ratio * maxStart);
1596
1636
  }, [vertical, trackLength, thumbLength, emitRange, min, maxStart]);
1597
1637
  const handleThumbPointerDown = (event) => {
@@ -1623,7 +1663,7 @@ function RangeInput(props) {
1623
1663
  const coordinate = vertical ? event.clientY : event.clientX;
1624
1664
  const delta = coordinate - state.startCoord;
1625
1665
  const ratio = state.startRatio + delta / trackLength2;
1626
- const nextStart = clamp(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
1666
+ const nextStart = clamp2(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
1627
1667
  emitRange(nextStart);
1628
1668
  event.preventDefault();
1629
1669
  }, [emitRange, vertical]);
@@ -1754,7 +1794,7 @@ function RangeInput(props) {
1754
1794
  }
1755
1795
 
1756
1796
  // dist/scrollbar-widget.js
1757
- var clamp2 = (value, min, max) => {
1797
+ var clamp3 = (value, min, max) => {
1758
1798
  if (value < min) {
1759
1799
  return min;
1760
1800
  }
@@ -1862,7 +1902,7 @@ var ScrollbarWidget = class extends import_core13.Widget {
1862
1902
  }
1863
1903
  getClampedOffset() {
1864
1904
  const maxScroll = this.getMaxScroll();
1865
- return clamp2(this.scrollOffset, 0, maxScroll);
1905
+ return clamp3(this.scrollOffset, 0, maxScroll);
1866
1906
  }
1867
1907
  isVertical() {
1868
1908
  return this.props.orientation !== "horizontal";
@@ -1881,7 +1921,7 @@ var ScrollbarWidget = class extends import_core13.Widget {
1881
1921
  }
1882
1922
  emitScroll(next) {
1883
1923
  const maxScroll = this.getMaxScroll();
1884
- const target = clamp2(Math.round(next), 0, maxScroll);
1924
+ const target = clamp3(Math.round(next), 0, maxScroll);
1885
1925
  const viewport = this.viewport;
1886
1926
  if (viewport && target !== this.getClampedOffset()) {
1887
1927
  const pixel = viewport.project(viewport.position);