日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開源 > 綜合技術(shù) > React Native開發(fā)之動(dòng)畫(Animations)

React Native開發(fā)之動(dòng)畫(Animations)

來(lái)源:程序員人生   發(fā)布時(shí)間:2016-08-09 08:16:17 閱讀次數(shù):3640次

博主這個(gè)系列的文章

  • React Native開發(fā)之IDE(Atom+Nuclide)
  • React Native開發(fā)之FlexBox代碼+圖解
  • React Native的Navigator詳解

另外,我在Github上建立了1個(gè)倉(cāng)庫(kù)來(lái)搜集優(yōu)秀的React Native庫(kù)和優(yōu)秀的博客等

ReactNativeMaterials


資料

  • 官方關(guān)于動(dòng)畫的介紹
  • 官方給出的復(fù)雜動(dòng)畫的示例
  • 開源項(xiàng)目react-native-animatable
  • React Native Animation Book
  • 可以用在實(shí)際項(xiàng)目里的:react-motion

概述

目前,React Native的版本是0.28,主要的動(dòng)畫分為兩大類

  • LayoutAnimation 用來(lái)實(shí)現(xiàn)布局切換的動(dòng)畫
  • Animated 更加精確的交互式的動(dòng)畫

目前React native的release速度還是比較快的,每隔2周左右就release1次。


準(zhǔn)備工作

本文默許讀者已

  1. 安裝好了React Native
  2. 安裝好了IDE(本文使用Atom+Nuclide),如果沒(méi)有安裝過(guò),可以參照最上面的鏈接進(jìn)行安裝
  3. 使用react-native init Demo --verbose初始化了1個(gè)Demo項(xiàng)目

1個(gè)簡(jiǎn)單的動(dòng)畫

