Animated
Anlat anlat bitmeyecek, kesin bir hiyerarşisi olmayan, resmi dökümanda dahi tüm özellikleriyle anlatılmamış en sevdiğim API. Burası benim kendi yorumum. Şimdi üçüncü ağızdan anlatmaya başlayalım.
Animated API özellikle syntax itibariyle karışık gelebilir. Bu dökümanda tüm özellikleriyle bahsedebilmem çok zor. Sadece buraya sınırlı kalamayacağınız için kendi dökümanı hariç önereceğim kaynaklar aşağıdaki gibi;
(Bahsedilen tüm kaynaklar browniefed mahlaslı arkadaşa ait)
- İngilizce döküman
- Temel anlamda Animated API egghead eğitim videoları
- Gerçek case'lere göre advanced animasyon egghead eğitim videoları
Temel felsefe, bir tane animatedValue() yarat. Bu değişkenin değerini değiştir ve componentin style objesine de değiştirdiğin değeri yaz, animatedValue'ya göre animasyon yarat.
1 - animatedValue() yarat
this._animatedValue = new Animated.Value(0);
2 - animatedValue() değerini değiştir
this._animatedValue.setValue(150);
3 - style objesine set et
<Animated.View style={{left: this._animatedValue}} />
Şimdi şuradaki layoutAnimation örneğini bu kez Animated API ile yapalım.
ilk önce constructor'da bir animatedValue yaratalım
constructor() {
super();
this.state = {
animValue: new Animated.Value(250)
};
}
Sonra bir tane dikdörtgen bir obje yaratalım.Ve bu objemizin height değeri, yarattığımız animatedValue()
'a göre değişsin. Burada dikkat etmeniz gereken şey, Animated.View
. Her component animated API'ı kullanabilir. Bunu createAnimatedComponent()
fonksiyonuyla sağlayabilirsiniz. Bunun yanında react native sık kullanılan componentler için bazılarını bize hazır olarak Animated API içinde veriyor. Bunlar; Animated.View, Animated.Image, Animated.ScrollView ve Animated.Text.
renderRectangle = () => {
const customStyle = {
height: this.state.animValue,
};
return (
<Animated.View style={[styles.rectangle, customStyle]}>
<TouchableWithoutFeedback onPress={() => this.handleSelect()}>
<View style={{ flex: 1 }} />
</TouchableWithoutFeedback>
</Animated.View>
);
};
Dikdörtgen objemize dokununca, height değeri 250 ise 450, 450 ise 250 olsun.
handleSelect = () => {
this.state.animValue._value > 250
? this.state.animValue.setValue(250)
: this.state.animValue.setValue(450);
};
Oley, setState olmadan tekrar tekrar render ettik. Ama bir saniye hiç animasyona benzer bir tarafı yok bunun :(
Animasyonu sağlamak için bize 3 tane animasyon tipi sunuluyor ve bir çok ihtiyacı karşılıyor daha doğrusu ben karşılamadığı bir case görmedim.Bunlar;
Animated.decay()
: Bir başlangıç hız değeri ile başlar, kademe kademe yavaşlayan animasyonlara yararAnimated.spring()
: Fizik kurallarına göre animasyonlar hazırlamaya yararAnimated.timing()
:Zamana göre animasyon hazırlamaya yarar
Şimdi bu örneğimiz de handleSelect fonksyionunu Animated.timing() yardımı ile değiştirelim.
handleSelect = () => {
this.state.animValue._value > 250
? Animated.timing(this.state.animValue, {
toValue: 250,
duration: 500
}).start()
: Animated.timing(this.state.animValue, {
toValue: 450,
duration: 500
}).start();
};
burada kullandığımız this.state.animValue'ya göre sadece height özelliğini animasyon yaptık. Bununla beraber rengini değiştirip biraz da döndürelim.
Bunun için interPolation yapacaz. İşin burasını anlamak çok önemli. Mesela aşağıdaki kodu inceleyerek anlamaya çalışalım;
let rotateAnimation = this.state.animValue.interpolate({
inputRange: [250, 450],
outputRange: ['0deg', '360deg']
});
animationValue olan this.state.animValue
içinden çağırdığımız interpolate
fonksiyonu içine inputRange
ve outputRange
keylerine sahip bir obje alıyor. inputRange
250'den --> 450'ye doğru giderken, outputRange
'de 0deg'den ---> 360deg'e doğru gidiyor. Bu arada mesela inputRange
350 civarrındayken tahminim outputRange
'de 180deg'ye yakın oluyordur. Biz araya girip (interpolate'in kelime anlamlarından biri araya girmek) inputRange
350 iken 720deg ol sonra 350 ve 450 arasında, kendini ayarla ve 360deg'e doğru hızla ilerle diyebiliriz.
Bu kadar basit bir mevzuyu anlatamadıysam lütfen beni uyarın.
inputRange | outputRange |
---|---|
250 | 0deg |
... | ... |
350 | 180deg |
... | ... |
450 | 360deg |
şimdi yarattığımız rotateAnimation'ı style objesine atayalım.
const customStyle = {
height: this.state.animValue,
transform:[{rotate:rotateAnimation}]
};
Maalesef gif yapmak için kullandığım tool pek animasyonları doğru yansıtamadı. Kodun tamamını canlı olarak şuradan izleyebilirsiniz. ( https://snack.expo.io/rk0oekzGb )