React Native Reanimated 4: Ghid Complet pentru Animații CSS și Worklets

Învață să folosești React Native Reanimated 4: animații CSS declarative, tranziții, keyframes, worklets cu withSpring și withTiming — toate pe UI thread la 120 FPS. Cu exemple practice, migrare de la v3 și sfaturi de performanță.

De Ce Reanimated 4 Schimbă Regulile Jocului

Hai să fim sinceri — animațiile au fost mereu punctul slab al React Native. Câți dintre noi n-am trecut prin momentul ăla frustrant când o animație aparent simplă începea să sacadeze exact în momentul demonstrației pentru client? API-ul Animated integrat rula pe thread-ul JavaScript, ceea ce însemna că orice încărcare pe acel thread (procesare de date, apeluri API, actualizări de state) afecta direct fluiditatea animațiilor. Nu era ideal, ce să zic.

Ei bine, lucrurile s-au schimbat radical.

React Native Reanimated 4, lansat de Software Mansion în versiune stabilă în 2025, vine cu un sistem de animații CSS declarative care rulează nativ pe UI thread, oferind performanță de până la 120 FPS. Și nu, nu exagerez. Dar ce mi se pare și mai mișto e că păstrează compatibilitatea completă cu API-ul de worklets din versiunea 3 — deci ai practic cel mai bun din ambele lumi.

În acest ghid, parcurgem tot ce trebuie să știi: de la instalare și configurare, prin conceptele fundamentale (shared values, animated styles), la noul sistem de animații CSS cu tranziții și keyframes, exemple practice pas cu pas și migrarea de la versiunea 3. Fie că ești la prima animație în React Native sau ai lucrat cu worklets de ani de zile, ghidul ăsta te pune la zi cu tot ce oferă Reanimated 4 în 2026.

Cerințe și Instalare

Arhitectura Nouă — Obligatorie

Primul lucru de reținut: Reanimated 4.x funcționează exclusiv cu Noua Arhitectură React Native (Fabric). Fără excepții.

Dacă aplicația ta încă rulează pe arhitectura veche (Paper), ai două opțiuni: migrezi la Noua Arhitectură sau rămâi pe Reanimated 3.x, care e în continuare menținut activ. Sincer, dacă tot ești pe React Native 0.76+, merită să faci saltul.

Concret, ai nevoie de:

  • React Native 0.76+ (Noua Arhitectură activată implicit)
  • Hermes ca motor JavaScript (recomandat și pentru debugging)
  • Expo SDK 52+ (dacă folosești Expo)

Instalarea Pachetelor

O schimbare arhitecturală importantă în Reanimated 4: worklets-urile au fost extrase într-un pachet separat, react-native-worklets. Abordarea asta modulară permite și altor biblioteci să folosească funcționalitatea worklets fără a depinde de Reanimated — un detaliu care pare mic, dar face o diferență mare în practică.

Pentru proiecte Expo:

npx expo install react-native-reanimated react-native-worklets

Pentru React Native CLI:

npm install react-native-reanimated react-native-worklets
cd ios && pod install && cd ..

Configurarea Babel

Trebuie să actualizezi plugin-ul Babel — schimbă referința de la react-native-reanimated/plugin la react-native-worklets/plugin:

// babel.config.js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: ['react-native-worklets/plugin'],
};

Dacă folosești Expo SDK 52 sau mai nou, plugin-ul Worklets Babel e inclus implicit în template-ul de start, deci nu trebuie să-l adaugi manual. Un lucru mai puțin de configurat.

Concepte Fundamentale: Shared Values și Animated Styles

Înainte de a sări direct la animații, trebuie să înțelegi cei doi piloni pe care se construiește tot în Reanimated: shared values și animated styles. Promit că n-o să fie complicat.

useSharedValue — Starea Animației

Shared values sunt mecanismul central de stare al Reanimated. Spre deosebire de useState din React (care trăiește pe thread-ul JavaScript), shared values trăiesc direct pe UI thread. Practic, actualizările lor nu declanșează re-render-uri React și nu depind de performanța thread-ului JS.

import { useSharedValue } from 'react-native-reanimated';

