react-native的Animated動畫基本詳解

一.介紹

動畫類型:

spring:基礎(chǔ)的單次彈跳物理模型
timing:從時間范圍映射到漸變的值
decay:以一個初始速度開始并且逐漸減慢停止

創(chuàng)建動畫的參數(shù):

value:AnimatedValue | AnimatedValueXY(X軸或Y軸 | X軸和Y軸)
config:SpringAnimationConfig | TimingAnimationConfig | DecayAnimationConfig(動畫的參數(shù)配置)

組件類型:

Animated.Text
Animated.Image
Animated.View:可以用來包裹任意視圖
Animated.createAnimatedComponent():其它組件(較少用,用Animated.View包裹可以達(dá)到同樣的效果)

import React, {Component} from 'react';

import {
    StyleSheet,
    View,
    Animated,
    Image,
    Easing
} from 'react-native';
import {Button} from "react-native-elements";

/**
 * @mark 文件內(nèi)變量
 */

//文件內(nèi)變量結(jié)束

export default class AnimatedDeomo extends React.Component {

    /***
     * default props value
     * @mark propTypes 默認(rèn)屬性值
     */
    static defaultProps = {}

    /***
     * props types for helper text
     * @mark propTypes 屬性類型
     */
    static propTypes = {}

    /**
     * @mark state
     */
    state = {
        fadeOutOpacity: new Animated.Value(0),
        trans: new Animated.ValueXY({
            x: 0,
            y: 0
        }),
        rotation: new Animated.Value(0),
        scale: new Animated.Value(1),
        left: new Animated.Value(0),
    }

    /**
     * @mark constructor
     */
    constructor(props) {
        super(props);
    }

    /**
     * @mark 組件聲明周期區(qū)域
     */

    /**
     * @mark 第一次加載 只運行一次
     */
    componentDidMount() {

    }

    //聲明周期代碼結(jié)束

    /**
     * @mark 自定義代碼區(qū)
     */

    /**
     * @mark 淡入淡出
     */
    OpacityHandle(){
        this.startOpacity();
    }
    startOpacity() {
        Animated.timing(this.state.fadeOutOpacity, {
            toValue: 1,
            duration: 2000,
            easing: Easing.linear,// 線性的漸變函數(shù)
        }).start();
    }


    /**
     * @mark 位移
     */
    TransHandle(){
        this.startTrans();
    }
    startTrans() {
        Animated.timing(this.state.trans, {
            toValue: {
                x: 100,
                y: 100
            },
            duration: 2000,
        }).start();
    }
    /**
     * @mark 旋轉(zhuǎn)并且持續(xù)進(jìn)行動畫
     */
    RotationHandle(){
        this.startRotation();
    }
    startRotation(){
        this.state.rotation.setValue(0);
        Animated.timing(this.state.rotation, {
            toValue: 1,        //屬性目標(biāo)值
            duration: 2000    //動畫執(zhí)行時間
        }).start(() => this.RotationHandle());   //執(zhí)行動畫
    }

    /**
     * @mark 縮放+spring摩擦力
     */
    ScaleHandle(){
        this.startScale();
    }
    startScale(){

        Animated.spring(this.state.scale, {
            toValue: 2,  //屬性目標(biāo)值
            duration: 500,
            friction: 5,        //摩擦力 (越小 振幅越大)
            tension: 1000,        //拉力
        }).start();            //執(zhí)行動畫
        /*Animated.timing(this.state.scale, {
            toValue: 2,
            duration: 500,
        }).start();*/
    }

    /**
     * @mark 滾動
     */
    LeftHandle(){
        this.startLeft();
    }
    startLeft(){
        Animated.timing(this.state.left, {
            toValue: 1,
            duration: 3000,
        }).start();
    }


    //自定義代碼區(qū)結(jié)束

    /**
     * @mark render
     */
    render() {
        return <View style={styles.AnimatedDeomo}>
            <Animated.View // 可選的基本組件類型: Image, Text, View(可以包裹任意子View)
                style = {{alignItems: 'center',justifyContent: 'center',width:Theme.size.width,height:Theme.size.height/2,
                    opacity: this.state.fadeOutOpacity,

                    //可以修改成Left 豪硅,Right伪很,top幸缕,進(jìn)行位移轉(zhuǎn)換
                    bottom:this.state.left.interpolate({
                        inputRange:[0,1],
                        outputRange:[0, Theme.size.width/2]
                    }),
                    transform:[
                        {
                            rotateX: this.state.rotation.interpolate({
                                inputRange:[0,1],
                                outputRange:['0deg','360deg']
                            })
                        },

                        {scale: this.state.scale}
                    ]}}>
                <Image resizeMode="cover" style={{width:40,height:40,}} source = {require("../../imgs/logo.png")}
                />
            </Animated.View >
            <Button
                fontSize={Theme.fontSize.max}
                buttonStyle={styles.loginBtn}
                onPress={this.OpacityHandle.bind(this)}
                title='淡入淡出'
            />
            <Button
                fontSize={Theme.fontSize.max}
                buttonStyle={styles.loginBtn}
                onPress={this.TransHandle.bind(this)}
                title='位移'
            />
            <Button
                fontSize={Theme.fontSize.max}
                buttonStyle={styles.loginBtn}
                onPress={this.RotationHandle.bind(this)}
                title='旋轉(zhuǎn)'
            />
            <Button
                fontSize={Theme.fontSize.max}
                buttonStyle={styles.loginBtn}
                onPress={this.ScaleHandle.bind(this)}
                title='縮放'
            />
            <Button
                fontSize={Theme.fontSize.max}
                buttonStyle={styles.loginBtn}
                onPress={this.LeftHandle.bind(this)}
                title='滾動'
            />
        </View>
    }
}

