React Native Academy · Oppitunti

Spring- ja decay-animaatiot

Käyttäkää Animated.springiä joustavan, fysiikkaan perustuvan liikkeen luomiseen, säätäkää tension- ja friction-parametreja ja käyttäkää Animated.decayta liike-energiaan perustuvien vieritystehosteiden toteuttamiseen.

Oppitunti 2/413 vaihetta

Spring- ja decay-animaatiot on ilmainen React Native Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu React Native Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. React Native Academy-kurssilla on yhteensä 4 oppituntia.

Lineaarista liikettä pidemmälle: fysiikkaan perustuva liike

Lineaariset ajoitusanimaatiot tuntuvat mekaanisilta, koska tosimaailman esineet liikkuvat harvoin tasaisella nopeudella. Fysiikkaan perustuvat animaatiot jäljittelevät luonnollisia voimia, kuten jousia ja liikemäärää, mikä tekee käyttöliittymän liikkeestä elävää ja luonnollista. React Nativen Animated API tarjoaa kaksi fysiikkamoottoria: Animated.spring elastiseen pomppuun ja Animated.decay liikemäärään perustuvaan hidastumiseen.

Oikean animaatiotyypin valinta vaikuttaa merkittävästi koettuun laatuun. Ajoitus sopii opacity-häivytyksiin, jousi vuorovaikutteisiin elementteihin, kuten painikkeisiin ja kortteihin, ja hidastuminen pyyhkäisemällä suljettaviin eleisiin.

Animated.spring: joustava liike

Animated.spring simuloi jousta, joka vetää arvoa kohti tavoitetta. Arvo ylittää tavoitteen ja värähtelee, kunnes asettuu paikalleen — näin syntyy klassinen pomppiva vaikutelma. Vähintään on määritettävä toValue ja useNativeDriver.

Jousianimaatiot tuntuvat luonnollisilta käyttäjän vuorovaikutukseen reagoivissa elementeissä, kuten painettaessa suurenevassa painikkeessa tai alhaalta liukuvassa modaalissa. Jousen oletusparametrit on jo säädetty mobiililaitteilla miellyttäviksi, mutta voitte mukauttaa niitä.

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();

Jousen säätäminen tension- ja friction-arvoilla

Jousianimaation tuntumaa ohjaavat kaksi parametria: tension ja friction. Tension määrittää, kuinka nopeasti jousi vetää arvoa kohti tavoitetta — suurempi tension tarkoittaa nopeampaa ja napakampaa liikettä. Friction määrittää, kuinka nopeasti värähtely vaimenee — pienempi friction tarkoittaa voimakkaampaa pomppimista.

Oletusarvoinen tension on 40 ja friction 7. Kokeilkaa nopeaan ja herkästi reagoivaan tuntumaan arvoja tension 100 ja friction 10. Hitaaseen ja huojuvaan vaikutelmaan sopivat arvot tension 20 ja friction 3. Kokeilemalla löydätte käyttöliittymäänne sopivan tuntuman.

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();

Jousi stiffness-, mass- ja damping-arvoilla

React Native tukee myös fysiikan lakeja tarkemmin jäljittelevää jousimallia, jossa käytetään parametreja stiffness, mass ja damping. Ne vastaavat jousijärjestelmän fysikaalisia ominaisuuksia: stiffness on jousivakio, mass tarkoittaa kappaleen massaa ja damping vastaa vastuskerrointa.

Tämä malli on yhteensopiva iOS:n UIKit-jousianimaatioiden ja verkkosivujen Framer Motionin kanssa, joten prototyyppityökaluilla suunniteltujen animaatioiden jäljittely on helpompaa. Käyttäkää joko tension/friction-mallia tai stiffness/mass/damping-mallia – älkää molempia samanaikaisesti.

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

Jousimaisen painallusefektin rakentaminen

Yleinen jousianimaatiomalli on pienentää painiketta painettaessa hieman ja palauttaa se vapautettaessa täyteen kokoonsa. Tämä antaa miellyttävän tuntopalautteen. Käyttäkää Pressable-komponenttia sekä onPressIn- ja onPressOut-tapahtumia jousianimaatioiden käynnistämiseen skaalan arvon perusteella.

Nopea pienentyminen painettaessa ja palautuminen vapautettaessa saavat painikkeet tuntumaan fyysisiltä ja reagoivilta. Tämä on miellyttävämpää kuin pelkkä peittävyyden muuttaminen, ja sitä käytetään laajasti viimeistellyissä mobiilisovelluksissa.

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>
);

Mikä on Animated.decay?

Animated.decay simuloi liikemäärää: se käynnistää arvon liikkeen annetulla nopeudella ja hidastaa sitä vähitellen ajan kuluessa aivan kuin siihen vaikuttaisi kitka. Kohdearvoa ei ole, vaan animaatio jatkuu, kunnes liikemäärä loppuu.

Decay täydentää pyyhkäisyeleitä luonnollisella tavalla. Kun käyttäjä pyyhkäisee korttia tai luetteloa, eleen vapautusnopeus siirtyy suoraan decay-animaatioon. Näin elementti jatkaa liikettään ja hidastuu luonnollisesti – juuri kuten mobiilisovellukset toimivat ennen digitaalisten käyttöliittymien aikaa.

// 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();