function MyComponent() {
  const opacity = useSharedValue(1);
  const translateY = useSharedValue(0);
  const scale = useSharedValue(1);

  // Modificarea valorii — instantanee, fără re-render
  const handlePress = () => {
    opacity.value = 0.5;
    translateY.value = -20;
  };
}

Observă sintaxa: accesezi și modifici valoarea prin proprietatea .value. Pare un detaliu minor, dar e important — orice atribuire directă pe .value declanșează actualizarea pe UI thread fără a trece prin bridge-ul JavaScript.

useAnimatedStyle — Stiluri Reactive

useAnimatedStyle creează un obiect de stiluri care se actualizează automat când shared values-urile asociate se schimbă. Callback-ul rulează pe UI thread, nu pe cel JavaScript:

import Animated, {
  useSharedValue,
  useAnimatedStyle,
} from 'react-native-reanimated';

function FadeBox() {
  const opacity = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    opacity: opacity.value,
  }));

  return (
    <Animated.View style={[styles.box, animatedStyle]} />
  );
}

Sfat de performanță: Definește doar partea dinamică a stilurilor cu useAnimatedStyle. Stilurile statice ar trebui să rămână în StyleSheet — eviți recalculări inutile la fiecare frame și menții lucrurile curate.

Animații cu Worklets: withTiming și withSpring

Acum că ai fundamentele, hai să vedem cum adaugi efectiv mișcare. Reanimated oferă două funcții principale de animație: withTiming (bazată pe durată) și withSpring (bazată pe fizică). Le vei folosi constant, deci merită să le înțelegi bine.

withTiming — Animație cu Durată Fixă

withTiming animă o valoare de la punctul curent la o valoare țintă într-o durată specificată, cu o curbă de easing configurabilă:

import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  Easing,
} from 'react-native-reanimated';
import { View, Button, StyleSheet } from 'react-native';

function ExpandingBar() {
  const width = useSharedValue(100);

  const animatedStyle = useAnimatedStyle(() => ({
    width: withTiming(width.value, {
      duration: 500,
      easing: Easing.bezier(0.25, 0.1, 0.25, 1),
    }),
  }));

  return (
    <View style={styles.container}>
      <Animated.View style={[styles.bar, animatedStyle]} />
      <Button
        title="Extinde"
        onPress={() => {
          width.value = Math.random() * 300 + 50;
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', padding: 20 },
  bar: { height: 60, backgroundColor: '#6366f1', borderRadius: 12 },
});

Proprietățile cheie ale withTiming:

  • duration — cât durează animația în milisecunde (implicit 300ms)
  • easing — curba de accelerare/decelerare. Easing.bezier() îți oferă control complet, dar poți folosi și preseturi ca Easing.ease, Easing.linear, Easing.bounce

withSpring — Animație cu Fizică de Resort

withSpring funcționează diferit — simulează fizica unui resort real, ceea ce dă mișcări naturale și organice. Onest, am ajuns s-o prefer în majoritatea cazurilor. Parametrii principali sunt mass (masa), stiffness (rigiditatea) și damping (amortizarea):

import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';
import { Pressable, Text, StyleSheet } from 'react-native';

function BouncyButton() {
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }],
  }));

  return (
    <Pressable
      onPressIn={() => {
        scale.value = withSpring(0.92, {
          damping: 12,
          stiffness: 180,
        });
      }}
      onPressOut={() => {
        scale.value = withSpring(1, {
          damping: 8,
          stiffness: 200,
        });
      }}
    >
      <Animated.View style={[styles.button, animatedStyle]}>
        <Text style={styles.buttonText}>Apasă-mă</Text>
      </Animated.View>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  button: {
    backgroundColor: '#8b5cf6',
    paddingHorizontal: 32,
    paddingVertical: 16,
    borderRadius: 16,
    alignItems: 'center',
  },
  buttonText: { color: '#fff', fontSize: 18, fontWeight: '600' },
});

Ca regulă generală: folosește withSpring pentru interacțiuni inițiate de utilizator (apăsări, gesturi, drag-and-drop) și withTiming pentru animații controlate programatic — tranzițiile între ecrane, loader-uri, baruri de progres. O dată ce îți intră în reflex, alegerea vine de la sine.

Combinarea Animațiilor: withSequence, withDelay, withRepeat

Reanimated oferă și funcții pentru combinarea animațiilor în secvențe mai complexe. Aici începe partea distractivă:

