react-routerでページ遷移時アニメーション実装
概要
ページ遷移時スライドやフェードなどアニメーションを追加します。 ReactCSSTransitionGroupによってCSSアニメーション実装です。 locationの変化によってアニメーションを入れるかどうかを決めます。
実装
App.jsx
const HORIZONTAL_SLIDE_TRANSITION_PAGES = new RegExp([ "/abc", "/def", ].join("|")); const PAGE_TRANSITIOM_DURATION = 300; class App extends React.Component { constructor(props) { super(props); this.state = { pageTransition: "none" }; } componentWillReceiveProps(nextProps) { if (this.props.location !== nextProps.location) { if (HORIZONTAL_SLIDE_TRANSITION_PAGES.test(nextProps.location.pathname)) { this.setState({ pageTransition: "slide-up" }); } if (HORIZONTAL_SLIDE_TRANSITION_PAGES.test(this.props.location.pathname)) { this.setState({ pageTransition: "slide-down" }); setTimeout(() => { this.setState({ pageTransition: "none" }); }, PAGE_TRANSITIOM_DURATION); } } } render() { const { location } = this.props; const { pageTransition } = this.state; const isPageTransition = pageTransition !== "none"; return ( <ReactCSSTransitionGroup transitionName={pageTransition} transitionEnterTimeout={PAGE_TRANSITIOM_DURATION} transitionLeaveTimeout={PAGE_TRANSITIOM_DURATION} transitionEnter={isPageTransition} transitionLeave={isPageTransition} > <Switch location={location}> <Route path="/abc" component={AbcPage} /> <Route path="/def" component={DefPage} /> <Route path="/ghi" component={GhiPage} /> <Route path="/" component={TopPage} /> </Switch> </ReactCSSTransitionGroup> ); } }
styles.css
.slide-up-enter { position: absolute; width: 100%; transform: translateY(100vh); z-index: 10; } .slide-up-enter.slide-up-enter-active { transform: translateY(0); transition: transform 300ms cubic-bezier(0.14, 0.68, 0.36, 1); } .slide-down-leave { position: absolute; top: 0; transform: translateY(0); width: 100%; z-index: 10; } .slide-down-leave.slide-down-leave-active { transform: translateY(100vh); transition: transform 300ms cubic-bezier(0.14, 0.68, 0.36, 1); }