React Native動畫-Animated


動畫類型:

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

創建動畫的參數:

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

值類型:

  • AnimatedValue:單個值
  • AnimatedValueXY:向量值

多數情況下,AnimatedValue可以滿足需求(上面的示例),但有些情況下我們可能會需要AnimatedValueXY

比如:我們需要圖片沿着X軸和Y軸交叉方向,向右下角移動一小段距離。

組件類型:

  • Animated.Text
  • Animated.Image
  • Animated.View:可以用來包裹任意視圖
  • Animated.createAnimatedComponent():其它組件(較少用,用Animated.View包裹可以達到同樣的效果
  • 讓我們來看一個示例:圖片透明度2秒內從不透明到全透明,線性變化。

     

    class Demo8 extends Component {
      // 構造
      constructor(props) {
          super(props);
          // 初始狀態
          this.state = {
              fadeOutOpacity: new Animated.Value(0),
          };
      }
      render() {
          return ( 
            <Animated.View // 可選的基本組件類型: Image, Text, View(可以包裹任意子View)
                style = {{flex: 1,alignItems: 'center',justifyContent: 'center',
                        opacity: this.state.fadeOutOpacity,}}> 
                <Image source = {{uri: 'http://i.imgur.com/XMKOH81.jpg'}}
                    style = {{width: 400,height: 400}}/>
            </Animated.View > 
          );
      }
      startAnimation() {
          this.state.fadeOutOpacity.setValue(1);
          Animated.timing(this.state.fadeOutOpacity, {
              toValue: 0,
              duration: 2000,
              easing: Easing.linear,// 線性的漸變函數
          }).start();
      }
      componentDidMount() {
          this.startAnimation();
      }
    }
    AppRegistry.registerComponent('Demo8', () = >Demo8);

     

插值函數:
將輸入值范圍轉換為輸出值范圍,如下:將0-1數值轉換為0deg-360deg角度,旋轉View時你會用到

//其中,transform是一個變換數組,常用的有scale, scaleX, scaleY, translateX, translateY, rotate, rotateX, rotateY, rotateZ:
...
transform: [  // scale, scaleX, scaleY, translateX, translateY, rotate, rotateX, rotateY, rotateZ
    {scale: this.state.bounceValue},  // 縮放
    {rotate: this.state.rotateValue.interpolate({ // 旋轉,使用插值函數做值映射
        inputRange: [0, 1],
        outputRange: ['0deg', '360deg']})},
    {translateX: this.state.translateValue.x}, // x軸移動
    {translateY: this.state.translateValue.y}, // y軸移動
],
...
this.state.rotateValue.interpolate({ // 旋轉,使用插值函數做值映射
        inputRange: [0, 1],
        outputRange: ['0deg', '360deg']})

 

組合動畫:

  • parallel:同時執行
  • sequence:順序執行
  • stagger:錯峰,其實就是插入了delay的parrllel
  • delay:組合動畫之間的延遲方法,嚴格來講,不算是組合動畫

 

監聽當前的動畫值:
addListener(callback):動畫執行過程中的值
stopAnimation(callback):動畫執行結束時的值
監聽AnimatedValueXY類型translateValue的值變化:

this.state.translateValue.addListener((value) => { 
  console.log("translateValue=>x:" + value.x + " y:" + value.y);
});
this.state.translateValue.stopAnimation((value) => { 
  console.log("translateValue=>x:" + value.x + " y:" + value.y);
});

 監聽AnimatedValue類型rotateValue的值變化:

this.state.rotateValue.addListener((state) => { 
  console.log("rotateValue=>" + state.value);
});
this.state.rotateValue.stopAnimation((state) => { 
  console.log("rotateValue=>" + state.value);
});

讓我們來看一個示例:圖片首先縮小80%,2秒之后,旋轉360度,之后沿着X軸與Y軸交叉方向向右下角移動一段距離,最后消失變成全透明

import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Animated,
    Easing,
    Image
} from 'react-native';

class DomeTwo extends Component {
    // 構造
    constructor(props) {
        super(props);
        // 初始狀態
        this.state = {
            bounceValue: new Animated.Value(0),
            rotateValue: new Animated.Value(0),
            translateValue: new Animated.ValueXY({x:0, y:0}), // 二維坐標
            fadeOutOpacity: new Animated.Value(0),
        };
    }

    render() {
        return (
            <Animated.View                         // 可選的基本組件類型: Image, Text, View(可以包裹任意子View)
                style={{
                  flex: 1,
                  alignItems: 'center',
                  justifyContent: 'center',
                  transform: [  // scale, scaleX, scaleY, translateX, translateY, rotate, rotateX, rotateY, rotateZ
                    {scale: this.state.bounceValue},  // 縮放
                    {rotate: this.state.rotateValue.interpolate({ // 旋轉,使用插值函數做值映射
                            inputRange: [0, 1],
                            outputRange: ['0deg', '360deg'],
                        })
                    },
                    {translateX: this.state.translateValue.x}, // x軸移動
                    {translateY: this.state.translateValue.y}, // y軸移動
                  ],
                  opacity: this.state.fadeOutOpacity, // 透明度
                }}>
                <Image
                    source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}}
                    style={{width: 400, height: 400}}
                />
            </Animated.View>
    );
    }

    startAnimation(){
        this.state.bounceValue.setValue(1.5);     // 設置一個較大的初始值
        this.state.rotateValue.setValue(0);
        this.state.translateValue.setValue({x:0, y:0});
        this.state.fadeOutOpacity.setValue(1);

        Animated.sequence(
            [
                Animated.sequence([  //  組合動畫 parallel(同時執行)、sequence(順序執行)、stagger(錯峰,其實就是插入了delay的parrllel)和delay(延遲)
                    Animated.spring( //  基礎的單次彈跳物理模型
                        this.state.bounceValue,
                        {
                            toValue: 0.8,
                            friction: 1, // 摩擦力,默認為7.
                            tension: 40, // 張力,默認40。
                        }
                    ),
                    Animated.delay(2000), // 配合sequence,延遲2秒
                    Animated.timing( // 從時間范圍映射到漸變的值。
                        this.state.rotateValue,
                        {
                            toValue: 1,
                            duration: 800, // 動畫持續的時間(單位是毫秒),默認為500
                            easing: Easing.out(Easing.quad), // 一個用於定義曲線的漸變函數
                            delay: 0, // 在一段時間之后開始動畫(單位是毫秒),默認為0。
                        }
                    ),
                    Animated.decay( // 以一個初始速度開始並且逐漸減慢停止。  S=vt-(at^2)/2   v=v - at
                        this.state.translateValue,
                        {
                            velocity: 10, // 起始速度,必填參數。
                            deceleration: 0.8, // 速度衰減比例,默認為0.997。
                        }
                    ),

                ]),
                Animated.timing(
                    this.state.fadeOutOpacity,
                    {
                        toValue: 0,
                        duration: 2000,
                        easing: Easing.linear, // 線性的漸變函數
                    }
                ),
            ]
        ).start(() => this.startAnimation()); // 循環執行動畫

        // 監聽值的變化
        this.state.rotateValue.addListener((state) => {
            console.log("rotateValue=>" + state.value);
        });

        // ValueXY
        this.state.translateValue.addListener((value) => {
            console.log("translateValue=>x:" + value.x + " y:" + value.y);
        });

        this.state.fadeOutOpacity.addListener((state) => {
            console.log("fadeOutOpacity=>" + state.value);
        });
    }

    componentDidMount() {
        this.startAnimation();
    }
}
export default DomeTwo;

原文:http://www.jianshu.com/p/2532c0e99c85


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM