React-Native專案中使用動畫-Animated
阿新 • • 發佈:2019-02-07
動畫 Animated
RN中的動畫在某種程度上可以理解為“屬性動畫”,也就是以某種過渡方式改變元件樣式屬性值(如元件樣式的left值),驅動元件以動畫的形式發生變化(位移、形變或轉動)
可動畫化的元件:
- View (Animated.View)
- Text (Animated.Text)
- Image (Animated.Image)
- 使用
createAnimatedComponent
自定義
三種動畫型別:
- spring 基礎的單次彈跳物理模型
- decay 以一個初始速度開始並且按一定的衰減比逐漸減慢直至停止
- timing 時間和變數線性變化
1.關聯屬性的初始化
關聯屬性指的是動畫過程中對應變化的屬性,這個屬性的型別是Animated.Value
new
Animated.Value()
、new Animated.ValueXY()
(處理2D動畫)等方法初始化,如下:
class PlaygroundContainer extends Component {
constructor(props) {
super(props);
this.state = {
left1: new Animated.Value(0),
rotation2: new Animated.Value(0),
pan: new Animated.Value ({x:0, y:0})
}
}
...
}
2.與元件關聯
用spring實現的動畫
import loadingImage from '../../assets/0.gif'
...
class PlaygroundContainer extends Component {
constructor(props) {
super(props);
this.state = {
left1: new Animated.Value(0),
}
}
componentDidMount() {
Animated .spring(this.state.left1, {
toValue: 100, //屬性目標值
friction: 1, //摩擦力 (越小 振幅越大)
tension: 100, //拉力
}).start(); //執行動畫
}
render(){
return (
...
<Animated.Image
style={[styles.image,{left: this.state.left1}]}
source={ loadingImage }/>
...
)
}
}
用timing實現的翻轉動畫效果
import loadingImage from '../../assets/0.gif'
...
class PlaygroundContainer extends Component {
constructor(props) {
super(props);
this.state = {
rotation2: new Animated.Value(0),
}
}
componentDidMount() {
Animated.timing(this.state.rotation2, {
toValue: 1, //屬性目標值
duration: 3000 //動畫執行時間
}).start(); //執行動畫
}
render(){
return (
...
<Animated.Image
style={[styles.image,{
transform:[
{
rotateX: this.state.rotation2.interpolate({
inputRange:[0,1],
outputRange:['0deg','360deg']
})
}
]
}]}
source={ loadingImage }/>
...
)
}
}
這裡用到<l style="color:red">插值函式</l>interpolate
,它可以接受一個輸入區間,然後將其對映到另一個的輸出區間,如下:
{
rotateX: this.state.rotation2.interpolate({
inputRange:[0,1],
outputRange:['0deg','360deg']
})
}
通過對映,
rotation2的value | 對映輸出 |
---|---|
0 | 0° |
0.2 | 72° |
0.5 | 180° |
1 | 360° |
用decay實現衰減動畫
import loadingImage from '../../assets/0.gif'
...
class PlaygroundContainer extends Component {
constructor(props) {
super(props);
this.state = {
decayLeft4: new Animated.Value(0),
}
}
componentDidMount() {
Animated.decay(this.state.decayLeft4, {
velocity: 2,// 起始速度,必填引數。
deceleration:0.992 //速度衰減比例,預設為0.997。
}).start();
}
render(){
return (
...
<Animated.Image
style={[styles.image,{
left: this.state.decayLeft4
}]}
source={ loadingImage }/>
...
)
}
}
組合畫效果
static sequence(animations: Array<CompositeAnimation>)
(接受一個動畫陣列,<b style="color: red">依次</b>執行數組裡的動畫)-
static parallel(animations: Array<CompositeAnimation>, config?: ParallelConfig)
(接受一個動畫陣列,<b style="color: red">同時</b>執行數組裡的動畫)import loadingImage from '../../assets/0.gif' ... class PlaygroundContainer extends Component { constructor(props) { super(props); this.state = { left3: new Animated.Value(0), rotation3: new Animated.Value(0), scale3: new Animated.Value(0.5), } } componentDidMount() { //序列執行 Animated.sequence([ // 並行執行(滾動,同時旋轉) Animated.parallel([ Animated.timing(this.state.left3, { toValue: 1, duration: 3000, }), Animated.timing(this.state.rotation3, { toValue: 1, duration: 1000, }), ]), // 滾動、旋轉結束 執行縮放 Animated.timing(this.state.scale3, { toValue: 1, duration: 500, }) ]).start() //執行動畫 } render(){ return ( ... <Animated.Image style={[styles.image,{ left: this.state.left3.interpolate({ inputRange:[0,1], outputRange:[0, width - 100] }), transform:[ {rotateZ: this.state.rotation3.interpolate({ inputRange:[0,1], outputRange:['0deg','360deg']}) }, {rotateX: this.state.rotation3.interpolate({ inputRange:[0,1], outputRange:['0deg','360deg']}) }, {scale: this.state.scale3} ] }]} source={ loadingImage }/> ... ) } }
用delay做延時動畫
Animated.delay(1000)
延時1000ms
把delay
動畫放進sequence
執行序列的動畫陣列中
import loadingImage from '../../assets/0.gif'
...
class PlaygroundContainer extends Component {
constructor(props) {
super(props);
this.state = {
left5: new Animated.Value(0),
}
}
componentDidMount() {
Animated.sequence([
// 1000 ms後執行
Animated.delay(1000),
Animated.timing(this.state.left5, {
toValue: 100,// 起始速度,必填引數。
duration: 1000
})
]).start()
}
render(){
return (
...
<Animated.Image
style={[styles.image,{
left: this.state.left5
}]}
source={ loadingImage }/>
...
)
}
}