Las animaciones hacen que los sitios web sencillos se conviertan en experiencias emocionantes e inolvidables. Le dan a su sitio web un poco de personalidad y singularidad y dejan al visitante admirando la estética general.

Es una obviedad que los seres humanos aman las cosas bellas. A todos nos gustan los productos que parecen fáciles en los ojos.

En este artículo, vamos a aprender a crear animaciones que wow usuarios con el uso de Framer movimiento y React-Router-Dom.

Requisitos previos

Para poder seguir lo que estamos haciendo en este artículo, debes tener algún conocimiento de React, Framer motion y React-Router-DOM.

Para aprender mejor Framer motion, puedes estudiar su documentación.

Node.js también debería estar instalado en tu sistema, y deberías tener un editor de código que funcione. Yo voy a utilizar VS Code.

Cómo configurar el proyecto

Para configurar nuestro proyecto vamos a utilizar Vite para configurar nuestro entorno de desarrollo React.

  1. Abre el terminal en VScode. Puedes usar Ctrl + backtick(`)

  2. En su terminal, introduzca el siguiente comando:

npm create vite@latest
  1. Sigue las instrucciones para nombrar tu proyecto y elegir el framework que desees. En nuestro caso, estamos usando React. Este será un proyecto de JavaScript.

  2. Ve a tu directorio de proyecto y use npm i en la terminal.

  3. Para iniciar tu proyecto, use npm run dev.

  4. Recuerda limpiar tu proyecto eliminando el código en App.js y los archivos CSS en la carpeta src.

Cómo Inicializar Framer Motion y React-Router-Dom

  1. Para instalar Framer-motion en tu proyecto, abre la terminal y introduce:
npm i framer-motion
  1. Para instalar React-Router-DOM en tu proyecto, abre la terminal y introduce:
npm i react-router-dom

Cómo Configurar Componentes y Ruteo Básico con React-Router-Dom

Vamos a configurar nuestros componentes y las páginas a las que se dirigirá este proyecto.

  1. En src, crea una nueva carpeta llamada components.

  2. Agregaremos cuatro archivos en esta carpeta con los nombres Home.jsx, About.jsx, Projects.jsx y Navbar.jsx.

  3. Dentro de los primeros tres, vamos a crear un componente funcional de React. Cambiemos el contenido de la etiqueta h1 en cada componente:

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

 export default Home
  1. En el Navbar, necesitamos importar Link de React-Router-DOM para crear elementos de enlace. A continuación, necesitamos crear un contenedor que contenga nuestro logotipo y los enlaces de navegación. El logotipo enlazará los puntos hacia nuestra página de índice.
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. Ahora vayamos a nuestro archivo index.js o main.js. El objetivo es wrapar nuestra aplicación completa con BrowserRouter que permitirá la navegación dentro de nuestra aplicación.
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. Ahora en App.js, vamos a completar el último paso de nuestra configuración. Importaremos nuestros componentes y algunas características de React-Router-DOM y renderizaremos nuestros componentes. Mediante el uso de la característica useLocation de React-Router-DOM, podemos establecer la ubicación actual de las rutas estableciendo la clave en la ruta actual.
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. Ahora podemos agregar nuestro estilo en 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. Después de seguir todos los pasos, tu aplicación debería verse como este:

página estilizada sin animación

Cómo Crear Transiciones Usando Framer Motion

Finalmente, vamos a crear nuestra animación para las transiciones entre páginas.

  1. Cree un archivo en los componentes llamado Box.jsx y import motion from framer-motion.

  2. Entonces podemos devolver dos divs, con las classNames de slide-in y slide-out, uno para deslizar dentro y otro para deslizar fuera.

  3. Insertamos nuestra animación en estos divs con la ayuda de 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. A continuación, agregamos nuestro estilo en nuestro archivo CSS para slide-in y slide-out en nuestro 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, el último paso es utilizar AnimatePresence de framer-motion en nuestro archivo App.js y enrollar toda la App en AnimatePresence y establecer el modo como wait. Si quieres aprender más sobre un AnimatePresence visita las documentaciones de 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, nuestro trabajo debería verse igual que en el video de abajo:

Conclusión

La creación de animaciones de multiples páginas con Framer Motion y React-Router-Dom mejora la experiencia del usuario proporcionando transiciones suaves.

Esta integración aprovecha las capacidades de animación de Framer Motion junto con las características de navegación de React-Router-Dom, generando aplicaciones web dinámicas e interactivas.