发布于 2026-01-06 0 阅读
0

使用 Framer Motion 在 React 中实现动画

使用 Framer Motion 在 React 中实现动画

介绍

既然有了 Framer Motion 这样的工具,为什么还要编写大量的 CSS 代码来创建动画呢?带有动画效果的 Web 应用程序看起来更加生动美观。

许多开发者避免在 Web 应用中添加动画,因为动画代码编写起来可能非常繁琐。然而,有了 Framer Motion,只需几行代码即可实现动画效果。这个 React.js 外部库让动画变得极其简单,使开发者能够专注于项目的其他方面。

在本文中,我们将通过使用 Framer Motion 来制作文本和图像动画,从而了解其功能、安装过程和易用性。

我们将介绍以下步骤:

先决条件

要学习本教程,您需要:

  • 对前端基本技术有清晰的理解,例如 HTML、CSS 和 JavaScript。
  • 熟悉 React.js
  • Node.js已安装。

Framer Motion是什么?

Framer Motion 是Framer 公司出品的一款功能强大的生产级动画库,它可以在 DOM 元素中创建不同的动画样式。Framer Motion 是创建复杂 CSS 动画的绝佳替代方案。要使用 Framer Motion,您需要安装该库并将其集成到您的 React 项目中。

React 中的 Framer Motion 入门

React 要求我们先使用 npm 包安装所有外部库。请使用以下命令安装 Framer motion。

npm install framer-motion
Enter fullscreen mode Exit fullscreen mode

下一步是将你想要使用的 Framer Motion 组件导入到你的 React 应用中。

注意:
本文将分为两部分,第一部分是文本动画,第二部分是图像动画。最后,我们将把两者合并到一个 React 应用中。

文本动画入门

在本节中,我们将演示如何在使用组件为文本添加动画时使用 Framer Motion motion

将以下代码添加到您的App.js文件中。

import { motion } from "framer-motion";

function App() {
    return (
        <div className="App">
            <motion.h1
                animate={{ x: [50, 150, 50], opacity: 1, scale: 1 }}
                transition={{
                    duration: 5,
                    delay: 0.3,
                    ease: [0.5, 0.71, 1, 1.5],
                }}
                initial={{ opacity: 0, scale: 0.5 }}
                whileHover={{ scale: 1.2 }}
            >
                Animation made easy with Framer Motion
            </motion.h1>
        </div>
    );
}
export default App;
Enter fullscreen mode Exit fullscreen mode

我们导入了Framer Motion的motion组件。仔细观察这个h1元素,你会发现它与标准h1元素的不同之处。

使用 Framer Motion 进行动画制作的第一步是使用motion组件,该组件可以与任何标准 HTML 元素一起使用。

motion我们将利用组件h1和 Framer Motion属性,为文本添加一个炫酷的进入动画,使其在页面重新加载时逐渐显示animate

通过这种方法,我们可以根据需要为文本添加动画效果。首先,我们为文本指定一个位置,指示动画发生的位置。然后,我们将文本沿 x 轴进行动画处理。您可以设置 x 轴x的值[0, 150, 50]

接下来,我们给它赋值opacity为 1。

我们需要给炫酷的进入动画设定一个缩放比例。我们不希望它太大。我们可以把缩放比例设为 1。这样,当文本动画达到 1 的缩放比例时,它的尺寸就不会再增加了。

最后,我们使用 Framer Motiontransition属性,因为任何有效的动画都需要过渡效果。我们将在这个属性中指定文本动画的持续时间duration、延迟delay和缓ease动效果。设置持续时间为 5,延迟为 3,缓动效果为[0.5, 0.71, 1, 1.01]

缓动效果显示了文本动画进入初始状态后,再恢复到原始状态时的尺寸。

缩放 gif

但是,我们并不想止步于炫酷的文字动画开头。让我们为文字添加一个漂亮的悬停效果。当鼠标悬停在文字上时,文字看起来会弹跳或放大。

为了实现这一点,我们将使用该whileHover属性并将其缩放至 1.2。

