使用 framer-motion 和 React.js 的动画共享布局
以下方法介绍了如何使用 framer-motion 和 ReactJS 创建动画共享布局。
先决条件:
- JavaScript(ES6)知识
- 熟悉 HTML/CSS。
- 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 组件motion和AnimatePresence的动画布局。
- 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/ ,您将看到以下输出: