Fermer

octobre 26, 2020

Présentation de Framer Motion15 minutes de lecture



À propos de l'auteur

Nefe est un développeur frontend qui aime apprendre de nouvelles choses et partager ses connaissances avec les autres.
En savoir plus sur
Nefe

Les animations, lorsqu'elles sont bien faites, sont puissantes. Cependant, créer des animations accrocheuses avec CSS peut être délicat. En vient Framer Motion. Avec Framer Motion, vous n'avez pas besoin d'être un expert CSS pour créer de belles animations. Framer Motion nous fournit des animations prêtes pour la production et une API de bas niveau avec laquelle nous pouvons interagir pour intégrer ces animations dans nos applications.

Dans cet article, nous examinerons de plus près comment Framer Motion nous aide à créer de superbes animations. Nous allons découvrir le fonctionnement des composants de mouvement et comment enchaîner des animations. Nous verrons comment créer des animations déclenchées par des gestes, chronométrées et défilées avec Framer motion. En cours de route, nous utiliserons ce que nous avons appris pour créer cinq applications de démonstration que j'ai configurées pour nous montrer comment intégrer Framer Motion dans des applications du monde réel.

Ce didacticiel sera utile aux lecteurs intéressés dans l'intégration d'animations dans leur application React.

Remarque: Cet article nécessite une compréhension de base de React et CSS.

Qu'est-ce que Framer Motion?

Framer Motion est une bibliothèque d'animations qui permet de créer animations faciles. Son API simplifiée nous aide à faire abstraction de la complexité des animations et nous permet de créer facilement des animations.

Composants de mouvement

Ce sont les éléments de base du mouvement Framer. Les composants de mouvement sont créés en préfixant motion à votre élément HTML et SVG normal (par exemple, motion.h1 ). Les composants de mouvement peuvent accepter plusieurs accessoires, le support de base étant le animate . Cet accessoire prend dans un objet où nous définissons les propriétés de ce composant que nous voulons animer. Les propriétés que nous définissons seront animées lors du montage du composant dans le DOM.

Animons un texte h1 en utilisant Framer Motion. Tout d'abord, nous installons la bibliothèque framer-motion et importons motion .

 npm i framer-motion
import {motion} from 'framer-motion'; 

Ensuite, nous convertissons le h1 en un composant de mouvement.


   Ceci est un composant de mouvement
 

Cela fera glisser le h1 de 20px vers la droite et se déplacer de 20px vers le haut lors du chargement. Lorsque les unités ne sont pas ajoutées, les calculs sont effectués à l’aide de pixels. Cependant, vous pouvez définir explicitement les unités sur lesquelles vous souhaitez que les calculs soient basés, animate = {{x: "20rem", y: "-20rem"}}> .

Par défaut, a Le composant de mouvement sera animé de l'état défini à partir de ses styles jusqu'à ceux de l'accessoire animate . Cependant, si nous le voulions, nous pourrions détourner et définir l'état d'animation initial du composant en utilisant le prop initial . Alors que l'accessoire animate est utilisé pour définir le comportement des composants lors de leur montage, l'accessoire initial définit leur comportement avant leur montage.

Si nous voulons que notre h1 provienne de la gauche, nous contrôlons cela en utilisant la prop initiale.


    Ceci est une composante de mouvement
 

Maintenant, lorsque le h1 monte, il glisse par la gauche.

Nous ne sommes pas limités à une seule animation. Nous pouvons définir une série d'animations appelées images clés dans un tableau de valeurs. Chaque valeur sera animée en séquence.


    Ceci est un composant de mouvement

Le prop transition nous permet de définir comment les animations se produisent. Avec lui, nous définissons comment les valeurs s'animent d'un état à un autre. Entre autres, nous pouvons définir la durée le délai et le type de l'animation à l'aide de cet accessoire.


     Il s'agit d'un composant de mouvement

Supposons que nous devions animer plusieurs composants de mouvement simultanément, comme dans l'extrait de code ci-dessous.

