如何用FramerMotion让React页面实现长尾词动画效果?

2026-04-02 08:461阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1758个文字,预计阅读时间需要8分钟。

如何用FramerMotion让React页面实现长尾词动画效果?

目录+前言+效果体验+快速开始+安装+输入+使用方式+示例+节点的挂载与卸载(mount、unmount)+列表+更多API+美中不足+前言+信心+许多前端同学或多或少的和动画打过交道。有的时侯是产品想想要一个动画效果,但不知道怎么做。

目录
  • 前言
  • 效果体验
  • 快速开始
    • 安装
    • 输入
  • 使用方式
    • 示例
      • 节点的挂载与卸载(mount、unmount)
      • 列表
    • 更多API
      • 美中不足

    前言

    相信很多前端同学都或多或少和动画打过交道。有的时候是产品想要的过度效果;有的时候是UI想要的酷炫动画。但是有没有人考虑过,是不是我们的页面上面的每一次变化,都可以像是自然而然的变化;是不是每一次用户点击所产生的交互,都可以在页面上活过来呢?

    欢迎你打开了新的前端动画世界——《Framer Motion》

    效果体验

    这里,我在framer官网上面给大家录制了一下大概的使用效果。

    在我们的常规认知中,实现这样的效果其实需要很多的css来实现,或者说需要我们进行大量的定制化逻辑编写。但是如果我们使用framer motion的话,只需要如下代码:

    import { AnimatePresence, motion } from 'framer-motion'; const [selectedId, setSelectedId] = useState(null); {items.map(item => ( <motion.div layoutId={item.id} onClick={() => setSelectedId(item.id)}> <motion.h5>{item.subtitle}</motion.h5> <motion.h2>{item.title}</motion.h2> </motion.div> ))} <AnimatePresence> {selectedId && ( <motion.div layoutId={selectedId}> <motion.h5>{item.subtitle}</motion.h5> <motion.h2>{item.title}</motion.h2> <motion.button onClick={() => setSelectedId(null)} /> </motion.div> )} </AnimatePresence>

    从上面的实现我们可以看出,framer-motion可以说是我们在用react动效开发过程中的必备利器。那么接下来,我给大家简单介绍一些framer motion的基础用法。

    快速开始

    Framer Motion 需要 React 18 或更高版本。

    安装

    从npm安装framer-motion

    npm install framer-motion

    输入

    安装后,您可以通过framer-motion引入Framer Motion

    import { motion } from "framer-motion" export const MyComponent = ({ isVisible }) => ( <motion.div animate={{ opacity: isVisible ? 1 : 0 }} /> )

    使用方式

    Framer motion的核心API是motion的组件。每个HTMLSVG标签都有对应的motion组件。

    他们渲染的结果与对应的原生组件完全一致,并在其之上增加了一些动画和手势相关的props

    比如:

    <motion.div /> <motion.span /> <motion.h1 /> <motion.svg /> ...

    示例

    比如我们现在想要实现一个侧边栏效果。

    节点的挂载与卸载(mount、unmount)

    如果我们自己来实现的话,可能要考虑它的keyframe,它的初始状态与最终的css样式。那么如果用framer-motion来如何实现呢?

    首先我们来设计一个会动的按钮Icon:

    import * as React from "react"; import { motion } from "framer-motion"; const Path = props => ( <motion.path fill="transparent" strokeWidth="3" stroke="hsl(0, 0%, 18%)" strokeLinecap="round" {...props} /> ); const MenuToggle = ({ toggle }) => ( <button onClick={toggle}> <svg width="23" height="23" viewBox="0 0 23 23"> <Path variants={{ closed: { d: "M 2 2.5 L 20 2.5" }, open: { d: "M 3 16.5 L 17 2.5" } }} /> <Path d="M 2 9.423 L 20 9.423" variants={{ closed: { opacity: 1 }, open: { opacity: 0 } }} transition={{ duration: 0.1 }} /> <Path variants={{ closed: { d: "M 2 16.346 L 20 16.346" }, open: { d: "M 3 2.5 L 17 16.346" } }} /> </svg> </button> );

    接下来,就由这个按钮来控制侧边栏的展示(mount)与隐藏(unmount):

    import * as React from "react"; import { useRef } from "react"; import { motion, useCycle } from "framer-motion"; import { useDimensions } from "./use-dimensions"; const sidebar = { open: (height = 1000) => ({ clipPath: `circle(${height * 2 + 200}px at 40px 40px)`, transition: { type: "spring", stiffness: 20, restDelta: 2 } }), closed: { clipPath: "circle(30px at 40px 40px)", transition: { delay: 0.5, type: "spring", stiffness: 400, damping: 40 } } }; export const Example = () => { const [isOpen, toggleOpen] = useCycle(false, true); const containerRef = useRef(null); const { height } = useDimensions(containerRef); return ( <motion.nav initial={false} animate={isOpen ? "open" : "closed"} custom={height} ref={containerRef} > <motion.div className="background" variants={sidebar} /> <MenuToggle toggle={() => toggleOpen()} /> </motion.nav> ); };

    也就是说,其实我们更多需要做的事情,从思考如何设计各元素之间的css联动与keyframe书写变成了如何按照文档写好framer-motion的配置。哪个更轻松相信大家一目了然。

    列表

    侧边栏一般都是带有菜单的,那么我们是不是可以让这个侧边栏也有一个逐次出现的效果呢?就像这样:

    这里我们是不是已经开始肌肉记忆般的计算延迟时间,思考如何进行整体效果的分配。那么如果这里我们使用frame motion,它的实现方式应该是怎么样的呢?

    首先我们先来进行单个Item的封装:

    import * as React from "react"; import { motion } from "framer-motion"; const variants = { open: { y: 0, opacity: 1, transition: { y: { stiffness: 1000, velocity: -100 } } }, closed: { y: 50, opacity: 0, transition: { y: { stiffness: 1000 } } } }; const colors = ["#FF008C", "#D309E1", "#9C1AFF", "#7700FF", "#4400FF"]; export const MenuItem = ({ i }) => { const style = { border: `2px solid ${colors[i]}` }; return ( <motion.li variants={variants} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.95 }} > <div className="icon-placeholder" style={style} /> <div className="text-placeholder" style={style} /> </motion.li> ); };

    然后我们在已封装Item的基础上,再进行整个菜单的封装:

    import * as React from "react"; import { motion } from "framer-motion"; const itemIds = [0, 1, 2, 3, 4]; const variants = { open: { transition: { staggerChildren: 0.07, delayChildren: 0.2 } }, closed: { transition: { staggerChildren: 0.05, staggerDirection: -1 } } }; export const Navigation = () => ( <motion.ul variants={variants}> {itemIds.map(i => ( <MenuItem i={i} key={i} /> ))} </motion.ul> );

    没错,动画!就是这么简单!

    更多API

    更详细、更具体的功能大家可以参考下官方的使用文档,我就不在这里一一列举了。

    如何用FramerMotion让React页面实现长尾词动画效果?

    美中不足

    其实不难看出,不论是实现的效果,还是使用方式,对于前端的同学来说framer-motion都是非常友好的工具。这一点从npm的Weekly Downloads以及github的star上面都不难看出。

    但是目前也有一个问题,那就是包的体积问题。

    这个包的大小对于部分的系统来说,还是不够友好。这也是很多人不选择使用它的原因。

    以上就是React动画实现方案Framer Motion让页面自己动起来的详细内容,更多关于React 动画 Framer Motion的资料请关注自由互联其它相关文章!

    本文共计1758个文字,预计阅读时间需要8分钟。

    如何用FramerMotion让React页面实现长尾词动画效果?

    目录+前言+效果体验+快速开始+安装+输入+使用方式+示例+节点的挂载与卸载(mount、unmount)+列表+更多API+美中不足+前言+信心+许多前端同学或多或少的和动画打过交道。有的时侯是产品想想要一个动画效果,但不知道怎么做。

    目录
    • 前言
    • 效果体验
    • 快速开始
      • 安装
      • 输入
    • 使用方式
      • 示例
        • 节点的挂载与卸载(mount、unmount)
        • 列表
      • 更多API
        • 美中不足

      前言

      相信很多前端同学都或多或少和动画打过交道。有的时候是产品想要的过度效果;有的时候是UI想要的酷炫动画。但是有没有人考虑过,是不是我们的页面上面的每一次变化,都可以像是自然而然的变化;是不是每一次用户点击所产生的交互,都可以在页面上活过来呢?

      欢迎你打开了新的前端动画世界——《Framer Motion》

      效果体验

      这里,我在framer官网上面给大家录制了一下大概的使用效果。

      在我们的常规认知中,实现这样的效果其实需要很多的css来实现,或者说需要我们进行大量的定制化逻辑编写。但是如果我们使用framer motion的话,只需要如下代码:

      import { AnimatePresence, motion } from 'framer-motion'; const [selectedId, setSelectedId] = useState(null); {items.map(item => ( <motion.div layoutId={item.id} onClick={() => setSelectedId(item.id)}> <motion.h5>{item.subtitle}</motion.h5> <motion.h2>{item.title}</motion.h2> </motion.div> ))} <AnimatePresence> {selectedId && ( <motion.div layoutId={selectedId}> <motion.h5>{item.subtitle}</motion.h5> <motion.h2>{item.title}</motion.h2> <motion.button onClick={() => setSelectedId(null)} /> </motion.div> )} </AnimatePresence>

      从上面的实现我们可以看出,framer-motion可以说是我们在用react动效开发过程中的必备利器。那么接下来,我给大家简单介绍一些framer motion的基础用法。

      快速开始

      Framer Motion 需要 React 18 或更高版本。

      安装

      从npm安装framer-motion

      npm install framer-motion

      输入

      安装后,您可以通过framer-motion引入Framer Motion

      import { motion } from "framer-motion" export const MyComponent = ({ isVisible }) => ( <motion.div animate={{ opacity: isVisible ? 1 : 0 }} /> )

      使用方式

      Framer motion的核心API是motion的组件。每个HTMLSVG标签都有对应的motion组件。

      他们渲染的结果与对应的原生组件完全一致,并在其之上增加了一些动画和手势相关的props

      比如:

      <motion.div /> <motion.span /> <motion.h1 /> <motion.svg /> ...

      示例

      比如我们现在想要实现一个侧边栏效果。

      节点的挂载与卸载(mount、unmount)

      如果我们自己来实现的话,可能要考虑它的keyframe,它的初始状态与最终的css样式。那么如果用framer-motion来如何实现呢?

      首先我们来设计一个会动的按钮Icon:

      import * as React from "react"; import { motion } from "framer-motion"; const Path = props => ( <motion.path fill="transparent" strokeWidth="3" stroke="hsl(0, 0%, 18%)" strokeLinecap="round" {...props} /> ); const MenuToggle = ({ toggle }) => ( <button onClick={toggle}> <svg width="23" height="23" viewBox="0 0 23 23"> <Path variants={{ closed: { d: "M 2 2.5 L 20 2.5" }, open: { d: "M 3 16.5 L 17 2.5" } }} /> <Path d="M 2 9.423 L 20 9.423" variants={{ closed: { opacity: 1 }, open: { opacity: 0 } }} transition={{ duration: 0.1 }} /> <Path variants={{ closed: { d: "M 2 16.346 L 20 16.346" }, open: { d: "M 3 2.5 L 17 16.346" } }} /> </svg> </button> );

      接下来,就由这个按钮来控制侧边栏的展示(mount)与隐藏(unmount):

      import * as React from "react"; import { useRef } from "react"; import { motion, useCycle } from "framer-motion"; import { useDimensions } from "./use-dimensions"; const sidebar = { open: (height = 1000) => ({ clipPath: `circle(${height * 2 + 200}px at 40px 40px)`, transition: { type: "spring", stiffness: 20, restDelta: 2 } }), closed: { clipPath: "circle(30px at 40px 40px)", transition: { delay: 0.5, type: "spring", stiffness: 400, damping: 40 } } }; export const Example = () => { const [isOpen, toggleOpen] = useCycle(false, true); const containerRef = useRef(null); const { height } = useDimensions(containerRef); return ( <motion.nav initial={false} animate={isOpen ? "open" : "closed"} custom={height} ref={containerRef} > <motion.div className="background" variants={sidebar} /> <MenuToggle toggle={() => toggleOpen()} /> </motion.nav> ); };

      也就是说,其实我们更多需要做的事情,从思考如何设计各元素之间的css联动与keyframe书写变成了如何按照文档写好framer-motion的配置。哪个更轻松相信大家一目了然。

      列表

      侧边栏一般都是带有菜单的,那么我们是不是可以让这个侧边栏也有一个逐次出现的效果呢?就像这样:

      这里我们是不是已经开始肌肉记忆般的计算延迟时间,思考如何进行整体效果的分配。那么如果这里我们使用frame motion,它的实现方式应该是怎么样的呢?

      首先我们先来进行单个Item的封装:

      import * as React from "react"; import { motion } from "framer-motion"; const variants = { open: { y: 0, opacity: 1, transition: { y: { stiffness: 1000, velocity: -100 } } }, closed: { y: 50, opacity: 0, transition: { y: { stiffness: 1000 } } } }; const colors = ["#FF008C", "#D309E1", "#9C1AFF", "#7700FF", "#4400FF"]; export const MenuItem = ({ i }) => { const style = { border: `2px solid ${colors[i]}` }; return ( <motion.li variants={variants} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.95 }} > <div className="icon-placeholder" style={style} /> <div className="text-placeholder" style={style} /> </motion.li> ); };

      然后我们在已封装Item的基础上,再进行整个菜单的封装:

      import * as React from "react"; import { motion } from "framer-motion"; const itemIds = [0, 1, 2, 3, 4]; const variants = { open: { transition: { staggerChildren: 0.07, delayChildren: 0.2 } }, closed: { transition: { staggerChildren: 0.05, staggerDirection: -1 } } }; export const Navigation = () => ( <motion.ul variants={variants}> {itemIds.map(i => ( <MenuItem i={i} key={i} /> ))} </motion.ul> );

      没错,动画!就是这么简单!

      更多API

      更详细、更具体的功能大家可以参考下官方的使用文档,我就不在这里一一列举了。

      如何用FramerMotion让React页面实现长尾词动画效果?

      美中不足

      其实不难看出,不论是实现的效果,还是使用方式,对于前端的同学来说framer-motion都是非常友好的工具。这一点从npm的Weekly Downloads以及github的star上面都不难看出。

      但是目前也有一个问题,那就是包的体积问题。

      这个包的大小对于部分的系统来说,还是不够友好。这也是很多人不选择使用它的原因。

      以上就是React动画实现方案Framer Motion让页面自己动起来的详细内容,更多关于React 动画 Framer Motion的资料请关注自由互联其它相关文章!