動畫類型:
- 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
