Como criar animações interativas usando o React Spring – SitePoint


Assim, e . Esses elementos animados podem ser usados ​​no lugar de seus elementos HTML normais, permitindo que apliquem animações usando os ganchos de animação do React Spring.

Ganchos

O React Spring fornece vários ganchos que ajudam a criar animações nos componentes do React. Esses ganchos simplificam o processo de gerenciamento de animações e facilitam a integração de nossos componentes. Aqui estão alguns dos ganchos principais fornecidos pelo React Spring:

  • usapring. Isso geralmente é usado na maioria dos casos, pois cria uma única animação de mola que altera os dados do estado inicial para outro.

  • USETRANSITION. Isso anima a adição, remoção ou reordenação dos itens da lista. Ele gerencia o ciclo de vida da animação de elementos quando eles entram ou deixam o DOM, permitindo transições suaves entre diferentes estados de uma lista.

  • USETRAIL. Isso é usado para criar várias animações de primavera que criam um efeito “trilha”, onde cada primavera segue ou trilhas atrás do anterior.

  • Usechain. Assim como uma corrente, isso é usado para definir uma sequência de animações usando especificando a ordem em que elas devem ocorrer.

  • usaprings. Embora isso seja semelhante a useSpringAssim, useSprings é usado para gerenciar várias animações de primavera ao mesmo tempo, enquanto useSpring Gerencia uma única animação de primavera.

Para entender melhor como esses funcionam, vejamos os diferentes estilos de animação que podemos alcançar com cada um desses ganchos.

Usando o UsoPring para criar animações

O useSpring O gancho no React Spring é usado para criar animações usando a física da primavera. Ele nos permite definir os pontos de partida e final de uma animação e usa sua biblioteca para lidar com a transição entre eles. Por exemplo:

 const props = useSpring({ 
 opacity: 1,
  from: { opacity: 0 } 
  });

Neste exemplo, criamos uma função que altera a opacidade de um elemento de 0 para 1. Essa função pode ser chamada em vários elementos, dependendo de nossos efeitos de animação. Vejamos as etapas a serem tomadas ao usar o useSpring gancho para criar animações…

Primeiro, importe as dependências necessárias para a animação:

import { useSpring, animated } from "react-spring";

Em seguida, precisamos definir um componente e usar o useSpring gancho para criar valores animados. O useSpring Hook aceita dois argumentos principais:

  1. Objeto de configuração. Isso define as propriedades de nossa animação, incluindo:

    • de: O estado inicial do valor animado (como opacidade: 0)
    • para: O estado -alvo do valor animado (como opacidade: 1)
    • Config (opcional): um objeto para ajustar o comportamento da física da primavera (como massa, tensão, atrito)
  2. Função de retorno de chamada (opcional). Podemos usar uma função para criar uma configuração dinâmica com base em adereços ou dados.

Criando um useSpring A animação pode ser alcançada usando dois métodos diferentes: usando um objeto literal e usando um parâmetro de função.

Usando um objeto literal

Podemos definir um objeto com as propriedades que queremos animar, como opacity ou colore passar para o useSpring gancho. Essa abordagem nos permite especificar os valores de destino diretamente para a animação.

Para explicar como isso funciona, vamos criar um componente simples que anima a opacidade de um elemento:

import React, { useState } from 'react';
import { useSpring, animated } from 'react-spring';

function App() {
  const (isVisible, setIsVisible) = useState(false);

  const opacityAnimation = useSpring({
    opacity: isVisible ? 1 : 0,
    config: {
      tension: 200, 
      friction: 20 
    }
  });

  const toggleVisibility = () => setIsVisible(!isVisible);

  return (
    <div>
      <button onClick={toggleVisibility} aria-label={isVisible ? 'Hide' : 'Show'}>
        {isVisible ? 'Hide' : 'Show'}
      </button>
      <animated.div style={opacityAnimation}>
        This text will fade in and out with spring physics.
      </animated.div>
    </div>
  );
}
export default App;

Neste trecho de código, criamos um botão que alterna a visibilidade de algum texto quando clicado. Faz isso usando dois ganchos, useState e useSpring.

