使用 Framer motion 在 NextJS 中创建出色的页面过渡效果

2025-06-07

使用 Framer motion 在 NextJS 中创建出色的页面过渡效果

我最近决定用 NextJs 重新设计我的作品集。于是我开始在网上搜索一些很酷的页面过渡效果,希望能用在我的作品集上,然后我偶然发现了这个类似的效果。(类似于Barba.js
替代文本

所以,我决定弄清楚并创建这个过渡效果。在本教程中,我将讲解创建这个漂亮的页面过渡效果的步骤。
让我们开始吧。

注意:本例中,我仅讨论与动画相关的 CSS。如果您也需要完整的 CSS,请参阅本教程末尾提到的 GitHub 代码库。

新项目,哇喔!!

首先,我们需要通过在终端中输入以下命令来创建一个新的 NextJS 项目。

npx create-next-app nextjs-page-transition-example
Enter fullscreen mode Exit fullscreen mode

现在,在您最喜欢的编辑器中打开新创建的项目文件夹。

在终端中输入npm run dev以在端口 3000 上启动开发服务器。

安装 Framer motion

键入npm install framer-motion --save以将框架运动安装到您的项目中。

一些设置

现在我们已经安装了 framer motion,接下来需要进行一些设置。打开pages 目录中的_app.js文件,从 framer-motion 中导入AnimatePresence,并将其包裹在主内容周围,如下所示。

import "../styles/globals.css";
import { AnimatePresence } from "framer-motion";

function MyApp({ Component, pageProps, router }) {
  return (
    <AnimatePresence exitBeforeEnter>
      <Component {...pageProps} key={router.route} />
    </AnimatePresence>
  );
}

export default MyApp;
Enter fullscreen mode Exit fullscreen mode

AnimatePresence 有助于在 React 组件从 React 树中移除时为其添加动画效果。它有助于制作组件的退出动画。AnimatePresenceexitBeforeEnter属性指示 framer-motion 使用动画移除当前组件,然后启动新组件的动画。

创建页面

现在,我们需要创建不同的页面,以便在它们之间实现过渡动画。在本例中,我们将创建三个简单的页面(主页、关于、服务)。

打开pages 目录中的index.js ,并创建一个基本的 React 组件。

function Home() {
  return (
    <main>
      <h1>Home Page</h1>
    </main>
  );
}

export default Home;
Enter fullscreen mode Exit fullscreen mode

现在,我们需要像这样创建另外两个文件about.jsservices.js 。

function Services() {
  return (
    <main>
      <h1>Services Page</h1>
    </main>
  );
}

export default Services;
Enter fullscreen mode Exit fullscreen mode
function Services() {
  return (
    <main>
      <h1>Services Page</h1>
    </main>
  );
}

export default Services;
Enter fullscreen mode Exit fullscreen mode

创建导航栏

现在我们已经创建了三个基本页面,我们需要一个带有链接的导航栏,以便页面之间切换。在根目录中创建一个名为components
的文件夹,并在该文件夹中创建包含以下内容的Navbar.js文件。

import Link from "next/link";

export default function Navbar() {
  return (
    <nav className="navbar">
      <div className="container">
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
        <Link href="/services">Services</Link>
      </div>
    </nav>
  );
}
Enter fullscreen mode Exit fullscreen mode

这是一个基本的导航栏,用于在页面之间导航。Link是一个内置的 NextJS模块,它会在 DOM 中创建一个链接,用于导航到其他页面。

现在,我们需要将导航栏导入到我们创建的页面中!最终的文件应该看起来像这样。

function Home() {
  return (
    <main>
      <h1>Home Page</h1>
    </main>
  );
}
export default Home;
Enter fullscreen mode Exit fullscreen mode
function About() {
  return (
    <main>
      <h1>About Page</h1>
    </main>
  );
}

export default About;

Enter fullscreen mode Exit fullscreen mode
function Services() {
  return (
    <main>
      <h1>Services Page</h1>
    </main>
  );
}

export default Services;
Enter fullscreen mode Exit fullscreen mode

动画页面——有趣的部分

我们先来理解一下动画。这个动画分为两部分:当前页面的滑入动画和下一页的滑出动画。为了更好地理解,请看下图。
第一页的滑入动画 第二页的滑出动画
滑入

滑出

我们需要为每个需要动画的页面添加两个 div(一个用于滑入动画,另一个用于滑出动画)。我们可以为这两个 div 创建一个组件,但将这两个 div 添加到每个页面可能会很麻烦,所以我们将为此创建一个“高阶组件” 。

HOC

创建一个名为 HOC 的文件夹,并在其中创建一个名为withTransition.js的文件。在这个文件中,我们将从 framer motion 导入 motion ,并创建一个函数,该函数将返回一个包含动画 div 的新组件。

import { motion } from "framer-motion";

const withTransition = (OriginalComponent) => {
  return () => (
    <>
      <OriginalComponent />
      <motion.div
        className="slide-in"
        initial={{ scaleX: 0 }}
        animate={{ scaleX: 0 }}
        exit={{ scaleX: 1 }}
        transition={{ duration: 1, ease: "easeInOut" }}
      />
      <motion.div
        className="slide-out"
        initial={{ scaleX: 1 }}
        animate={{ scaleX: 0 }}
        exit={{ scaleX: 0 }}
        transition={{ duration: 1, ease: "easeInOut" }}
      />
    </>
  );
};

export default withTransition;
Enter fullscreen mode Exit fullscreen mode
  .slide-in {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 100%;
    background: #066bb8;
    transform-origin: left;
  }

  .slide-out {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 100%;
    background: #066bb8;
    transform-origin: right;
  }
Enter fullscreen mode Exit fullscreen mode

现在,我们需要在每个需要页面过渡的页面中添加这个 HOC。例如,我想为所有 3 个页面添加动画,那么我需要在每个页面中导入withTransition,并像下面这样传递组件。

import Navbar from "../components/Navbar";
import withTransition from "../HOC/withTransition";

function Home() {
  return (
    <>
      <Navbar />
      <main>
        <h1>Home Page</h1>
      </main>
    </>
  );
}

export default withTransition(Home);
Enter fullscreen mode Exit fullscreen mode
import Navbar from "../components/Navbar";
import withTransition from "../HOC/withTransition";

function About() {
  return (
    <>
      <Navbar />
      <main>
        <h1>About Page</h1>
      </main>
    </>
  );
}

export default withTransition(About);
Enter fullscreen mode Exit fullscreen mode
import Navbar from "../components/Navbar";
import withTransition from "../HOC/withTransition";

function Services() {
  return (
    <>
      <Navbar />
      <main>
        <h1>Services Page</h1>
      </main>
    </>
  );
}

export default withTransition(Services);
Enter fullscreen mode Exit fullscreen mode

就是这样....🎊️

至此,页面过渡效果已完成。演示及 GitHub 链接如下:
演示 - https://nextjs-transition-example.vercel.app/
GitHub 仓库 - https://github.com/shaan71845/nextjs-page-transition-example

请随意留下🌠️
感谢您的阅读!!

文章来源:https://dev.to/shaancodes/create-awesome-page-transitions-in-nextjs-using-framer-motion-2pln
PREV
我创建了一个 VS Code 主题🔥️
NEXT
如何让您的网站离线运行🌐