初始化雪花
首先來(lái)個(gè)五十片雪花吧,在class外面定義一個(gè)數(shù)組操软。
const snowNumber = 50;
for (var i = 0; i < snowNumber; i++) {
arr.push(i);
}
設(shè)置每片雪花動(dòng)畫的初始值
為了創(chuàng)建一個(gè)動(dòng)畫嘁锯,我們首先要?jiǎng)?chuàng)建一個(gè)動(dòng)畫使用的值。
import React from 'react';
import {
View,
StyleSheet,
PanResponder,
Dimensions,
Animated,
Image,
Easing
} from 'react-native';
export default class Snow extends React.Component {
constructor(props) {
super(props);
arr.forEach((value) => {
this.animatedValue[value] = new Animated.Value(0);
});
}
為每片雪花創(chuàng)建一個(gè)animated view
由于每片雪花的動(dòng)畫是一樣的聂薪,因此我們讓每片雪花使用同樣的樣式this.snowAnimate()
,該方法返回一個(gè)樣式對(duì)象家乘。
render() {
const animations = arr.map((a, i) => {
return (
<Animated.View
key={i}
style={[styles.snowBox, this.snowAnimate(a)]}
>
<Image source={Snow} style={styles.snow}/>
</Animated.View>
);
});
return (
<View style={styles.container}>
{animations}
</View>
);
}
為每片雪花的創(chuàng)建動(dòng)畫
由于想讓無(wú)限的落雪,因此在函數(shù)一開始又將每片雪花的動(dòng)畫值設(shè)置成了0藏澳。
使用animated.timing
創(chuàng)建了一個(gè)動(dòng)畫仁锯,使一個(gè)值按照一個(gè)過(guò)渡曲線而隨時(shí)間變化。(消耗類型的)笆载,在它開始后又調(diào)用了本身扑馁,這是創(chuàng)建無(wú)限動(dòng)畫的一種方式涯呻。Animated.stagger():一個(gè)動(dòng)畫數(shù)組,傳入一個(gè)時(shí)間參數(shù)來(lái)設(shè)置隊(duì)列動(dòng)畫間的延遲腻要,即在前一個(gè)動(dòng)畫開始之后复罐,隔一段指定時(shí)間才開始執(zhí)行下一個(gè)動(dòng)畫里面的動(dòng)畫,并不關(guān)心前一個(gè)動(dòng)畫是否已經(jīng)完成雄家,所以有可能會(huì)出現(xiàn)同時(shí)執(zhí)行(重疊)的情況效诅。設(shè)置好,每片雪花的相隔時(shí)間趟济,這樣就能讓雪一片一片飄落啦乱投!
animateSnow () {
arr.forEach((value) => {
this.animatedValue[value].setValue(0)
});
const animations = arr.map((item) => {
return Animated.timing(
this.animatedValue[item],
{
toValue: snowNumber,
duration: 10000,
easing: Easing.linear
}
);
})
Animated.stagger(300, animations).start(() => this.animateSnow());
}
每片雪花的動(dòng)畫樣式
為了讓雪花飄落顯得真實(shí)自然,這里使用Math.random
打亂了雪花的左右順序顷编。
snowAnimate (item) {
return {
position: 'absolute',
left: parseInt(Math.random()*(deviceWidth),10),
top: this.animatedValue[item].interpolate({
inputRange: [0, snowNumber],
outputRange: [-100, deviceHeight-100],
})
}
}
雪花效果圖哦~