多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > React Native開發之動畫(Animations)

React Native開發之動畫(Animations)

來源:程序員人生   發布時間:2016-08-09 08:16:17 閱讀次數:3626次

博主這個系列的文章

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

另外,我在Github上建立了1個倉庫來搜集優秀的React Native庫和優秀的博客等

ReactNativeMaterials


資料

  • 官方關于動畫的介紹
  • 官方給出的復雜動畫的示例
  • 開源項目react-native-animatable
  • React Native Animation Book
  • 可以用在實際項目里的:react-motion

概述

目前,React Native的版本是0.28,主要的動畫分為兩大類

  • LayoutAnimation 用來實現布局切換的動畫
  • Animated 更加精確的交互式的動畫

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


準備工作

本文默許讀者已

  1. 安裝好了React Native
  2. 安裝好了IDE(本文使用Atom+Nuclide),如果沒有安裝過,可以參照最上面的鏈接進行安裝
  3. 使用react-native init Demo --verbose初始化了1個Demo項目

1個簡單的動畫

1個最基本的Animated創建進程以下

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

基于上述的原理,我們來實現第1個動畫。

創建1個Demo工程的時候,運行后,摹擬器截圖應當是醬紫的。

然后,只保存第1行文字,然后我們給這個默許的視圖創建fade in動畫,效果以下

代碼

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

所以說,簡單的動畫就是用Animated.Value指定初始值,然后在Animated.timing中設置結束值,其他的交給React native讓它自動創建,我們只需要調用start開始動畫便可。

在當前版本0.27種,可動畫的視圖包括

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

Animated詳解

方法

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

屬性

  • Value,類型是AnimatedValue,驅動基本動畫
  • AnimatedValueXY,類型是AnimatedValueXY,驅動2維動畫

AnimatedValue類型

1個AnimatedValue1次可以驅動多個可動畫屬性,但是1個AnimatedValue1次只能由1個機制驅動。比如,1個Value可以同時動畫View的透明度和位置,但是1個Value1次只能采取線性時間函數

方法

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

AnimatedValueXY

和AnimatedValue類似,用在2維動畫,使用起來和AnimatedValue類似,這里不在介紹,這里是文檔。


1個更加復雜動畫

有了上文的知識支持,我們可以設計并實現1個更加復雜的動畫了。

  • 這個動畫由button驅動
  • 1個AnimatedValue同時驅動兩3個屬性,透明度,Y的位置和scale

效果

代碼(省略了import和style)

class Demo extends React.Component { state: { fadeAnim: Animated, currentAlpha:number, }; constructor(props) { super(props); this.state = {//設置初值 currentAlpha: 1.0,//標志位,記錄當前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, //透明度動畫 transform: [//transform動畫 { translateY: this.state.fadeAnim.interpolate({ inputRange: [0, 1], outputRange: [60, 0] //線性插值,0對應60,0.6對應30,1對應0 }), }, { scale:this.state.fadeAnim }, ], }}> Welcome to React Native! </Animated.Text> <TouchableOpacity onPress = {()=> this.startAnimation()} style={styles.button}> <Text>Start Animation</Text> </TouchableOpacity> </View> ); } }

手動控制動畫

通過上文的講授,相信讀者已對如何用Animated創建動畫有了最基本的認識。而有些時候,我們需要根據Scroll或手勢來手動的控制動畫的進程。這就是我接下來要講的。
手動控制動畫的核心是Animated.event,
這里的Aniamted.event的輸入是1個數組,用來做數據綁定
比如,
ScrollView中

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

Pan手勢中

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驅動

目標效果 - 隨著ScrollView的相左滑動,最左側的1個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} //水平滑動 showsHorizontalScrollIndicator={false} style={{width:deviceWidth,height:deviceHeight}}//設置大小 onScroll={Animated.event( [{nativeEvent: {contentOffset: {x: this.state.xOffset}}}]//把contentOffset.x綁定給this.state.xOffset )} scrollEventThrottle={100}//onScroll回調間隔 > <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> ); } }

手勢驅動

React Native最經常使用的手勢就是PanResponser,

由于本文側重講授動畫,所以不會特別詳細的介紹PanResponser,僅僅介紹用到的幾個屬性和回調方法

onStartShouldSetPanResponder: (event, gestureState) => {}//是不是相應pan手勢 onPanResponderMove: (event, gestureState) => {}//在pan移動的時候進行的回調 onPanResponderRelease: (event, gestureState) => {}//手離開屏幕 onPanResponderTerminate: (event, gestureState) => {}//手勢中斷

其中,

