成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

讓React應(yīng)用“動(dòng)”起來(lái)

xiyang / 2236人閱讀

摘要:因?yàn)槠浣M件只是根據(jù)提供的及屬性,生成動(dòng)畫的數(shù)據(jù),業(yè)務(wù)應(yīng)用中拿到生成的數(shù)據(jù)后根據(jù)需要添加需要?jiǎng)赢嫷慕M件樣式。除了上述簡(jiǎn)單的動(dòng)畫應(yīng)用,在復(fù)雜動(dòng)畫的實(shí)現(xiàn)方面,表現(xiàn)非常優(yōu)越。

WEB應(yīng)用中動(dòng)畫很重要

不管是web應(yīng)用還是原生應(yīng)用,也不論是PC端應(yīng)用還是移動(dòng)端應(yīng)用,動(dòng)畫都扮演了一個(gè)重要的角色。

盡管動(dòng)畫并不會(huì)添加應(yīng)用的實(shí)際動(dòng)能,但一個(gè)好的動(dòng)畫,一個(gè)流暢且優(yōu)雅,選擇在恰當(dāng)時(shí)機(jī)出現(xiàn)的動(dòng)畫,能為應(yīng)用增色不少,能很好的引導(dǎo)用戶進(jìn)行下一步操作,讓應(yīng)用的場(chǎng)景切換更合理。一個(gè)小小的細(xì)節(jié)動(dòng)畫,就能幾個(gè)層次的提升應(yīng)用的用戶體驗(yàn)。

舉個(gè)簡(jiǎn)單的例子,應(yīng)用中最常見(jiàn)的頁(yè)面間切換,如果缺少切換動(dòng)畫,那就會(huì)是這個(gè)樣子:

非常生硬,頁(yè)面的出現(xiàn)顯得非常突兀。作為對(duì)比,我們可以看下添加了動(dòng)畫的頁(yè)面切換是什么樣子的呢:

增加了用戶預(yù)期,也能較好的提示用戶頁(yè)面的層級(jí)關(guān)系。

再舉個(gè)彈窗的例子,先放兩個(gè)對(duì)比圖,左邊是無(wú)動(dòng)畫的效果,右邊是添加完動(dòng)畫的效果:

動(dòng)畫雖然沒(méi)有添加什么實(shí)際可見(jiàn)的功能,但是通過(guò)對(duì)比,不難發(fā)現(xiàn),動(dòng)畫的添加,讓彈窗的出現(xiàn)顯得平滑自然,讓頁(yè)面的場(chǎng)景替換有一個(gè)過(guò)程,減少突兀感,讓用戶體驗(yàn)感受增色不少不是嗎?

當(dāng)然有可能因?yàn)殇浿频膯?wèn)題,動(dòng)畫效果不是很明顯,你可能有不同的看法。
動(dòng)畫實(shí)現(xiàn)的基本原理

web應(yīng)用的基本骨架是DOM,正是一個(gè)個(gè)的DOM節(jié)點(diǎn),構(gòu)建出web應(yīng)用,換句話說(shuō),就是web應(yīng)用呈現(xiàn)出來(lái)的樣子是DOM決定的(當(dāng)然這里把CSS樣式,歸納為了DOM的一部分)。所以動(dòng)畫的實(shí)現(xiàn),從本質(zhì)上來(lái)講,就是操作DOM:讓DOM在不同的時(shí)間節(jié)點(diǎn),在不同的位置、有不同的大小、透明度、呈現(xiàn)不同的背景色等,并且讓這種變化連續(xù)起來(lái),則構(gòu)成了我們能觀察到的動(dòng)畫。

基于web動(dòng)畫實(shí)現(xiàn)的基本原理,在我們直接操作DOM的時(shí)代,實(shí)現(xiàn)動(dòng)畫相對(duì)我們來(lái)說(shuō),非常直觀——只要知道怎么操作DOM即可。比如需要實(shí)現(xiàn)一個(gè)黑色背景的div方塊,1s內(nèi)從離左邊距100px的位置,移動(dòng)到離左邊距200px的位置,則我們只需要每秒控制該div的left值增加(200-100)/60px即可實(shí)現(xiàn)一個(gè)勻速的動(dòng)畫效果。怎么樣,很簡(jiǎn)單吧。