Ceci est un mouvement h1 Ceci est un mouvement h2 Ceci est une motion h3 Ceci est une motion h4

Pendant que cela fonctionne, l'accessoire variants de Framer Motion nous permet d'extraire nos définitions d'animation dans un objet de variantes. Non seulement les variantes rendent notre code plus propre, mais elles nous permettent de créer des animations encore plus puissantes et complexes.

En extrayant nos définitions d'animation en objets variantes, nous avons ceci:

 const H1Variants = {
  initiale: {x: -1000},
  animer: {x: 0},
  transition: {
    type: "tween",
    durée: 2,
    délai: 1
  }
}
const H2Variants = {
  initiale: {y: -1000},
  animer: {y: 0},
  transition: {
    type: "tween",
    durée: 1,
    retard: .4
  }
}
const H3Variants = {
  initiale: {x: 100, opacité: 0},
  animer: {x: 0, opacité: 1}
}
const H4Variants = {
  initiale: {échelle: 0,7},
  animer: {échelle: 1.7},
  transition:{
    type: "tween",
    durée: "2",
    délai: "1"
  }
} 

Au lieu de transmettre directement les définitions d'animation dans les accessoires initiaux et animés d'un composant, nous extrayons ces définitions dans des objets de variante autonomes. Dans les objets de variante, nous définissons des noms de variante qui décrivent le nom de chaque animation comme des variantes.

 
C'est un mouvement h1 Ceci est un mouvement h2 Ceci est une motion h3 Ceci est une motion h4

Dans l'accessoire variants on passe le nom des objets variantes pour chaque composant de mouvement puis on passe les animations à l'initiale et animate accessoires.

Nous pouvons prendre notre configuration actuelle avec des variantes plus loin pour réduire la répétition. En utilisant des variantes, nous pouvons propager les attributs d'animation dans le DOM à partir d'un composant de mouvement parent. Pour que cela fonctionne, nous créons des variantes pour le parent motion.div avec des noms d'animation similaires dans son objet variant comme ses enfants. Ce faisant, nous n’aurons pas à transmettre les noms d’animation à chaque composant enfant. Dans les coulisses, l'élément parent gère cela pour nous.

 const ContainerVariants = {
  initiale: {},
  animer: {}
};
const H1Variants = {
  initiale: {x: -1000},
  animer: {x: 0},
  transition: {
    type: "tween",
    durée: 2,
    délai: 1
  }
};
// plus de variantes ci-dessous


       Ceci est un mouvement h1 
       Ceci est un mouvement h2 
       Ceci est un mouvement h3 
       Ceci est un mouvement h4 
 

Nous avons maintenant un code plus propre sans répétitions. Nous avons transformé le conteneur div en un composant de mouvement afin de pouvoir passer dans l'objet ContainerVariants que nous avons défini. Comme nous ne définissons aucune animation sur le conteneur, nous passons des objets vides à initial et animate . Vos noms d'animation doivent être les mêmes dans chaque objet de variante pour que la propagation fonctionne.

Nous comprenons maintenant les bases de Framer Motion. Commençons par créer notre première liste de 5 applications de démonstration.

Icon Shop

Nous pouvons créer des animations interactives basées sur des gestes. Les composants de mouvement peuvent actuellement écouter la détection des mouvements de survol, de tapotement, de panoramique et de glissement. Nous allons construire cette application Icon Shop en utilisant la whileHover prop.

Components

  • App.js : contient les textes d'en-tête.
  • Card .jsx : ici, nous définissons les animations des cartes d'icônes.
  • CardContainer.jsx : nous importons et bouclons les icônes.
  • styles.js : créer, styliser et exporter les composants de mouvement. J'ai utilisé des composants stylisés pour styliser les composants.

Commençons par App.js .

 import {H1, H2} de "./Styles";
importer CardContainer depuis "./CardContainer";

  revenir (
    

Boutique d'icônes

Survolez les cartes pour voir la magie du mouvement

);