import {
  withSequence,
  withDelay,
  withRepeat,
  withTiming,
  withSpring,
} from 'react-native-reanimated';

// Secvență: fade out, apoi fade in
opacity.value = withSequence(
  withTiming(0, { duration: 400 }),
  withTiming(1, { duration: 400 })
);

// Întârziere: așteaptă 1s, apoi animează
translateY.value = withDelay(
  1000,
  withSpring(-50, { damping: 10 })
);

// Repetare: pulsează la infinit
scale.value = withRepeat(
  withSequence(
    withTiming(1.1, { duration: 600 }),
    withTiming(1, { duration: 600 })
  ),
  -1,  // -1 = infinit
  true // reverse la fiecare iterație
);

Noutatea Majoră: Animații CSS în Reanimated 4

Și acum ajungem la ce face Reanimated 4 cu adevărat special: animațiile CSS declarative.

Echipa de la Software Mansion a ales standardul CSS animations/transitions ca bază, și alegerea mi se pare inspirată — e un standard bine-cunoscut, testat în producție timp de ani pe web, și familiar pentru milioane de dezvoltatori. Dacă ai scris vreodată CSS (și cine n-a scris?), o să te simți ca acasă.

Ideea e simplă dar puternică: în loc să definești manual shared values, animated styles și funcții de animație, pur și simplu declari proprietățile de tranziție direct în stilurile componentei. Reanimated se ocupă de tot restul.

CSS Transitions — Animații Automate între Stări

Tranzițiile CSS sunt perfecte pentru animarea schimbărilor de stare ale componentelor. Definești ce proprietăți vrei să animezi, durata și easing-ul, iar Reanimated animă automat între valoarea veche și cea nouă. Simplu și elegant.

import React, { useState } from 'react';
import { Pressable, Text, StyleSheet, SafeAreaView } from 'react-native';
import Animated from 'react-native-reanimated';

function ToggleCard() {
  const [expanded, setExpanded] = useState(false);

  return (
    <SafeAreaView style={styles.container}>
      <Pressable onPress={() => setExpanded(prev => !prev)}>
        <Animated.View
          style={{
            width: expanded ? 300 : 160,
            height: expanded ? 200 : 80,
            backgroundColor: expanded ? '#6366f1' : '#a78bfa',
            borderRadius: 16,
            padding: 16,
            justifyContent: 'center',
            alignItems: 'center',
            // Proprietăți CSS Transition
            transitionProperty: ['width', 'height', 'backgroundColor'],
            transitionDuration: 350,
            transitionTimingFunction: 'ease-in-out',
          }}
        >
          <Animated.Text
            style={{
              color: '#fff',
              fontSize: expanded ? 20 : 14,
              fontWeight: '600',
              transitionProperty: ['fontSize'],
              transitionDuration: 350,
            }}
          >
            {expanded ? 'Card Expandat' : 'Apasă'}
          </Animated.Text>
        </Animated.View>
      </Pressable>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f8fafc',
  },
});

Uită-te cât de puțin cod e necesar comparativ cu abordarea clasică! Nu ai nevoie de useSharedValue, useAnimatedStyle sau funcții withTiming — totul e declarat direct în stiluri, exact ca în CSS pe web. Prima dată când am încercat asta, am rămas plăcut surprins de cât de natural se simte.

Proprietățile principale ale tranzițiilor CSS:

  • transitionProperty — array cu proprietățile de animat (ex: ['width', 'opacity', 'transform'])
  • transitionDuration — durata în milisecunde
  • transitionTimingFunction — funcția de easing ('ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear')
  • transitionDelay — întârzierea înainte de start

CSS Keyframes — Animații Complexe în Pași

Pentru animații mai elaborate, cu etape intermediare, folosești keyframes. Definesc starea animației la diferite puncte procentuale, exact ca @keyframes din CSS:

import React from 'react';
import { View, StyleSheet } from 'react-native';
import Animated from 'react-native-reanimated';

const pulseKeyframes = {
  from: { opacity: 1, transform: [{ scale: 1 }] },
  '50%': { opacity: 0.5, transform: [{ scale: 1.05 }] },
  to: { opacity: 1, transform: [{ scale: 1 }] },
};

