paint-brush
Criei um componente utilitário React para animações com Tailwind e CSS: AnimateInpor@johnpolacek
1,764 leituras
1,764 leituras

Criei um componente utilitário React para animações com Tailwind e CSS: AnimateIn

por John Polacek5m2024/01/17
Read on Terminal Reader
Read this story w/o Javascript

Muito longo; Para ler

<AnimateIn/> é um componente React reutilizável que criei para usar sempre que quiser adicionar rapidamente alguns efeitos de animação aos meus projetos. Um componente utilitário simples, ele combina animação CSS com classes Tailwind para criar animações fluidas e atraentes com o mínimo de esforço.
featured image - Criei um componente utilitário React para animações com Tailwind e CSS: AnimateIn
John Polacek HackerNoon profile picture


<AnimateIn/> Animação da página de demonstração


Já faz algum tempo que uso o mesmo padrão de animação em meus projetos para animar elementos na tela. Em sua forma mais simples, você teria um elemento estilizado com opacidade zero e, em seguida, alteraria o estilo para ter uma opacidade de um com uma transição CSS de um segundo.


Podemos desenvolver isso adicionando outras propriedades de transição, alterando a duração, adicionando um atraso ou definindo uma atenuação personalizada.


<AnimateIn/> é um componente React reutilizável que criei para usar sempre que quiser adicionar rapidamente alguns efeitos de animação aos meus projetos. Um componente utilitário simples, ele combina animação CSS com classes Tailwind para criar animações fluidas e atraentes com o mínimo de esforço.


Vamos dar uma olhada em como ele é usado. Após importar o componente, defina os estados from e to com classes Tailwind. Envolva o elemento de destino em <AnimateIn/> para ver a animação ganhar vida.


 import AnimateIn from '../animation/AnimateIn'; <AnimateIn from="opacity-0 scale-90" to="opacity-100 scale-100" duration={500} > <YourComponent /> </AnimateIn>


Aqui está um exemplo um pouco mais complexo que usa mais propriedades para animar um título e um subtítulo.

 import AnimateIn from '../animation/AnimateIn'; <header> <AnimateIn as="h1" from="opacity-0 translate-y-32" to="opacity-100 translate-y-0" delay={500} duration={300} className="text-4xl" style={{transitionTimingFunction:"cubic-bezier(0.25, 0.4, 0.55, 1.4)"}} > My Big Headline </AnimateIn> <AnimateIn as="h2" from="opacity-0 scale-0" to="opacity-100 scale-100" delay={800} duration={500} className="text-lg" > This is a subtitle below the headline </AnimateIn> </header>


No exemplo do título, <AnimateIn/> é usado para criar um efeito deslizante combinado com um fade-in. Veja como cada propriedade contribui para a animação:


  • propriedade as : Ao definir as="h1" , dizemos ao AnimateIn para renderizar a animação como um elemento <h1> .


  • Propriedades from e to : A propriedade from inicia o título fora da tela ( translate-y-32 , movendo-o 32 unidades para baixo) e invisível ( opacity-0 ). A propriedade to então traz o título para sua posição final (de volta para translate-y-0 ) e o torna totalmente visível ( opacity-100 ).


  • Propriedade duration : a animação é definida para começar imediatamente, sem atraso, e dura 300 ms.


  • Propriedade className : O className="text-4xl" aplica a classe de utilitário do Tailwind para definir o tamanho da fonte, fazendo com que o título se destaque.


  • propriedade style : a transitionTimingFunction personalizada ( cubic-bezier(0.25, 0.4, 0.55, 1.4) ) adiciona uma facilidade única à animação, dando-lhe um efeito de salto.


A legenda usa um conjunto diferente de animações para complementar o título, criando um fluxo visual coeso.

  • propriedade as : aqui, as="h2" renderiza o componente como um elemento <h2> , adequado para uma legenda.


  • Propriedades from e to : A legenda começa reduzida a zero ( scale-0 ) e invisível ( opacity-0 ), depois aumenta até seu tamanho natural ( scale-100 ) e se torna totalmente visível ( opacity-100 ). Este efeito de escala, combinado com um fade-in, adiciona profundidade à animação.


  • propriedades delay e duration : a legenda também começa após um atraso de 800 ms, para que comece depois que o título estiver totalmente animado. Essa abordagem escalonada garante que cada elemento tenha seu momento de foco.


  • Propriedade className : O className="text-lg" define o tamanho da fonte da legenda, tornando-a menor que o título, mas ainda significativa.


Para entender melhor o que está acontecendo, vamos dar uma olhada no código fonte de <AnimateIn/> no Github :


<AnimateIn/> usa um gancho useState para inicializar o estado da animação com a propriedade from , que deve ser uma ou mais classes de utilitário Tailwind, preparando o cenário para o ponto inicial da animação antes que qualquer animação ocorra.


O primeiro gancho useEffect no componente é para respeitar as preferências do usuário para movimento reduzido. Ao ouvir a consulta de mídia (prefers-reduced-motion: reduce) , o comportamento da animação é baseado nas configurações do sistema do usuário. Se o movimento reduzido for preferido, a animação será totalmente ignorada, definindo diretamente o estado da animação para a propriedade to , permitindo uma experiência acessível.


O segundo gancho useEffect é onde reside a lógica da animação. Se o usuário não indicou uma preferência por movimento reduzido, o componente define um temporizador que altera o estado da animação from valor inicial to o valor final após o atraso especificado. Essa transição cria o efeito visual de animação.


A função de limpeza deste gancho (a instrução return) limpa o cronômetro, evitando possíveis vazamentos de memória, como se o componente fosse desmontado antes da conclusão da animação.


A chamada da função React.createElement é o mecanismo de renderização do componente. Ele cria dinamicamente um elemento HTML baseado na propriedade as , permitindo o uso do componente em diferentes elementos HTML. O className é construído usando a função cn popularizada por shadcn , que combina as classes de utilitário do Tailwind, o className personalizado passado como um suporte e o estado atual da animação. Essa atribuição dinâmica de classe é o que aplica os estilos e transições desejados ao elemento.


Além disso, há um atributo style que pode ser passado para definir diretamente as propriedades de estilo no contêiner de animação. A transitionDuration é definida com base na propriedade duration , mas muda de forma inteligente para 0ms se o usuário preferir movimento reduzido, desativando efetivamente a animação enquanto mantém a funcionalidade do componente.


Se você quiser usar <AnimateIn/> em seu próprio projeto e ele já usa shadcn , então você já tem tudo que precisa, basta baixar AnimateIn.tsx e adicioná-lo aos seus componentes.


Caso contrário, você desejará instalar o Tailwind , bem como mxcn o utilitário útil para mesclar classes do tailwind.


Assim como o shadcn, <AnimateIn/> foi criado para ser um componente reutilizável que você pode copiar e colar em seus aplicativos e personalizar de acordo com suas necessidades. O código é seu.


Além disso, criei uma bela página de demonstração para brincar com a criação de diferentes animações com <AnimateIn/> em animate-in.vercel.app .


Também publicado aqui