1.React經過setState讓界面迅速發生變化,但動畫的哲學告訴咱們,變化要慢,得用一個逐漸變化的過程來過渡,從而幫助用戶理解頁面.
界面的變化能夠分爲DOM節點(或組件)的增與減以及DOM節點(或屬性)的變化.
其中React提供的ReactCSSTransition可以幫助咱們便捷的識別出增長或刪除的組件,
從而讓咱們可以專一於更加簡單的屬性變化的動畫.
2.這裏統一將緩動函數經過js實現的動畫稱做js動畫,緩動函數由css提供的動畫稱做css動畫.
3.ReactCSSTransition插件就是利用CSS的Transition和animation來實現組件的出場和入場動畫.css
1.css3過渡是元素從一種樣式逐漸改變爲另外一種的效果.react
.ani2 { width: 100px; height: 100px; border: 1px solid #ccc; transition: width 1s, transform 1s; animation: myfirst 3s infinite; &:hover { width: 200px; transform: rotate(360deg); } }
1.@keyframes用於建立動畫,而後捆綁到某個選擇器.css3
@keyframes myfirst { 0% { background: #f00; } 50% { background: #0f0; } 100% { background: #ccc; } } .ani2 { width: 100px; height: 100px; border: 1px solid #ccc; transition: width 1s, transform 1s; animation: myfirst 3s infinite; &:hover { width: 200px; transform: rotate(360deg); } }
1.react-addons-transition-group插件,就是在transition和animation兩個css屬性上實現的.
2.ReactCSSTransition工做原理
當組件出現時,會在組件添加transitionName-appear,而後下一時刻會給組件添加transitionName-appear-active類,
當組件進場時,給組件添加transitionName-enter類,而後下一時刻會給組件添加transitionName-enter-active類;
當組件出場時,會給組件添加transitionName-leave類,而後下一時刻給組件添加transitionName-leave-active類,
咱們則能夠在css文件中,經過設置transition,設置咱們須要執行的動畫.
通常狀況下,咱們主要使用後兩種,而且,只有當組件的出場動畫徹底執行完之後,組件纔會被移除.
2.ReactCSSTransitionGroup組件參數
ReactCSSTransitionGroup其實就是一個組件,他規定了特定的參數,咱們經過設置這些特定的參數,將這些參數反應到被其包裹的子組件中.
transitionName:設置動態生成類的自定義前綴.
component:字符串,設置ReactCSSTransition生成包裹子組件的標籤,默認時span,咱們能夠經過這個參數自定義,如div,li
transitionEnter:布爾值,設置是否使用出場動畫,默認時true.
transitionEnterTimeout:數值,設置入場動畫的執行時間,須要在css中和這裏同時設置,不然會提示警告.
transitionLeave:布爾值,設置是否使用出場動畫,默認時true.
transitionLeaveTimeout:數值,設置出場動畫的執行時間,須要在css中和這裏同時設置,不然會提示警告.
3.使用步驟
1.引包app
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
2.將ReactCSSTransition組件添加到render中
ReactCSSTransitionGroup組件須要添加到已經掛載到頁面上的dom元素中.dom
class TodoList extends Component { constructor(props) { super(props); this.state = { items: ['1111', '2222', '3333', '4444'] }; } handleAdd = () => { var newItems = this.state.items.concat([prompt('enter some text')]); this.setState({ items: newItems }); } handleRemove = (i) => { var newItems = this.state.items.slice(); newItems.splice(i, 1); this.setState({ items: newItems }); } render() { return ( <div> <button onClick={ this.handleAdd }>Add Item</button> <ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={ 500 } transitionLeaveTimeout={ 300 } > { this.state.items.map((item, i) => { return ( <div key={ i } onClick={ this.handleRemove.bind(this, i) }> { item } </div> ) }) } </ReactCSSTransitionGroup> </div> ); } } .example-enter { opacity: 0.01; } .example-enter.example-enter-active { opacity: 1; transition: opacity 500ms ease-in; } .example-leave { opacity: 1; } .example-leave.example-leave-active { opacity: 0.01; transition: opacity 300ms ease-in; }
class ImageCarousel extends Component { constructor(props) { super(props); this.state = { a: [ 'https://s1.sonkwo.com/FhXx9C5gqykP4UUJHPKfpS1cexVP', 'http://7fvk4m.com1.z0.glb.clouddn.com/Fjn9lT9RdzW1dpIJ_7vSrxB4UKNB', 'http://7fvk4m.com1.z0.glb.clouddn.com/FsDTCVnB9DYkWF-m0p7zNdVfadTg' ], current: 0 }; } componentDidMount() { setInterval(() => { let current = this.state.current; current++; if (current > this.state.a.length - 1) { current = 0; } this.setState({ current }); }, 5000); } render() { let { a, current } = this.state; return ( <div className="react-slide"> <ReactCSSTransitionGroup component={'li'} transitionName="carousel" transitionEnterTimeout={ 1000 } transitionLeaveTimeout={ 1000 } > <img src={ a[current] } key={ a[current] } /> </ReactCSSTransitionGroup> </div> ); } } .react-slide { li { width: 440px; height: 260px; overflow: hidden; } .carousel-enter { opacity: 0.01; } .carousel-enter.carousel-enter-active { opacity: 1; transition: opacity 1s ease-in-out; } .carousel-leave { opacity: 1; } .carousel-leave.carousel-leave-active { opacity: 0.01; transition: opacity 1s ease-in-out; } }