Animate leaving screen with React Navigation
I found the answer by myself, I hope will help someone in the future.
I was wrong assuming that screenInterpolator
is describing only the behaviour of the screen B
, because is actually describing the animation of both A
and B
. Or better, it's the interpolate
function with inputRange
and outputRange
that allows you to describe the animation for both the entering (B
) and leaving (A
) screen.
Let's have a closer look to this snippet, keeping in mind that the interpolate
function is just creating a 1-1 association between the values of inputRange
and outputRange
(deeper explanation here).
const { index } = sceneconst translateX = position.interpolate({ inputRange: [index - 1, index, index + 1], outputRange: [-initWidth, 0, 0],})
Assumptions:
B
andA
are screens- we are navigating from
A
toB
width(B) = width(A) = 320
width(deviceScreen) = 320
initWidth = 320
Explanation
index-1
represents the screen that is going to appear (screenB
) and it's mapped to-initWidth
. With this we are saying that the screen it's going to appear (screenB
) should be X-translated (respect the viewport) of a value equal its width. So it will start the animation fromX = 320
(i.e. outside the screen)index
represents the screen that is going to appear, but once is appeared (still screenB
). Mapping it to0
we are saying that screenB
once is appeared should be in positionX = 0
index + 1
represents the screen once is going to disappear. This is what it led me to the error. At the beginning I thought this was still and only the screenB
, but just when it would have disappeared because of a navigation likeB->C
. However from ourA->B
point of view, it's the screenA
the one that is going to disappear! So both line of thoughts are correct, it's all about seeing things from a different perspective. So, mappingindex+1
to0
we are saying that screenA
should stay atX=0
when it's going to disappear (i.e. whenB
is going to appear)
Result
This is the animation realized by the code above. As you can see, the screen A
remains where it is because of the association index+1 <-> 0
(no translation, so no animation for screen A
).
If we change the association of index+1
to index+1 <-> -initWidth
, then screen A
will also be translated and hence animated :)
const translateX = position.interpolate({ inputRange: [index - 1, index, index + 1], outputRange: [initWidth, 0, -initWidth],})