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.
-
Abra o terminal no VScode. Você pode usar Ctrl + backtick(`)
-
No seu terminal, digite o seguinte comando:
npm create vite@latest
-
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.
-
Vá para o diretório do seu projeto e use
npm i
no terminal. -
Para iniciar seu projeto, use
npm run dev
. -
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
- Para instalar o Framer-motion no seu projeto, abra o terminal e insira:
npm i framer-motion
- 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.
-
No
src
, crie uma nova pasta chamadacomponents
. -
Vamos adicionar quatro arquivos nesta pasta chamados
Home.jsx
,About.jsx
,Projects.jsx
eNavbar.jsx
. -
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
- 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>
)
}
- Agora vamos para o nosso arquivo
index.js
oumain.js
. O objetivo é envolver todo o nosso aplicativo comBrowserRouter
, 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>,
)
- 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 recursouseLocation
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
- 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;
}
- 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.
-
Crie um arquivo em componentes chamado
Box.jsx
eimport motion from framer-motion
. -
Podemos então retornar duas divs, com
classNames
deslide-in
eslide-out
uma para deslizar para dentro e outra para deslizar para fora. -
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>
)
}
- De seguida, adicionamos o nosso estilo no nosso ficheiro CSS para
slide-in
eslide-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;
}
- Finalmente, o último passo é usar o
AnimatePresence
do framer-motion no nosso ficheiroApp.js
e envolver toda a App noAnimatePresence
e definir o modo como wait. Se você quiser saber mais sobre umAnimatePresence
, 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
- 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.