應(yīng)用首次加載時(shí)候的動(dòng)畫。
首次加載.gif
切換路由時(shí)候的動(dòng)畫
切換.gif
做react路由動(dòng)畫比較復(fù)雜,最好了解三個(gè)前提知識(shí),
react動(dòng)畫組件炊昆,react-transition-group 文檔
react路由組件,react-router 文檔
css動(dòng)畫語法威根, CSS動(dòng)畫簡介 文檔
直接上代碼
這里我直接用了官方的demo代碼凤巨,并且稍微改了一下動(dòng)畫樣式。附上我寫好的github項(xiàng)目地址
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { TransitionGroup, CSSTransition } from "react-transition-group";
import './App.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
// 這個(gè)動(dòng)畫是頁面首次加載的動(dòng)畫洛搀,設(shè)置appear={true} 這個(gè)屬性敢茁,并且動(dòng)畫時(shí)間設(shè)置為500ms,和css中的需要一致留美。
// 一定要用 TransitionGroup 包著 CSSTransition彰檬,動(dòng)畫才有效伸刃,
// 原因是TransitionGroup 負(fù)責(zé)檢測并自動(dòng)給CSSTransition添加‘in’的prop,
// 并且TransitionGroup 要一直存在逢倍,不能放在動(dòng)態(tài)生成的組件中.
<TransitionGroup>
<CSSTransition
appear={true}
classNames="appAppear"
timeout={500}
>
<App/>
</CSSTransition>
</TransitionGroup>,
document.getElementById('root')
);
registerServiceWorker();
// app.js
import React from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import { BrowserRouter , Switch, Route, Link, Redirect } from "react-router-dom";
import './App.css'
const AnimationRoute = () => (
<BrowserRouter>
<Route
render={({ location }) => (
<div style={styles.fill}>
<Route
exact
path="/"
render={() => <Redirect to="/hsl/10/90/50" />}
/>
<ul style={styles.nav}>
<NavLink to="/hsl/10/90/50">Red</NavLink>
<NavLink to="/hsl/120/100/40">Green</NavLink>
<NavLink to="/rgb/33/150/243">Blue</NavLink>
<NavLink to="/rgb/240/98/146">Pink</NavLink>
</ul>
<div>{console.log(location)}</div>
<div style={styles.content}>
{/*和平時(shí)使用動(dòng)畫組件沒啥區(qū)別捧颅,*/}
{/*在渲染的路由的地方加一個(gè)用動(dòng)畫組件包著,并添加css屬性即可较雕;*/}
<TransitionGroup>
<CSSTransition
// 需要加一個(gè)key屬性碉哑,讓react認(rèn)識(shí)每個(gè)組件,并進(jìn)行正確的加載亮蒋。
// 這里我改了官方demo的代碼扣典, 原來是設(shè)置成location.key, 這樣的話每次點(diǎn)擊同一個(gè)路由鏈接的時(shí)候都會(huì)渲染慎玖。
key={location.pathname}
// classNames 就是設(shè)置給css動(dòng)畫的標(biāo)示激捏,記得'classNames'帶's'的。
classNames="fade"
// 動(dòng)畫時(shí)間設(shè)置為800ms凄吏,和css中的需要一致。
timeout={800}
>
<Switch location={location}>
<Route exact path="/hsl/:h/:s/:l" component={HSL} />
<Route exact path="/rgb/:r/:g/:b" component={RGB} />
<Route render={() => <div>Not Found</div>} />
</Switch>
</CSSTransition>
</TransitionGroup>
</div>
</div>
)}
/>
</BrowserRouter>
);
const NavLink = props => (
<li style={styles.navItem}>
<Link {...props} style={{ color: "inherit" }} />
</li>
);
const HSL = ({ match: { params } }) => (
<div
style={{
...styles.fill,
...styles.hsl,
background: `hsl(${params.h}, ${params.s}%, ${params.l}%)`
}}
>
hsl({params.h}, {params.s}%, {params.l}%)
</div>
);
const RGB = ({ match: { params } }) => (
<div
style={{
...styles.fill,
...styles.rgb,
background: `rgb(${params.r}, ${params.g}, ${params.b})`
}}
>
rgb({params.r}, {params.g}, {params.b})
</div>
);
const styles = {};
styles.fill = {
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0
};
styles.content = {
...styles.fill,
top: "40px",
textAlign: "center"
};
styles.nav = {
padding: 0,
margin: 0,
position: "absolute",
top: 0,
height: "40px",
width: "100%",
display: "flex"
};
styles.navItem = {
textAlign: "center",
flex: 1,
listStyleType: "none",
padding: "10px"
};
styles.hsl = {
...styles.fill,
color: "white",
paddingTop: "20px",
fontSize: "30px"
};
styles.rgb = {
...styles.fill,
color: "white",
paddingTop: "20px",
fontSize: "30px"
};
export default AnimationRoute;
//App.css
/*這里定義整個(gè)應(yīng)用加載時(shí)的動(dòng)畫闰蛔,進(jìn)場前這里設(shè)置了縮放為0痕钢,
進(jìn)場過程中縮放變?yōu)?,也就是100%序六,持續(xù)時(shí)間為500ms任连,
時(shí)間曲是ease-out瘟檩,一種先快后慢的變化曲線*/
.appAppear-appear{
opacity: 0;
transform: scale(0);
}
.appAppear-appear.appAppear-appear-active{
opacity: 1;
transform: scale(1);
transition: 500ms ease-out;
}
/*設(shè)置進(jìn)場前透明度為0萎河,放縮為0*/
.fade-enter {
opacity: 0;
transform: scale(0);
}
/*設(shè)置進(jìn)場過程中 透明度為1,放縮為1荸型,放縮的位置為左上角繁涂,持續(xù)時(shí)間為500ms拱她,時(shí)間曲是ease-out */
.fade-enter.fade-enter-active {
opacity: 1;
transform: scale(1);
transform-origin: top left;
transition: 800ms ease-out;
}
/*設(shè)置退場前透明度為1,放縮為1*/
.fade-exit{
opacity: 1;
transform: scale(1);
}
/*設(shè)置退場過程中 透明度為0扔罪,放縮為0秉沼,放縮的位置默認(rèn)是中間,所以不設(shè)置也可以矿酵,
持續(xù)時(shí)間為500ms唬复,時(shí)間曲是ease-out */
.fade-exit.fade-exit-active{
opacity:0;
transform: scale(0);
transition: 800ms ease-out;
}