  • 通過event可以取得觸摸de位置,時間戳等信息。
  • 通過gestureState可以獲得移動的距離,速度等

目標效果- View隨著手拖動而移動,手指離開會到原點

核心代碼

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, //響應手勢 onPanResponderMove: Animated.event( [null, {dx: this.state.trans.x, dy:this.state.trans.y}] // 綁定動畫值 ), onPanResponderRelease: ()=>{//手松開,回到原始位置 Animated.spring(this.state.trans,{toValue: {x: 0, y: 0}} ).start(); }, onPanResponderTerminate:()=>{//手勢中斷,回到原始位置 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個位置變化到另外一個位置的時候,在下1個Layout周期自動創建動畫。通常在setState前掉用LayoutAnimation.configureNext

1個簡單的Demo

代碼

class Demo extends React.Component { state: { marginBottom:number, }; constructor(props) { super(props); this.state = {//設置初值 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> ); } }

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

LayoutAnimation詳解

配置相干

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

屬性

對應3種時間函數

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

我們先創建1個默許的Navigator轉場Demo
回拉的時候,前1個時圖的移動距離要小于后1個視圖

這時候候的核心代碼以下,MainScreen和DetailScreen就是帶1個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的默許的轉場動畫的實現都可以在這里找到NavigatorSceneConfigs.js。

So,我們有兩種方式來實現自定義的轉場動畫

  • 完全的依照NavigatorSceneConfigs.js寫1個轉場
  • 修改NavigatorSceneConfigs.js中已配置的轉場的若干屬性

篇幅限制,本文只修改默許的轉場

比如,我想把默許的PushFromRight動畫中,第1個視圖的移動距離改成全屏幕。

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}

這時候候的動畫以下


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 欧美黄色免费 | 一级白嫩美女毛片免费 | 九九精品久久久久久久久 | 麻豆 一区 精品 在线 | 中文国产成人精品久久一 | 狍和美女一级aa毛片 | 久久亚洲欧美综合激情一区 | 久久精品一区二区三区中文字幕 | 一区视频在线播放 | 国产午夜精品一区二区三区 | 一区二区三区 | 中文字幕在线第一页 | 欧美最猛性xxxxx亚洲精品 | 亚洲 欧美 日韩中文字幕一区二区 | 毛片新网址 | 92看片淫黄大片欧美看国产片 | 在线91色| 色综合天天综合网国产成人网 | 亚洲色图日韩 | 亚洲免费黄色片 | 最近免费中文字幕4 | 亚a在线| 中文字幕久久久久一区 | 国产精品久久久久久搜索 | 日本大蕉香蕉大视频在线观看 | 欧美一本 | 亚州毛色毛片免费观看 | 欧美日韩亚洲国产精品一区二区 | 欧美日本综合 | 精品一区二区三区自拍图片区 | 俄罗斯freexxxx性| 一区二区三区精品 | 在线高清一级欧美精品 | 亚洲日本高清 | 在线看黄色网址 | 亚洲产在线精品第一站不卡 | 国产精品国产亚洲精品看不卡 | 久久亚洲精中文字幕冲田杏梨 | 欧洲性xxx| 国产一区二区三区在线观看精品 | 嫩草影院在线观看未满十八 |