function SkeletonLoader() {
  return (
    <View style={styles.container}>
      <Animated.View
        style={{
          width: '100%',
          height: 20,
          backgroundColor: '#e2e8f0',
          borderRadius: 8,
          marginBottom: 12,
          animationName: pulseKeyframes,
          animationDuration: 1500,
          animationIterationCount: 'infinite',
          animationTimingFunction: 'ease-in-out',
        }}
      />
      <Animated.View
        style={{
          width: '70%',
          height: 20,
          backgroundColor: '#e2e8f0',
          borderRadius: 8,
          animationName: pulseKeyframes,
          animationDuration: 1500,
          animationIterationCount: 'infinite',
          animationTimingFunction: 'ease-in-out',
          animationDelay: 200,
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { padding: 20 },
});

Proprietățile cheie ale animațiilor CSS cu keyframes:

  • animationName — obiectul cu keyframes-urile (definit ca obiect JS, nu ca string CSS)
  • animationDuration — durata unui ciclu de animație
  • animationIterationCount — de câte ori se repetă ('infinite' sau un număr)
  • animationDirection — direcția ('normal', 'reverse', 'alternate')
  • animationFillMode — cum se aplică stilurile înainte/după animație
  • animationPlayState'running' sau 'paused' pentru control dinamic

react-native-css-animations — Preseturi Gata de Folosit

Software Mansion oferă și o bibliotecă companion, react-native-css-animations, cu preseturi gata de utilizat. Dacă ai nevoie de un spinner sau skeleton rapid, nu trebuie să reinventezi roata:

npm install react-native-css-animations
import { pulse, bounce, spin, shimmer } from 'react-native-css-animations';

// Skeleton loading
<Animated.View style={{ ...pulse, width: 200, height: 20 }} />

// Spinner
<Animated.View style={{ ...spin, width: 40, height: 40 }} />

// Indicator scroll-down
<Animated.View style={{ ...bounce, width: 30, height: 30 }} />

// Shimmer loading effect
<Animated.View style={{ ...shimmer, width: '100%', height: 60 }} />

Exemplu Practic: Notification Toast Animat

Deci, hai să punem totul cap la cap cu un exemplu din lumea reală — un toast de notificare care intră cu slide-in de sus, stă 3 secunde, apoi dispare. Combinăm aici atât worklets cât și concepte de animație mai avansate:

import React, { useState, useCallback } from 'react';
import {
  View,
  Text,
  Pressable,
  StyleSheet,
  SafeAreaView,
} from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  withDelay,
  withSequence,
  runOnJS,
} from 'react-native-reanimated';

type ToastType = 'success' | 'error' | 'info';

const TOAST_COLORS: Record<ToastType, string> = {
  success: '#22c55e',
  error: '#ef4444',
  info: '#3b82f6',
};

function AnimatedToast() {
  const [visible, setVisible] = useState(false);
  const [toastType, setToastType] = useState<ToastType>('success');
  const translateY = useSharedValue(-100);
  const opacity = useSharedValue(0);

  const showToast = useCallback((type: ToastType) => {
    setToastType(type);
    setVisible(true);

    translateY.value = withSequence(
      withTiming(0, { duration: 400 }),
      withDelay(
        3000,
        withTiming(-100, { duration: 300 }, () => {
          runOnJS(setVisible)(false);
        })
      )
    );

    opacity.value = withSequence(
      withTiming(1, { duration: 400 }),
      withDelay(3000, withTiming(0, { duration: 300 }))
    );
  }, []);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateY: translateY.value }],
    opacity: opacity.value,
  }));

  const messages: Record<ToastType, string> = {
    success: 'Operațiunea a reușit!',
    error: 'A apărut o eroare!',
    info: 'Informație importantă',
  };

  return (
    <SafeAreaView style={styles.screen}>
      {visible && (
        <Animated.View
          style={[
            styles.toast,
            { backgroundColor: TOAST_COLORS[toastType] },
            animatedStyle,
          ]}
        >
          <Text style={styles.toastText}>
            {messages[toastType]}
          </Text>
        </Animated.View>
      )}

      <View style={styles.buttonGroup}>
        <Pressable
          style={[styles.btn, { backgroundColor: '#22c55e' }]}
          onPress={() => showToast('success')}
        >
          <Text style={styles.btnText}>Succes</Text>
        </Pressable>
        <Pressable
          style={[styles.btn, { backgroundColor: '#ef4444' }]}
          onPress={() => showToast('error')}
        >
          <Text style={styles.btnText}>Eroare</Text>
        </Pressable>
        <Pressable
          style={[styles.btn, { backgroundColor: '#3b82f6' }]}
          onPress={() => showToast('info')}
        >
          <Text style={styles.btnText}>Info</Text>
        </Pressable>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  screen: { flex: 1, backgroundColor: '#f8fafc' },
  toast: {
    position: 'absolute',
    top: 60,
    left: 20,
    right: 20,
    padding: 16,
    borderRadius: 12,
    zIndex: 100,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.15,
    shadowRadius: 8,
    elevation: 6,
  },
  toastText: { color: '#fff', fontSize: 16, fontWeight: '600' },
  buttonGroup: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
  },
  btn: {
    paddingHorizontal: 32,
    paddingVertical: 14,
    borderRadius: 12,
  },
  btnText: { color: '#fff', fontSize: 16, fontWeight: '600' },
});

