I'm currently working on a ReactNative
app that has 2 screens. The goal is to animate the screens such that they push each other up or down depending on which screen you're coming from. The GIF
below is the transition I am trying to achieve.
Currently I'm using createAnimatedSwitchNavigator
to create the effect, the problem is that my current transition only pushes the screens up. Is there a way to detect which screen I'm currently on within the animated switch navigator so that I can change the direction of the transition?
const MySwitch = createAnimatedSwitchNavigator(
{
Home: {
screen: Home
},
Page2: {
screen: Page2
},
},
{
transition: (
<Transition.Together>
<Transition.Out
type="slide-top"
durationMs={400}
interpolation="easeIn"
/>
<Transition.In type="slide-bottom" durationMs={500} />
</Transition.Together>
)
}
);
Kindly guide me for this.
Thanks
Did some researching and was able to get this working with the following code:
const AppNavigator = createStackNavigator({
Home: {
screen: Home
},
Page2: {
screen: Page2
}
},
{
initialRouteName: "Home",
headerMode: "none",
defaultNavigationOptions: {
gesturesEnabled: false
},
transitionConfig: () => ({
transitionSpec: {
duration: 1400,
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
screenInterpolator: sceneProps => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
const height = layout.initHeight;
const translateY = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [height, 0, -height],
});
const opacity = position.interpolate({
inputRange: [index - 1, index - 0.99, index],
outputRange: [0, 1, 1],
});
return { opacity, transform: [{ translateY }] };
},
}),
});
The hardest part was understanding interpolation as there seems to be a lot of seemingly arbitrary values. I didn't find the documentation the greatest, however was able to come up with the following understanding:
Take the code below for example. Here the first thing is setting the type of translation, which in this case is translateY
const translateY = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [height, 0, -height],
});
The next confusing part is the input and output ranges, what do these numbers mean? Well the input range actually maps to the output range. Looking something like this:
inputRange: [newScreen, currentScreen, previousScreen]
In inputRange we specify which screens we want to animate, then in output range we specify what we want to do with those screens. Modifying outputRange[0]
would modify the newScreen, etc.
Since we already set the translation type to translateY
we know the screen is either moving up or down.
outputRange: [height, 0, -height]
This is now telling the new screen to move up to the top of the screen and the old screen to also move up, beyond the top of the screen (hence the -height, which would be the same as -100vh in CSS).