Animated API — asoslar
Muammodan boshlaylik
Mahsulot savatga qo'shildi — "Qo'shildi ✓" xabari birdan paydo bo'ladi va birdan yo'qoladi. Modal sakrab ochiladi. Ro'yxat elementlari "tarsillab" chiqadi.
Hammasi ishlaydi — lekin "arzon" va qo'pol his qilinadi. Native ilovalarda deyarli hamma narsa harakatlanadi: silliq paydo bo'lish, yumshoq siljish, bosilganda biroz kichrayish. Animatsiya — bezak emas: u foydalanuvchiga nima bo'layotganini tushuntiradi.
React Native da ikki asosiy vosita: o'rnatilgan Animated (bu dars) va Reanimated (keyingi dars).
Asosiy g'oya
Oddiy useState bilan animatsiya qilsangiz — har kadrda (soniyasiga 60 marta) React butun komponentni qayta chizadi. Sekin va uzilib-uzilib.
Animated — maxsus animatsiyalanadigan qiymat va maxsus komponentlar. Qiymat o'zgarganda React qayta chizilmaydi — faqat stil yangilanadi.
import { Animated } from 'react-native';
import { useRef, useEffect } from 'react';
export function PaydoBoluvchi({ children }: { children: React.ReactNode }) {
const shaffoflik = useRef(new Animated.Value(0)).current; // 0 dan boshlanadi
useEffect(() => {
Animated.timing(shaffoflik, {
toValue: 1,
duration: 400,
useNativeDriver: true,
}).start();
}, []);
return <Animated.View style={{ opacity: shaffoflik }}>{children}</Animated.View>;
}
Uch qadam:
- Qiymat —
new Animated.Value(0),useRefichida (har render da qayta yaratilmasin) - Animatsiya —
Animated.timing(qiymat, { toValue, duration })→.start() - Animatsiyalanadigan komponent —
Animated.View,Animated.Text,Animated.Image; stilga qiymatni ulash
useNativeDriver: true
useNativeDriver: true
Animatsiya native qatlamda ishlaydi — JavaScript band bo'lsa ham (masalan, katta ro'yxat yuklanmoqda) silliq qoladi.
Cheklov: faqat opacity va transform (siljish, masshtab, burilish) uchun. width, height, backgroundColor, top — useNativeDriver: false bilan, va ular sekinroq.
Qoida: iloji boricha opacity va transform bilan animatsiya qiling — va doim useNativeDriver: true.
Animatsiya turlari
timing — vaqt bo'yicha
import { Easing } from 'react-native';
Animated.timing(qiymat, {
toValue: 1,
duration: 300,
easing: Easing.out(Easing.cubic), // tez boshlanib, sekin tugaydi
useNativeDriver: true,
}).start();
Easing — harakat tezligining egri chizig'i. Easing.linear — mexanik va noto'g'ri his qilinadi. Tabiatda hech narsa bir tekis harakatlanmaydi. Easing.out(...) — paydo bo'luvchi elementlar uchun eng tabiiy.
spring — prujina
Animated.spring(masshtab, {
toValue: 1,
friction: 5, // kamroq — ko'proq "sakraydi"
tension: 80,
useNativeDriver: true,
}).start();
Davomiylik yo'q — fizika: massa, prujina kuchi, ishqalanish. Natija — tirik va tabiiy. Tugmalar, "yoqtirish" yuragi, kartalar uchun ideal.
decay — sekinlashuvchi
Surilgan elementning inersiya bilan to'xtashi. Asosan imo-ishoralar bilan.
transform
<Animated.View
style={{
opacity: shaffoflik,
transform: [
{ translateY: siljish }, // vertikal siljish
{ scale: masshtab }, // kattalashish
{ rotate: burilish }, // burilish — string kerak: '45deg'
],
}}
/>
interpolate — bitta qiymatdan ko'p effekt
Bitta 0 → 1 qiymatdan bir nechta xususiyatni boshqarish:
const p = useRef(new Animated.Value(0)).current;
const siljish = p.interpolate({ inputRange: [0, 1], outputRange: [40, 0] });
const burilish = p.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] });
<Animated.View style={{ opacity: p, transform: [{ translateY: siljish }] }} />
p 0 dan 1 ga o'tganda: element shaffofdan ko'rinadiganga va 40 birlik pastdan joyiga. Bitta animatsiya — ikki effekt, mukammal sinxron.
extrapolate: 'clamp' — qiymat diapazondan chiqsa, natija chegarada qolsin.
Misol: "Savatga qo'shildi" toast
export function Toast({ matn, korinsin }: { matn: string; korinsin: boolean }) {
const p = useRef(new Animated.Value(0)).current;
useEffect(() => {
Animated.spring(p, { toValue: korinsin ? 1 : 0, useNativeDriver: true, friction: 8 }).start();
}, [korinsin]);
return (
<Animated.View
pointerEvents="none"
style={{
position: 'absolute', bottom: 100, alignSelf: 'center',
backgroundColor: '#0f172a', paddingHorizontal: 20, paddingVertical: 12, borderRadius: 999,
opacity: p,
transform: [{ translateY: p.interpolate({ inputRange: [0, 1], outputRange: [20, 0] }) }, { scale: p.interpolate({ inputRange: [0, 1], outputRange: [0.9, 1] }) }],
}}
>
<Text style={{ color: 'white', fontWeight: '600' }}>{matn}</Text>
</Animated.View>
);
}
Animatsiyalarni birlashtirish
Animated.sequence([ // ketma-ket
Animated.timing(a, { toValue: 1, duration: 200, useNativeDriver: true }),
Animated.delay(1500),
Animated.timing(a, { toValue: 0, duration: 200, useNativeDriver: true }),
]).start();
Animated.parallel([...]).start(); // bir vaqtda
Animated.stagger(60, elementlar.map((v) => // har biri 60 ms kechikish bilan — "to'lqin"
Animated.timing(v, { toValue: 1, duration: 300, useNativeDriver: true })
)).start();
Animated.loop(Animated.timing(...)).start(); // cheksiz — yuklanish belgisi
Scroll bilan bog'lash
Scroll qilganda sarlavha kichrayadi yoki shaffoflanadi:
const scrollY = useRef(new Animated.Value(0)).current;
const sarlavhaShaffoflik = scrollY.interpolate({ inputRange: [0, 120], outputRange: [0, 1], extrapolate: 'clamp' });
<Animated.ScrollView
onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], { useNativeDriver: true })}
scrollEventThrottle={16}
>
Animated.event — scroll pozitsiyasini to'g'ridan-to'g'ri animatsiya qiymatiga yozadi, JavaScript siz.
Oddiy holatlar uchun: LayoutAnimation
Ro'yxatga element qo'shildi yoki o'chirildi — qolganlar birdan siljiydi. Bitta qator bilan silliq qilish:
import { LayoutAnimation } from 'react-native';
function ochir(id: number) {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setRoyxat((r) => r.filter((x) => x.id !== id));
}
Keyingi layout o'zgarishi avtomatik animatsiya qilinadi. Cheklangan nazorat, lekin minimal kod.
Nima uchun shunday?
Nima uchun animatsiya qiymatlari React holatidan (useState) alohida?
Chunki React ning qayta chizish mexanizmi animatsiya uchun juda og'ir. 60 kadr/soniyada har bir kadr uchun 16 ms bor. setState — komponentni qayta chizish, virtual daraxtni solishtirish, native qatlamga yuborish — ko'pincha 16 ms dan ko'p. Animated qiymat esa React ni chetlab o'tadi: u faqat bitta stil xususiyatini to'g'ridan-to'g'ri yangilaydi, useNativeDriver bilan esa butun animatsiya native tomonda boshlanib, JavaScript ga umuman bog'liq bo'lmaydi.
Xulosa
Eslab qoling:
useRef(new Animated.Value(0)).current— qiymatAnimated.timing(vaqt + easing),Animated.spring(fizika) →.start()Animated.View+ stilga qiymatuseNativeDriver: true— faqatopacityvatransform, lekin silliqinterpolate— bitta qiymatdan ko'p effekt;extrapolate: 'clamp'sequence,parallel,stagger,loop— birlashtirishAnimated.event— scroll bilan bog'lashLayoutAnimation— ro'yxat o'zgarishlari uchun eng oddiy yo'l
Keyingi dars
45-dars: Reanimated — silliq animatsiyalar