上述動(dòng)畫實(shí)現(xiàn)的方式,我們稱為JS動(dòng)畫。是由JS腳本邏輯,動(dòng)態(tài)的改變DOM的CSS屬性值。

CSS3中,添加了動(dòng)畫的實(shí)現(xiàn)的方案,所以web中第二種動(dòng)畫實(shí)現(xiàn),被我們稱為CSS動(dòng)畫。CSS動(dòng)畫,最主要的幾個(gè)CSS屬性是: transition,transform,animation,由于與本文的主題不是密切相關(guān),此處就不做詳細(xì)介紹,有興趣可以自行搜索相關(guān)文章查閱。

MV*模式下的動(dòng)畫實(shí)現(xiàn)

這里的MV*模式我們不展開(kāi)說(shuō),特指React中動(dòng)畫的實(shí)現(xiàn)。React由于加入了虛擬DOM等諸多特性,并且其開(kāi)發(fā)模式讓開(kāi)發(fā)者不需要或者不推薦直接接觸到真實(shí)的DOM結(jié)構(gòu)。所以其動(dòng)畫實(shí)現(xiàn),與常規(guī)的開(kāi)發(fā)方式下的動(dòng)畫實(shí)現(xiàn),存在一定得差異。

動(dòng)畫的實(shí)現(xiàn)最終一定是落地到操作DOM,MV*模式的框架則是數(shù)據(jù)驅(qū)動(dòng)DOM的展示。如果我們因?yàn)閯?dòng)畫實(shí)現(xiàn)的需要,對(duì)DOM的操作出現(xiàn)問(wèn)題,勢(shì)必會(huì)影響到應(yīng)用的相關(guān)操作。我們先不去深入探討怎么解決這個(gè)問(wèn)題,先看看React官方和社區(qū)對(duì)這個(gè)問(wèn)題是怎么解決的,讓我們能先給我們的React應(yīng)用添加上需要的動(dòng)畫。

由淺及深,我們先學(xué)會(huì)怎么使用,再去了解內(nèi)部的實(shí)現(xiàn)原理,從而根據(jù)應(yīng)用自身需求,能實(shí)現(xiàn)自定義的動(dòng)畫,能實(shí)現(xiàn)更為復(fù)雜的交互動(dòng)畫等。

React中我們?cè)趺刺砑觿?dòng)畫

React的動(dòng)畫庫(kù)中,比較常用的是react-addons-css-transition-groupreact-addons-transition-group 以及react-motion 。其中, react-addons-css-transition-groupreact-addons-transition-groupHigh-Level API庫(kù),react-addons-css-transtion-group是基于react-addons-transition-group的上層封裝。目前react-addons-css-transition-groupreact-addons-transition-group合并成一個(gè)庫(kù),叫react-transition-group

[email protected]版本中的API, 基本保持與兩個(gè)多帶帶庫(kù)的API形式一致,但@v2.x版本中的API變化較大,并不能完全切換,這個(gè)需要注意。本文的示例是以獨(dú)立庫(kù),也就是類[email protected]API提供的。

另一個(gè)常用的React動(dòng)畫庫(kù)是react-motion 。該庫(kù)擁有非常棒的特性,能夠創(chuàng)建出非常細(xì)膩的動(dòng)畫,接著往下看,會(huì)介紹下基本的使用,然后參照其官方文檔,相信可以實(shí)現(xiàn)出大多數(shù)你想要的動(dòng)畫的。

1. ReactCSSTransitionGroup

react-addons-css-transition-group,一般稱其export的組件為ReactCSSTransitionGroup,它提供一種聲明的方式來(lái)定義CSS動(dòng)畫。ReactCSSTransitionGroup子組件必須大于或等于1個(gè),不能為空。