//@mark style
const styles = StyleSheet.create({
    AnimatedDeomo: {
        flex:1
    },
    loginBtn:{
        marginTop:Theme.padding.less,
        backgroundColor:Theme.color.orange,
        borderRadius:Theme.radius.small
    }
});

通過上文的講解漠烧,相信讀者已經(jīng)對如何用Animated創(chuàng)建動畫有了最基本的認(rèn)識梆掸。而有些時候栋烤,我們需要根據(jù)Scroll或者手勢來手動的控制動畫的過程。這就是我接下來要講的股淡。
手動控制動畫的核心是Animated.event,
這里的Aniamted.event的輸入是一個數(shù)組,用來做數(shù)據(jù)綁定
比如,

ScrollView中

onScroll={Animated.event(
           [{nativeEvent: {contentOffset: {x: this.state.xOffset}}}]//把contentOffset.x綁定給this.state.xOffset
)}
export default class ScrollAnimated extends React.Component {

    /***
     * default props value
     * @mark propTypes 默認(rèn)屬性值
     */
    static defaultProps = {}

    /***
     * props types for helper text
     * @mark propTypes 屬性類型
     */
    static propTypes = {}

    /**
     * @mark state
     */
    state = {
        xOffset: new Animated.Value(0)
    }

    /**
     * @mark constructor
     */
    constructor(props) {
        super(props);
    }

    /**
     * @mark 組件聲明周期區(qū)域
     */

    /**
     * @mark 第一次加載 只運行一次
     */
    componentDidMount() {

    }

    //聲明周期代碼結(jié)束

    /**
     * @mark 自定義代碼區(qū)
     */


    //自定義代碼區(qū)結(jié)束

    /**
     * @mark render
     */
    render() {
        return <View style={styles.ScrollAnimated}>

            <ScrollView
                        style={{height: Theme.size.height, width: Theme.size.width}}//設(shè)置大小
                        onScroll={Animated.event(
                            [{nativeEvent: {contentOffset: {y: this.state.xOffset}}}]//把contentOffset.x綁定給this.state.xOffset
                        )}
                        scrollEventThrottle={100}//onScroll回調(diào)間隔
            >

                <Image source={require('../../imgs/1.png')} style={{height: Theme.size.height, width: Theme.size.width}}
                       resizeMode="cover"/>
                <Image source={require('../../imgs/2.png')} style={{height: Theme.size.height, width: Theme.size.width}}
                       resizeMode="cover"/>
                <Image source={require('../../imgs/3.png')} style={{height: Theme.size.height, width: Theme.size.width}}
                       resizeMode="cover"/>
            </ScrollView>
            <Animated.View // 可選的基本組件類型: Image, Text, View(可以包裹任意子View)
                style = {[ styles.titleView,{ opacity:this.state.xOffset.interpolate({//映射到0.0,1.0之間
                    inputRange: [0,Theme.size.height],
                    outputRange: [0.0, 1.0]
                }),

                }]}>
                <Text style={{color:Theme.color.white,fontSize:15,textAlign:'center'}}>標(biāo)題</Text>
            </Animated.View >
        </View>
    }
}

//@mark style
const styles = StyleSheet.create({
    ScrollAnimated: {
    },
    titleView:{
        alignItems: 'center',
        justifyContent: 'center',
        width:Theme.size.width,
        height:40,
        backgroundColor:Theme.color.orange,
        position: "absolute",
        top: 0,
        left: 0
    }
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末廷区,一起剝皮案震驚了整個濱河市唯灵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隙轻,老刑警劉巖埠帕,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垢揩,死亡現(xiàn)場離奇詭異,居然都是意外死亡敛瓷,警方通過查閱死者的電腦和手機(jī)叁巨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呐籽,“玉大人锋勺,你說我怎么就攤上這事〗频” “怎么了庶橱?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贪惹。 經(jīng)常有香客問我苏章,道長,這世上最難降的妖魔是什么奏瞬? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任枫绅,我火速辦了婚禮,結(jié)果婚禮上硼端,老公的妹妹穿的比我還像新娘并淋。我一直安慰自己,他們只是感情好显蝌,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布预伺。 她就那樣靜靜地躺著,像睡著了一般曼尊。 火紅的嫁衣襯著肌膚如雪酬诀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天骆撇,我揣著相機(jī)與錄音瞒御,去河邊找鬼。 笑死神郊,一個胖子當(dāng)著我的面吹牛肴裙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涌乳,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蜻懦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了夕晓?” 一聲冷哼從身側(cè)響起宛乃,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后征炼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體析既,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年谆奥,在試婚紗的時候發(fā)現(xiàn)自己被綠了眼坏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡酸些,死狀恐怖宰译,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情擂仍,我是刑警寧澤囤屹,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站逢渔,受9級特大地震影響肋坚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肃廓,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一智厌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盲赊,春花似錦铣鹏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绘迁,卻和暖如春合溺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缀台。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工棠赛, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膛腐。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓睛约,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哲身。 傳聞我的和親對象是個殘疾皇子辩涝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

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