Progression
0 %
0/32 étapes terminées
Avancé · 13 min de lecture
Reanimated et les gestes
Des animations à 60 images par seconde qui suivent le doigt
1Définition
react-native-reanimated exécute la logique d'animation sur le thread UI grâce aux worklets, de petites fonctions JavaScript copiées dans un environnement d'exécution séparé. Associé à react-native-gesture-handler, il permet des interactions tactiles fluides même quand le thread JavaScript est occupé.
2Principes fondamentaux
01
Les shared values
useSharedValue crée une valeur lisible et modifiable depuis les deux threads. Modifier .value ne provoque pas de rendu React.
02
Les styles animés
useAnimatedStyle renvoie un style recalculé sur le thread UI à chaque changement des shared values qu'il lit.
03
Les fonctions d'animation
withTiming, withSpring, withDecay, combinables avec withSequence, withRepeat et withDelay.
04
Les gestes
Gesture.Pan(), Gesture.Tap(), Gesture.Pinch() décrivent des gestes composables, attachés avec <GestureDetector>.
3Exemples pratiques
Une carte qu'on fait glisser
1import { Gesture, GestureDetector } from 'react-native-gesture-handler';2import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';3 4export function CarteGlissable() {5 const x = useSharedValue(0);6 const y = useSharedValue(0);7 8 const glisser = Gesture.Pan()9 .onChange((e) => {10 x.value += e.changeX;11 y.value += e.changeY;12 })13 .onEnd(() => {14 x.value = withSpring(0);15 y.value = withSpring(0);16 });17 18 const style = useAnimatedStyle(() => ({19 transform: [{ translateX: x.value }, { translateY: y.value }, { rotate: x.value / 20 + 'deg' }],20 }));21 22 return (23 <GestureDetector gesture={glisser}>24 <Animated.View style={[styles.carte, style]} />25 </GestureDetector>26 );27}Les callbacks du geste sont des worklets : la carte suit le doigt image par image, puis revient avec un ressort.
4Erreurs courantes
Lire une shared value pendant le rendu
À éviter
return <Text>{progression.value}</Text>;À faire
// affiche via un style animé, ou synchronise vers le state avec runOnJS si nécessairePourquoi : Lire .value dans le rendu ne s'abonne à rien : l'affichage ne suivra pas les changements.
Appeler une fonction JS depuis un worklet
À éviter
.onEnd(() => { enregistrerScore(); // fonction JS classique})À faire
.onEnd(() => { runOnJS(enregistrerScore)();})Pourquoi : Un worklet s'exécute sur le thread UI : pour appeler du code JavaScript normal, il faut repasser explicitement sur le thread JS.
5Subtilités à connaître
- ◆Les « layout animations » (
entering,exiting,layout) animent l'apparition et la disparition d'éléments en une ligne. - ◆
interpolateetExtrapolation.CLAMPtransforment une valeur de geste en opacité, rotation ou couleur. - ◆Les versions récentes de Reanimated s'appuient sur la nouvelle architecture.
6Techniques d'expert
Suivre la vitesse du geste
Dans onEnd, e.velocityX permet de décider si la carte est « lancée » hors de l'écran (swipe) ou revient à sa place.
Animer au défilement
useAnimatedScrollHandler et useScrollViewOffset donnent l'offset de défilement sur le thread UI : en-têtes qui se rétractent, parallaxe, barre qui se colore.
const offset = useSharedValue(0);const onScroll = useAnimatedScrollHandler((e) => { offset.value = e.contentOffset.y;}); <Animated.ScrollView onScroll={onScroll} scrollEventThrottle={16} />Composer les gestes
Gesture.Simultaneous(pinch, rotation) ou Gesture.Exclusive(doubleTap, tap) résolvent les conflits entre gestes sans hacks.
7Sur le terrain
- Les applis de rencontre et de flashcards utilisent le swipe avec seuil de vitesse.
- Les lecteurs de musique animent une mini-barre qui s'étend en plein écran en suivant le doigt.
- Les applis de cartographie combinent pincement, rotation et glissement simultanés.
8Vérifie ta compréhension
Question 1/3
Score 0
Où s'exécute un worklet d'animation ?
Envie d'essayer ? Ouvre le Labo et recopie les exemples pour les modifier.