Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Navigation custom navigator transitions

I'm looking to create a Stack Navigator that can handle animating specific elements between 2 screens. Fluid Transitions looked like a library I could use, but it doesn't support react-navigation 5.X. If there's a package that has this functionality for react-navigation v5, that would be great.

However, if there is no current package for v5, I'd like to extend the StackNavigator to handle this kind of functionality. I've been able to remove the default animations for the StackNavigator with something similar to the following (where transition is a bool taken in the options prop for the Stack.Screen:

const CustomTransitionStackNavigator = ({
  initialRouteName,
  children,
  screenOptions,
  ...rest
}) => {
  if (descriptors[state.routes[state.index].key].options.transition) {
    return (
      <View style={{ flex: 1 }}>
        {descriptors[state.routes[state.index].key].render()}
      </View>
    );
  }

  return (
    <StackView
      {...rest}
      descriptors={descriptors}
      navigation={navigation}
      state={state}
    />
  );
};

I'd like to be able to use a Context (or some other method) of passing the transition progress to the scene's descendants in order to handle the animations. Is there some way to get the transition progress in v5? Or would this CustomTransitionStackNavigator need to manage that state? Thanks!

like image 880
Taylor Johnson Avatar asked Feb 28 '20 01:02

Taylor Johnson


1 Answers

You can use CardAnimationContext or useCardAnimation (which is just a convenience wrapper for the first one) to get transition progress in a stack navigator.

For example:

import { useCardAnimation } from '@react-navigation/stack';
import React from 'react';
import { Animated } from 'react-native';

export const SomeScreen = () => {
  const { current } = useCardAnimation();

  return (
    <Animated.View
      style={{
        width: 200,
        height: 200,
        backgroundColor: 'red',
        transform: [{ scale: current.progress }],
      }}
    />
  );
};

This feature seems to be undocumented at the moment, but you can check TypeScript definitions to get some more information.

like image 57
Infensus Avatar answered Sep 19 '22 10:09

Infensus