React Native Academy · Lektion

Spring- og decay-animationer

Brug Animated.spring til at skabe fjedrende, fysikbaserede bevægelser, justér parametrene for tension og friction, og anvend Animated.decay til scroll-effekter baseret på fremdrift.

Lektion 2 af 413 trin

Spring- og decay-animationer er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 2 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.

Ud over lineær bevægelse: fysikbaseret bevægelse

Lineære timing-animationer føles mekaniske, fordi genstande i den virkelige verden sjældent bevæger sig med konstant hastighed. Fysikbaserede animationer simulerer naturlige kræfter som fjedre og momentum, så bevægelse i brugergrænsefladen føles levende og naturlig. React Natives Animated API indeholder to fysikmotorer: Animated.spring til elastisk opspring og Animated.decay til nedbremsning baseret på momentum.

Valget af den rigtige animationstype påvirker den oplevede kvalitet markant. Timing egner sig til opacitetsudtoninger, spring egner sig til interaktive elementer som knapper og kort, og decay egner sig til bevægelser, der kan stryges væk.

Animated.spring: Spændstig bevægelse

Animated.spring simulerer en fjeder, der trækker en værdi mod et mål. Værdien overskrider målet og svinger, indtil den falder til ro — den klassiske opspringseffekt. Som minimum skal du angive toValue og useNativeDriver.

Spring-animationer føles naturlige for elementer, der reagerer på brugerinteraktion, for eksempel en knap, der skaleres op ved tryk, eller en modal, der glider ind nedefra. Standardparametrene for spring er allerede indstillet til at føles gode på mobilen, men du kan tilpasse dem.

import { Animated } from 'react-native';
import { useRef } from 'react';

const scale = useRef(new Animated.Value(0)).current;

Animated.spring(scale, {
  toValue: 1,
  useNativeDriver: true,
}).start();

Justering af spring med spænding og friktion

Fornemmelsen af en spring-animation styres af to parametre: tension og friction. Tension styrer, hvor hurtigt springet trækker mod målet — højere tension betyder hurtigere og mere kontant bevægelse. Friction styrer, hvor hurtigt svingningerne dæmpes — lavere friction betyder mere opspring.

Standardværdien for tension er 40, og for friction er den 7. Prøv tension 100 og friction 10 for en hurtig og responsiv fornemmelse. Prøv tension 20 og friction 3 for en langsom og vaklende effekt. Eksperimentér for at finde den rette fornemmelse til din brugergrænseflade.

Animated.spring(scale, {
  toValue: 1,
  tension: 100,    // higher = snappier
  friction: 10,    // higher = less bouncy
  useNativeDriver: true,
}).start();

// Wobbly alternative:
Animated.spring(scale, {
  toValue: 1,
  tension: 20,
  friction: 3,
  useNativeDriver: true,
}).start();

Spring med stiffness, mass og damping

React Native understøtter også en mere fysisk nøjagtig fjeder-model ved hjælp af stivhed, masse og dæmpning. Disse svarer til de fysiske egenskaber ved et fjeder-system — stivhed er fjederkonstanten, masse er objektets vægt, og dæmpning er modstandskoefficienten.

Denne model er kompatibel med fjederanimationer i iOS UIKit og Framer Motion på nettet, hvilket gør det nemmere at matche animationer, der er designet i prototypingsværktøjer. Brug enten spændings-/friktionsmodellen eller stivheds-/masse-/dæmpningsmodellen — ikke begge på samme tid.

Animated.spring(translateY, {
  toValue: 0,
  stiffness: 120,
  mass: 1,
  damping: 14,
  useNativeDriver: true,
}).start();

Sådan bygger du en fjeder-effekt ved tryk på en knap

Et almindeligt mønster for fjederanimationer er at skalere en knap en smule ned ved tryk og tilbage til fuld størrelse ved slip, hvilket giver en tilfredsstillende taktil feedback. Brug Pressable sammen med onPressIn og onPressOut til at udløse fjederanimationer for skaleringsværdien.

Den hurtige nedskalering ved tryk og tilbagespringet ved slip får knapper til at føles fysiske og reagerende. Det er mere tilfredsstillende end en simpel ændring af gennemsigtigheden og bruges i vid udstrækning i gennemarbejdede mobilapps.

const scale = useRef(new Animated.Value(1)).current;

const onPressIn = () => {
  Animated.spring(scale, { toValue: 0.9, useNativeDriver: true }).start();
};
const onPressOut = () => {
  Animated.spring(scale, { toValue: 1, useNativeDriver: true }).start();
};

return (
  <Pressable onPressIn={onPressIn} onPressOut={onPressOut}>
    <Animated.View style={{ transform: [{ scale }] }}>
      <Text>Press Me</Text>
    </Animated.View>
  </Pressable>
);

Hvad er Animated.decay?

Animated.decay simulerer fremdrift: Den begynder at bevæge en værdi med en given hastighed og sænker den gradvist over tid, som om der virkede friktion på den. Der er ingen målværdi — animationen kører, indtil fremdriften er opbrugt.

Decay er det naturlige supplement til swipe-bevægelser. Når en bruger svirper et kort eller en liste, føres sliphastigheden fra bevægelsen direkte ind i en decay-animation, så elementet fortsætter med at bevæge sig og naturligt sænker farten — præcis som mobilapps fungerede før digitale brugergrænseflader.