function App() {
    return (
        <div className="App">
            <motion.h1
              ...
                // ====>
                whileHover={{ scale: 1.2 }}
                // <====
            >
                Animation made easy with Framer Motion
            </motion.h1>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

比例尺文本


GitHub 支持横幅

图像动画入门

在本节中,我们将演示如何在图像动画中使用 Framer Motion。

首先,需要在“src”文件夹内创建一个名为“image”的文件夹来存放图片。为了演示,我使用了随机图片。您可以随意使用任何您喜欢的图片。

在“src”文件夹内创建一个名为“image.js”的文件,并将以下代码添加到该文件中:

import fox from "./images/pexels-fox-1071249.jpg";
import jill from "./images/jill.jpg";
import cha1 from "./images/cha1.jpg";
import cha2 from "./images/cha2.jpg";

export default[fox, jill, cha1,cha2]
Enter fullscreen mode Exit fullscreen mode

在将图片用于我们的文件之前,我们将先把所有图片导入到image.js上面提到的文件中App.js。这样可以避免在需要使用这些图片的地方重复导入。

将以下代码添加到您的App.css文件中。

.item{
  min-height: 10rem;
  min-width: 30rem;
  padding: 5px;
}

.item img{
  width: 60%;
  height: 50%;
  border-radius: 1rem;
  pointer-events: none;
  padding: 15%;
}

.inner-carousel {
  display: flex;
  background: rgb(76, 76, 76);
  height: 23rem;
}

.carousel{
  cursor: grab;
  overflow: hidden;
  background: rgb(215, 216, 215);
  height: 23rem;
}
Enter fullscreen mode Exit fullscreen mode

修改App.js文件,添加以下代码:

import { motion } from "framer-motion";
import "./App.css";
import images from "./image";

function App() {
    return (
        <div className="App">
            <motion.div className="carousel">
                <motion.div
                    animate={{
                        scale: [1, 1, 1, 1, 1],
                        rotate: [0, 30, 60, 240, 360],
                    }}
                >
                    {images.map((image) => {
                        return (
                            <motion.div
                                whileHover={{ scale: 1.2 }}
                                whileTap={{ scale: 2 }}
                                className="item"
                                transition={{ duration: 3 }}
                                key={image}
                            >
                                <img src={image} alt="image" />
                            </motion.div>
                        );
                    })}
                </motion.div>
            </motion.div>
        </div>
    );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

图片动画将以轮播图的形式呈现,每次页面刷新时都会有旋转效果,每次鼠标靠近时都会有悬停效果,每次触摸图片时都会有点击效果。

对于轮播图,创建三个容器:一个用于外层轮播图,一个用于内层轮播图,一个用于图片。这三个容器都应该使用 Framer Motionmotion组件创建,并且一个嵌套在另一个容器中。

animate内部旋转动画将实现旋转和滑动效果。此时将调用框架运动道具,将其缩放至指定值[1,1,1,1,1],并旋转至指定角度[0,30, 60, 240, 360]

这将赋予它独特的旋转效果,如下所示:

拖

我们将使用dragConstraint道具和帧运动drag来营造类似旋转木马的效果。“X”将作为参数传递给道具,drag因为我们需要旋转木马沿x轴移动。

要固定住挡块,请使用dragConstraint支撑杆。为了让旋转木马向左移动,然后再返回到原来的位置,我们设置了挡块dragConstraint:{ right: 0, left: -1100 }

drag prop如果只用拖拽动作,效果似乎太单调了dragConstraint;不如我们在拖拽动作的两端各添加一个类似弹跳的效果。这可以通过drag transitionFramer Motion 的道具来实现。

我们将使用“bounceStiffner”和“bounceDamping”这两个drag transition属性,bounceStiffnerbounceDamping分别赋予它们600和8的值。最后,我们将浏览此容器中导入的图片,并将每张图片添加回轮播图中。

将高亮显示的代码添加到App.js

function App() {
    return (
        <div className="App">
            <motion.div className="carousel">
                <motion.div
                   ...
                   // highlight-start
                    drag="x" 
                    dragConstraints={{right: 0, left:-1100}} 
                    dragTransition={{ bounceStiffness: 600, bounceDamping: 8 }} 
                    // highlight-end
                >
                    ...
                </motion.div>
            </motion.div>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

悬停时

轮播图的最后一个div区域将用于显示返回的图片。为了在其中创建合适的动画,div,我们将使用帧动画whileHoverwhileTap过渡动画和转场属性。

使用缩放比例为 1.2 的帧动画whileHover,可以为图像添加漂亮的悬停效果。当鼠标悬停在图像上时,图像只会放大到此最大值。

然后,将whileTap道具的缩放比例设为 2,我们就可以为图片添加点击效果,使其在点击时产生弹跳感。我们需要定义一个过渡持续时间,使悬停和点击操作更具吸引力。我们选择 3 秒作为持续时间。

function App() {
    return (
        <div className="App">
            <motion.div className="carousel">
                <motion.div>
                    {images.map((image) => {
                        return (
                            <motion.div
                                ...
                            // ====>
                                whileHover={{ scale: 1.2 }}
                                whileTap={{ scale: 2 }}
                            // <==== 
                            >
                                <img src={image} alt="image" />
                            </motion.div>
                        );
                    })}
                </motion.div>
            </motion.div>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

最后一个gif

与普通的 CSS 不同,我们可以看到,使用 Framer Motion 可以快速创建上述动画,而且只需要几行代码。有些程序员喜欢用纯 CSS 编写动画,但如果你像我一样更喜欢简单的解决方案,那么你可以使用 Framer Motion 来实现你的动画。

您可以在这里访问该应用程序。

结论

本文介绍了如何使用 Framer Motion 为 React 应用创建简单的文本和图像动画。与传统的 CSS 相比,我们看到只需几行代码即可轻松实现这些动画。我们也了解了如何使用 Framer Motion 的一些组件和属性。Framer Motion还有其他一些强大的功能,本文并未涵盖,建议您进一步了解。希望本文对您有所帮助。

*作者:乔尔·埃兹莫拉 *


Discord 横幅


构建基于 React 的 CRUD 应用程序,不受任何限制

现代 CRUD 应用程序需要从许多不同的来源获取数据,从自定义 API 到 Supabase、Hasura、Airtable 和 Strapi 等后端服务。

如果您对后端无关、无头框架感兴趣,并且希望借助内置提供程序和社区插件连接 15 个以上的数据源,那么可以了解一下refine 。


优化博客徽标

refine是一个基于 React 的开源框架,用于构建不受限制的 CRUD 应用程序。
它可以将开发速度提升高达3 倍,同时又不影响样式自定义项目工作流程的自由度。

refine从设计上就是无头的,它开箱即用地连接了30 多个后端服务,包括自定义 REST 和 GraphQL API。

访问refine GitHub 存储库以获取更多信息、演示、教程和示例项目。

文章来源:https://dev.to/refine/animations-in-react-with-framer-motion-57gl