React Navigation page transition animation is not showing when i render React Native Vision Camera

63 Views Asked by At

I am developing a mobile application with React Navigation and React Native Vision Camera.

I am using native-stack and added the animation to each Stack.Screen.

  <Stack.Screen
    ...
    options={{animation: 'slide_from_right',...}}
   />

They are working well until i navigate user back from ScanScreen, which contained a react native vision camera component.

My working flow is Home -> Scan -> Result -> back to Home.

The animation is working when i navigate to ScanScreen, but if i call goBack() in ScanScreen, or call popToTop() in ResultScreen, the animation will be gone and the app looks like stucked little bit.

Here is the code of my ScanScreen

const ScanScreen = ({route, navigation}) => {
  const {locations} = route.params;

  // permission
  const {hasPermission, requestPermission} = useCameraPermission();
  // if camera page is active
  const isFocussed = useIsFocused();
  const isForeground = useIsForeground();
  const isActive = isFocussed && isForeground;

  // camera torch control
  const [torch, setTorch] = useState('off');
  // get device
  const device = useCameraDevice('back');
  // inititalization
  const [isCameraInitialized, setIsCameraInitialized] = useState(false);
  const onInitialized = useCallback(() => {
    console.log('Camera initialized!');
    setIsCameraInitialized(true);
  }, []);

  const codeScanner = useCodeScanner({
    codeTypes: ['qr', 'ean-13'],
    onCodeScanned: codes => {
      onQRCodeScan({codes});
    },
  });

 useFocusEffect(
    useCallback(() => {
      if (!hasPermission) {
        requestPermission();
      }
      return () => {
    //    setIsCameraReady(false);
      };
    }, []),
  );

     {device != null && (
        <Camera
          style={{flex: 1}}
          device={device}
          isActive={isActive}
          onInitialized={onInitialized}
          codeScanner={codeScanner}
          torch={torch}
        />
      )}
})

I am thinking if the vision camera is too heavy? or maybe i am wokring with a wrong lifecycle. I have not try it on IOS yet.

I tried to deactivate the camera before leaving the page, however the transitionStart is not fired after i can goBack()

React.useEffect(() => {
  const unsubscribe = navigation.addListener('transitionStart', (e) => {
    // Do something
  });

  return unsubscribe;
}, [navigation]);
1

There are 1 best solutions below

1
Talha On

You can handle this on you Stack.Navigator you should not to used on your every screen.

like:

<Stack.Navigator initialRouteName="Tabs" screenOptions={screenOptions}>
  <Stack.Screen
    name={Route.SPECS_FEATURES}
    component={SpecAndFeatures}
    options={{headerShown: false, gestureEnabled: false}}
  />
</Stack.Navigator>

screenOptions

const screenOptions = {
  cardStyle: {backgroundColor: colors.background, opacity: 1},
  headerShadowVisible: false,
  headerBackTitleVisible: false,
  headerTitleAlign: 'center',
  gestureDirection: 'horizontal',
  gestureEnabled: false,
  cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
  headerTitleStyle: {color: 'white', justifyContent: 'center'},
  transitionSpec: {open: config,close: closeConfig},
};

My config

const config = {
  animation: 'spring',
  config: {
    stiffness: 1000,
    damping: 100,
    mass: 3,
    overshootClamping: false,
    restDisplacementThreshold: 0.01,
    restSpeedThreshold: 0.01,
  },
};

My closeConfig:

const closeConfig = {
  animation: 'timing',
  config: {
    duration: 400,
    stiffness: 1000,
    damping: 500,
    mass: 100,
    overshootClamping: false,
    restDisplacementThreshold: 0.5,
    restSpeedThreshold: 0.5,
  },
};

If you want to change the navigation animation style you should have to change in cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS it provide many default animation that you want and also you can update in your config or closeConfig to change animation style.

For more details you can visit CardStyleInterpolators