Skip to content

Commit d9daf27

Browse files
authored
Fix: prevent map from re-zooming on UI state changes (#336)
1 parent 601a5ce commit d9daf27

File tree

1 file changed

+73
-42
lines changed

1 file changed

+73
-42
lines changed

src/components/map/index.tsx

Lines changed: 73 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ export const MapComponent = () => {
8686
const directionsPanelOpen = useCommonStore(
8787
(state) => state.directionsPanelOpen
8888
);
89-
const settingsPanelOpen = useCommonStore((state) => state.settingsPanelOpen);
9089
const updateSettings = useCommonStore((state) => state.updateSettings);
9190
const setMapReady = useCommonStore((state) => state.setMapReady);
9291
const { profile, style } = useSearch({ from: '/$activeTab' });
@@ -421,49 +420,81 @@ export const MapComponent = () => {
421420
return newMarkers;
422421
}, [waypoints, geocodeResults]);
423422

424-
// Zoom to coordinates
423+
//Stores the route content
424+
const lastZoomedCoordKeyRef = useRef<string | null>(null);
425+
425426
useEffect(() => {
426-
if (coordinates && coordinates.length > 0 && mapRef.current) {
427-
const firstCoord = coordinates[0];
428-
if (!firstCoord || !firstCoord[0] || !firstCoord[1]) return;
429-
430-
const bounds: [[number, number], [number, number]] = coordinates.reduce<
431-
[[number, number], [number, number]]
432-
>(
433-
(acc, coord) => {
434-
if (!coord || !coord[0] || !coord[1]) return acc;
435-
return [
436-
[Math.min(acc[0][0], coord[1]), Math.min(acc[0][1], coord[0])],
437-
[Math.max(acc[1][0], coord[1]), Math.max(acc[1][1], coord[0])],
438-
];
439-
},
440-
[
441-
[firstCoord[1], firstCoord[0]],
442-
[firstCoord[1], firstCoord[0]],
443-
]
444-
);
445-
446-
const paddingTopLeft = [
447-
screen.width < 550 ? 50 : directionsPanelOpen ? 420 : 50,
448-
50,
449-
];
450-
451-
const paddingBottomRight = [
452-
screen.width < 550 ? 50 : settingsPanelOpen ? 420 : 50,
453-
50,
454-
];
455-
456-
mapRef.current.fitBounds(bounds, {
457-
padding: {
458-
top: paddingTopLeft[1] as number,
459-
bottom: paddingBottomRight[1] as number,
460-
left: paddingTopLeft[0] as number,
461-
right: paddingBottomRight[0] as number,
462-
},
463-
maxZoom: coordinates.length === 1 ? 11 : 18,
464-
});
427+
//When a route is cleared resets the key to null
428+
if (!coordinates || coordinates.length === 0) {
429+
lastZoomedCoordKeyRef.current = null;
430+
return;
465431
}
466-
}, [coordinates, directionsPanelOpen, settingsPanelOpen]);
432+
433+
//If No Cordinates then return early
434+
if (!mapRef.current) return;
435+
436+
//First Point
437+
const firstCoord = coordinates[0];
438+
if (!firstCoord || !firstCoord[0] || !firstCoord[1]) return;
439+
440+
//Last Point
441+
const lastCoord = coordinates[coordinates.length - 1]!;
442+
443+
const coordKey =
444+
coordinates.length +
445+
':' +
446+
firstCoord[0] +
447+
',' +
448+
firstCoord[1] +
449+
':' +
450+
lastCoord[0] +
451+
',' +
452+
lastCoord[1];
453+
//Compare with what was last zoomed
454+
if (coordKey === lastZoomedCoordKeyRef.current) return;
455+
//Store thr new Key
456+
lastZoomedCoordKeyRef.current = coordKey;
457+
458+
const bounds: [[number, number], [number, number]] = coordinates.reduce<
459+
[[number, number], [number, number]]
460+
>(
461+
(acc, coord) => {
462+
if (!coord || !coord[0] || !coord[1]) return acc;
463+
return [
464+
[Math.min(acc[0][0], coord[1]), Math.min(acc[0][1], coord[0])],
465+
[Math.max(acc[1][0], coord[1]), Math.max(acc[1][1], coord[0])],
466+
];
467+
},
468+
[
469+
[firstCoord[1], firstCoord[0]],
470+
[firstCoord[1], firstCoord[0]],
471+
]
472+
);
473+
474+
//Read panel from the store directly
475+
//avoids re-running the effect when panels open or close
476+
const state = useCommonStore.getState();
477+
const dpOpen = state.directionsPanelOpen;
478+
const spOpen = state.settingsPanelOpen;
479+
480+
const paddingTopLeft = [screen.width < 550 ? 50 : dpOpen ? 420 : 50, 50];
481+
const paddingBottomRight = [
482+
screen.width < 550 ? 50 : spOpen ? 420 : 50,
483+
50,
484+
];
485+
486+
mapRef.current.fitBounds(bounds, {
487+
padding: {
488+
top: paddingTopLeft[1] as number,
489+
bottom: paddingBottomRight[1] as number,
490+
left: paddingTopLeft[0] as number,
491+
right: paddingBottomRight[0] as number,
492+
},
493+
maxZoom: coordinates.length === 1 ? 11 : 18,
494+
});
495+
//only rerun when coordinates change
496+
//panel change no longer rerun this
497+
}, [coordinates]);
467498

468499
const handleMapTilesClick = useCallback(
469500
(event: maplibregl.MapLayerMouseEvent) => {

0 commit comments

Comments
 (0)