Explorar el Código

android map zoom fix

Viktoriia hace 3 semanas
padre
commit
7aa600eeda
Se han modificado 1 ficheros con 69 adiciones y 31 borrados
  1. 69 31
      src/screens/InAppScreens/MapScreen/index.tsx

+ 69 - 31
src/screens/InAppScreens/MapScreen/index.tsx

@@ -790,16 +790,12 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
     if (route.params?.lon && route.params?.lat) {
       setMarkerCoords([route.params.lon, route.params.lat]);
       const timeoutId = setTimeout(() => {
-        if (cameraRef.current) {
-          cameraController.setCamera({
-            centerCoordinate: [route.params?.lon, route.params?.lat],
-            zoomLevel: 15,
-            animationDuration: 800,
-            animationMode: 'flyTo'
-          });
-        } else {
-          console.warn('Camera ref is not available.');
-        }
+        cameraController.setCamera({
+          centerCoordinate: [route.params?.lon, route.params?.lat],
+          zoomLevel: 15,
+          animationDuration: 800,
+          animationMode: 'flyTo'
+        });
       }, 800);
 
       return () => clearTimeout(timeoutId);
@@ -911,6 +907,54 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
   const cameraRef = useRef<MapLibreRN.CameraRef>(null);
   const shapeSourceRef = useRef<MapLibreRN.ShapeSourceRef>(null);
 
+  const androidCancelRef = useRef<null | (() => void)>(null);
+
+  const setCameraAndroid = (config: any) => {
+    androidCancelRef.current?.();
+    androidCancelRef.current = null;
+
+    setRenderCamera(true);
+
+    let frame = 0;
+    let cancelled = false;
+    const startedAt = Date.now();
+    const MAX_WAIT_MS = 1500;
+
+    const cleanup = () => {
+      cancelled = true;
+      if (frame) cancelAnimationFrame(frame);
+      isAnimatingRef.current = false;
+      setRenderCamera(false);
+    };
+
+    androidCancelRef.current = cleanup;
+
+    const trySetCamera = () => {
+      if (cancelled) return;
+
+      if (cameraRef.current) {
+        cameraRef.current.setCamera(config);
+
+        const duration = (config.animationDuration || 1000) + 200;
+        animationTimeoutRef.current && clearTimeout(animationTimeoutRef.current);
+        animationTimeoutRef.current = setTimeout(() => {
+          if (!cancelled) cleanup();
+        }, duration);
+
+        return;
+      }
+
+      if (Date.now() - startedAt > MAX_WAIT_MS) {
+        cleanup();
+        return;
+      }
+
+      frame = requestAnimationFrame(trySetCamera);
+    };
+
+    frame = requestAnimationFrame(trySetCamera);
+  };
+
   const cameraController = {
     setCamera: useCallback((config: any) => {
       isAnimatingRef.current = true;
@@ -922,17 +966,8 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
       if (Platform.OS === 'android') {
         setRenderCamera(true);
 
-        requestAnimationFrame(() => {
-          cameraRef.current?.setCamera(config);
-        });
-
-        animationTimeoutRef.current = setTimeout(
-          () => {
-            isAnimatingRef.current = false;
-            setRenderCamera(false);
-          },
-          (config.animationDuration || 1000) + 200
-        );
+        setCameraAndroid(config);
+        return;
       } else {
         cameraRef.current?.setCamera(config);
 
@@ -1054,6 +1089,13 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
     }, [])
   };
 
+  useEffect(() => {
+    return () => {
+      androidCancelRef.current?.();
+      if (animationTimeoutRef.current) clearTimeout(animationTimeoutRef.current);
+    };
+  }, []);
+
   useEffect(() => {
     if (userInfo) {
       setUserInfoData(JSON.parse(userInfo));
@@ -1101,16 +1143,12 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
   useEffect(() => {
     if (initialRegion && !route.params?.id) {
       const timeoutId = setTimeout(() => {
-        if (cameraRef.current) {
-          cameraController.setCamera({
-            centerCoordinate: [initialRegion.longitude, initialRegion.latitude],
-            zoomLevel: Math.log2(360 / initialRegion.latitudeDelta),
-            animationDuration: 500,
-            animationMode: 'flyTo'
-          });
-        } else {
-          console.warn('Camera ref is not available.');
-        }
+        cameraController.setCamera({
+          centerCoordinate: [initialRegion.longitude, initialRegion.latitude],
+          zoomLevel: Math.log2(360 / initialRegion.latitudeDelta),
+          animationDuration: 500,
+          animationMode: 'flyTo'
+        });
       }, 500);
 
       return () => clearTimeout(timeoutId);