Skip to content

Commit 1a35006

Browse files
mfkj8866hongkai1991cursoragent
authored
fix(map): allow grabbing the map during inertial pan (#1961)
* fix(map): allow grabbing the map during inertial pan jumpTo resets drag handlers, so skip applyView while a pan or rotate gesture is active. Fixes #1959. Co-authored-by: Cursor <cursoragent@cursor.com> * test(map): cover applyView skip while dragRotate is active Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: hongkai <179992106@qq.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 7839ed0 commit 1a35006

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

packages/map/src/map-controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,8 @@ export class MapController {
11211121

11221122
applyView(view: MapViewState): void {
11231123
if (!this.map) return;
1124+
// jumpTo stop()s drag handlers, so skip while the user is still panning.
1125+
if (this.map.dragPan.isActive() || this.map.dragRotate.isActive()) return;
11241126
this.map.jumpTo(constrainMapView(view, this.mapPreferences, this.map));
11251127
}
11261128

tests/map-controller.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ function makeFakeMap(initialBasemapLayers: string[] = ["basemap-bg"]): {
180180
// A laid-out viewport, so the camera helpers that scale with the canvas
181181
// (the globe-safe fit ceiling) have a real size to work from.
182182
getCanvas: () => ({ clientWidth: 576, clientHeight: 648 }),
183+
jumpTo: record("jumpTo"),
184+
dragPan: { isActive: () => false },
185+
dragRotate: { isActive: () => false },
183186
flyTo: record("flyTo"),
184187
fitBounds: record("fitBounds"),
185188
cameraForBounds: (...args: unknown[]) => {
@@ -868,6 +871,57 @@ describe("MapController camera and query helpers", () => {
868871
});
869872
});
870873

874+
it("does not jumpTo while the user is dragging, so inertia can be grabbed", () => {
875+
const { map, fake } = makeFakeMap();
876+
(map as { dragPan: { isActive: () => boolean } }).dragPan = { isActive: () => true };
877+
const controller = controllerWith(map);
878+
879+
controller.applyView({
880+
center: [12, 48],
881+
zoom: 6,
882+
bearing: 0,
883+
pitch: 0,
884+
});
885+
886+
assert.ok(
887+
!fake.calls.some((c) => c.method === "jumpTo"),
888+
"jumpTo would Camera.stop() the in-progress drag",
889+
);
890+
});
891+
892+
it("does not jumpTo while the user is rotating", () => {
893+
const { map, fake } = makeFakeMap();
894+
(map as { dragRotate: { isActive: () => boolean } }).dragRotate = {
895+
isActive: () => true,
896+
};
897+
const controller = controllerWith(map);
898+
899+
controller.applyView({
900+
center: [12, 48],
901+
zoom: 6,
902+
bearing: 0,
903+
pitch: 0,
904+
});
905+
906+
assert.ok(!fake.calls.some((c) => c.method === "jumpTo"));
907+
});
908+
909+
it("jumps when the user is not dragging", () => {
910+
const { map, fake } = makeFakeMap();
911+
const controller = controllerWith(map);
912+
913+
controller.applyView({
914+
center: [12, 48],
915+
zoom: 6,
916+
bearing: 0,
917+
pitch: 0,
918+
});
919+
920+
const jump = fake.calls.find((c) => c.method === "jumpTo");
921+
assert.ok(jump);
922+
assert.deepEqual((jump.args[0] as { center: [number, number] }).center, [12, 48]);
923+
});
924+
871925
it("normalizes the projection to globe/mercator", () => {
872926
const { map } = makeFakeMap();
873927
const controller = controllerWith(map);

0 commit comments

Comments
 (0)