Animate leaving screen with React Navigation
I am developing a React Native application which uses React Navigation
to manage the routing between screens.
I know reading React Navigation documentation and watching this video on Egghead.io (highly suggested) that is possible to define custom animations for transitions between screens passing the transitionConfig
property to a StackNavigator
.
For example, the following code is defining a slide from left animation that is basically the mirror of the iOS default push animation:
const TransitionConfig = () => ({
screenInterpolator: ({ layout, position, scene }) => {
const { index } = scene
const { initWidth } = layout
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [-initWidth, 0, 0],
})
return {
transform: [{ translateX }],
}
}
})
const MyNavigator = createStackNavigator(
{
A: {screen: ScreenA},
B: {screen: ScreenB},
},
{ transitionConfig: TransitionConfig }
)
Considering the code above and the fact we are navigating from screen A
to screen B
, the screenInterpolator
function body is basically describing the animation the screen B
should follow when it's going to appear (it's reverted when it disappears). In this case the code it's saying to translate the screen B
along the X axis to achieve a slide in effect.
Is it possible to also define the animation for the screen that is disappearing (screen A
in our case)? I would like to define something like this:
B
should appear sliding from left to right
A
should disappear sliding from top to bottom
reactjs react-native react-navigation
add a comment |
I am developing a React Native application which uses React Navigation
to manage the routing between screens.
I know reading React Navigation documentation and watching this video on Egghead.io (highly suggested) that is possible to define custom animations for transitions between screens passing the transitionConfig
property to a StackNavigator
.
For example, the following code is defining a slide from left animation that is basically the mirror of the iOS default push animation:
const TransitionConfig = () => ({
screenInterpolator: ({ layout, position, scene }) => {
const { index } = scene
const { initWidth } = layout
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [-initWidth, 0, 0],
})
return {
transform: [{ translateX }],
}
}
})
const MyNavigator = createStackNavigator(
{
A: {screen: ScreenA},
B: {screen: ScreenB},
},
{ transitionConfig: TransitionConfig }
)
Considering the code above and the fact we are navigating from screen A
to screen B
, the screenInterpolator
function body is basically describing the animation the screen B
should follow when it's going to appear (it's reverted when it disappears). In this case the code it's saying to translate the screen B
along the X axis to achieve a slide in effect.
Is it possible to also define the animation for the screen that is disappearing (screen A
in our case)? I would like to define something like this:
B
should appear sliding from left to right
A
should disappear sliding from top to bottom
reactjs react-native react-navigation
add a comment |
I am developing a React Native application which uses React Navigation
to manage the routing between screens.
I know reading React Navigation documentation and watching this video on Egghead.io (highly suggested) that is possible to define custom animations for transitions between screens passing the transitionConfig
property to a StackNavigator
.
For example, the following code is defining a slide from left animation that is basically the mirror of the iOS default push animation:
const TransitionConfig = () => ({
screenInterpolator: ({ layout, position, scene }) => {
const { index } = scene
const { initWidth } = layout
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [-initWidth, 0, 0],
})
return {
transform: [{ translateX }],
}
}
})
const MyNavigator = createStackNavigator(
{
A: {screen: ScreenA},
B: {screen: ScreenB},
},
{ transitionConfig: TransitionConfig }
)
Considering the code above and the fact we are navigating from screen A
to screen B
, the screenInterpolator
function body is basically describing the animation the screen B
should follow when it's going to appear (it's reverted when it disappears). In this case the code it's saying to translate the screen B
along the X axis to achieve a slide in effect.
Is it possible to also define the animation for the screen that is disappearing (screen A
in our case)? I would like to define something like this:
B
should appear sliding from left to right
A
should disappear sliding from top to bottom
reactjs react-native react-navigation
I am developing a React Native application which uses React Navigation
to manage the routing between screens.
I know reading React Navigation documentation and watching this video on Egghead.io (highly suggested) that is possible to define custom animations for transitions between screens passing the transitionConfig
property to a StackNavigator
.
For example, the following code is defining a slide from left animation that is basically the mirror of the iOS default push animation:
const TransitionConfig = () => ({
screenInterpolator: ({ layout, position, scene }) => {
const { index } = scene
const { initWidth } = layout
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [-initWidth, 0, 0],
})
return {
transform: [{ translateX }],
}
}
})
const MyNavigator = createStackNavigator(
{
A: {screen: ScreenA},
B: {screen: ScreenB},
},
{ transitionConfig: TransitionConfig }
)
Considering the code above and the fact we are navigating from screen A
to screen B
, the screenInterpolator
function body is basically describing the animation the screen B
should follow when it's going to appear (it's reverted when it disappears). In this case the code it's saying to translate the screen B
along the X axis to achieve a slide in effect.
Is it possible to also define the animation for the screen that is disappearing (screen A
in our case)? I would like to define something like this:
B
should appear sliding from left to right
A
should disappear sliding from top to bottom
reactjs react-native react-navigation
reactjs react-native react-navigation
edited Nov 16 '18 at 9:17
toioski
asked Nov 14 '18 at 16:54
toioskitoioski
144110
144110
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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 } = scene
const 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],
})
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305193%2fanimate-leaving-screen-with-react-navigation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 } = scene
const 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],
})
add a comment |
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 } = scene
const 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],
})
add a comment |
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 } = scene
const 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],
})
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 } = scene
const 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],
})
edited Nov 15 '18 at 17:11
answered Nov 15 '18 at 16:25
toioskitoioski
144110
144110
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305193%2fanimate-leaving-screen-with-react-navigation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown