動畫效果,是一個頁面上必不可少的功能,學習一個新的東西,當然就要學習,如何用新的東西,用它的方法去實現以前的東西啦。今天呢,我就在這里介紹一個試用react-addons-css-transition-group插件,在react中實現輪播圖效果。
首先,大家需要了解的是,頁面中的動畫,可以分為兩種,一種是js動畫,這是用js腳本來驅動的動畫,另一種呢,就是用css的transiton和animation來實現的動畫效果。而我要講的插件,就是利用CSS的Transition和animation來實現組件的出場和入場動畫。
所以呢,我將先給大家簡單介紹一下transition和animation,然后在介紹如何使用react-addons-css-transition-group插件,最后附上我實現的輪播圖。
1. CSS3 transition
現在假設我們想讓一個元素,當我們hover時,它的寬高從50px變為100px。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box { width: 50px; height: 50px; background-color: #f00; } .box:hover { width: 100px; height: 100px; } </style> </head> <body> <div class="box"></div> </body> </html>
如果我們之間運行上面這段代碼,當我們hover時,元素大小瞬間就變成了100x100,很突兀,視覺效果很差。
如果我們使用過渡transition屬性的話,我們就可以讓元素在我們指定的時間內,完成50x50到100x100的過渡動畫。
.box:hover { width: 100px; height: 100px; /* 指定過渡動畫執行的時間,以及要執行動畫的屬性, 如果不指定直接改變,這里我們制定了寬高執行1s的過渡動畫 */ transition: 1s width, 1s height; }
可以看到,使用transition后,變化就不再那么生硬了。我們還可以通過設置transition-delay,transition-timing-function 來設置延遲時間和過渡使用的變化函數。
當然從上面的動態圖,你也可以發現,transition的缺點,比如只有開始和結束兩個狀態,不能設置中間態,以及必須需要事件驅動,一條規則對應一個屬性等。因此css3 animation屬性出現啦。
2. CSS3 animation
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box { width: 100px; height: 100px; -moz-animation: rainbow 5s; /* Firefox */ } @-moz-keyframes rainbow { 0% { background-color: #f40; } 16% { background-color: #FF6100; } 33% { background-color: #FF0; } 50% { background-color: #0F0; } 66% { background-color: #00F; } 83% { background-color: #0FF; } 100% { background-color: #A020F0; } } </style> </head> <body> <div class="box"></div> </body> </html>
最終執行效果為:
動畫是使元素從一種樣式逐漸變化為另一種樣式的效果,我們使用animation屬性指定這個屬性播放的動畫名稱,事件,動畫函數等,我們用keyframes定義動畫,規定在動畫在關鍵幀樣式。這是一個css3屬性,在各大瀏覽器中使用,我們需要加相應的前綴。
我們還可以通過animation的一些屬性,自定義設置, 如延遲,結束狀態,停止狀態等等。
3. React react-addons-css-transition-group插件
react-addons-css-transition-group插件,就是在上面兩個css屬性上實現,就像之前說的那樣,它是利用css的transition和animation實現組件的進場和出場動畫的。ReactCSSTransitionGroup是在ReactTransitionGroup的基礎上進行再封裝。
我先直接附上我的代碼,然后進行詳細講解。
import React, {PropTypes} from 'react'; import CSSTransitionGroup from 'react-addons-css-transition-group'; /* 定義參數類型 */ const propTypes = { imageSrc: PropTypes.array.isRequired, currentIndex: PropTypes.number.isRequired, enterDelay: PropTypes.number.isRequired, leaveDelay: PropTypes.number.isRequired, name: PropTypes.string.isRequired, component: PropTypes.string.isRequired } /* 輪播圖片組件,無狀態組件 */ function CarouselImage(props) {
/* 對象解析,參數分別對應:圖片地址數組,當前展示圖片索引,進場動畫執行時間,出場動畫執行時間,transition對應唯一key值,自動生成的包裹元素類型 */ let {imageSrc, currentIndex, enterDelay, leaveDelay, name, component} = props; return ( <ul className="carousel-image"> <CSSTransitionGroup component={component} transitionName={name} transitionEnterTimeout={enterDelay} transitionLeaveTimeout={leaveDelay} className={name}> <img src={imageSrc[currentIndex]} key={imageSrc[currentIndex]} /> </CSSTransitionGroup> </ul> ); } CarouselImage.propTypes = propTypes; export default CarouselImage;
1. ReactCSSTransitionGroup工作原理
當組件出現時,會在組件添加transitionName-appear類(transitionName由我們自己設置值),然后下一時刻會給組件添加transitionName-appear-active類;當組件進場時,給組件添加transitionName-enter類,然后下一時刻會給組件添加transitionName-enter-active類;當組件出場時,會給組件添加transitionName-leave類,然后下一時刻輝給組件添加transitionName-leave-active類,我們則可以在css文件中,通過設置transition,設置我們需要執行的動畫。
一般情況下,我們主要使用后兩種,並且,只有當組件的出場動畫完全執行玩以后,組件才會被移除。
2. ReactCSSTransitionGroup組件參數
ReactCSSTransitionGroup其實就是一個組件,它規定了特定的參數,我們通過設置這些特定的參數,將這些參數反應到被其包裹的子組件中。下面,我們就其幾個常見的參數進行講解。
# transitionName: 設置動態生成類的自定義前綴,如果我們設置為carousel-image-item,那么,就會相應的生成carousel-image-item-enter, carousel-image-item-enter-active等。
# component: 字符串,設置ReactCSSTransitionGroup生成包裹子組件的標簽,默認時span,我們可以通過這個參數自定義,如div。
# transitionEnter: 布爾值,設置是否使用出場動畫,默認時true。
# transitionEnterTimeout: 數值,設置入場動畫的執行時間,需要在css中和這里同時設置,否則會提示警告。
# transitionLeave: 布爾值,設置是否使用出場動畫,默認時true。
# transitionLeaveTimeout: 數值,設置出場動畫的執行時間,需要在css中和這里同時設置,否則會提示警告。
最后,說一下transitionAppear,它和其他兩個不同,它默認時false,默認不執行。
3. 使用步驟
1)引包
import CSSTransitionGroup from 'react-addons-css-transition-group'; // ES6引包語法
2)將 CSSTransitionGroup組件添加到render中
return ( <ul className="carousel-image"> <CSSTransitionGroup component={component} transitionName={name} transitionEnterTimeout={enterDelay} transitionLeaveTimeout={leaveDelay} className={name}> <img src={imageSrc[currentIndex]} key={imageSrc[currentIndex]} /> </CSSTransitionGroup> </ul> );
在這里需要注意的是:CSSTransitionGroup組件需要添加到已經掛載到頁面上的dom元素中(可以理解為,需要放在render函數中,且需要被包裹),或者transitionAppear設置為true的組件上。
最后,我們只需在自己的css文件中,添加對應類的樣式即可。
我們可以在我們的生成的頁面中看到下面結果:
最后的最后,提一下六個TransitionGroup組件生命周期吧。其實我們上面使用的是別人給我們封裝好的,我們直接添加參數,就可以實現這些效果,但是這只能實現簡單的出場入場效果,如果要自定義一些動畫的話,我們就需要通過在這些聲明周期中設置回調函數,自定義動畫。下面我們來簡單了解一下着六個生命周期函數吧。
1)ComponentWillAppear:組件將要出現時調用
2) ComponentDidAppear: 組件出現時調用
3) ComponentWillEnter: 組件將要進場時調用
4) ComponentDidEnter:進場的下一時刻調用
5) ComponentWillLeave:組件將要出場時調用
6) ComponentDidLeave:出場的下一時刻調用
4. 輪播圖效果
最后,給大家分享我做的輪播圖效果,以及代碼。
github地址:https://github.com/DiligentYe/react-carousel
過程中,由於直接用webpack的css-loader加載scss文件,會改變自定義類名的問題,我不得自定義index頁面,在頁面中引入bundle.js文件和解析后的css文件。