ReactCSSTranstionGroup組件暴露的屬性有:

transitionAppear/transitionEnter/transitionLeave: Boolean 類型,標(biāo)識(shí)是否開(kāi)啟動(dòng)畫

transitionAppearTimeout/transitionEnterTimeout/transitionLeaveTimeout: 定義各階段動(dòng)畫的時(shí)長(zhǎng)

transitionName:自定義各階段動(dòng)畫的 CSS 樣式名

component: ReactCSSTranstion以什么組件包裹(wrap)子組件,默認(rèn)為span,可以是React Element 。

我們以 todo-list 為例,看看ReactCSSTransitionGroup怎么使用。由于篇幅限制,todo-list 相關(guān)的業(yè)務(wù)代碼忽略,可以在這里查看完整代碼。以下是動(dòng)畫部分代碼:

index.js:

import React , { Component } from "react" ;
import ReactCSSTranstionGroup from "react-addons-css-transition-group" ;

export default class App extends Component{
    ... ,
    
    render(){
        const { items } = this.state ;
        
        return (
            
... ,
{ items.map((item)=>(
{item}
)) }
) } }

style.css:

.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;
}

有兩點(diǎn)需要注意:

每個(gè)子組件必須有key,這樣ReactCSSTrasntionGroup才能正確的mountingunmounting子組件。

自定義的動(dòng)畫時(shí)長(zhǎng),需要與CSS樣式中定義的動(dòng)畫時(shí)長(zhǎng)對(duì)應(yīng)上。

關(guān)于react-addons-css-transition-group,知乎這篇文章CSS 動(dòng)畫及其在 React 中的應(yīng)用有較為詳細(xì)的介紹。

2. ReactTransitionGroup

react-addons-transition-groupreact-addons-css-transition-grouplow-level API,其提供動(dòng)畫執(zhí)行中需要的各生命周期函數(shù):

componentWillAppear(): componentDidMount時(shí)執(zhí)行, 渲染TransitionGroup時(shí)執(zhí)行并且只會(huì)執(zhí)行一次。

componentDidAppear(): 傳給componentWillAppear的callback執(zhí)行后執(zhí)行。

componentWillEnter(): componentDidMount時(shí)執(zhí)行,子組件添加進(jìn)TransitionGroup時(shí)執(zhí)行。

componentDidEnter(): 傳給componentWillEnter的callback執(zhí)行后執(zhí)行。

componentWillLeave(): 子組件從TransitionGroup中移除時(shí)執(zhí)行,Though the child has been removed, TransitionGroup will keep it in the DOM until callback is called.

componentDidLeave(): componentWillLeave的callback執(zhí)行后執(zhí)行。通常情況下與ComponentWillUnmount的時(shí)機(jī)一致。

那我們看看,同樣以 todo-list 為例, ReactTransitionGroup需要怎么做呢?

index.js:

import React,{ Component } from "react" ;
import ReactTransitionGroup from "react-addons-transition-group" ;

class Item extends Component{
    
    // 獲取組件真實(shí)DOM
    getRef(ref){
        this.ref=ref ;
    }
    
    componentWillEnter(callback){
        this.ref.classList.add("example-enter") ;
        setTimeout(()=>{
          callback() ;
        },500) ;
    }
    
    componentDidEnter(){
        this.ref.classList.add("example-enter-active") ;
    }
    
    componentWillLeave(){
        this.ref.classList.remove("example-enter","example-enter-active") ;
        this.ref.classList.add("example-leave-active","example-leave") ;
        setTimeout(()=>{
          callback() ;
        },300) ;
    }

    render(){
        const { text , onRemove } = this.props ;
        return (
            
{text}
) } } export class App extends Component{ ... , render(){ const { items } = this.state ; return (
... ,
{ items.map((item,i)=>( )) }
) } }

style.css:

.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;
}

