dynamic page sliding animation with React Router v4 and react-transition-group v2

人走茶凉 提交于 2019-12-11 01:58:22

问题


I asked a question before about how to realize the page sliding animation: page sliding animation with React Router v4 and react-transition-group v2.

After that, I got a more difficult problem.

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

class Routers extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      prevDepth: getPathDepth(props.location)
    };
  }

  componentWillReceiveProps() {
    this.setState({ prevDepth: getPathDepth(this.props.location) });
  }

  render() {
    return (
      <Route render={({ location }) => {
        return (
          <TransitionGroup>
            <CSSTransition
              key={location.key}
              timeout={500}
              classNames={ getPathDepth(location) - this.state.prevDepth > 0 ? 'pageSliderLeft' : 'pageSliderRight' }
              classNames={classNames}
              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 } />
                <Route path="/games/dota" component={ DotA } />
                <Route path="/games" component={ Games } />
              </Switch>
            </CSSTransition>
          </TransitionGroup>
        );
      }} />
    )
  }
}

const WrapRouters = withRouter(Routers);

export default function RouterMap() {
  return (
    <BrowserRouter>
      <WrapRouters />
    </BrowserRouter>
  );
}

The CSS:

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

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

The animation:

If only sliding from '/' to '/games' and then from '/games' back to '/', everything is fine. But with more routes, it gets complicated.

When from '/' to '/games', the Games's exit animation is specified, not changeable. But obviously, it should be dynamic.

  • '/' --> '/games' && '/games' --> '/', exit animation should be 'slide to right'
  • '/' --> '/games' && '/games' --> '/games/lol', exit animation should be 'slide to left'

More generally, when getting deeper route, the sliding animation should be 'slide to left'. Otherwise, the animation should be 'slide to right'.

How to set the animation dynamically?


回答1:


So looking further as I already mentioned in the comment, I think the issue is that the exiting element has outdated state. To solve that I think that you would have to use the child factory and clone the element with new props before it exits.

Alternatively one could simplify the animation a bit (and it should also have better performance on mobile) by doing only the enter animation, and ignore the exit animation. Think of it like a stack of cards.

Something like this: CSS:

.pageSlider-exit  > .page{
    z-index:1;
}
.pageSlider-enter > .page{
    z-index:10;
}
.pageSlider-enter.left > .page{
    transform: translate3d(100%, 0, 0);
}

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

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

Full example: https://codepen.io/anon/pen/yoGqxQ



来源:https://stackoverflow.com/questions/45978263/dynamic-page-sliding-animation-with-react-router-v4-and-react-transition-group-v

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!