中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Framer?Motion實現React動畫

發布時間:2022-10-31 09:29:23 來源:億速云 閱讀:127 作者:iii 欄目:開發技術

這篇文章主要介紹“怎么使用Framer Motion實現React動畫”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“怎么使用Framer Motion實現React動畫”文章能幫助大家解決問題。

在我們的常規認知中,實現這樣的效果其實需要很多的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.h6>{item.subtitle}</motion.h6>
    <motion.h3>{item.title}</motion.h3>
  </motion.div>
))}
<AnimatePresence>
  {selectedId && (
    <motion.div layoutId={selectedId}>
      <motion.h6>{item.subtitle}</motion.h6>
      <motion.h3>{item.title}</motion.h3>
      <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.h2 />
<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的配置。哪個更輕松相信大家一目了然。

列表

首先我們先來進行單個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>
);

關于“怎么使用Framer Motion實現React動畫”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万盛区| 炎陵县| 武陟县| 察雅县| 香格里拉县| 双辽市| 久治县| 项城市| 延川县| 卢湾区| 丹棱县| 佛坪县| 高安市| 来凤县| 堆龙德庆县| 济南市| 汝南县| 定远县| 民权县| 巴东县| 增城市| 安徽省| 东至县| 滨海县| 辽阳县| 西贡区| 南华县| 兴宁市| 翁牛特旗| 石台县| 新余市| 建湖县| 富蕴县| 盐源县| 朝阳市| 宾川县| 济宁市| 津南区| 饶平县| 霍州市| 饶河县|