动画正是让平凡的网站变得激动人心和难以忘怀的原因。它们为您的网站增添了一些个性和独特性,并使访客欣赏整体美学。

人们喜欢美丽的事物是毫无疑问的。我们都喜欢看起来悦目的产品。

在本文中,我们将学习如何使用Framer动效和React-Router-Dom创建令人惊叹的动画。

前提条件

为了能够理解本文中我们所做的工作,您应该对ReactFramer motionReact-Router-DOM有一些了解。

为了更好地学习Framer motion,您可以研究他们的文档。

Node.js也应该安装在您的系统上,并且您应该有一个可用的代码编辑器。我将使用VS Code

如何设置项目

为了设置我们的项目,我们将使用Vite来搭建React开发环境。

  1. 在VScode中打开终端。您可以使用Ctrl + backtick(`)

  2. 在您的终端中,输入以下命令:

npm create vite@latest
  1. 按照提示命名您的项目并选择您需要的框架。在我们的案例中,我们将使用React。这将是一个JavaScript项目。

  2. 转到您的项目目录并在终端中使用npm i

  3. 要启动您的项目,请使用npm run dev

  4. 记得通过删除App.js中的代码以及src文件夹中的CSS文件来清理您的项目。

如何初始化Framer Motion和React-Router-Dom

  1. 要在您的项目中安装Framer Motion,请在终端中输入:
npm i framer-motion
  1. 要在您的项目中安装React-Router-DOM,请在终端中输入:
npm i react-router-dom

如何使用React-Router-DOM设置组件和基本路由

让我们为这个项目设置我们的组件和将要路由到的页面。

  1. src中,创建一个名为components的新文件夹。

  2. 我们将在该文件夹中添加四个文件,分别命名为Home.jsxAbout.jsxProjects.jsxNavbar.jsx

  3. 在前面三个文件中,我们将创建一个React函数式组件。更改每个组件中h1标签的内容:

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

 export default Home
  1. 在Navbar组件中,我们需要从React-Router-DOM中导入Link以创建锚点元素。然后我们需要创建一个容器,包含我们的徽标和导航链接。徽标将链接到我们的索引页面。
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. 现在让我们转到我们的index.jsmain.js文件。我们的目标是用BrowserRouter包裹整个应用程序,这将使我们的应用程序内能够实现路由。
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. 现在在App.js中,我们将完成配置的最后一步。我们将导入我们的组件,以及React-Router-DOM中的一些特性,并渲染我们的组件。通过使用React-Router-DOM中的useLocation特性,我们可以通过设置键为当前路径来设置路由的当前位置。
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. 现在我们可以在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. 按照所有步骤操作后,你的应用程序应该看起来像这样:

无动画的样式网页

如何使用Framer Motion创建过渡效果

最后让我们为页面之间的过渡创建我们的动画。

  1. 在组件中创建一个名为Box.jsx的文件,并import motion from framer-motion

  2. 然后我们可以返回两个div,一个用于滑入,一个用于滑出,它们的classNames分别为slide-inslide-out

  3. 我们通过使用framer-motion在这些div中插入我们的动画:

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. 接下来,我们在我们的CSS文件中为slide-inslide-out添加样式。
.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. 最后一步是在我们的App.js文件中使用framer-motion的AnimatePresence,并将整个App包裹在AnimatePresence中,并将模式设置为等待。如果您想了解更多关于AnimatePresence的信息,请访问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. 最后,我们的工作应该与下面的视频一样:

结论

使用Framer Motion和React-Router-Dom创建多页面动画可以提升用户体验,提供流畅的过渡效果。

这种整合利用了Framer Motion的动画功能与React-Router-Dom的路由特性,实现了动态、互动的Web应用程序。