// velocity is obtained from a gesture handler's onGestureEvent
Animated.decay(position, {
  velocity: 0.8,       // initial velocity (pixels per millisecond)
  deceleration: 0.997, // how quickly momentum fades (0-1)
  useNativeDriver: true,
}).start();

Decay efter en swipe-bevægelse

Det typiske decay-mønster er at registrere fingerens position under en pan-bevægelse og ved slip sende den endelige hastighed fra bevægelsen til Animated.decay. Værdien deceleration (standardværdien er 0.997) styrer, hvor hurtigt elementet sænker farten — tættere på 1 betyder et længere glid, mens tættere på 0 betyder et hurtigt stop.

Når decay er færdig, fastlåser du typisk elementet til en sluttilstand ved hjælp af en fjederanimation, hvis det er nødvendigt (f.eks. ved at fastlåse et kort tilbage i midten eller til en afvist position).

// In a PanResponder onPanResponderRelease:
onPanResponderRelease: (evt, gestureState) => {
  Animated.decay(position, {
    velocity: gestureState.vx, // velocity at finger lift
    deceleration: 0.997,
    useNativeDriver: true,
  }).start(({ finished }) => {
    if (finished) {
      // optionally snap to final position
    }
  });
}

Sammenligning af spring, decay og timing

Det er afgørende for en naturlig brugergrænseflade at forstå, hvornår du skal bruge hver animationstype:

  • Animated.timing — forudsigelig med en fast varighed. Bedst til feedback i brugergrænsefladen, f.eks. ændringer af gennemsigtighed og statuslinjer, hvor den præcise timing er vigtig.
  • Animated.spring — elastisk og overskyder målet. Bedst til reaktive interaktive elementer som knapper, kort og modaler, der vises.
  • Animated.decay — baseret på fremdrift uden en fast slutning. Bedst til at fortsætte en bevægelse efter slip af en bevægelse, f.eks. swipes og svirp.

Brug af hastighed fra brugerinteraktion

Fjedre har også parameteren velocity, som angiver fjederens begyndelseshastighed, så de naturligt kan forbindes med bevægelser fra brugerbevægelser. Når en bruger trækker i et kort og slipper, kan du starte en fjeder med bevægelsens hastighed, så bevægelsen fortsætter jævnt.

Det skaber en sømløs overgang mellem bevægelse og animation — kortet føles, som om det blev kastet af brugerens hånd, i stedet for at blive teleporteret til sin hvileposition.

// After a pan gesture releases:
onPanResponderRelease: (evt, { vx, vy }) => {
  Animated.spring(position, {
    toValue: { x: 0, y: 0 }, // snap back to center
    velocity: { x: vx, y: vy },
    tension: 50,
    friction: 8,
    useNativeDriver: true,
  }).start();
}

Fjeder med Animated.ValueXY

Animated.ValueXY er en praktisk indpakning, der indeholder et par Animated.Values for x- og y-koordinater. Den forenkler 2D-animationer som trækning af kort. Både spring og decay fungerer med ValueXY, som også har hjælpemetoder som getTranslateTransform() til automatisk at oprette transformationsarrayet.

ValueXY reducerer standardkode, når du skal animere et elements position i et 2D-rum, fordi du ikke behøver at administrere to separate Animated.Values manuelt.

const position = useRef(new Animated.ValueXY({ x: 0, y: -200 })).current;

useEffect(() => {
  Animated.spring(position, {
    toValue: { x: 0, y: 0 },
    useNativeDriver: true,
  }).start();
}, []);

return (
  <Animated.View style={position.getTranslateTransform()}>
    <Text>Falls into place</Text>
  </Animated.View>
);

Nulstilling af Animated-værdier

Du kan nulstille en Animated.Value til dens oprindelige tilstand ved at kalde .setValue(initialValue). Det er nyttigt, før du kører en animation igen — f.eks. når du nulstiller en skalering til 0, før du kører endnu en spring-animation, eller nulstiller positionen, før du afspiller en indgangsanimation igen.

Nulstil altid synkront, før du starter animationen, for at undgå et blink. Kald setValue i den samme hændelsesbehandler eller useEffect, umiddelbart efterfulgt af Animated.spring(...).start().

function replay() {
  // Reset to start position
  scale.setValue(0);
  // Then spring to final position
  Animated.spring(scale, {
    toValue: 1,
    tension: 80,
    friction: 8,
    useNativeDriver: true,
  }).start();
}

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.spring skaber fysikbaserede, hoppende bevægelser, der finjusteres med spænding og friktion, at Animated.decay simulerer en fremdriftsbaseret opbremsning fra en begyndelseshastighed, og at hver animationstype passer til forskellige interaktionsmønstre — spring til feedback ved tryk og decay, når en bevægelse slippes. Som det næste undersøger vi, hvordan du sammensætter flere animationer parallelt og i sekvens.

Gratis at komme i gang

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 “Spring- og decay-animationer” gratis?

Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Spring- og decay-animationer”, 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 “Spring- og decay-animationer”?

Brug Animated.spring til at skabe fjedrende, fysikbaserede bevægelser, justér parametrene for tension og friction, og anvend Animated.decay til scroll-effekter baseret på fremdrift. 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 2 af 4.

Hvor lang tid tager lektionen “Spring- og decay-animationer”?

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

  1. Animated.Value og Animated.View
  2. Spring- og decay-animationer
  3. Parallelle animationer og animationer i sekvens
  4. useNativeDriver til animationer ved 60 fps
← Tilbage til React Native Academy