只需4个步骤:使用 React 实现页面过渡动画
来源:互联网 发布:原始杀戮卡顿怎么优化 编辑:程序博客网 时间:2024/05/22 12:58
使用 React 实现页面过渡动画(React Router 4、ReactTransitionGroup、Animated)
翻译:疯狂的技术宅
作者:Martin Haagensli
英文标题:Animated page transitions with React Router 4, ReactTransitionGroup and Animated
英文地址:https://hackernoon.com/animated-page-transitions-with-react-router-4-reacttransitiongroup-and-animated-1ca17bd97a1a
本文首发于公众号:jingchengyideng
在本文中,我将向你展示如何使用 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 路由
打开 src/index.js
文件,给 React 添加 BrowserRouter
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();
然后添加两个需要渲染的组建,首先是 src/Home.js
:
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> ) }}
接着是 src/Subpage.js
:
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> ) }}
下面打开src/App.js
文件并修改内容为:
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;
最后删除 src/App.css
的内容,并把下面的代码复制到src/index.css
文件中:
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 />
中。
首先把TransitionGroup导入你的 src/App.js
,像这样:
import TransitionGroup from "react-transition-group/TransitionGroup";
然后我们必须为 TransitionGroup 添加一个特殊的函数来渲染子组件。在 src/App.js
文件中class App extends ...
的前面添加这个函数:
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>)}/>
您现在可以访问新的生命周期方法了,比如 componentWillAppear()
,componentWillEnter()
和componentWillLeave()
。
让我们用它们来制作一个更高级的组件来实现我的的动画路由效果,现在好戏开场了!
4、创建Animated Wrapper 并用 Animated 实现动画
创建src/AnimatedWrapper.js
文件并复制下面的代码到文件中:
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 接收生命周期方法,我们可以用它来实现动画效果。
我们还用 Animated 创建了一个变量,可以用它来对封装的子组件中的 div 的不同样式属性实现动画效果。
让我们添加一些生命周期方法给组件添加动画效果。用Animated.template
渲染,并且/或者插入动画状态值。
按照下面的代码修改src/AnimatedWrapper.js
文件内容:
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;
然后我们需要在每个路由组件中导入它,然后像这样将它们封装起来:
修改 src/Home.js
如下:
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;
修改 src/Subpage.js
如下:
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文档来学习,但是现在相关文档很少。我们实用的Animated.template
函数在 Github-issues 以外的地方几乎找不到。它的文档在这里:http://animatedjs.github.io/interactive-docs/。
你可以通过下面的链接下载Demo的演示视频:
http://animate.mhaagens.me/
或者:
https://github.com/mhaagens/animated_routes_react
也可以关注我在Medium的博客或者我的Twitter,来学习更多 React 相关的内容。
https://twitter.com/mhaagens
欢迎扫描二维码关注公众号,每天第一时间推送我翻译的国外最新技术文章。
- 只需4个步骤:使用 React 实现页面过渡动画
- react-native实现搜索栏渐过渡动画
- 【android】平滑Activity过渡动画效果,类库已分离,使用只需1行代码
- [java]过渡动画实现
- 过渡动画的使用
- IOS页面切换过渡动画
- iOS 过渡动画的实现
- vue过渡动画实现原理
- android 页面过渡动画兼容库
- 获取APP的Launch Image,实现启动页面的过渡动画。
- 如何为复杂页面实现过渡页面
- 如何为复杂页面实现过渡页面
- React实现动画效果
- 实现图片左右旋转过渡动画
- 实现Android5.0过渡动画兼容库
- FLIP 动画实现多维网格的过渡
- 用css3的transition实现过渡动画
- 动画过渡实现鼠标跟随导航效果
- onclick事件没有反应的五种可能情况
- 定点小数的运算
- const static extern 存储与进程空间布局(二)
- 微信小程序开源Demo精选
- [P1120]小木棍
- 只需4个步骤:使用 React 实现页面过渡动画
- HDU3172-Virtual Friends
- Android JAVA 裁剪、压缩图片
- Java技能清单
- 脉冲频率对步进电机转矩的影响
- Linux系统调用(syscall)原理
- Python 列表、元组、字典、集合 区别
- sencha app build编译时乱码
- HTTP详解(十二):对称加密算法前世今生