Parallelle animationer og animationer i sekvens
Sammensæt animationer med Animated.parallel for at køre dem samtidigt og Animated.sequence for at kæde dem sammen én efter én til komplekse indgangsanimationer.
Parallelle animationer og animationer i sekvens er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.
Sammensætning af komplekse animationer
Animationer i virkelige brugergrænseflader er sjældent blot én værdi, der ændrer sig isoleret. En modal kan glide op og fade ind på samme tid. Et succesikon kan hoppe ind, hvorefter en etiket glider ind. React Natives Animated-API leverer hjælpere til sammensætning, så du kan orkestrere flere animationer, der arbejder sammen: Animated.parallel, Animated.sequence, Animated.stagger og Animated.delay.
Disse metoder til sammensætning returnerer animationsobjekter, som kan startes, stoppes og endda indlejres i hinanden for at skabe komplekse effekter i flere trin.
Animated.parallel: Samtidige animationer
Animated.parallel tager et array af animationer og kører dem alle på samme tid. Når alle animationerne i arrayet er færdige, er den parallelle gruppe færdig. Det er det rigtige valg, når flere egenskaber skal ændres sammen — f.eks. når noget fader ind, mens det glider op.
Som standard stopper alle andre animationer, hvis én animation i en parallel gruppe stopper (f.eks. på grund af en afbrydelse). Du kan tilsidesætte dette med { stopTogether: false } som det andet argument.
const opacity = useRef(new Animated.Value(0)).current;
const translateY = useRef(new Animated.Value(50)).current;
Animated.parallel([
Animated.timing(opacity, {
toValue: 1,
duration: 400,
useNativeDriver: true,
}),
Animated.timing(translateY, {
toValue: 0,
duration: 400,
useNativeDriver: true,
}),
]).start();Animated.sequence: Én efter én
Animated.sequence tager et array af animationer og kører dem én ad gangen — den næste animation starter først, når den forrige er færdig. Det er perfekt til koreografi i flere trin: først trykkes en knap ind, derefter vises en spinner, og til sidst springer et flueben ind.
Hvis en animation i en sekvens stoppes, kører de efterfølgende animationer ikke. Sekvenser kan indlejres i parallelle grupper og omvendt for at skabe kompleks koreografi.
const scale = useRef(new Animated.Value(1)).current;
const checkOpacity = useRef(new Animated.Value(0)).current;
Animated.sequence([
// Step 1: button shrinks
Animated.spring(scale, { toValue: 0.9, useNativeDriver: true }),
// Step 2: wait 300ms
Animated.delay(300),
// Step 3: checkmark appears
Animated.timing(checkOpacity, {
toValue: 1,
duration: 200,
useNativeDriver: true,
}),
]).start();Animated.delay: Pause mellem trin
Animated.delay gør ingenting i det angivne antal millisekunder. Den er kun nyttig i en sekvens, hvor den skaber en pause mellem animationstrin. Med delay kan du skabe et naturligt tempo i animationer i flere trin.
Du kan f.eks. vise en succesmeddelelse med en kort forsinkelse, efter en handling er fuldført, så brugeren får tid til at registrere, hvad der skete, før brugergrænsefladen ændres. Forsinkelser under 300 ms kan normalt ikke mærkes; 400-800 ms føles bevidst og velovervejet.
Animated.sequence([
Animated.timing(opacity, { toValue: 1, duration: 300, useNativeDriver: true }),
Animated.delay(500), // pause for half a second
Animated.timing(opacity, { toValue: 0, duration: 300, useNativeDriver: true }),
]).start();Animated.stagger: Kaskadeeffekter
Animated.stagger minder om parallel, men med en tidsforskydning mellem starten på hver animation. Den første animation starter med det samme, den anden starter efter stagger-forsinkelsen, den tredje efter 2× forsinkelsen osv. Det skaber flotte kaskadeeffekter, når lister eller menuer vises.
Stagger er perfekt til at animere listeelementer, når de kommer ind på skærmen — hvert element fader eller glider ind lidt efter det forrige, så øjet får en tydelig vej gennem indholdet.
const items = [0, 1, 2, 3];
const opacities = items.map(() => new Animated.Value(0));
Animated.stagger(
100, // 100ms between each start
opacities.map(opacity =>
Animated.timing(opacity, {
toValue: 1,
duration: 300,
useNativeDriver: true,
})
)
).start();Sådan bygger du en modal, der vises i flere trin
En gennemarbejdet modal kan vises sådan: (1) overlejringen fader ind, (2) modalens kort glider op og fader ind samtidig, (3) titelteksten vises. Denne koreografi i tre faser bruger en sekvens, hvor første trin er overlejringen, andet trin er en parallel animation for kortet, og tredje trin er titlen.
Hvis du pakker dette ind i en useEffect, der udløses, når modalen bliver synlig, får du den komplette indgangsanimation, som udløses af tilstanden.
const overlayOpacity = useRef(new Animated.Value(0)).current;
const cardTranslateY = useRef(new Animated.Value(80)).current;
const cardOpacity = useRef(new Animated.Value(0)).current;
useEffect(() => {
if (visible) {
Animated.sequence([
Animated.timing(overlayOpacity, { toValue: 0.5, duration: 200, useNativeDriver: true }),
Animated.parallel([
Animated.timing(cardOpacity, { toValue: 1, duration: 300, useNativeDriver: true }),
Animated.spring(cardTranslateY, { toValue: 0, useNativeDriver: true }),
]),
]).start();
}
}, [visible]);Sådan bygger du en afslutningsanimation til en modal
Afslutningsanimationer kører i omvendt rækkefølge: først glider kortet væk og fader ud, derefter fader overlejringen ud, og til sidst opdaterer du tilstanden for at afmontere modalen. Udløs afslutningen i lukkehændelsen, vent på, at animationen bliver færdig i callbacken, og kald først derefter setVisible(false).
Det forhindrer modalen i pludseligt at forsvinde, før animationen er færdig — en almindelig fejl, der får apps til at virke billige.
function closeModal() {
Animated.sequence([
Animated.parallel([
Animated.timing(cardOpacity, { toValue: 0, duration: 200, useNativeDriver: true }),
Animated.timing(cardTranslateY, { toValue: 80, duration: 200, useNativeDriver: true }),
]),
Animated.timing(overlayOpacity, { toValue: 0, duration: 150, useNativeDriver: true }),
]).start(() => setVisible(false)); // unmount AFTER animation
}Indlejret parallel i en sekvens
Metoder til sammensætning kan frit indlejres. En parallel animation inde i en sekvens betyder, at flere ting sker samtidig på det pågældende trin. En sekvens inde i en parallel betyder, at én gren kører trin for trin, mens en anden gren kører med det samme parallelt.
Tænk på det som planlægning af en teaterforestilling: Nogle skuespillere er på scenen samtidig (parallel), nogle scener foregår lige efter hinanden (sekvens), og nogle specialeffekter sker med en bølgeforsinkelse (stagger).
// Sequence with a parallel step inside
Animated.sequence([
Animated.timing(step1, { toValue: 1, duration: 300, useNativeDriver: true }),
Animated.parallel([
Animated.timing(step2a, { toValue: 1, duration: 400, useNativeDriver: true }),
Animated.spring(step2b, { toValue: 1, useNativeDriver: true }),
]),
Animated.timing(step3, { toValue: 1, duration: 200, useNativeDriver: true }),
]).start();Stop og nulstilling af sammensatte animationer
Det objekt, som metoderne til sammensætning returnerer, har en .stop()-metode. Gem animationen i en ref, så du kan stoppe den udefra (f.eks. når en komponent afmonteres midt i en animation, eller når en ny animation skal afbryde den aktuelle).
Stop altid animationer i oprydningen af useEffect for at forhindre advarsler om 'setState on unmounted component' og hukommelseslækager, især for gentagne eller langvarige sekvenser.
const animRef = useRef(null);
useEffect(() => {
animRef.current = Animated.sequence([
Animated.timing(a, { toValue: 1, duration: 500, useNativeDriver: true }),
Animated.timing(b, { toValue: 1, duration: 500, useNativeDriver: true }),
]);
animRef.current.start();
return () => {
if (animRef.current) animRef.current.stop();
};
}, []);Forsinkelse mellem listeelementer, når de vises på skærmen
En praktisk implementering af stagger initialiserer et array af Animated.Values (én pr. listeelement), alle med gennemsigtigheden 0, og kører derefter en stagger-animation i en useEffect, når data indlæses. Hvert element i den viste liste forbindes med sin animerede værdi via sit indeks.
Denne teknik får indholdstunge skærmbilleder til at føles mere dynamiske. Brugere oplever forskudt indlæsning som hurtigere end, at alt vises på én gang, selv om den samlede tid er længere.
const itemAnimations = useRef(data.map(() => new Animated.Value(0))).current;
useEffect(() => {
Animated.stagger(
80,
itemAnimations.map(anim =>
Animated.timing(anim, { toValue: 1, duration: 350, useNativeDriver: true })
)
).start();
}, [data]);
// In renderItem:
<Animated.View style={{ opacity: itemAnimations[index] }}>
<ItemComponent item={item} />
</Animated.View>Koordinering med komponentens livscyklus
Ved at sammensætte animationer med komponentens livscyklus sikrer du, at animationerne afspilles på det rigtige tidspunkt. Brug useEffect til animationer ved montering, effekter ved ændring af tilstand til betingede animationer og sammensætning via callbacks til afslutningsanimationer før afmontering.
Hold animationslogikken tæt på den komponent, der ejer de animerede værdier. Hvis animationslogikken bliver kompleks, kan du udtrække den til en tilpasset hook, der returnerer de animerede værdier og udløserfunktionerne, så JSX-laget forbliver rent.
// Custom hook pattern
function useFadeSlide() {
const opacity = useRef(new Animated.Value(0)).current;
const translateY = useRef(new Animated.Value(20)).current;
const animateIn = () =>
Animated.parallel([
Animated.timing(opacity, { toValue: 1, duration: 300, useNativeDriver: true }),
Animated.timing(translateY, { toValue: 0, duration: 300, useNativeDriver: true }),
]);
return { opacity, translateY, animateIn };
}Hurtigt tjek
Test din forståelse af begreberne inden for React Native Mobile Development fra denne lektion.
Opsummering af lektionen
I denne lektion har du lært, at Animated.parallel kører flere animationer samtidig, at Animated.sequence kæder animationer sammen, så hver animation starter, efter den forrige er færdig, og at Animated.stagger skaber kaskadeeffekter ved at forskyde starttidspunkterne i et array af animationer. Som det næste undersøger vi useNativeDriver for at opnå animationer ved 60 fps ved at flytte arbejdet til den native tråd.
Lær JavaScript med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “Parallelle animationer og animationer i sekvens” gratis?
Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Parallelle animationer og animationer i sekvens”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Parallelle animationer og animationer i sekvens”?
Sammensæt animationer med Animated.parallel for at køre dem samtidigt og Animated.sequence for at kæde dem sammen én efter én til komplekse indgangsanimationer. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på React Native Academy?
Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Parallelle animationer og animationer i sekvens”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne React Native Academy-lektion?
Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Animated.Value og Animated.View
- Spring- og decay-animationer
- Parallelle animationer og animationer i sekvens
- useNativeDriver til animationer ved 60 fps