【译】只需四个步骤:使用 React 实现页面过渡动画
在本文中,我将向你展示如何使用 ReactTransitionGroup 和 Animated 库中的生命周期方法来实现页面的过渡效果。 你可以通过这个视频 http://animate.mhaagens.me 来观看演示效果。 让我们看看该怎样设置一些简单的路由动画! 1、安装React首先安装 React 并创建一个 React 应用程序,很简单的就能创建一个 React 项目并让它运行。 如果你还没有安装 Create React App 就先装好(如果你已经安装,就跳过这一步): npm install -g create-react-app 然后创建我们的项目: create-react-app animatedroutes && cd animatedroutes 接下来安装 routes 和 animation 包: yarn add react-router-dom animated react-transition-group 现在用你喜欢的编辑器打开项目,并运行它: npm start 2、添加 React 路由打开 import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter } from "react-router-dom"; import App from "./App"; import registerServiceWorker from "./registerServiceWorker"; import "./index.css"; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>,document.getElementById("root") ); registerServiceWorker(); 然后添加两个需要渲染的组建,首先是 import React,{ Component } from "react"; export default class Home extends Component { render() { return ( <div className="page"> <h1>Home</h1> <p>Hello from the home page!</p> </div> ) } } 接着是 import React,{ Component } from "react"; export default class Subpage extends Component { render() { return ( <div className="page"> <h1>Subpage</h1> <p>Hello from a sub page!</p> </div> ) } } 下面打开 import React,{ Component } from 'react'; import { Route,Link } from "react-router-dom"; import Home from "./Home"; import Subpage from "./Subpage"; class App extends Component { render() { return ( <div className="App"> <div className="TopBar"> <Link to="/">Home</Link> <Link to="/subpage">Subpage</Link> </div> <Route exact path="/" component={Home} /> <Route exact path="/subpage" component={Subpage} /> </div> ); } } export default App; 最后删除 html,body,#root { height: 100%; width: 100%; } body { margin: 0; padding: 0; font-family: sans-serif; } .App { position: relative; display: flex; flex-flow: column; } .TopBar { position: fixed; top: 0; left: 0; display: flex; flex-flow: row nowrap; align-items: center; width: 100%; height: 62px; padding: 0 24px; } .TopBar a { margin-right: 18px; text-decoration: none; } .animated-page-wrapper { position: absolute; top: 62px; left: 0; width: 100%; height: 100%; } .page { padding: 0 24px; } 好了,现在可以通过路由在主页面和子页面之间进行导航了。 3、添加 TransitionGroup现在开始添加动画效果。我们需要做一些微不足道的工作来实现它。 现在,我们不再用默认的方式设置路由,而是要使用路由渲染方法来去渲染前面的组件,并将其封装到一个 首先把TransitionGroup导入你的 import TransitionGroup from "react-transition-group/TransitionGroup"; 然后我们必须为 TransitionGroup 添加一个特殊的函数来渲染子组件。在 const firstChild = props => { const childrenArray = React.Children.toArray(props.children); return childrenArray[0] || null; }; 然后删除你的路由,并替换成下面的代码: <Route exact path="/" children={({ match,...rest }) => ( <TransitionGroup component={firstChild}> {match && <Home {...rest} />} </TransitionGroup> )}/> <Route path="/subpage" children={({ match,...rest }) => ( <TransitionGroup component={firstChild}> {match && <Subpage {...rest} />} </TransitionGroup> )}/> 您现在可以访问新的生命周期方法了,比如 让我们用它们来制作一个更高级的组件来实现我的的动画路由效果,现在好戏开场了! 4、创建Animated Wrapper 并用 Animated 实现动画创建 import React,{ Component } from "react"; import * as Animated from "animated/lib/targets/react-dom"; const AnimatedWrapper = WrappedComponent => class AnimatedWrapper extends Component { constructor(props) { super(props); this.state = { animate: new Animated.Value(0) }; } render() { return ( <Animated.div className="animated-page-wrapper"> <WrappedComponent {...this.props} /> </Animated.div> ); } }; export default AnimatedWrapper; 这里有很多东西,我来解释一下。 我们用component来包装我们的路由组件。它将从 TransitionGroup 接收生命周期方法,我们可以用它来实现动画效果。 让我们添加一些生命周期方法给组件添加动画效果。用 按照下面的代码修改 import React,{ Component } from "react"; import * as Animated from "animated/lib/targets/react-dom"; const AnimatedWrapper = WrappedComponent => class AnimatedWrapper extends Component { constructor(props) { super(props); this.state = { animate: new Animated.Value(0) }; } componentWillAppear(cb) { Animated.spring(this.state.animate,{ toValue: 1 }).start(); cb(); } componentWillEnter(cb) { setTimeout( () => Animated.spring(this.state.animate,{ toValue: 1 }).start(),250 ); cb(); } componentWillLeave(cb) { Animated.spring(this.state.animate,{ toValue: 0 }).start(); setTimeout(() => cb(),175); } render() { const style = { opacity: Animated.template`${this.state.animate}`,transform: Animated.template` translate3d(0,${this.state.animate.interpolate({ inputRange: [0,1],outputRange: ["12px","0px"] })},0) ` }; return ( <Animated.div style={style} className="animated-page-wrapper"> <WrappedComponent {...this.props} /> </Animated.div> ); } }; export default AnimatedWrapper; 然后我们需要在每个路由组件中导入它,然后像这样将它们封装起来: 修改 import React,{ Component } from "react"; import AnimatedWrapper from "./AnimatedWrapper"; class HomeComponent extends Component { render() { return ( <div className="page"> <h1>Home</h1> <p>Hello from the home page!</p> </div> ) } } const Home = AnimatedWrapper(HomeComponent); export default Home; 修改 import React,{ Component } from "react"; import AnimatedWrapper from "./AnimatedWrapper"; class SubpageComponent extends Component { render() { return ( <div className="page"> <h1>Subpage</h1> <p>Hello from a sub page!</p> </div> ) } } const Subpage = AnimatedWrapper(SubpageComponent); export default Subpage; 就这样,现在你的页面切换效果应该是动态的了! 扩展阅读我建议通过Animated文档来学习,但是现在相关文档很少。我们实用的 也可以关注我在Medium的博客或者我的Twitter,来学习更多 React 相关的内容。 欢迎扫描二维码关注公众号,每天第一时间推送我翻译的国外最新技术文章。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |