diff --git a/apps/web/src/widgets/map3d/Map3D.tsx b/apps/web/src/widgets/map3d/Map3D.tsx index 241a0a7..af4d3be 100644 --- a/apps/web/src/widgets/map3d/Map3D.tsx +++ b/apps/web/src/widgets/map3d/Map3D.tsx @@ -605,7 +605,7 @@ export function Map3D({ setProjectionLoading(false); console.warn("Projection loading fallback timeout reached."); } - }, 18000); + }, 3000); } else { clearProjectionBusyTimer(); } @@ -862,6 +862,41 @@ export function Map3D({ const maxRetries = 18; const isTransition = projectionPrevRef.current !== projection; projectionPrevRef.current = projection; + let settleScheduled = false; + let settleCleanup: (() => void) | null = null; + + const startProjectionSettle = () => { + if (!isTransition || settleScheduled) return; + settleScheduled = true; + + const finalize = () => { + if (!cancelled && isTransition) setProjectionLoading(false); + }; + + const finalizeSoon = () => { + if (cancelled || !isTransition || projectionBusyRef.current === false) return; + if (!map.isStyleLoaded()) { + requestAnimationFrame(finalizeSoon); + return; + } + requestAnimationFrame(() => requestAnimationFrame(finalize)); + }; + + const onIdle = () => finalizeSoon(); + try { + map.on("idle", onIdle); + const styleReadyCleanup = onMapStyleReady(map, finalizeSoon); + settleCleanup = () => { + map.off("idle", onIdle); + styleReadyCleanup(); + }; + } catch { + requestAnimationFrame(finalize); + settleCleanup = null; + } + + finalizeSoon(); + }; if (isTransition) setProjectionLoading(true); @@ -985,17 +1020,7 @@ export function Map3D({ // ignore } if (isTransition) { - const mercatorReady = projection === "mercator" && !!overlayRef.current; - const globeReady = projection === "globe" && !!map.getLayer("deck-globe"); - if (mercatorReady || globeReady) { - setProjectionLoading(false); - } else if (!cancelled && retries < maxRetries) { - retries += 1; - window.requestAnimationFrame(() => syncProjectionAndDeck()); - return; - } else { - setProjectionLoading(false); - } + startProjectionSettle(); } pulseMapSync(); }; @@ -1007,6 +1032,7 @@ export function Map3D({ const stop = onMapStyleReady(map, syncProjectionAndDeck); return () => { cancelled = true; + if (settleCleanup) settleCleanup(); stop(); if (isTransition) setProjectionLoading(false); }; @@ -1014,6 +1040,7 @@ export function Map3D({ return () => { cancelled = true; + if (settleCleanup) settleCleanup(); if (isTransition) setProjectionLoading(false); }; }, [projection, clearGlobeNativeLayers, ensureMercatorOverlay, removeLayerIfExists, setProjectionLoading]);