Animações são o que transforma sites simples em experiências excitantes e inesquecíveis. Elas dão ao seu site um pouco de personalidade e unicidade, fazendo com que o visitante admire a estética geral.

É uma questão de conhecimento comum que os humanos amam coisas bonitas. Nós todos amamos produtos que sejam agradáveis à vista.

Neste artigo, vamos aprender a criar animações que impressionam os usuários com o uso de Framer motion e React-Router-Dom.

Pré-requisitos

Para conseguir acompanhar o que estamos fazendo neste artigo, você deve ter algum conhecimento de React, Framer motion e React-Router-DOM.

Para aprender melhor o Framer motion, você pode estudar a documentação dele.

O Node.js também deve estar instalado em seu sistema, e você deve ter um editor de código funcionando. Eu vou usar o VS Code.

Como Configurar o Projeto

Para configurar nosso projeto, vamos usar o Vite para configurar o ambiente de desenvolvimento React.

  1. Abra o terminal no VScode. Você pode usar Ctrl + backtick(`)

  2. No seu terminal, digite o seguinte comando:

npm create vite@latest
  1. Siga as instruções para nomear seu projeto e escolher o framework desejado. No nosso caso, estamos usando o React. Este será um projeto JavaScript.

  2. Vá para o diretório do seu projeto e use npm i no terminal.

  3. Para iniciar seu projeto, use npm run dev.

  4. Lembre-se de limpar seu projeto removendo o código em App.js e seus arquivos CSS na pasta src.

Como Inicializar Framer Motion e React-Router-Dom

  1. Para instalar o Framer-motion no seu projeto, abra o terminal e insira:
npm i framer-motion
  1. Para instalar o React-Router-DOM no seu projeto, abra o terminal e insira:
npm i react-router-dom

Como Configurar Componentes e Roteamento Básico com React-Router-DOM

Vamos configurar nossos componentes e as páginas para as quais faremos roteamento neste projeto.

  1. No src, crie uma nova pasta chamada components.

  2. Vamos adicionar quatro arquivos nesta pasta chamados Home.jsx, About.jsx, Projects.jsx e Navbar.jsx.

  3. Dentro dos primeiros três, vamos criar um componente funcional do React. Altere o conteúdo da tag h1 em cada componente:

const Home = () => {
 return (
    <div>
     <h1>Home</h1>
    </div>
 )
 }

 export default Home
  1. No Navbar, precisamos importar Link do React-Router-DOM para criar elementos âncora. Em seguida, precisamos criar um contêiner que abrigue nosso logotipo e links de navegação. O logotipo será um link que aponta para nossa página inicial.
import {Link} from "react-router-dom"

const Navbar () => {
 return (
     <div className="nav">
      <div className="logo">
         <Link className="nav-link" to="/">Lennythedev</Link>
     </div>
     <div>
        <div className="nav-links">
           <div className="nav-item">
            <Link className="nav-link" to="/">Home</Link>
           </div>
           <div className="nav-item">
            <Link className="nav-link" to="/">About</Link>
           </div>
           <div className="nav-item">
            <Link className="nav-link" to="/">Projects</Link>
           </div>
     </div>
     </div>
     </div>
  )
 }
  1. Agora vamos para o nosso arquivo index.js ou main.js. O objetivo é envolver todo o nosso aplicativo com BrowserRouter, que permitirá o roteamento dentro da nossa aplicação.
import React from "react"
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Router>
      <Routes>
        <Route path='/*' element={<App />} />
      </Routes>
    </Router>
  </React.StrictMode>,
)
  1. Agora no App.js, vamos completar a etapa final da nossa configuração. Vamos importar nossos componentes e alguns recursos do React-Router-DOM e renderizar nossos componentes. Usando o recurso useLocation do React-Router-DOM, podemos definir a localização atual das rotas definindo a chave para o caminho atual.
import './App.css'
import { Routes, Route, useLocation } from 'react-router-dom'
import NavBar from './components/NavBar';
import Home from './components/Home';
import Projects from './components/Projects';
import About from './components/About';

function App() {
  const location = useLocation();
  return (
    <>
       <NavBar />
       <AnimatePresence mode='wait'>
       <Routes location={location} key={location.pathname}>
        <Route index element={<Home />} />
        <Route path='/projects' element={<Projects />}/>
        <Route path='/about' element={<About />}/>
       </Routes>
       </AnimatePresence>
    </>
  )
}

export default App
  1. Agora podemos adicionar nosso estilo em App.css:
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  color: white;
  font-family: "Fira Sans Condensed", sans-serif;
}

html,
body {
  font-family: "Fira Sans Condensed", sans-serif;
  background: rgb(0, 162, 255);
}

.nav {
  position: fixed;
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.nav-links {
  display: flex;
  cursor: pointer;
}

.logo, .nav-item {
  margin: 2em;
  font-weight: 400;
  font-size: 1.5vw;
}

h1{
  width: 80%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  font-weight: 500;
  font-size: 10vw;
  line-height: 1;
  text-transform: uppercase;
}

a {
  text-decoration: none;
  font-weight: 500;
}
  1. Depois de seguir todos os passos, seu app deve ficar assim:

página estilizada sem animação

Como Criar Transições Usando Framer Motion

Finalmente vamos criar nossa animação para transições entre páginas.

  1. Crie um arquivo em componentes chamado Box.jsx e import motion from framer-motion.

  2. Podemos então retornar duas divs, com classNames de slide-in e slide-out uma para deslizar para dentro e outra para deslizar para fora.

  3. Inserimos nossa animação nessas divs com a ajuda do framer-motion:

import { motion } from "framer-motion"

export default function Box() {
  return(
    <div>
     <motion.div
        className="slide-in"
        initial={{ scaleY: 0 }}
        animate={{ scaleY: 0 }}
        exit={{ scaleY: 1 }}
        transition={{ duration: 1, ease: [0.22, 1, 0.36, 1] }}
     />
     <motion.div
     className="slide-out"
        initial={{ scaleY: 1 }}
        animate={{ scaleY: 0 }}
        exit={{ scaleY: 0 }}
        transition={{ duration: 1, ease: [0.22, 1, 0.36, 1] }}
     />
    </div>
  )
}
  1. De seguida, adicionamos o nosso estilo no nosso ficheiro CSS para slide-in e slide-out na nossa App.css
.slide-in {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background: #0f0f0f;
  transform-origin: bottom;
}

.slide-out {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  background: #0f0f0f;
  transform-origin: top;
}
  1. Finalmente, o último passo é usar o AnimatePresence do framer-motion no nosso ficheiro App.js e envolver toda a App no AnimatePresence e definir o modo como wait. Se você quiser saber mais sobre um AnimatePresence, visite os documentos do framer-motion.
import './App.css'
import { Routes, Route, useLocation } from 'react-router-dom'
import NavBar from './components/NavBar';
import Home from './components/Home';
import Projects from './components/Projects';
import About from './components/About';
import { AnimatePresence } from 'framer-motion';

function App() {
  const location = useLocation();
  return (
    <>
       <NavBar />
       <AnimatePresence mode='wait'>
       <Routes location={location} key={location.pathname}>
        <Route index element={<Home />} />
        <Route path='/projects' element={<Projects />}/>
        <Route path='/about' element={<About />}/>
       </Routes>
       </AnimatePresence>
    </>
  )
}

export default App
  1. Finalmente, nosso trabalho deve ser parecido com o vídeo abaixo:

Conclusão

Criar animações de várias páginas com o Framer Motion e o React-Router-Dom aprimora a experiência do usuário, fornecendo transições suaves.

Esta integração aproveita o poder das capacidades de animação do Framer Motion com as funcionalidades de roteamento do React-Router-Dom, resultando em aplicações web dinâmicas e interativas.