12

I'm using React Router v4 and react-transition-group v2 to test the page sliding animation.

const RouterMap = () => (
  <Router>
    <Route render={({ location }) =>
      <TransitionGroup>
        <CSSTransition key={location.pathname.split('/')[1]} timeout={500} classNames="pageSlider" mountOnEnter={true} unmountOnExit={true}>
          <Switch location={location}>
            <Route path="/" exact component={ Index } />
            <Route path="/comments" component={ Comments } />
            <Route path="/opinions" component={ Opinions } />
            <Route path="/games" component={ Games } />
          </Switch>
        </CSSTransition>
      </TransitionGroup>
    } />
  </Router>
)

And the CSS:

.pageSlider-enter {
  transform: translate3d(100%, 0, 0);
}

.pageSlider-enter.pageSlider-enter-active {
  transform: translate3d(0, 0, 0);
  transition: all 600ms;
}
.pageSlider-exit {
  transform: translate3d(0, 0, 0);
}

.pageSlider-exit.pageSlider-exit-active {
  transform: translate3d(-100%, 0, 0);
  transition: all 600ms;
}

The animation is as bellow:

enter image description here

As you see, the animation that index page slide to the detail page is all right(right to left). But when I click the Back icon, I hope index page comes out from left to right.

I know if I change the CSS as bellow, the page will come out from left to right:

.pageSlider-enter {
  transform: translate3d(-100%, 0, 0);
}
.pageSlider-exit.pageSlider-exit-active {
  transform: translate3d(100%, 0, 0);
  transition: all 600ms;
}

But how combine the two animations together? Generally speaking, whenever user clicks the back icon, the animation should be from left to right.


Update: 2017.08.31

Thanks for @MatijaG, using the path depth is really an awesome idea. I followed it and got a new problem.

function getPathDepth(location) {
  let pathArr = (location || {}).pathname.split('/');
  pathArr = pathArr.filter(n => n !== '');
  return pathArr.length;
}

<Route render={({ location }) =>
  <TransitionGroup>
    <CSSTransition
      key={location.pathname.split('/')[1]}
      timeout={500}
      classNames={ getPathDepth(location) - this.state.prevDepth > 0 ? 'pageSliderLeft' : 'pageSliderRight' }
      mountOnEnter={true}
      unmountOnExit={true}
    >
      <Switch location={location}>
        <Route path="/" exact component={ Index } />
        <Route path="/comments" component={ Comments } />
        <Route path="/opinions" component={ Opinions } />
        <Route path="/games/lol" component={ LOL } /> // add a new route
        <Route path="/games" component={ Games } />
      </Switch>
    </CSSTransition>
  </TransitionGroup>
} />

And updated CSS:

.pageSliderLeft-enter {
  transform: translate3d(100%, 0, 0);
}
.pageSliderLeft-enter.pageSliderLeft-enter-active {
  transform: translate3d(0, 0, 0);
  transition: all 600ms;
}
.pageSliderLeft-exit {
  transform: translate3d(0, 0, 0);
}
.pageSliderLeft-exit.pageSliderLeft-exit-active {
  transform: translate3d(100%, 0, 0);
  transition: all 600ms;
}

.pageSliderRight-enter {
  transform: translate3d(-100%, 0, 0);
}
.pageSliderRight-enter.pageSliderRight-enter-active {
  transform: translate3d(0, 0, 0);
  transition: all 600ms;
}
.pageSliderRight-exit {
  transform: translate3d(0, 0, 0);
}
.pageSliderRight-exit.pageSliderRight-exit-active {
  transform: translate3d(-100%, 0, 0);
  transition: all 600ms;
}

The animation:

enter image description here

From '/' to '/games' is ok, and from '/games' back to '/' is still ok(type 1: route A -> route B, only 2 routes). But if firstly from '/' to '/games', and then from '/games' to '/games/lol', the second phase lose the animation(type 2: route A -> route B -> route C, 3 or more routes). We also see that from '/games/lol' back to '/games' and then back to '/', the slide animation is not same as type 1.

Anyone has any idea about this problem?

4

4 に答える 4

0

反応ルーター v4 ネイティブの AnimatedSwitch を作成しました。

https://javascriptrambling.blogspot.com/2020/07/react-router-native-animatedswitch.html

history.action を使用して、進むか戻るか (つまり、スライドインまたはスライドアウト) を判断しました。次に、トランジションが適切なアクションを使用して、必要なアニメーションに一致することを確認しました。history.goBack または history.replace を使用してスライドさせます。通常の history.push またはスライドインします。

      if (history.action === 'POP' || history.action === 'REPLACE') {
        setNewAnimationStyle(animationType.backNew(anim));
        setPrevAnimationStyle(animationType.backPrevious(anim));
      } else {
        setNewAnimationStyle(animationType.new(anim));
        setPrevAnimationStyle(animationType.previous(anim));
      }

于 2020-08-20T22:50:43.047 に答える