Animate leaving screen with React Navigation












8















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










share|improve this question





























    8















    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










    share|improve this question



























      8












      8








      8


      2






      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










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 16 '18 at 9:17







      toioski

















      asked Nov 14 '18 at 16:54









      toioskitoioski

      144110




      144110
























          1 Answer
          1






          active

          oldest

          votes


















          5














          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 and A are screens

          • we are navigating from A to B

          • width(B) = width(A) = 320

          • width(deviceScreen) = 320

          • initWidth = 320


          Explanation





          • index-1 represents the screen that is going to appear (screen B) and it's mapped to -initWidth. With this we are saying that the screen it's going to appear (screen B) should be X-translated (respect the viewport) of a value equal its width. So it will start the animation from X = 320 (i.e. outside the screen)


          • index represents the screen that is going to appear, but once is appeared (still screen B). Mapping it to 0 we are saying that screen B once is appeared should be in position X = 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 screen B, but just when it would have disappeared because of a navigation like B->C. However from our A->B point of view, it's the screen A 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, mapping index+1 to 0 we are saying that screen A should stay at X=0 when it's going to disappear (i.e. when B 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).



          Description here



          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],
          })


          enter image description here









          share|improve this answer

























            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            5














            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 and A are screens

            • we are navigating from A to B

            • width(B) = width(A) = 320

            • width(deviceScreen) = 320

            • initWidth = 320


            Explanation





            • index-1 represents the screen that is going to appear (screen B) and it's mapped to -initWidth. With this we are saying that the screen it's going to appear (screen B) should be X-translated (respect the viewport) of a value equal its width. So it will start the animation from X = 320 (i.e. outside the screen)


            • index represents the screen that is going to appear, but once is appeared (still screen B). Mapping it to 0 we are saying that screen B once is appeared should be in position X = 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 screen B, but just when it would have disappeared because of a navigation like B->C. However from our A->B point of view, it's the screen A 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, mapping index+1 to 0 we are saying that screen A should stay at X=0 when it's going to disappear (i.e. when B 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).



            Description here



            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],
            })


            enter image description here









            share|improve this answer






























              5














              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 and A are screens

              • we are navigating from A to B

              • width(B) = width(A) = 320

              • width(deviceScreen) = 320

              • initWidth = 320


              Explanation





              • index-1 represents the screen that is going to appear (screen B) and it's mapped to -initWidth. With this we are saying that the screen it's going to appear (screen B) should be X-translated (respect the viewport) of a value equal its width. So it will start the animation from X = 320 (i.e. outside the screen)


              • index represents the screen that is going to appear, but once is appeared (still screen B). Mapping it to 0 we are saying that screen B once is appeared should be in position X = 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 screen B, but just when it would have disappeared because of a navigation like B->C. However from our A->B point of view, it's the screen A 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, mapping index+1 to 0 we are saying that screen A should stay at X=0 when it's going to disappear (i.e. when B 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).



              Description here



              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],
              })


              enter image description here









              share|improve this answer




























                5












                5








                5







                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 and A are screens

                • we are navigating from A to B

                • width(B) = width(A) = 320

                • width(deviceScreen) = 320

                • initWidth = 320


                Explanation





                • index-1 represents the screen that is going to appear (screen B) and it's mapped to -initWidth. With this we are saying that the screen it's going to appear (screen B) should be X-translated (respect the viewport) of a value equal its width. So it will start the animation from X = 320 (i.e. outside the screen)


                • index represents the screen that is going to appear, but once is appeared (still screen B). Mapping it to 0 we are saying that screen B once is appeared should be in position X = 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 screen B, but just when it would have disappeared because of a navigation like B->C. However from our A->B point of view, it's the screen A 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, mapping index+1 to 0 we are saying that screen A should stay at X=0 when it's going to disappear (i.e. when B 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).



                Description here



                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],
                })


                enter image description here









                share|improve this answer















                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 and A are screens

                • we are navigating from A to B

                • width(B) = width(A) = 320

                • width(deviceScreen) = 320

                • initWidth = 320


                Explanation





                • index-1 represents the screen that is going to appear (screen B) and it's mapped to -initWidth. With this we are saying that the screen it's going to appear (screen B) should be X-translated (respect the viewport) of a value equal its width. So it will start the animation from X = 320 (i.e. outside the screen)


                • index represents the screen that is going to appear, but once is appeared (still screen B). Mapping it to 0 we are saying that screen B once is appeared should be in position X = 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 screen B, but just when it would have disappeared because of a navigation like B->C. However from our A->B point of view, it's the screen A 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, mapping index+1 to 0 we are saying that screen A should stay at X=0 when it's going to disappear (i.e. when B 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).



                Description here



                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],
                })


                enter image description here










                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 15 '18 at 17:11

























                answered Nov 15 '18 at 16:25









                toioskitoioski

                144110




                144110
































                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Bressuire

                    Vorschmack

                    Quarantine