1個(gè)最基本的Animated創(chuàng)建進(jìn)程以下

  1. 創(chuàng)建Animated.Value,設(shè)置初始值,比如1個(gè)視圖的opacity屬性,最開始設(shè)置Animated.Value(0),來(lái)表示動(dòng)畫的開始時(shí)候,視圖是全透明的。
  2. AnimatedValue綁定到Style的可動(dòng)畫屬性,比如透明度,{opacity: this.state.fadeAnim}
  3. 使用Animated.timing來(lái)創(chuàng)建自動(dòng)的動(dòng)畫,或使用Animated.event來(lái)根據(jù)手勢(shì),觸摸,Scroll的動(dòng)態(tài)更新動(dòng)畫的狀態(tài)(本文會(huì)側(cè)重講授Animated.timing
  4. 調(diào)用Animated.timeing.start()開始動(dòng)畫

基于上述的原理,我們來(lái)實(shí)現(xiàn)第1個(gè)動(dòng)畫。

創(chuàng)建1個(gè)Demo工程的時(shí)候,運(yùn)行后,摹擬器截圖應(yīng)當(dāng)是醬紫的。

然后,只保存第1行文字,然后我們給這個(gè)默許的視圖創(chuàng)建fade in動(dòng)畫,效果以下

代碼

class Demo extends React.Component { state: { //可以不寫,我這里寫是為了去除flow正告 fadeAnim: Object, }; constructor(props) { super(props); this.state = { fadeAnim: new Animated.Value(0), //設(shè)置初始值 }; } componentDidMount() { Animated.timing( this.state.fadeAnim,//初始值 {toValue: 1}//結(jié)束值 ).start();//開始 } render() { return ( <View style={styles.container}> <Animated.Text style={{opacity: this.state.fadeAnim}}>//綁定到屬性 Welcome to React Native! </Animated.Text> </View> ); } }

所以說(shuō),簡(jiǎn)單的動(dòng)畫就是用Animated.Value指定初始值,然后在Animated.timing中設(shè)置結(jié)束值,其他的交給React native讓它自動(dòng)創(chuàng)建,我們只需要調(diào)用start開始動(dòng)畫便可。

在當(dāng)前版本0.27種,可動(dòng)畫的視圖包括

  • View
  • Text
  • Image
  • createAnimatedComponent(自定義)

Animated詳解

方法

  • static decay(value, config) 阻尼,將1個(gè)值根據(jù)阻尼系數(shù)動(dòng)畫到 0
  • static timing(value, config 根據(jù)時(shí)間函數(shù)來(lái)處理,常見的比如線性,加速開始減速結(jié)束等等,支持自定義時(shí)間函數(shù)
  • static spring(value, config) 彈性動(dòng)畫
  • static add(a, b) 將兩個(gè)Animated.value相加,返回1個(gè)新的
  • static multiply(a, b) 將兩個(gè)Animated.value相乘,返回1個(gè)新的
  • static modulo(a, modulus),將a對(duì)modulus取余,類似操作符%
  • static delay(time)延遲1段時(shí)間
  • static sequence(animations) 順次開始1組動(dòng)畫,后1個(gè)在前1個(gè)結(jié)束后才會(huì)開始,如果其中1個(gè)動(dòng)畫中途停止,則全部動(dòng)畫組停止
  • static parallel(animations, config?),同時(shí)開始1組動(dòng)畫,默許1個(gè)動(dòng)畫中途停止,則全都停止。可以通過(guò)設(shè)置stopTogether來(lái)重寫這1特性
  • static stagger(time, animations),1組動(dòng)畫可以同時(shí)履行,但是會(huì)依照延遲順次開始
  • static event(argMapping, config?),利用手勢(shì),Scroll來(lái)手動(dòng)控制動(dòng)畫的狀態(tài)
  • static createAnimatedComponent(Component),自定義的讓某1個(gè)Component支持動(dòng)畫

屬性

  • Value,類型是AnimatedValue,驅(qū)動(dòng)基本動(dòng)畫
  • AnimatedValueXY,類型是AnimatedValueXY,驅(qū)動(dòng)2維動(dòng)畫

AnimatedValue類型

1個(gè)AnimatedValue1次可以驅(qū)動(dòng)多個(gè)可動(dòng)畫屬性,但是1個(gè)AnimatedValue1次只能由1個(gè)機(jī)制驅(qū)動(dòng)。比如,1個(gè)Value可以同時(shí)動(dòng)畫View的透明度和位置,但是1個(gè)Value1次只能采取線性時(shí)間函數(shù)

方法

  • constructor(value) 構(gòu)造器
  • setValue(value) 直接設(shè)置值,會(huì)致使動(dòng)畫終止
  • setOffset(offset) 設(shè)置當(dāng)前的偏移量
  • flattenOffset() 將偏移量合并到最初值中,并把偏移量設(shè)為0,
  • addListener(callback) ,removeListener(id),removeAllListeners(),增加1個(gè)異步的動(dòng)畫監(jiān)聽者
  • stopAnimation(callback?) 終止動(dòng)畫,并在動(dòng)畫結(jié)束后履行callback
  • interpolate(config) 插值,在更新可動(dòng)畫屬性前用插值函數(shù)對(duì)當(dāng)前值進(jìn)行變換
  • animate(animation, callback) 通常在React Native內(nèi)部使用
  • stopTracking(),track(tracking) 通常在React Native內(nèi)部使用

AnimatedValueXY

和AnimatedValue類似,用在2維動(dòng)畫,使用起來(lái)和AnimatedValue類似,這里不在介紹,這里是文檔。


1個(gè)更加復(fù)雜動(dòng)畫

有了上文的知識(shí)支持,我們可以設(shè)計(jì)并實(shí)現(xiàn)1個(gè)更加復(fù)雜的動(dòng)畫了。

  • 這個(gè)動(dòng)畫由button驅(qū)動(dòng)
  • 1個(gè)AnimatedValue同時(shí)驅(qū)動(dòng)兩3個(gè)屬性,透明度,Y的位置和scale

效果

代碼(省略了import和style)

class Demo extends React.Component { state: { fadeAnim: Animated, currentAlpha:number, }; constructor(props) { super(props); this.state = {//設(shè)置初值 currentAlpha: 1.0,//標(biāo)志位,記錄當(dāng)前value fadeAnim: new Animated.Value(1.0) }; } startAnimation(){ this.state.currentAlpha = this.state.currentAlpha == 1.0?0.0:1.0; Animated.timing( this.state.fadeAnim, {toValue: this.state.currentAlpha} ).start(); } render() { return ( <View style={styles.container}> <Animated.Text style={{opacity: this.state.fadeAnim, //透明度動(dòng)畫 transform: [//transform動(dòng)畫 { translateY: this.state.fadeAnim.interpolate({ inputRange: [0, 1], outputRange: [60, 0] //線性插值,0對(duì)應(yīng)60,0.6對(duì)應(yīng)30,1對(duì)應(yīng)0 }), }, { scale:this.state.fadeAnim }, ], }}> Welcome to React Native! </Animated.Text> <TouchableOpacity onPress = {()=> this.startAnimation()} style={styles.button}> <Text>Start Animation</Text> </TouchableOpacity> </View> ); } }

手動(dòng)控制動(dòng)畫

通過(guò)上文的講授,相信讀者已對(duì)如何用Animated創(chuàng)建動(dòng)畫有了最基本的認(rèn)識(shí)。而有些時(shí)候,我們需要根據(jù)Scroll或手勢(shì)來(lái)手動(dòng)的控制動(dòng)畫的進(jìn)程。這就是我接下來(lái)要講的。
手動(dòng)控制動(dòng)畫的核心是Animated.event,
這里的Aniamted.event的輸入是1個(gè)數(shù)組,用來(lái)做數(shù)據(jù)綁定
比如,
ScrollView中

onScroll={Animated.event( [{nativeEvent: {contentOffset: {x: this.state.xOffset}}}]//把contentOffset.x綁定給this.state.xOffset )}

Pan手勢(shì)中

onPanResponderMove: Animated.event([ null,//疏忽native event {dx: this.state.pan.x, dy: this.state.pan.y},//dx,dy分別綁定this.state.pan.x和this.state.pan.y ])

Scroll驅(qū)動(dòng)

目標(biāo)效果 - 隨著ScrollView的相左滑動(dòng),最左側(cè)的1個(gè)Image透明度逐步下降為0

核心代碼

var deviceHeight = require('Dimensions').get('window').height; var deviceWidth = require('Dimensions').get('window').width; class Demo extends React.Component { state: { xOffset: Animated, }; constructor(props) { super(props); this.state = { xOffset: new Animated.Value(1.0) }; } render() { return ( <View style={styles.container}> <ScrollView horizontal={true} //水平滑動(dòng) showsHorizontalScrollIndicator={false} style={{width:deviceWidth,height:deviceHeight}}//設(shè)置大小 onScroll={Animated.event( [{nativeEvent: {contentOffset: {x: this.state.xOffset}}}]//把contentOffset.x綁定給this.state.xOffset )} scrollEventThrottle={100}//onScroll回調(diào)間隔 > <Animated.Image source={require('./s1.jpg')} style={{height:deviceHeight, width:deviceWidth, opacity:this.state.xOffset.interpolate({//映照到0.0,1.0之間 inputRange: [0,375], outputRange: [1.0, 0.0] }),}} resizeMode="cover" /> <Image source={require('./s2.jpg')} style={{height:deviceHeight, width:deviceWidth}} resizeMode="cover" /> <Image source={require('./s3.jpg')} style={{height:deviceHeight, width:deviceWidth}} resizeMode="cover" /> </ScrollView> </View> ); } }

手勢(shì)驅(qū)動(dòng)

React Native最經(jīng)常使用的手勢(shì)就是PanResponser,

由于本文側(cè)重講授動(dòng)畫,所以不會(huì)特別詳細(xì)的介紹PanResponser,僅僅介紹用到的幾個(gè)屬性和回調(diào)方法

onStartShouldSetPanResponder: (event, gestureState) => {}//是不是相應(yīng)pan手勢(shì) onPanResponderMove: (event, gestureState) => {}//在pan移動(dòng)的時(shí)候進(jìn)行的回調(diào) onPanResponderRelease: (event, gestureState) => {}//手離開屏幕 onPanResponderTerminate: (event, gestureState) => {}//手勢(shì)中斷

其中,

  • 通過(guò)event可以取得觸摸de位置,時(shí)間戳等信息。
  • 通過(guò)gestureState可以獲得移動(dòng)的距離,速度等

目標(biāo)效果- View隨著手拖動(dòng)而移動(dòng),手指離開會(huì)到原點(diǎn)

核心代碼

class Demo extends React.Component { state:{ trans:AnimatedValueXY, } _panResponder:PanResponder; constructor(props) { super(props); this.state = { trans: new Animated.ValueXY(), }; this._panResponder = PanResponder.create({ onStartShouldSetPanResponder: () => true, //響應(yīng)手勢(shì) onPanResponderMove: Animated.event( [null, {dx: this.state.trans.x, dy:this.state.trans.y}] // 綁定動(dòng)畫值 ), onPanResponderRelease: ()=>{//手松開,回到原始位置 Animated.spring(this.state.trans,{toValue: {x: 0, y: 0}} ).start(); }, onPanResponderTerminate:()=>{//手勢(shì)中斷,回到原始位置 Animated.spring(this.state.trans,{toValue: {x: 0, y: 0}} ).start(); }, }); } render() { return ( <View style={styles.container}> <Animated.View style={{width:100, height:100, borderRadius:50, backgroundColor:'red', transform:[ {translateY:this.state.trans.y}, {translateX:this.state.trans.x}, ], }} {...this._panResponder.panHandlers} > </Animated.View> </View> ); } }

LayoutAnimation

LayoutAnimation在View由1個(gè)位置變化到另外一個(gè)位置的時(shí)候,在下1個(gè)Layout周期自動(dòng)創(chuàng)建動(dòng)畫。通常在setState前掉用LayoutAnimation.configureNext

1個(gè)簡(jiǎn)單的Demo

代碼

class Demo extends React.Component { state: { marginBottom:number, }; constructor(props) { super(props); this.state = {//設(shè)置初值 marginBottom:0 }; } _textUp(){ LayoutAnimation.spring(); this.setState({marginBottom:this.state.marginBottom + 100}) } render() { return ( <View style={styles.container}> <TouchableOpacity onPress = {()=>this._textUp()} style={{ width:120, height:40, alignItems:'center', marginBottom:this.state.marginBottom, justifyContent:'center', backgroundColor:'#00ffff', borderRadius:20}}> <Text>Text UP</Text> </TouchableOpacity> </View> ); } }

其實(shí)代碼里只是調(diào)用了這1行LayoutAnimation.spring();,布局修改的時(shí)候就顯得不那末僵硬了

LayoutAnimation詳解

配置相干

//配置下1次切換的效果,其中config可配置的包括duration(時(shí)間),create(配置新的View),update(配置更新的View) static configureNext(config, onAnimationDidEnd?) //configureNext的方便方法 static create(duration, type, creationProp) #

屬性

對(duì)應(yīng)3種時(shí)間函數(shù)

easeInEaseOut: CallExpression # linear: CallExpression # spring: CallExpression #

我們先創(chuàng)建1個(gè)默許的Navigator轉(zhuǎn)場(chǎng)Demo
回拉的時(shí)候,前1個(gè)時(shí)圖的移動(dòng)距離要小于后1個(gè)視圖

這時(shí)候候的核心代碼以下,MainScreen和DetailScreen就是帶1個(gè)Button的視圖

class Demo extends React.Component{ render(){ return ( <Navigator style = {styles.container} initialRoute={{id:"main",}} renderScene={this.renderNav} configureScene={(route, routeStack) => Navigator.SceneConfigs.PushFromRight} /> ); } renderNav(route,nav){ switch (route.id) { case 'main': return <MainScreen navigator={nav} title="Main"/ >; case 'detail': return (<DetailScreen navigator={nav} title="Detail"/ >); } } }

Navigator的默許的轉(zhuǎn)場(chǎng)動(dòng)畫的實(shí)現(xiàn)都可以在這里找到NavigatorSceneConfigs.js。

So,我們有兩種方式來(lái)實(shí)現(xiàn)自定義的轉(zhuǎn)場(chǎng)動(dòng)畫

  • 完全的依照NavigatorSceneConfigs.js寫1個(gè)轉(zhuǎn)場(chǎng)
  • 修改NavigatorSceneConfigs.js中已配置的轉(zhuǎn)場(chǎng)的若干屬性

篇幅限制,本文只修改默許的轉(zhuǎn)場(chǎng)

比如,我想把默許的PushFromRight動(dòng)畫中,第1個(gè)視圖的移動(dòng)距離改成全屏幕。

var ToTheLeftCustom = { transformTranslate: { from: {x: 0, y: 0, z: 0}, to: {x: -SCREEN_WIDTH, y: 0, z: 0},//修改這1行 min: 0, max: 1, type: 'linear', extrapolate: true, round: PixelRatio.get(), }, opacity: { value: 1.0, type: 'constant', }, }; var baseInterpolators = Navigator.SceneConfigs.PushFromRight.animationInterpolators; var customInterpolators = Object.assign({}, baseInterpolators, { out: buildStyleInterpolator(ToTheLeftCustom), }); var baseConfig = Navigator.SceneConfigs.PushFromRight; var CustomPushfromRight = Object.assign({}, baseConfig, { animationInterpolators: customInterpolators, });

然后,修改Navigator的configScene

configureScene={(route, routeStack) => baseConfig}

這時(shí)候候的動(dòng)畫以下


生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 国产精品一级片 | 在线射 | 91在线视频播放 | 国产精品视频1区 | 久久久在线 | 免费偷拍视频 | 国产成人高清 | 国产精品一区二区av | 国产成人精品在线 | 精品视频在线播放 | 亚洲一区高清 | 波多野结衣精品视频 | 国产精品国产馆在线真实露脸 | 中文字幕一区二区三区在线视频 | 91久久精品国产91久久 | 毛片久久久| 亚洲精品一区二区三区 | 久久99精品久久久久久久青青日本 | www久久com| 久久精品视频偷拍 | 麻豆网站 | 牛牛在线视频 | 911影院在线观看网站 | 国产91一区 | 999精品视频 | 国产欧美日韩在线 | 黄网在线免费观看 | 久久小视频 | 精品国产31久久久久久 | 久久999免费视频 | 性欧美另类 | 美女视频91 | 成人黄色av网站 | 国产 欧美 日韩 一区 | 亚洲欧美日韩系列 | 日本色综合 | 久久久蜜桃| 国产精品18久久久 | 色五月成人 | 五月婷婷精品 | 成年女人免费又黄又爽视频 |