Exemplul ăsta e un pattern pe care-l folosesc destul de des în proiectele mele. E suficient de simplu să-l înțelegi, dar destul de complet să-l adaptezi la nevoile tale.

Când Folosești CSS Transitions vs. Worklets

Reanimated 4 îți pune la dispoziție două sisteme de animație, și e important să știi când le folosești pe fiecare. Nu e neapărat o alegere „sau una, sau alta" — mai degrabă depinde de context.

Folosește CSS Transitions și Keyframes când:

  • Animezi schimbări de stare (expanded/collapsed, visible/hidden, active/inactive)
  • Creezi loading indicators — skeletons, shimmers, spinners
  • Implementezi hover effects și feedback vizual simplu
  • Vrei cod minimal — fără hooks suplimentare, fără shared values
  • Animația este controlată de state React (toggle, setState)

Folosește Worklets și Shared Values când:

  • Ai animații conduse de gesturi (drag, swipe, pinch-to-zoom)
  • Creezi animații legate de scroll — parallax, header collapse
  • Ai nevoie de control frame-by-frame asupra animației
  • Implementezi tranzițiile între ecrane de navigare
  • Orchestrezi animații multiple derivate dintr-o singură sursă

Vestea bună: cele două sisteme funcționează simultan și interoperabil. Poți adopta animațiile CSS treptat, fără a rescrie animațiile existente bazate pe worklets. Am făcut asta eu însumi pe un proiect și tranziția a fost foarte smooth (pun intended).

Reanimated vs. API-ul Animated Integrat

O întrebare pe care o primesc des: mai merită să folosești API-ul Animated integrat în React Native, sau ar trebui să treci complet pe Reanimated?

Răspunsul scurt: pentru orice aplicație de producție în 2026, Reanimated e alegerea recomandată. Iată de ce:

  • Performanță: Animated rulează pe thread-ul JavaScript — dacă JS thread-ul e ocupat, animațiile sacadează. Reanimated rulează pe UI thread, oferind 60-120 FPS constant
  • API modern: Animated folosește o abordare imperativă (new Animated.Value(), .start()). Reanimated oferă hooks declarative și acum CSS transitions — mult mai ergonomic
  • Capabilități: Unele proprietăți (de exemplu, width, height) nu pot fi animate nativ cu Animated, dar funcționează perfect cu Reanimated
  • Integrare gesturi: Reanimated se integrează nativ cu react-native-gesture-handler
  • Layout Animations: Animarea automată a elementelor la intrare, ieșire sau reordonare — funcționalitate unică în Reanimated

Singura excepție: pentru animații foarte simple (un fade-in rapid, de exemplu) într-o aplicație minimalistă unde nu vrei dependențe extra, Animated rămâne o opțiune validă. Dar sincer, o dată ce adaugi Reanimated, n-o să mai vrei să te întorci.

Migrarea de la Reanimated 3 la 4

Dacă folosești deja Reanimated 3.x, migrarea la 4.x e destul de directă. Vestea bună: se păstrează compatibilitatea cu API-urile existente. Animațiile tale bazate pe worklets, shared values și useAnimatedStyle vor continua să funcționeze fără modificări.

