2

之前问过一个关于如何实现页面滑动动画的问题:使用 React Router v4 和 react-transition-group v2实现页面滑动动画。

在那之后,我遇到了一个更困难的问题。

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

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

动画:

在此处输入图像描述

如果只是从“/”滑到“/games”,然后从“/games”滑回“/”,一切都很好。但是路线越多,就越复杂。

从 '/' 到 '/games' 时,游戏的退出动画是指定的,不可更改。但显然,它应该是动态的。

  • '/' --> '/games' && '/games' --> '/', 退出动画应该是'向右滑动'
  • '/' --> '/games' && '/games' --> '/games/lol', 退出动画应该是'向左滑动'

更一般地,当获得更深的路线时,滑动动画应该是“向左滑动”。否则,动画应该是“向右滑动”。

如何动态设置动画?

4

1 回答 1

1

因此,正如我在评论中已经提到的那样,进一步看,我认为问题在于现有元素的状态已过时。为了解决这个问题,我认为您必须使用子工厂并在元素退出之前使用新道具克隆元素。

或者,可以通过仅执行进入动画并忽略退出动画来稍微简化动画(并且它在移动设备上也应该具有更好的性能)。把它想象成一堆卡片。

在此处输入图像描述

像这样的东西: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;
}

完整示例: https ://codepen.io/anon/pen/yoGqxQ

于 2017-09-01T10:26:09.313 回答