Ele usa useState Para verificar se o texto é visível ou não e cria uma animação que altera a opacidade de um texto com base na condição:

opacity: isVisible ? 1 : 0

Isso dá um efeito de animação quando o botão que chama o toggleVisibility() A função é clicada.

Texto desaparecendo em uma saída com cada botão Clique

Usando um parâmetro de função

Como alternativa, podemos passar uma função para o useSpring gancho. Esta função recebe os valores animados anteriores e retorna um objeto com os valores atualizados para a animação. Isso nos dá mais controle sobre como a animação se comporta ao longo do tempo:

 const opacityConfig = {
    tension: 300,
    friction: 40,
  };

  
  const opacityAnimation = useSpring(() => ({
    opacity: isVisible ? 1 : 0,
    config: opacityConfig,
  }));

Nesta abordagem, a configuração (tensão e atrito) é extraída em um objeto separado – opacityConfig – e isso oferece maior flexibilidade para controle dinâmico com base em estado ou adereços.

Itens de lista de animação com USETransition

UseTransition é um gancho de primavera do React que anima elementos em matrizes à medida que são adicionados ou removidos do DOM. É particularmente útil para criar animações fluidas em listas ou modais. Para fazer isso, aceita uma lista de configurações possíveis:

  • from Define os estilos iniciais para os itens que entram no DOM.
  • enter Especifica os estilos para animar quando os itens são adicionados. Podemos criar animações em várias etapas, fornecendo uma variedade de objetos.
  • leave Define os estilos aplicados quando os itens são removidos do DOM.
  • update Controla como animar mudanças entre os itens existentes.
  • key nos permite definir explicitamente uma chave única para cada item. Isso possibilita definir animações específicas para itens individuais.
  • from e to com transições: elas podem ser usadas dentro enterAssim, leavee update Para animações mais complexas com os estados iniciais e finais definidos de forma independente.

Para ilustrar como useTransition Trabalha, vamos criar um componente que adiciona e remove itens de uma matriz:

import React, { useState } from "react";
import { useTransition, animated } from "react-spring";

function App() {
  const (items, setItems) = useState(());

  const addItem = () => {
    const newItem = `Item ${items.length + 1}`;
    setItems((...items, newItem));
  };

  const removeItem = () => {
    if (items.length === 0) return;
    const newItems = items.slice(0, -1);
    setItems(newItems);
  };

  const transitions = useTransition(items, {
    from: { opacity: 0, transform: "translate3d(0, -40px, 0)" },
    enter: { opacity: 1, transform: "translate3d(0, 0, 0)" },
    leave: { opacity: 0, transform: "translate3d(0, -40px, 0)" },
  });

  return (
    <div className="transitionDiv">
      <div>
        <button onClick={addItem}>Add Item</button>
        <button onClick={removeItem}>Remove Item</button>
      </div>
      <div className="transitionItem">
        {transitions((style, item) => (
          <animated.div style={style} className ='list'>{item}</animated.div>
        ))}
      </div>
    </div>
  );
}

export default App;

Neste exemplo, temos um App Componente que gerencia uma lista de itens. Ele fornece botões para adicionar ou remover dinamicamente os itens da lista. Quando o Adicionar item o botão é clicado, um novo item é adicionado à matriz e quando o Remova o item O botão é clicado, o último item é removido da matriz.

O useTransition O gancho é usado para gerenciar as transições dos itens na matriz. Sempre que a matriz mudar (devido à adição ou remoção de itens), useTransition lida com as animações para essas alterações de acordo com a configuração especificada (definida pelo fromAssim, entere leave propriedades).

Clicar em Adicionar e remover botões Adicionar e remove elementos

Animando matrizes sem mudanças

Se não houver mudanças dinâmicas na própria matriz, como adicionar ou remover elementos, useTransition ainda pode ser usado para animar cada elemento na matriz. Por exemplo:

import { useTransition, animated } from "@react-spring/web";
import "./App.css";

const name = "Product1";
const name1 = "Product2";
const name2 = "Product3";