Pașii principali de migrare:

  1. Instalează react-native-worklets — pachetul nou separat pentru funcționalitatea worklets
  2. Actualizează babel.config.js — schimbă plugin-ul de la react-native-reanimated/plugin la react-native-worklets/plugin
  3. Asigură-te că ai Noua Arhitectură — Reanimated 4 nu suportă arhitectura Legacy (Paper)
  4. Verifică API-urile depreciate — versiunea 4 elimină câteva API-uri marcate ca depreciate în v3 (consultă changelog-ul oficial pentru lista completă)
  5. Reconstruiește aplicația nativă — un simplu reload nu e suficient, trebuie un build complet

Odată migrat, poți adopta noile animații CSS incremental. Recomandarea mea: începe cu animații simple de stare (toggle-uri, expand/collapse) și treci treptat spre keyframes pentru loading indicators. Nu te grăbi să rescrii tot dintr-o dată.

Sfaturi de Performanță

Reanimated rulează pe UI thread, dar asta nu înseamnă că nu poți avea probleme de performanță dacă nu ești atent. Am învățat asta pe propria piele, so iată câteva sfaturi practice:

  • Menține useAnimatedStyle lean: Callback-ul rulează la fiecare frame — dacă faci calcule costisitoare acolo, vei pierde frame-uri. Mută logica complexă în afara callback-ului
  • Separă stilurile statice de cele dinamice: Folosește StyleSheet.create() pentru tot ce nu se schimbă și useAnimatedStyle doar pentru proprietățile animate
  • Evită re-render-urile inutile: Shared values nu declanșează re-render-uri, dar dacă folosești useState pentru a controla animațiile, componentele se vor re-randa la fiecare schimbare. Preferă shared values unde e posibil
  • Folosește cancelAnimation(): Dacă pornești o nouă animație pe aceeași shared value înainte ca cea anterioară să se termine, anulează explicit animația veche
  • CSS transitions sunt mai ușor de optimizat: Reanimated înțelege mai multe detalii despre ce proprietăți sunt animate, deci poate face optimizări interne mai eficiente decât la worklets

Întrebări Frecvente (FAQ)

Pot folosi Reanimated 4 cu arhitectura veche (Paper)?

Nu. Reanimated 4.x suportă exclusiv Noua Arhitectură React Native (Fabric). Dacă aplicația ta încă folosește arhitectura veche, ai două variante: migrezi la Noua Arhitectură (recomandată începând cu React Native 0.76, unde e activată implicit) sau rămâi pe Reanimated 3.x, care e în continuare menținut activ.

Reanimated 4 funcționează cu Expo?

Da! Funcționează cu Expo SDK 52 și versiunile ulterioare. Template-ul Expo include deja plugin-ul Worklets Babel, deci configurarea e minimală. Instalezi cele două pachete cu npx expo install și ești gata.

Care e diferența dintre animațiile CSS din Reanimated și cele din browser?

Conceptual sunt similare, dar nu identice. În browser, CSS transitions și keyframes sunt definite în fișiere CSS cu proprietăți ca transition și @keyframes. În Reanimated 4, aceleași concepte sunt exprimate ca proprietăți JavaScript pe stilurile componentei Animated.View. Proprietățile (transitionProperty, transitionDuration, animationName etc.) sunt inspirate din standardul CSS, dar aplicate ca obiecte JS.

Pot combina animațiile CSS cu worklets în același proiect?

Absolut. Cele două sisteme sunt proiectate să coexiste. Poți avea componente animate cu CSS transitions pentru schimbări simple de stare și altele cu worklets pentru gesturi și animații complexe — totul în aceeași aplicație. Poți chiar migra treptat de la un sistem la altul, la ritmul tău.

Trebuie să rescriu toate animațiile când migrez la Reanimated 4?

Nu, deloc. Reanimated 4 păstrează compatibilitatea cu API-urile din versiunea 3. Animațiile existente cu useSharedValue, useAnimatedStyle, withTiming și withSpring funcționează fără nicio modificare. Singurele schimbări obligatorii sunt instalarea react-native-worklets și actualizarea plugin-ului Babel. Noul sistem CSS e o adăugare, nu o înlocuire.

Despre Autor Editorial Team

Our team of expert writers and editors.