Reanimated — silliq animatsiyalar
Muammodan boshlaylik
O'rnatilgan Animated ning cheklovlari tez seziladi:
useNativeDriverfaqatopacityvatransform— kenglik, rang, balandlik animatsiyasi sekin- Animatsiya davomida mantiq (masalan, "qiymat 0.5 dan oshsa — tebranish") yozib bo'lmaydi
- Imo-ishoralar bilan (barmoq orqasidan ergashish) ishlash noqulay
- Kod — ko'p
useRef,interpolate,.start()
React Native Reanimated — professional ilovalarda standart. Animatsiyalar to'liq UI thread da ishlaydi, har qanday stil xususiyati bilan, va kod ancha qisqa.
O'rnatish
Expo shablonida allaqachon bor. Bo'lmasa:
npx expo install react-native-reanimated react-native-worklets
Expo Go da ishlaydi.
Asosiy tushunchalar
import Animated, { useSharedValue, useAnimatedStyle, withTiming, withSpring } from 'react-native-reanimated';
export function Quti() {
const kenglik = useSharedValue(100);
const stil = useAnimatedStyle(() => ({
width: kenglik.value,
}));
return (
<>
<Animated.View style={[{ height: 100, backgroundColor: '#0284c7', borderRadius: 12 }, stil]} />
<Tugma matn="Kattalashtir" onPress={() => { kenglik.value = withSpring(kenglik.value + 50); }} />
</>
);
}
| Element | Vazifasi |
|---|---|
useSharedValue(x) |
Animatsiya qiymati — JS va UI thread o'rtasida umumiy |
.value |
O'qish va yozish |
useAnimatedStyle(() => ({...})) |
Qiymatdan stil hisoblovchi funksiya — UI thread da ishlaydi |
withTiming, withSpring |
Qiymatni animatsiya bilan o'zgartirish |
Animated.View |
react-native-reanimated dan |
kenglik.value = withSpring(150) — "150 ga prujina bilan bor". .start() yo'q, useNativeDriver yo'q, va width ham silliq.
[!WARNING]
.valueni render paytida o'qimang (<Text>{kenglik.value}</Text>) — qiymat yangilanmaydi va ogohlantirish chiqadi..value— faqatuseAnimatedStyleichida va hodisa funksiyalarida.
Animatsiya funksiyalari
import { withTiming, withSpring, withDelay, withSequence, withRepeat, Easing } from 'react-native-reanimated';
x.value = withTiming(1, { duration: 300, easing: Easing.out(Easing.cubic) });
x.value = withSpring(1, { damping: 12, stiffness: 150 });
x.value = withDelay(200, withTiming(1));
x.value = withSequence(withTiming(1.2, { duration: 100 }), withSpring(1)); // "puls"
x.value = withRepeat(withTiming(360, { duration: 1000 }), -1); // cheksiz
Tugash hodisasi:
x.value = withTiming(0, { duration: 200 }, (tugadi) => {
if (tugadi) runOnJS(yopish)(); // JS funksiyasini UI thread dan chaqirish
});
Misol: "Yoqtirish" yuragi
import Animated, { useSharedValue, useAnimatedStyle, withSequence, withSpring, withTiming } from 'react-native-reanimated';
import * as Haptics from 'expo-haptics';
const AnimatedIonicons = Animated.createAnimatedComponent(Ionicons);
export function Yurak({ yoqdi, almashtir }: { yoqdi: boolean; almashtir: () => void }) {
const masshtab = useSharedValue(1);
const stil = useAnimatedStyle(() => ({ transform: [{ scale: masshtab.value }] }));
function bos() {
masshtab.value = withSequence(withTiming(1.3, { duration: 120 }), withSpring(1, { damping: 6 }));
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
almashtir();
}
return (
<Pressable onPress={bos} hitSlop={10}>
<AnimatedIonicons name={yoqdi ? 'heart' : 'heart-outline'} size={28} color={yoqdi ? '#ef4444' : '#64748b'} style={stil} />
</Pressable>
);
}
Kattalashib, prujina bilan qaytadi va tebranadi — Instagram dagi kabi.
createAnimatedComponent — istalgan komponentni animatsiyalanadigan qilish.
Layout animatsiyalari — eng kuchli imkoniyat
Element paydo bo'lishi, yo'qolishi va joyi o'zgarishini bitta xususiyat bilan:
import Animated, { FadeInDown, FadeOut, LinearTransition } from 'react-native-reanimated';
{royxat.map((v, i) => (
<Animated.View
key={v.id}
entering={FadeInDown.delay(i * 50).springify()} // paydo bo'lish
exiting={FadeOut.duration(200)} // yo'qolish
layout={LinearTransition.springify()} // qolganlar silliq siljiydi
>
<VazifaKarta vazifa={v} />
</Animated.View>
))}
entering— mount bo'lganda:FadeIn,FadeInDown,SlideInRight,ZoomIn,BounceIn...exiting— unmount bo'lganda:FadeOut,SlideOutLeft,ZoomOut...layout— joyi o'zgarganda (boshqa element o'chirildi).delay(),.duration(),.springify()— sozlash
Animated bilan bu o'nlab qator va murakkab mantiq bo'lardi. Reanimated da — uchta xususiyat. FlatList uchun — Animated.FlatList va itemLayoutAnimation.
Modal / bildirishnoma
{korinsin && (
<Animated.View entering={SlideInDown.springify().damping(15)} exiting={SlideOutDown} style={styles.toast}>
<Text>Savatga qo'shildi</Text>
</Animated.View>
)}
Shartli render + entering / exiting — animatsiyali paydo bo'lish va yo'qolish.
Scroll bilan
import Animated, { useAnimatedScrollHandler, useSharedValue, useAnimatedStyle, interpolate, Extrapolation } from 'react-native-reanimated';
const y = useSharedValue(0);
const handler = useAnimatedScrollHandler((e) => { y.value = e.contentOffset.y; });
const sarlavhaStil = useAnimatedStyle(() => ({
opacity: interpolate(y.value, [0, 100], [0, 1], Extrapolation.CLAMP),
transform: [{ translateY: interpolate(y.value, [0, 100], [-10, 0], Extrapolation.CLAMP) }],
}));
const rasmStil = useAnimatedStyle(() => ({
transform: [{ scale: interpolate(y.value, [-200, 0], [1.5, 1], Extrapolation.CLAMP) }], // pastga tortilsa kattalashadi
}));
<Animated.ScrollView onScroll={handler} scrollEventThrottle={16}>
<Animated.Image source={...} style={[{ width: '100%', height: 300 }, rasmStil]} />
</Animated.ScrollView>
Mahsulot sahifasidagi "parallax" rasm va scroll qilganda paydo bo'ladigan sarlavha.
Worklet — UI thread dagi funksiya
useAnimatedStyle, useAnimatedScrollHandler ichidagi funksiyalar — worklet: ular JavaScript thread da emas, UI thread da bajariladi. Shuning uchun:
- Ular ichida oddiy JS funksiyalarni (holat yangilash,
router.push,fetch) to'g'ridan-to'g'ri chaqirib bo'lmaydi —runOnJS(funksiya)(argumentlar)orqali - O'z worklet ingiz: funksiya boshida
'worklet';direktivasi
function chegarala(v: number, min: number, max: number) {
'worklet';
return Math.min(Math.max(v, min), max);
}
Animated yoki Reanimated?
Animated |
Reanimated | |
|---|---|---|
| O'rnatish | O'rnatilgan | Kutubxona (Expo da tayyor) |
| Native animatsiya | Faqat opacity, transform |
Har qanday xususiyat |
| Layout animatsiyalari | LayoutAnimation (cheklangan) |
entering, exiting, layout |
| Imo-ishoralar | Noqulay | Gesture Handler bilan ideal (46-dars) |
| Kod | Ko'proq | Qisqaroq |
Yangi loyihalarda — Reanimated. Animated ni bilish — eski kod va oddiy holatlar uchun.
Nima uchun shunday?
Nima uchun animatsiya UI thread da ishlashi bunchalik muhim?
React Native ilovasida ikki asosiy thread bor: JavaScript (sizning mantiqingiz, React) va UI (ekranni chizish). JS thread band bo'lishi oddiy holat: katta JSON ni qayta ishlash, ro'yxatni chizish, navigatsiya. Agar animatsiya JS da hisoblansa — shu paytlarda u "qotadi". Reanimated animatsiya mantiqini butunlay UI thread ga ko'chiradi: JS band bo'lsa ham, barmoq ostidagi element 60 (yoki 120) kadr/soniyada silliq harakatlanadi. Foydalanuvchi aynan shuni "sifatli ilova" deb his qiladi.
Xulosa
Eslab qoling:
useSharedValue+useAnimatedStyle+Animated.Viewx.value = withTiming / withSpring / withSequence / withRepeat(...)- Har qanday stil xususiyati silliq — UI thread da
.valueni render da o'qimang- Layout animatsiyalari:
entering,exiting,layout— eng kam kod, eng katta effekt useAnimatedScrollHandler+interpolate— scroll effektlari- Worklet lar ichidan JS ga —
runOnJS - Yangi loyihalarda — Reanimated
Keyingi dars
46-dars: Gesture Handler — surish, tortish, swipe-to-delete