Nous importons les composants de mouvement H1 et H2 que nous avons créés dans le fichier Styles.js . Comme ce sont des composants de mouvement, nous utilisons les accessoires initiaux et animés pour définir leur comportement avant et quand ils se montent. Ici, nous importons et affichons également le composant CardContiner .

Maintenant, le CardContainer.js .

 import {Container} de "./Styles";
importer la carte depuis "./Card";
import {ReactComponent as AddIcon} depuis "./assets/add.svg";
import {ReactComponent as AirplaneIcon} depuis "./assets/airplane.svg";
import {ReactComponent as AlarmIcon} depuis "./assets/alarm.svg";
// plus d'importations svg ci-dessous ...

icônes const = [
  ,
  ,
  ,
  // plus d'icônes ci-dessous
];

const CardContainer = () => {
  revenir (
    
      {icons.map ((icon) => (
        
      ))}
    
  );
}; 

Ici, nous importons les SVG, le composant de mouvement Container et le composant Card .

Similaire à H1 and H2 dans App.js nous définissons les animations du Container en utilisant les accessoires initial et animate . Quand il se charge, il créera un effet sympa de glisser depuis la gauche du navigateur.

Maintenant, Card.js

 import {CardBox, IconBox} de "./Styles";
const CardVariants = {
  beforeHover: {},
  En vol stationnaire: {
    échelle: 1,1
  }
};
const IconVariants = {
  beforeHover: {
    opacité: 0,
    y: -50
  },
  En vol stationnaire: {
    opacité: 1,
    y: 0,
    échelle: 1,5,
    transition: {
      type: "tween"
    }
  }
};

Const Card = ({icon}) => {
  console.log (icône);
  revenir (
    
       {icône} 
    
  );
}; 

Ici, nous créons deux objets variantes avec les animations beforeHover et onHover . Dans l'objet CardVariants nous ne voulons rien faire au départ, donc beforeHover est un objet vide. onHover nous augmentons l'échelle de la boîte de la carte.

Dans l'objet IconVariants nous définissons l'état initial de IconBox dans son beforeHover . Nous définissons son opacité sur 0 et la poussons vers le haut de 50 pixels. Ensuite, dans onHover nous remettons l'opacité à 1, la repoussons à sa position par défaut et changeons le type de transition en tween . Ensuite, nous passons les variantes à leurs composantes de mouvement respectives. Nous utilisons la propagation, nous n'avons donc pas besoin de définir explicitement les accessoires initiaux et animés au composant IconBox .

Barre de navigation animée [19659003] Nous allons construire un composant de navigation simple, et nous verrons comment nous pouvons créer des relations temporelles entre les composants de mouvement parents et enfants.

Composants

  • App.js : il contient les textes d'en-tête. [19659052] Styles.js : créer, styliser et exporter les composants de mouvement. Les composants sont stylisés à l'aide de composants stylisés.

Jetons un coup d'œil au fichier App.js .

 import {Header, Nav, Link, SvgBox} de "./Styles";

function App () {
  const [isOpen, setIsOpen] = useState (faux);
  const iconVariants = {
    ouvert: {
      rotation: 135
    },
    fermé: {
      rotation: 0
    }
  };
  const menuVariants = {
    ouvert: {
      haut: 0,
      transition: {
        quand: "avant les enfants",
        DécalageEnfants: 0,5
      }
    },
    fermé: {
      haut: "-90vh"
    }
  };
  const linkVariants = {
    ouvert: {
      opacité: 1,
      y: 50
    },
    fermé: {
      opacité: 0,
      y: 0
    }
  };

Nous créons un état isOpen qui sera utilisé pour vérifier si la Navbar est ouverte ou non. Nous créons 3 objets variantes, iconVariants menuVariants et linkVariants où nous définissons les animations pour le SvgBox Nav et Link composants de mouvement respectivement. L'icône iconVariants est utilisée pour faire pivoter la SvgBox de 135 degrés lorsqu'elle est survolée. Nous n'avons pas besoin d'ajouter «deg» à la valeur. Dans le menuVariants nous contrôlons la position supérieure du Nav comme vous le feriez en utilisant la propriété position dans CSS. Nous basculons la position supérieure de Nav en fonction de l'état isOpen .

Avec des variantes, nous pouvons créer des relations temporelles entre les composants de mouvement parents et enfants. Nous définissons la relation entre le parent Nav et son enfant, Link en utilisant la propriété when dans l'objet de transition. Ici, définissez-le sur beforeChildren afin que les animations du composant parent se terminent avant le début de l'animation de l'enfant.

En utilisant la propriété staggerChildren nous définissons un ordre de synchronisation pour chaque lien. Chaque lien prendra 0,5 seconde pour apparaître l'un après l'autre. Cela crée un bon signal visuel lorsque le Nav est ouvert. Dans les linkVariants nous animons l'opacité et la position verticale de chaque lien.

setIsOpen (! IsOpen)} >