function App({ data = (name, name1, name2) }) {
  const transitions = useTransition(data, {
    from: { scale: 0 },
    enter: { scale: 1 },
    leave: { scale: 0.5 },
    config: { duration: 2500 },
  });

  return transitions((style, item) => (
    <div className="nameBody">
      <animated.div style={style} className="nameDiv">
        {item}
      </animated.div>
    </div>
  ));
}

export default App;

Neste exemplo, o App O componente renderiza uma lista de itens e aplica animações sempre que a página carrega.

Três círculos de produto vertical crescem do nada

Criando animações seqüenciais com USetrail

O useTrail A animação é usada para criar uma série de transições animadas para um grupo ou lista de elementos da interface do usuário.

Ao contrário dos métodos de animação tradicionais que animam os elementos individualmente, useTrail nos permite animar elementos um após o outro, criando assim um efeito “trilha”. Isso geralmente é usado ao criar listas dinâmicas, galerias de imagens, transições de página ou qualquer cenário em que os elementos precisem animar sequencialmente.

Aqui está a estrutura básica da sintaxe:

const trail = useTrail(numberOfItems, config, (trailOptions));

Vamos quebrar isso:

  1. numberOfItems. Esse é um número necessário que especifica quantos elementos queremos animar na “trilha”.

  2. config. Este é um objeto que define as propriedades de animação para cada elemento na trilha. Cada chave no objeto representa uma propriedade de animação e seu valor pode ser baseado em nossa animação pretendida. Por exemplo:

    from: { opacity: 0, transform: 'translateX(50%)' },
    to: { opacity: 1, transform: 'translateX(0)' },
    transition: {
      duration: 500,
      easing: 'easeInOutCubic',
    },
    
  3. trailOptions (opcional). Esta é uma variedade de opções adicionais para a trilha. Algumas opções comuns são:

    • trailKey: uma função para gerar teclas exclusivas para cada elemento na trilha (útil para a reconciliação do React).
    • reset: uma função para redefinir todas as animações na trilha.

Vamos dar uma olhada em como funciona:

import React, { useState, useEffect } from "react";
import { useTrail, animated } from "react-spring";

function App() {
  const (items, setItems) = useState((
    { id: 1, content: "This is a div illustrating a trail animation" },
    { id: 2, content: "This is a div illustrating a trail animation" },
    { id: 4, content: "This is a div illustrating a trail animation" },
    { id: 5, content: "This is a div illustrating a trail animation" },
  ));
 ());

  const trail = useTrail(items.length, {

    from: { opacity: 1, transform: "translateY(0px)" },
    to: { opacity: 0, transform: "translateY(100px)" },
    delay: 400, 
    duration: 2000, 
  });

  return (
    <div className="container">
      {trail.map((props, index) => (
        <animated.div key={items(index).id} style={props} className="item">
          {items(index).content}
        </animated.div>
      ))}
    </div>
  );
}

export default App;

No trecho de código acima, criamos um CardCarousel componente que utiliza o useTrail gancho para criar uma trilha de animações para cada carrossel de cartão com base no comprimento dos itens da matriz.

Nota: Para saber mais sobre o useEffect Gancho, confira Entendendo o React useEffect.

const trail = useTrail(items.length, {

  from: { opacity: 1, transform: "translateY(0px)" },
  to: { opacity: 0, transform: "translateY(100px)" },
  delay: 400, 
  duration: 2000, 
});

Aqui, ele define os estados iniciais e finais da animação (de e para), bem como a configuração de transição (duração e flexibilização), que afeta a maneira como a animação é mostrada.

Renderizando cada cartão

Para renderizar cada cartão, o componente retorna um

with the class card-carousel e mapas sobre a matriz da trilha para renderizar cada cartão animado. Cada cartão é então envolto em um animated.div componente que aplica os estilos animados (opacidade e transformação) definidos no useTrail gancho:

return (
    <div className="container">
      {trail.map((props, index) => (
        <animated.div key={items(index).id} style={props} className="item">
          {items(index).content}
        </animated.div>
      ))}
    </div>
  );

animando uma pilha de cartas

Dominar sequências de animação com usechain

Ao contrário das animações independentes, useChain é usado para vincular várias animações e define uma sequência sobre como as animações predefinidas são realizadas. Isso é particularmente útil ao criar interfaces dinâmicas do usuário, onde os elementos precisam animar um após o outro.

Vejamos a sintaxe.

useChain Aceita uma matriz de refs de animação e um objeto de configuração opcional. Cada referência de animação representa uma animação separada e eles são executados na ordem em que aparecem na matriz. Também podemos especificar atrasos para cada animação para controlar o tempo da sequência usando esta sintaxe:

useChain((ref1, ref2, ref3), { delay: 200 });

Para ilustrar como isso funciona, vamos criar um componente que aplique duas animações em diferentes elementos e controla as animações usando useChain:

import "./App.css";

import React, { useRef } from "react";
import {
  useTransition,
  useSpring,
  useChain,
  animated,
  useSpringRef,
} from "react-spring";

const data = ("", "", "", "");

function App() {
  const springRef = useSpringRef();
  const springs = useSpring({
    ref: springRef,
    from: { size: "20%" },
    to: { size: "100%" },
    config: { duration: 2500 },
  });

  const transRef = useSpringRef();
  const transitions = useTransition(data, {
    ref: transRef,
    from: { scale: 0, backgroundColor: "pink" },
    enter: { scale: 1, backgroundColor: "plum" },
    leave: { scale: 0, color: "pink" },
    config: { duration: 3500 },
  });

  useChain((springRef, transRef));

  return (
    <animated.div
      style={{
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        height: "400px",
        width: springs.size,
        background: "white",
      }}
    >
      {transitions((style, item) => (
        <animated.div
          style={{
            width: "200px",
            height: "200px",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            textAlign: "center",
            marginLeft: "50px",
            color: "white",
            fontSize: "35px",
            borderRadius: "360px",
            ...style,
          }}
          className="products"
        >
          {item}
        </animated.div>
      ))}
    </animated.div>
  );
}

export default App;

No código acima, estamos criando duas animações diferentes, usando useString e useTransitione usando o useChain Para gerenciar as diferentes animações:

useChain((springRef, transRef));

uma fileira de círculos se expandindo horizontal e verticalmente

Criando várias animações usando o gancho de usesprings

Como mencionamos anteriormente, useSprings é usado para criar várias animações de mola ao mesmo tempo, e cada uma dessas animações tem suas configurações. Isso nos permite animar vários elementos ou propriedades independentemente do mesmo componente. Por exemplo:

import { useSprings, animated } from "@react-spring/web";

function App() {
  const (springs, api) = useSprings(
    3,
    () => ({
      from: { scale: 0, color: "blue" },
      to: { scale: 1, color: "red" },
      config: { duration: 2500 },
    }),
    ()
  );

  return (
    <div>
      {springs.map((props) => (
        <animated.div style={props} className="springsText">
          _______
        </animated.div>
      ))}
    </div>
  );
}

export default App;

Neste exemplo, useSprings Gerencia uma variedade de animações de primavera, cada uma representando a animação para um item na matriz de itens. Cada item da lista está associado a uma configuração de mola que define os valores iniciais e de destino para as propriedades de cor e escala. O React Spring então anima cada item com base em sua configuração correspondente.

Três linhas horizontais que se movem para a esquerda através da página e mudando de cor

Conclusão

O React Spring é uma poderosa biblioteca de animação que nos permite criar animações impressionantes e interativas em nossos aplicativos React. Como vimos, essas animações podem ser aplicadas em vários elementos em nossos projetos.

Ao alavancar as características do React Spring, podemos obter transições mais suaves com efeitos de aparência mais natural e maior controle sobre nossas animações.

Yemi é desenvolvedor de software e escritor técnico. Ela gosta de explicar conceitos técnicos relacionados à programação e software em termos compreensíveis. Você pode ler mais sobre as postagens do blog dela em dev.to/hyemiie.

animações



Source link