Maison  >  Article  >  interface Web  >  Réanimons

Réanimons

王林
王林original
2024-08-29 11:08:04335parcourir

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.

Let

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.

Installation

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",
  },
});

Let

Ajouter un gestionnaire de gestes

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

Gérer les événements gestuels

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à

Let

Références

  • réagir-native-réanimé
  • réagir-native-gesture-handler
  • Les bases de PanGestureHandler avec React Native Reanimated 2
  • UI basée sur les données avec UIKit

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:[Flatiron SE] Jour 24Article suivant:[Flatiron SE] Jour 24