Ici, on passe dans les variantes à leurs composants respectifs. Dans SvgBox nous basculons l’état de isOpen chaque fois qu’on clique dessus, puis nous l’animons conditionnellement en fonction de l’état. Comme le SvgBox nous animons conditionnellement le Nav et le Link s basés sur l'état de isOpen .

Modal animé [19659003] Nous allons créer un composant modal et découvrirons AnimatePresence de Framer Motion, et comment il nous permet d'animer des éléments lorsqu'ils quittent le DOM.

Composants:

  • App.js : nous configurons ici l'état showModal .
  • Modal.jsx : l'animation proprement dite a lieu ici.
  • Styles.js : créer, styliser et exporter le mouvement Composants. Les composants sont stylisés à l'aide de composants stylisés.

Examinons App.js

 import {ToggleButton, Container} de "./Styles";
import Modal depuis "./Modal";

function App () {
  const [showModal, setShowModal] = useState (faux);
  const toggleModal = () => {
    setShowModal (! showModal);
  };
  revenir (
    
      
         Basculer en mode modal
      
      
    
  );
}

Nous créons un état showModal qui sera utilisé pour rendre conditionnellement le modal. La fonction toggleModal bascule l'état à chaque fois que le ToggleButton est cliqué. ToggleButton est un composant de mouvement, nous pouvons donc lui définir des animations. Lorsqu'il monte, il se glisse par la gauche. Cette animation dure 0,5 seconde. Nous passons également de l'état showModal à l'état Modal via les accessoires.

Maintenant, Modal.jsx

 import {AnimatePresence} de "encadreur- mouvement";
import {ModalBox, ModalContent, Container} depuis "./Styles";


  
     {showModal && (
      
        
            Contenu modal !!!!
        
      
    )}
  
 

Nous importons AnimatePresence de framer-motion . Cela nous permet de définir des animations de sortie pour les composants lorsqu'ils quittent le DOM. Nous rendons conditionnellement le Modal basé sur l'état showModal . Nous définissons les animations pour les ModalBox et ModalContent via leurs accessoires initiaux et animés . Il y a aussi un nouvel accessoire ici, exit . Avoir AnimatePresence comme wrapper nous permet d'ajouter des animations de sortie à ModalBox dans la sortie prop.

Scroll Animation

Nous utiliserons une combinaison du crochet useAnimation et react-intersection-observer pour créer des animations déclenchées par défilement.

Composants

  • App.js : nous configurons les animations pour le Composant Box et restituer dans App
  • Styles.js : créer, styliser et exporter les composants de mouvement. Les composants sont stylisés à l'aide de composants stylisés.
 import React, {useEffect} from "react";
import {useAnimation} de "framer-motion";
import {useInView} de "react-intersection-observer";
import {Container, H1, StyledBox} depuis "./Styles";  const BoxVariants = {
 visible: {opacity: 1, x: 0, transition: {duration: 1}},
 masqué: {opacity: 0, x: 300},
};  const Box = () => {
 contrôles const = useAnimation ();
 const [ref, inView] = useInView ();
 useEffect (() => {
 if (inView) {
 controls.start ("visible");
 }
 }, [controls, inView]);
 revenir (