相比于ReactCSSTransitionGroup,我們需要自己去控制組件的動(dòng)畫生命周期,增加了一定的復(fù)雜度,但是對(duì)自動(dòng)以動(dòng)畫,又能提供更好的靈活度??梢愿鶕?jù)業(yè)務(wù)場(chǎng)景,選擇合適的Group,去實(shí)現(xiàn)我們的需求。

通常情況下,我們用ReactCSSTransitionGroup就能滿足較多的業(yè)務(wù)場(chǎng)景了,并且從實(shí)現(xiàn)上會(huì)容易很多。

3. ReactMotion

react-motion提供了5個(gè)API接口:

spring: 動(dòng)畫生成方法

Motion: React 組件

StaggeredMotion: React 組件

TransitionMotion: React 組件

presets: spring方法的配置項(xiàng)

跟其他React動(dòng)畫庫(kù)一樣,react-motion也提供React組件去包裹需要?jiǎng)赢嫷臉I(yè)務(wù)組件。其中:

Motion組件只接受一個(gè)children組件

StaggeredMotion組件接受一組children組件

TranstionMotion組件可以支持其children組件mountingunmounting定義動(dòng)畫

仍然是 todo-list 的例子,react-motion的實(shí)現(xiàn)也非常簡(jiǎn)單:

import React,{ Component } from "react" ;
import { Motion , spring } from "react-motion";

export default class App extends Component{
    ... ,
    
    render(){
        const { items } = this.state ;
        return (
            
... ,
{ items.map((item)=>{ return ( { interpolatingStyle => (
{item}
) }
) }) }
) } }

通過(guò)上述簡(jiǎn)單的代碼,即可實(shí)現(xiàn)每個(gè)Item在mounting的時(shí)候漸現(xiàn)的效果。

另一方面,觀察上述實(shí)現(xiàn),我們不難發(fā)現(xiàn),react-motion不僅僅支持React web應(yīng)用,它應(yīng)該也能輕松的應(yīng)用到React-Native中。因?yàn)槠銻eact組件只是根據(jù)提供的defaultStylestyle屬性,生成動(dòng)畫的數(shù)據(jù),業(yè)務(wù)應(yīng)用中拿到生成的數(shù)據(jù)后根據(jù)需要添加需要?jiǎng)赢嫷慕M件樣式。react-motion在web應(yīng)用中性能表現(xiàn)較為可觀,在React-Native應(yīng)用中的性能表現(xiàn),有待我們調(diào)研。

除了上述簡(jiǎn)單的動(dòng)畫應(yīng)用,react-motion在復(fù)雜動(dòng)畫的實(shí)現(xiàn)方面,表現(xiàn)非常優(yōu)越。下面的動(dòng)圖是react-motion實(shí)現(xiàn)的一個(gè)動(dòng)畫演示:

這個(gè)示例展示了部分react-motion的能力,更多關(guān)于react-motion的應(yīng)用就讓我們一起去發(fā)現(xiàn)吧。

結(jié)語(yǔ)

當(dāng)然React動(dòng)畫相關(guān)的庫(kù)還有很多,本文不過(guò)多介紹。通過(guò)上述對(duì)這些庫(kù)的使用做簡(jiǎn)單介紹,筆者希望通過(guò)對(duì)它們實(shí)現(xiàn)進(jìn)行分析,讓讀者能更好的理解與掌握,能對(duì)React動(dòng)畫的實(shí)現(xiàn)原理和實(shí)現(xiàn)方式,有更為清晰的認(rèn)識(shí)。

但是對(duì)相關(guān)代碼的研究,深入度還不足以給讀者朋友分享,所以暫時(shí)留坑,后續(xù)會(huì)將相關(guān)源碼的學(xué)習(xí),記錄在文檔React動(dòng)畫的實(shí)現(xiàn)原理一文中,并計(jì)劃添加從零開(kāi)始,實(shí)現(xiàn)React動(dòng)畫文章作為學(xué)習(xí)成果。如果對(duì)React動(dòng)畫保有興趣,可以關(guān)注這兩篇文章的后續(xù)內(nèi)容。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94656.html