Vaimennus pyyhkäisyeleen jälkeen

Tyypillisessä decay-mallissa seurataan sormen sijaintia pan-eleen aikana. Kun sormi nostetaan, eleen lopullinen nopeus välitetään komennolle Animated.decay. Arvo deceleration (oletusarvo 0.997) määrittää, kuinka nopeasti kohde hidastuu: arvo 1 tarkoittaa pidempää liukua ja arvo 0 nopeaa pysähtymistä.

Decay-animaation päätyttyä kohde yleensä kiinnitetään tarvittaessa lopulliseen tilaan jousianimaatiolla, esimerkiksi palauttamalla kortti keskelle tai siirtämällä se hylättyyn sijaintiin.

// 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
    }
  });
}

Jousen, vaimennuksen ja ajoituksen vertailu

On tärkeää ymmärtää, milloin kutakin animaatiotyyppiä käytetään, jotta käyttöliittymä tuntuu luonnolliselta:

  • Animated.timing – ennakoitava ja kestoltaan vakio. Sopii parhaiten käyttöliittymän palautteeseen, kuten peittävyyden muutoksiin ja edistymispalkkeihin, joissa tarkka ajoitus on tärkeää.
  • Animated.spring – joustava ja kohteen ylittävä. Sopii parhaiten reagoiviin vuorovaikutteisiin elementteihin, kuten painikkeisiin, kortteihin ja modaalien avautumiseen.
  • Animated.decay – perustuu liikemäärään eikä sillä ole kiinteää loppua. Sopii parhaiten eleen vapauttamisen jälkeisen liikkeen jatkamiseen, kuten pyyhkäisyihin.

Käyttäjän vuorovaikutuksesta saadun nopeuden käyttäminen

Jousilla on myös velocity-parametri, joka määrittää jousen alkunopeuden ja yhdistää sen luonnollisesti eleen liikkeeseen. Kun käyttäjä vetää korttia ja vapauttaa sen, jousi voidaan käynnistää eleen nopeudella, jolloin liike jatkuu sulavasti.

Näin eleen ja animaation välinen siirtymä on saumaton: kortti tuntuu käyttäjän kädestä heitetyltä eikä siltä, että se olisi siirretty hetkessä lepoasentoonsa.

// 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();
}

Jousi Animated.ValueXY:n kanssa

Animated.ValueXY on apukääre, joka sisältää x- ja y-koordinaattien Animated.Value-arvoparin. Se helpottaa kaksiulotteisia animaatioita, kuten korttien vetämistä. Sekä jousi että decay toimivat ValueXY:n kanssa, ja se sisältää esimerkiksi getTranslateTransform()-apumetodin, joka muodostaa muunnostaulukon automaattisesti.

ValueXY vähentää toistuvaa koodia, kun elementin sijaintia on animoitava kaksiulotteisessa tilassa, koska kahta erillistä Animated.Value-arvoa ei tarvitse hallita käsin.

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>
);

Animated-arvojen palauttaminen

Animated.Value-arvon voi palauttaa alkutilaansa kutsumalla komentoa .setValue(initialValue). Tämä on hyödyllistä ennen animaation suorittamista uudelleen, esimerkiksi palautettaessa skaala arvoon 0 ennen uutta pop-in-jousianimaatiota tai palautettaessa sijainti ennen sisääntuloanimaation toistamista.

Palauttakaa arvo aina synkronisesti ennen animaation käynnistämistä välähdyksen välttämiseksi. Kutsukaa setValue-komentoa saman tapahtumankäsittelijän tai useEffect-kutsun sisällä ja suorittakaa heti sen jälkeen 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();
}

Pikatarkistus

Testatkaa, kuinka hyvin ymmärrätte tämän oppitunnin React Native Mobile Development -käsitteet.

Oppitunnin kertaus

Tässä oppitunnissa opitte, että Animated.spring luo fysiikkaan perustuvaa, tension- ja friction-arvoilla säädettävää joustavaa liikettä, Animated.decay simuloi alkunopeudesta johtuvaa liikemäärään perustuvaa hidastumista ja kukin animaatiotyyppi sopii erilaisiin vuorovaikutusmalleihin: jousi napautuksen palautteeseen ja decay eleen vapautuksen jälkeiseen liikkeeseen. Seuraavaksi tutustumme useiden animaatioiden suorittamiseen rinnakkain ja peräkkäin.

Aloita maksutta

Opi JavaScript tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”Spring- ja decay-animaatiot” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa React Native Academy-oppimispolun 3 oppituntia, myös oppitunnin “Spring- ja decay-animaatiot”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. React Native Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Spring- ja decay-animaatiot”?

Käyttäkää Animated.springiä joustavan, fysiikkaan perustuvan liikkeen luomiseen, säätäkää tension- ja friction-parametreja ja käyttäkää Animated.decayta liike-energiaan perustuvien vieritystehosteide… Harjoittelet React Native Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni React Native Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin React Native Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Spring- ja decay-animaatiot”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä React Native Academy-oppitunnilla?

Kyllä. Jokainen React Native Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Animated.Value ja Animated.View
  2. Spring- ja decay-animaatiot
  3. Useiden ominaisuuksien animointi rinnakkain ja peräkkäin
  4. useNativeDriver 60 fps:n animaatioissa
← Takaisin: React Native Academy