Dessiner du texte et des images est une chose, mais le véritable test d'un cadre d'interface utilisateur réside dans sa qualité d'animation de contenu.
Et mon test d'animation est le MoveMe classique basé sur l'exemple de code d'Apple.
L'idée est de dessiner trois cases sur l'écran. Lorsqu'elle est sélectionnée, la boîte change de couleur et s'agrandit, puis peut être déplacée avec le geste de glisser et revient finalement à sa couleur et sa taille d'origine une fois relâchée.
Créons cet exemple à l'aide de la bibliothèque Reanimated de React Native.
Je suis les documents officiels mais je n'utilise pas leur modèle. J'ai donc créé un projet de base avec le modèle vierge et installé les dépendances
npx create-expo-app playground --template blank npx expo install react-native-reanimated npx expo install react-native-gesture-handler
Ensuite, j'ai ajouté le plugin
module.exports = function (api) { api.cache(true); return { presets: ["babel-preset-expo"], plugins: ["react-native-reanimated/plugin"], }; };
Et puis dessinez 3 carrés à l'écran :
import { StatusBar } from "expo-status-bar"; import { StyleSheet, View } from "react-native"; import Animated from "react-native-reanimated"; function Square() { return <Animated.View style={styles.square}></Animated.View>; } export default function App() { return ( <View style={styles.container}> <StatusBar style="auto" /> <Square /> <Square /> <Square /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", alignItems: "center", justifyContent: "space-evenly", }, square: { width: 100, height: 100, backgroundColor: "blue", }, });
Pour ajouter la prise en charge des gestionnaires de gestes, nous devons d'abord envelopper le contenu dans GestureHandlerRootView
<GestureHandlerRootView style={styles.container}> <Square /> <Square /> <Square /> </GestureHandlerRootView>
Et puis enveloppez chaque carré dans GestureDetector
function Square() { const gesture = Gesture.Pan(); return ( <GestureDetector gesture={gesture}> <Animated.View style={styles.square} /> </GestureDetector> ); }
Pour gérer le geste, nous devons d'abord créer une SharedValue qui est comme State mais pour les états d'animation. Par exemple, pour changer la couleur d'arrière-plan lorsqu'elle est sélectionnée, nous devons écouter les événements onBegin et onFinalize et mettre à jour le style :
function Square() { const isPressed = useSharedValue(false); const animStyle = useAnimatedStyle(() => { return { backgroundColor: isPressed.value ? "red" : "blue", }; }); const gesture = Gesture.Pan() .onBegin(() => { isPressed.value = true; }) .onFinalize(() => { isPressed.value = false; }); return ( <GestureDetector gesture={gesture}> <Animated.View style={[styles.square, animStyle]} /> </GestureDetector> ); }
La prise en charge de la traînée est similaire. Nous devons stocker les positions de départ et actuelles, puis mettre à jour la position actuelle lors de l'événement onChange. Le onChange fournit le changement delta que nous devons ensuite ajouter à la position de départ pour calculer la position actuelle finale. Et puis, enfin, lors de l'événement onFinalize, nous pouvons synchroniser les positions de départ et actuelles.
function Square() { const isPressed = useSharedValue(false); const startPos = useSharedValue({ x: 0, y: 0 }); const pos = useSharedValue({ x: 0, y: 0 }); const animStyle = useAnimatedStyle(() => { return { backgroundColor: isPressed.value ? "red" : "blue", transform: [ { translateX: pos.value.x }, { translateY: pos.value.y }, { scale: withSpring(isPressed.value ? 1.2 : 1) }, ], }; }); const gesture = Gesture.Pan() .onBegin(() => { isPressed.value = true; }) .onChange((e) => { pos.value = { x: startPos.value.x + e.translationX, y: startPos.value.y + e.translationY, }; }) .onFinalize(() => { isPressed.value = false; startPos.value = { x: pos.value.x, y: pos.value.y, }; }); return ( <GestureDetector gesture={gesture}> <Animated.View style={[styles.square, animStyle]} /> </GestureDetector> ); }
Et voilà
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!