相關(guān)文章

  • React Motion 緩動(dòng)函數(shù)剖析

    摘要:大家可以嘗試使用的,配置一個(gè)合適的勁度系數(shù)和空氣阻力。所做的事,只不過(guò)自己實(shí)現(xiàn)了一套緩動(dòng)函數(shù)。 根據(jù)經(jīng)典力學(xué)的觀點(diǎn),世界上所有的原子每時(shí)每刻仿佛都會(huì)根據(jù)當(dāng)前速度、受力和位置計(jì)算出下一刻的速度、受力和位置。上帝有一臺(tái)超級(jí)計(jì)算機(jī)嗎?非也,反而計(jì)算機(jī)是我們利用原子的這些特性拼裝出來(lái)的?,F(xiàn)在,我們卻要用計(jì)算機(jī),像上帝那樣,再造一個(gè)世界。 我不知道這個(gè)世界上有沒(méi)有仿世學(xué),但是既然動(dòng)畫是要模仿現(xiàn)實(shí)...

    wfc_666 評(píng)論0 收藏0
  • react進(jìn)階漫談

    摘要:父組件向子組件之間非常常見(jiàn),通過(guò)機(jī)制傳遞即可。我們應(yīng)該聽(tīng)說(shuō)過(guò)高階函數(shù),這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù),比如以及等函數(shù)。在傳遞數(shù)據(jù)的時(shí)候,我們可以用進(jìn)一步提高性能。 本文主要談自己在react學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些經(jīng)驗(yàn)和資源,內(nèi)容邏輯參考了深入react技術(shù)棧一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考。 本文的關(guān)鍵...

    neuSnail 評(píng)論0 收藏0
  • react進(jìn)階漫談

    摘要:父組件向子組件之間非常常見(jiàn),通過(guò)機(jī)制傳遞即可。我們應(yīng)該聽(tīng)說(shuō)過(guò)高階函數(shù),這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù),比如以及等函數(shù)。在傳遞數(shù)據(jù)的時(shí)候,我們可以用進(jìn)一步提高性能。 本文主要談自己在react學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些經(jīng)驗(yàn)和資源,內(nèi)容邏輯參考了深入react技術(shù)棧一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考。 本文的關(guān)鍵...

    wyk1184 評(píng)論0 收藏0
  • react進(jìn)階漫談

    摘要:父組件向子組件之間非常常見(jiàn),通過(guò)機(jī)制傳遞即可。我們應(yīng)該聽(tīng)說(shuō)過(guò)高階函數(shù),這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù),比如以及等函數(shù)。在傳遞數(shù)據(jù)的時(shí)候,我們可以用進(jìn)一步提高性能。 本文主要談自己在react學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些經(jīng)驗(yàn)和資源,內(nèi)容邏輯參考了深入react技術(shù)棧一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考。 本文的關(guān)鍵...

    junnplus 評(píng)論0 收藏0
  • 使用 React Native 構(gòu)建 Facebook Paper 類似的 UI

    摘要:我模仿的應(yīng)用構(gòu)建了一個(gè)開(kāi)閉卡片的輪播效果作為技術(shù)演示它使用了及其動(dòng)畫庫(kù)當(dāng)人們聽(tīng)到后第一反應(yīng)會(huì)覺(jué)得它運(yùn)行緩慢這是因?yàn)橐话闳藭?huì)去這樣解釋它允許你通過(guò)構(gòu)建你的應(yīng)用程序而人們會(huì)認(rèn)為瀏覽器中運(yùn)行的性能并不夠好但事實(shí)是它采用的全部都是原生界面元素但你通 我模仿 Facebook 的 Paper 應(yīng)用構(gòu)建了一個(gè)開(kāi)閉卡片的輪播效果作為技術(shù)演示.它使用了 React Native 及其動(dòng)畫庫(kù). 當(dāng)人們聽(tīng)...

    justjavac 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<