📜  使用 framer-motion 和 React.js 的动画共享布局

📅  最后修改于: 2022-05-13 01:56:24.748000             🧑  作者: Mango

使用 framer-motion 和 React.js 的动画共享布局

以下方法介绍了如何使用 framer-motion 和 ReactJS 创建动画共享布局。

先决条件:

  1. JavaScript(ES6)知识
  2. 熟悉 HTML/CSS。
  3. ReactJS 的基础知识。

创建 React 应用程序并安装模块:

  • 第 1 步:使用以下命令创建一个 React 应用程序:

    npx create-react-app animated-layout
  • 第 2 步:创建项目文件夹(即动画布局)后,使用以下命令移动到该文件夹。

    cd animated-layout
  • 第 3 步:添加项目期间需要的 npm 包:

    npm install framer-motion

现在打开 src 文件夹并删除以下文件并创建一个名为Item.js的 JavaScript 文件。

  • 徽标.svg
  • serviceWorker.js
  • setupTests.js
  • App.test.js(如果有)
  • 索引.css

项目结构:您的项目结构树应如下所示:

文件夹结构

例子:

  • 我们将创建一个Item组件,它是使用 react useState hook 和 framer-motion 组件motionAnimatePresence的动画布局。
  • Content组件用于使用 HTML img 标签和 div & framer-motion 组件motion创建 Item 的(动画共享布局)内容。
  • toggleOpen是一个实用函数,用于将“isOpen”值设置为不是 (!) 的最后一个值。
  • App.js , itemList是我们想要创建的动画共享布局的数量,在我们的例子中是 3。
  • 在 App.js 中,我们将使用 framer-motion AnimatedSharedLayout组件来包装导入的Item组件,并通过 'itemsList' 数组映射来渲染动画布局。
App.js
import React from "react";
import { AnimateSharedLayout } from "framer-motion";
import Item from "./Item";
import "./styles.css";
  
// This is an example of animating shared layouts 
// using react and framer-motion library.
const itemsList = [
  {
    index: 0,
    content: `Motion components are DOM primitives 
  optimised for 60fps animation and gestures.`
  },
  {
    index: 1,
    content: `Motion can animate:
    Numbers: 0, 10 etc.
    Strings containing numbers: "0vh", "10px" etc.`
  },
  {
    index: 2,
    content: `Transform properties are accelerated by the GPU,
     and therefore animate smoothly. `
  }
];
  
const App = () => {
  return (
    // The framer-motion component to wrap Item component to animate it 
    
      {/* Mapping through itemList array to render layouts*/}
      {itemsList.map((item) => (
        
      ))}
    
  );
};
  
export default App;


Item.js
import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
  
const Content = ({ content }) => {
  
  const url = "https://media.geeksforgeeks.org/wp-content/cdn-uploads/" +
    "20200817185016/gfg_complete_logo_2x-min.png"
  
  return (
    
      
      
{content}
    
  ); };    const Item = ({ content }) => {   // React useState hook is used to manage the state of 'isOpen'   // that in turn toggles shared layout, user clicks on   const [isOpen, setIsOpen] = useState(false);      // Utility function to set 'isOpen' '!'(not) of its last value   const toggleOpen = () => setIsOpen(!isOpen);      const url = "https://yt3.ggpht.com/ytc/AAUvwnjJqZG9PvGfC3GoV" +     "27UlohMeBLxyUdhs9hUbc-Agw=s900-c-k-c0x00ffffff-no-rj"      return (                     {" "}         {" "}              
      {isOpen && }            
  ); };    export default Item;


styles.css
body {
  min-height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
  
* {
  box-sizing: border-box;
}
  
ul,
li {
  list-style: none;
  margin: 0;
  padding: 0;
}
  
ul {
  width: 300px;
  display: flex;
  flex-direction: column;
  background: #fcfcfc;
  padding: 20px;
  border-radius: 25px;
}
  
li {
  background-color: rgba(214, 214, 214, 0.5);
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 20px;
  overflow: hidden;
  cursor: pointer;
  width: 300px;
}
  
li:last-child {
  margin-bottom: 0px;
}
  
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 20px;
}
  
.avatar img {
  width: 40px;
  border-radius: 100%;
}
  
.row {
  margin-top: 12px;
}
  
img {
  width: 250px;
  height: 40px;
}


项目.js

import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
  
const Content = ({ content }) => {
  
  const url = "https://media.geeksforgeeks.org/wp-content/cdn-uploads/" +
    "20200817185016/gfg_complete_logo_2x-min.png"
  
  return (
    
      
      
{content}
    
  ); };    const Item = ({ content }) => {   // React useState hook is used to manage the state of 'isOpen'   // that in turn toggles shared layout, user clicks on   const [isOpen, setIsOpen] = useState(false);      // Utility function to set 'isOpen' '!'(not) of its last value   const toggleOpen = () => setIsOpen(!isOpen);      const url = "https://yt3.ggpht.com/ytc/AAUvwnjJqZG9PvGfC3GoV" +     "27UlohMeBLxyUdhs9hUbc-Agw=s900-c-k-c0x00ffffff-no-rj"      return (                     {" "}         {" "}              
      {isOpen && }            
  ); };    export default Item;

样式.css

body {
  min-height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
  
* {
  box-sizing: border-box;
}
  
ul,
li {
  list-style: none;
  margin: 0;
  padding: 0;
}
  
ul {
  width: 300px;
  display: flex;
  flex-direction: column;
  background: #fcfcfc;
  padding: 20px;
  border-radius: 25px;
}
  
li {
  background-color: rgba(214, 214, 214, 0.5);
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 20px;
  overflow: hidden;
  cursor: pointer;
  width: 300px;
}
  
li:last-child {
  margin-bottom: 0px;
}
  
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 20px;
}
  
.avatar img {
  width: 40px;
  border-radius: 100%;
}
  
.row {
  margin-top: 12px;
}
  
img {
  width: 250px;
  height: 40px;
}

运行应用程序的步骤:从项目的根目录使用以下命令运行应用程序:

npm start

输出:现在打开浏览器并转到http://localhost:3000/ ,您将看到以下输出: