react常見的動畫方式

背景:
在當(dāng)下的前端背景下,前端的頁面對于用戶來說康愤,不僅僅是實(shí)現(xiàn)了功能,更要注重頁面的表現(xiàn)形式舶吗,來提升用戶的體驗(yàn)度征冷。React 作為最近幾年比較流行的前端開發(fā)框架,提出了虛擬 DOM 概念誓琼,所有 DOM 的變化都先發(fā)生在虛擬 DOM 上检激,通過 DOM diff 來分析網(wǎng)頁的實(shí)際變化,然后反映在真實(shí) DOM 上腹侣,從而極大地提升網(wǎng)頁性能叔收。并且react強(qiáng)調(diào)用數(shù)據(jù)去驅(qū)動頁面的展示,并不直接去操作DOM傲隶,從而在react中添加動畫就變得有點(diǎn)困難饺律,今天就介紹幾種在react中添加動畫的方式。

1.基于 React 組件狀態(tài)的 CSS 動畫

class App extends Component {
this.state = {
  switch: false
}
componentDidMount() {
  this.input.addEventListener('focus', this.focus);
  this.input.addEventListener('blur', this.focus);
}
focus = () => {
  this.setState((state) => ({ switch: !state.switch}))
}
render() {
  return (
    <div className="App">
      <div className="container">
        <input
          ref={input => this.input = input}
          className={['input', this.state.switch&& 'input-switch'].join(' ')}
        />
      </div>
    </div>
  );
}
}
  1. 我們通過一個狀態(tài)switch去控制input元素上的類名跺株,每個類名都加了css3動畫复濒。

2.在componentDidMount中去監(jiān)聽input元素獲取焦點(diǎn)和失去焦點(diǎn)時控制switch的變化,從而控制元素動畫的展現(xiàn)形式乒省。

2.React Motion

一個簡單的應(yīng)用:

<Motion defaultStyle={{left: 0}} style={{left: spring(10)}}>
    {interpolatingStyle => <div style={interpolatingStyle} />}
</Motion>

指定一個初始style(defaultStyle)芝薇,然后賦值一個目標(biāo)style(style),中間每幀都會由react-motion計算出對應(yīng)的style作儿,用戶只管使用生成的style(interpolatingStyle)洛二,不用關(guān)心物理效果的實(shí)現(xiàn),動畫中斷的處理,一切事情都交給react-motion晾嘶。
詳情可參考:https://github.com/chenglou/react-motion

3.react-addons-css-transition-group

react-addons-css-transition-group插件妓雾,是利用css的transition和animation實(shí)現(xiàn)組件的進(jìn)場和出場動畫的。ReactCSSTransitionGroup是在ReactTransitionGroup的基礎(chǔ)上進(jìn)行再封裝垒迂。

import React, {PropTypes} from 'react';
import CSSTransitionGroup from 'react-addons-css-transition-group';

/* 定義參數(shù)類型 */
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
}

/* 輪播圖片組件簿透,無狀態(tài)組件 */
function CarouselImage(props) {
  /* 對象解析亡问,參數(shù)分別對應(yīng):圖片地址數(shù)組龄砰,當(dāng)前展示圖片索引趣斤,進(jìn)場動畫執(zhí)行時間,出場動畫執(zhí)行時間吏奸,transition對應(yīng)唯一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工作原理

當(dāng)組件出現(xiàn)時,會在組件添加transitionName-appear類(transitionName由我們自己設(shè)置值)奋蔚,然后下一時刻會給組件添加transitionName-appear-active類她混;當(dāng)組件進(jìn)場時,給組件添加transitionName-enter類,然后下一時刻會給組件添加transitionName-enter-active類泊碑;當(dāng)組件出場時坤按,會給組件添加transitionName-leave類,然后下一時刻輝給組件添加transitionName-leave-active類馒过,我們則可以在css文件中臭脓,通過設(shè)置transition,設(shè)置我們需要執(zhí)行的動畫腹忽。

一般情況下谢鹊,我們主要使用后兩種,并且留凭,只有當(dāng)組件的出場動畫完全執(zhí)行玩以后,組件才會被移除偎巢。

2. ReactCSSTransitionGroup組件參數(shù)

ReactCSSTransitionGroup其實(shí)就是一個組件蔼夜,它規(guī)定了特定的參數(shù),我們通過設(shè)置這些特定的參數(shù)压昼,將這些參數(shù)反應(yīng)到被其包裹的子組件中求冷。下面,我們就其幾個常見的參數(shù)進(jìn)行講解窍霞。

transitionName: 設(shè)置動態(tài)生成類的自定義前綴匠题,如果我們設(shè)置為carousel-image-item,那么但金,就會相應(yīng)的生成carousel-image-item-enter, carousel-image-item-enter-active等韭山。

component: 字符串,設(shè)置ReactCSSTransitionGroup生成包裹子組件的標(biāo)簽,默認(rèn)時span钱磅,我們可以通過這個參數(shù)自定義梦裂,如div。

transitionEnter: 布爾值盖淡,設(shè)置是否使用出場動畫年柠,默認(rèn)時true。

transitionEnterTimeout: 數(shù)值褪迟,設(shè)置入場動畫的執(zhí)行時間冗恨,需要在css中和這里同時設(shè)置,否則會提示警告味赃。

transitionLeave: 布爾值掀抹,設(shè)置是否使用出場動畫,默認(rèn)時true洁桌。

transitionLeaveTimeout: 數(shù)值渴丸,設(shè)置出場動畫的執(zhí)行時間,需要在css中和這里同時設(shè)置另凌,否則會提示警告谱轨。

4.GSAP

GSAP 是一個老牌的專業(yè)級動畫庫,從古老的 Flash 動畫時代一直興盛至今吠谢,它是一個商業(yè)產(chǎn)品土童,雖然開發(fā)者可以免費(fèi)下載源代碼,但如果要在商業(yè)活動中使用它工坊,請購買相關(guān)的會員献汗。如果你沒有使用果 GSAP,建議閱讀《GSAP王污,專業(yè)的Web動畫庫》罢吃,接下來,我們嘗試將 GSAP 融入到 React 的開發(fā)中昭齐。

將 GSAP 與 React 結(jié)合有一個最簡單的方式:使用 ref尿招。通過 ref 獲取真實(shí)的 DOM 節(jié)點(diǎn),實(shí)現(xiàn)動畫的方式與傳統(tǒng)的實(shí)現(xiàn)方式一致:

// 導(dǎo)入通過 NPM 安裝的 GSAP
 import TweenMax from 'gsap'; 
// 保存 ref 指向的真實(shí)節(jié)點(diǎn) 
 let refNode; 
class App extends React.Component { 
componentDidMount () { 
TweenMax.to(refNode, 2, { x: '+=200px', backgroundColor: '#2196f3' });
 // TweenMax 可以做什么阱驾?
 // 暫停
 tween.pause(); 
// 繼續(xù)播放
 tween.resume(); 
// 反轉(zhuǎn)播放 
 tween.reverse(); 
// 跳轉(zhuǎn)到1s進(jìn)度處開始播放
 tween.seek(1);
 // 重播 
 tween.restart(); 
// 動畫變?yōu)槿端? tween.timeScale(3); }
 render () { 
    return ( <div id="ball" ref={c => (refNode = c)} 
        style={{ width: '100px', height: '100px',
        margin: '100px', borderRadius: '50%', backgroundColor: 'red' }}>         
     </div> ); } 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末就谜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子里覆,更是在濱河造成了極大的恐慌丧荐,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,835評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喧枷,死亡現(xiàn)場離奇詭異虹统,居然都是意外死亡弓坞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評論 2 383
  • 文/潘曉璐 我一進(jìn)店門窟却,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昼丑,“玉大人,你說我怎么就攤上這事夸赫∑械郏” “怎么了?”我有些...
    開封第一講書人閱讀 156,481評論 0 345
  • 文/不壞的土叔 我叫張陵茬腿,是天一觀的道長呼奢。 經(jīng)常有香客問我,道長切平,這世上最難降的妖魔是什么握础? 我笑而不...
    開封第一講書人閱讀 56,303評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮悴品,結(jié)果婚禮上禀综,老公的妹妹穿的比我還像新娘。我一直安慰自己苔严,他們只是感情好定枷,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,375評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著届氢,像睡著了一般欠窒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上退子,一...
    開封第一講書人閱讀 49,729評論 1 289
  • 那天岖妄,我揣著相機(jī)與錄音,去河邊找鬼寂祥。 笑死荐虐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丸凭。 我是一名探鬼主播福扬,決...
    沈念sama閱讀 38,877評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贮乳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恬惯,我...
    開封第一講書人閱讀 37,633評論 0 266
  • 序言:老撾萬榮一對情侶失蹤向拆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后酪耳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浓恳,經(jīng)...
    沈念sama閱讀 44,088評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刹缝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,443評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了颈将。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梢夯。...
    茶點(diǎn)故事閱讀 38,563評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晴圾,靈堂內(nèi)的尸體忽然破棺而出颂砸,到底是詐尸還是另有隱情,我是刑警寧澤死姚,帶...
    沈念sama閱讀 34,251評論 4 328
  • 正文 年R本政府宣布人乓,位于F島的核電站,受9級特大地震影響都毒,放射性物質(zhì)發(fā)生泄漏色罚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,827評論 3 312
  • 文/蒙蒙 一账劲、第九天 我趴在偏房一處隱蔽的房頂上張望戳护。 院中可真熱鬧,春花似錦瀑焦、人聲如沸腌且。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽切蟋。三九已至,卻和暖如春榆芦,著一層夾襖步出監(jiān)牢的瞬間柄粹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評論 1 264
  • 我被黑心中介騙來泰國打工匆绣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驻右,地道東北人。 一個月前我還...
    沈念sama閱讀 46,240評論 2 360
  • 正文 我出身青樓崎淳,卻偏偏與公主長得像堪夭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拣凹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,435評論 2 348

推薦閱讀更多精彩內(nèi)容