F

Framer Motion - 为 React 打造精美的动画和交互。🤤 什么是 Framer Motion?🤔 我们将要做什么?😏

2025-05-28

Framer Motion - 为 React 提供精美的动画和交互。🤤

Framer Motion 是什么?🤔

我们会做什么?😏

之前,我介绍了 React Spring,一个基于弹簧物理的动画库。我们制作了一些简单的切换动画,以及一个略微复杂的悬停动画/过渡。

嗯,一切都很棒,很酷,直到我想到 Framer Motion!这是一个非常棒的库,它能让你的原型栩栩如生,而且比 React Spring 的易用性高出一倍。

让我们看看它提供的功能以及为什么你应该在下一个 React 项目中使用它。


Framer Motion 是什么?🤔

Framer Motion是一个适用于 React 的生产级动效库。它充分利用了Framer原型设计工具的强大功能,并且完全开源

有一些开箱即用的功能或卖点:

  1. 动画(CodeSandbox 演示
  2. 变体。 (CodeSandbox 演示
  3. 手势。 (CodeSandbox 演示
  4. 拖动。(CodeSandbox 演示
  5. 滚动。(CodeSandbox 演示
  6. 路径。(CodeSandbox 演示

我最喜欢的是变体,点击下面进行互动:

还,

  1. 它使用服务器端渲染。
  2. 它支持 CSS 变量。
  3. 您可以轻松卸载动画。
  4. 它具有出色的可访问性选项。
  5. 您可以将设计从 Framer 转移到 Framer Motion。

在执行任何操作之前,我们需要了解一些基础知识,很可能是它的 API。

运动 API

这就是 Framer Motion 的核心所在。它为我们提供了各种各样的选项,包括你在上文中看到的那些。

motion组件。

它是库中内置的 React 组件,几乎适用于您在 UI 中使用的所有 HTML 或 SVG 元素。这些 DOM 元素已针对 60fps 动画和手势支持进行了优化。

好处是,我们可以轻松地将静态 HTML/SVG 元素转换为动态组件。例如,如果我们有一个常用的div,那么只需motion.在该 HTML 标签前面添加 ,就得到了一个motion组件!这样<div>就变成了<motion.div>

它允许您:

  • 以声明方式或命令方式为组件设置动画。
  • 通过变体在整个 React 树中进行动画处理
  • 用动画响应手势。
  • 添加拖动、平移、悬停和点击手势。

以下是一个例子:

<motion.div
    animate={{ rotate: 360 }}
    transition={{ duration: 2 }}
 />
Enter fullscreen mode Exit fullscreen mode

animation道具。

正如你在上面的代码片段中看到的,motion组件通过 prop 进行动画处理animate。当 animate 中的任何值发生变化时,组件将自动动画到更新的目标。

如果使用xscale值,则它们将通过弹簧模拟进行动画。而像opacity或 这样的值color将使用补间动画。

您可以通过传递transition道具来设置不同类型的动画。

以下是一个例子:

<motion.div
  animate={{ x: 100 }}
  transition={{ ease: "easeOut", duration: 2 }}
/>
Enter fullscreen mode Exit fullscreen mode

手势

所有motion组件都可以检测悬停点击平移拖动手势。每个组件都有可以附加的事件监听器。

motion该组件提供的两个常用手势道具是whileHoverwhileTap

以下是一个例子:

motion.button
  whileHover={{
    scale: 1.2,
    transition: { duration: 1 },
  }}
  whileTap={{ scale: 0.9 }}
/>
Enter fullscreen mode Exit fullscreen mode

运动值

用于跟踪动画值的状态速度。这些是自动创建的。但对于高级用例,可以手动创建。

它允许您:

  • 设置和获取状态。
  • 通过钩子链接 MotionValues useTransform
  • 传递给多个组件以同步它们之间的运动。

以下是一个例子:

export function MyComponent() {
  const x = useMotionValue(0)
  return <motion.div style={{ x }} />
}
Enter fullscreen mode Exit fullscreen mode

我们会做什么?😏

教程演示

是的!我们采用了创建 React 应用时提供的样板界面,并添加了一些有趣的交互元素。如您所见,以下是一些正在发生的事情:

  1. 首先,当页面加载时,它会淡入。这是唯一发生的动画。
  2. 接下来是交互。点击 React 徽标时,我们可以看到它像一个按钮一样。鼠标按下时,它会弹回;鼠标释放时,它会恢复正常状态。
  3. 我们还可以单击并水平拖动 React 徽标,它会随着远离中心而不断消失。
  4. 当鼠标悬停在徽标下方时,其文字会放大
  5. 为了水平移动文本的位置,我们有一个滑块可以控制它。
  6. 最后,我们可以使用切换按钮淡入或淡出相同的文本。

内容太多了,赶紧进入开发环节吧!

步骤 1:创建 React 项目并添加 Framer Motion

创建完React 应用程序后,只需使用以下命令安装 Framer Motion 依赖项:

npm i framer-motion
Enter fullscreen mode Exit fullscreen mode

第 2 步:导入库并转换元素!

对于这个演示,我们需要import这三个 API 函数motion,,useMotionValueuseTransform

import { motion, useMotionValue, useTransform } from 'framer-motion';
Enter fullscreen mode Exit fullscreen mode

我们已经讨论过前两个。现在,useTransform我们可以通过一个钩子将最新的 MotionValue 传递给一个更新函数,该函数获取最新的父值并对其进行转换。

导入后,我们需要将 React 样板文件自带的一些默认 HTML 标签更改为新的 Framer Motion 标签。在​​ App.js中执行以下更改:

  • <div>元素为<motion.div>
  • 将 React 徽标<img>标签包装在新创建的<motion.div>.
  • 标签<p><motion.p>
  • 添加一个新<input>元素,它将成为我们的范围滑块,其minmax值分别为-100100
  • 接下来创建一个新的<motion.button>文本为“Toggle Fade”。

以下是我们目前所做的工作:

<motion.div className='App'>

      <header className='App-header'>

        <motion.div>
          <img src={logo} className='App-logo' alt='logo' />
        </motion.div>

        <motion.p>
          Edit <code>src/App.js</code> and save to reload.
        </motion.p>

        <input
          type='range'
          name='range'
          min='-100'
          max='100'
        />

        <motion.button className='toggle-button'>
          Toggle Fade
        </motion.button>

      </header>

</motion.div>
Enter fullscreen mode Exit fullscreen mode

由于我们尚未编写任何道具,并且运动代码没有可用的属性,因此什么也不会发生。

步骤 3:添加动画和过渡!

页面淡入淡出动画:

对于初始淡入淡出动画,我们使用新的initialanimate和属性transitionmotion.div

  • 为初始化initial一个值animate
  • 具有animate动画的实际值
  • 用于transition添加从一帧变化到另一帧的默认过渡。

由于我们需要一个简单的淡入淡出动画,其中动画发生半秒,我们赋予以下属性motion.div

initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
Enter fullscreen mode Exit fullscreen mode

现在整个页面都消失了!

页面淡入淡出动画

React Logo 上的点击和拖动交互:

这是通过组件上的whileTap辅助drag动画道具实现的motion

  • whileTap当元素被按下/单击时,动画会出现
  • 启用drag元素的拖动手势,false默认设置为。

因此,点击徽标时,我们首先需要它稍微缩放一下,因此我们将scale属性添加到whileTapprop 中。对于拖动,我们需要传递要在哪个轴上进行拖动。在这里,我们水平拖动,所以是x轴。

x为了获得我们传入prop的 的实际值drag,我们将使用一个useMotionValue钩子来跟踪被拖动元素的状态和速度。最初,我们不希望启用拖动功能,因此我们传入了0

至于定义拖拽坐标,钩子会帮我们实现useTransform。通过钩子,我们可以传入x轴的最新值。这个值可以是任意数字,具体取决于你想要实现的拖拽的开销。

const x = useMotionValue(0);
const opacity = useTransform(x, [-200, 0, 200], [0, 1, 0]);
Enter fullscreen mode Exit fullscreen mode

现在,为了使这两个功能正常工作,我们需要传递styleprop,该 prop 接收我们上面提供的不同常量。因此,我们的图像拖动和点击交互代码如下所示:

const x = useMotionValue(0);
const opacity = useTransform(x, [-200, 0, 200], [0, 1, 0]);

.
.
.
<motion.div whileTap={{ scale: 0.9 }} drag='x' style={{ x, opacity }}>
    <img src={logo} className='App-logo' alt='logo' />
</motion.div>
.
.
.
Enter fullscreen mode Exit fullscreen mode

现在这个交互有效了!

React 徽标交互

文本互动:

我们在悬停和点击时有一个刻度,在移动滑块时有一个拖动,最后使用按钮完成淡入淡出切换。

缩放的操作与点击完全相同,只是这里的交互既包括点击也包括悬停,因此对于新的悬停交互,我们使用whileHover道具。

x变量用于水平拖动,因为我们需要相同的值。现在,为了约束它的值,我们可以使用dragConstraintsprop 对其进行微调,该 prop 允许我们传递拖动手势的left和约束。right

对于最终的交互,我们需要使用useStateReact Hook 来改变文本的拖动和淡入淡出状态。因此,我们为状态定义了以下两个变量:

const [value, setValue] = useState(0);
const [toggle, setToggle] = useState(1);
Enter fullscreen mode Exit fullscreen mode

<input />在我们一开始创建的元素上,它的onChange事件使用了HooksetValue()中的方法useState,我们传入用户拖动滑块时选择的当前值。 的 上也会触发类似的事件,<motion.button>onClick这里我们通过0交换1和 的状态来切换。

为了实现实际的淡入淡出,我们只需value从创建状态中获取(添加'px'字符串,使其作为实际的像素单位工作)并使用opacity等于toggle我们创建的值。

const [value, setValue] = useState(0);
const [toggle, setToggle] = useState(1);
.
.
.
<motion.p animate={{ x: value + 'px', opacity: toggle }}
          drag='x'
          dragConstraints={{ left: -100, right: 100 }}
          whileHover={{ scale: 1.1 }}
          whileTap={{ scale: 0.9 }}>
          Edit <code>src/App.js</code> and save to reload
</motion.p>

<input type='range' name='range' min='-100' max='100'
       value={value}
       onChange={(e) => setValue(e.target.value)} />

<motion.button onClick={() => setToggle((prevValue) 
                           => (prevValue ? 0 : 1))} 
               className='toggle-button'>Toggle Fade
</motion.button>
.
.
.
Enter fullscreen mode Exit fullscreen mode

按钮样式在 CSS 中很简单,比默认样式看起来更好:

.toggle-button {
  margin-top: 1.5em;
  width: 10em;
  border: 0;
  outline: none;
  padding: 1em;
  border-radius: 10em;
  font-weight: bold;
}

.toggle-button:hover {
  color: #282c34;
  background-color: #61dafb;
}
Enter fullscreen mode Exit fullscreen mode

现在我们的最终交互也有效了!

文本交互


如果你对这个库不感冒,可以看看 React Spring。我写了一篇相关的教程:


谢谢阅读,我非常感激!祝你拥有美好的一天。(✿◕‿◕✿)


如果你想给开发者留下深刻印象,可以尝试新的开源 Windows 终端。😎 在此处下载:https://t.co/bZQ78xBBr7

图片来源:https://t.co/GsUA5a7mlf #DevHumour pic.twitter.com/WQfKOWTjfa

— 英国微软开发者 (@msdevUK) 2020 年 10 月 15 日

📫 订阅我的每周开发者新闻通讯 📫

附言:从今年开始,我决定在 DEV Community 上写作。之前,我在 Medium 上写作。如果有人想看看我的文章,可以看看我的 Medium 个人资料。
文章来源:https://dev.to/vaibhavkhulbe/framer-motion-beautiful-animations-and-interactions-for-react-1d56
PREV
是时候提升你的 HTML 技能了!🔋
NEXT
赶紧收藏这些网站,为你的下一个 UI 项目做准备吧!🎨