如何在 MUI 中应用自定义动画效果@keyframes?
Posted
技术标签:
【中文标题】如何在 MUI 中应用自定义动画效果@keyframes?【英文标题】:How to apply custom animation effect @keyframes in MUI? 【发布时间】:2020-03-15 20:22:27 【问题描述】:我学会了使用@keyframe
在 CSS 中使用动画。但是,我想将自定义动画代码写入我的 React 项目(使用 MUI)。我的挑战是如何编写 javascript 代码来使用 MUI 中的 makeStyle()
自定义我的动画。
我希望能够以百分比自定义转换过程
这次是在 MUI。我需要能够在makeStyle()
中编写这样的代码,但我似乎不知道该怎么做。
@keyframes myEffect
0%
opacity:0;
transform: translateY(-200%);
100%
opacity:1;
transform: translateY(0);
【问题讨论】:
【参考方案1】:这是一个示例,演示 makeStyles
中的 keyframes
语法:
import React from "react";
import ReactDOM from "react-dom";
import makeStyles from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import clsx from "clsx";
const useStyles = makeStyles(theme => (
animatedItem:
animation: `$myEffect 3000ms $theme.transitions.easing.easeInOut`
,
animatedItemExiting:
animation: `$myEffectExit 3000ms $theme.transitions.easing.easeInOut`,
opacity: 0,
transform: "translateY(-200%)"
,
"@keyframes myEffect":
"0%":
opacity: 0,
transform: "translateY(-200%)"
,
"100%":
opacity: 1,
transform: "translateY(0)"
,
"@keyframes myEffectExit":
"0%":
opacity: 1,
transform: "translateY(0)"
,
"100%":
opacity: 0,
transform: "translateY(-200%)"
));
function App()
const classes = useStyles();
const [exit, setExit] = React.useState(false);
return (
<>
<div
className=clsx(classes.animatedItem,
[classes.animatedItemExiting]: exit
)
>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Button onClick=() => setExit(true)>Click to exit</Button>
</div>
exit && <Button onClick=() => setExit(false)>Click to enter</Button>
</>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
文档:https://cssinjs.org/jss-syntax/?v=v10.0.0#keyframes-animation
对于那些已经开始使用 Material-UI v5 并想知道如何使用 Emotion 而不是 makeStyles
的人,下面是使用 Emotion 进行等效样式的一种方法示例。
/** @jsxImportSource @emotion/react */
import React from "react";
import ReactDOM from "react-dom";
import css, keyframes from "@emotion/react";
import useTheme from "@mui/material/styles";
import Button from "@mui/material/Button";
const myEffect = keyframes`
0%
opacity: 0;
transform: translateY(-200%);
100%
opacity: 1;
transform: translateY(0);
`;
const myEffectExit = keyframes`
0%
opacity: 1;
transform: translateY(0);
100%
opacity: 0;
transform: translateY(-200%);
`;
function App()
const theme = useTheme();
const animatedItem = css`
animation: $myEffect 3000ms $theme.transitions.easing.easeInOut;
`;
const animatedItemExiting = css`
animation: $myEffectExit 3000ms $theme.transitions.easing.easeInOut;
opacity: 0;
transform: translateY(-200%);
`;
const [exit, setExit] = React.useState(false);
return (
<>
<div css=exit ? animatedItemExiting : animatedItem>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Button onClick=() => setExit(true)>Click to exit</Button>
</div>
exit && <Button onClick=() => setExit(false)>Click to enter</Button>
</>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
情感关键帧文档:https://emotion.sh/docs/keyframes
【讨论】:
【参考方案2】:V5
在 v5 中,您可以使用 keyframes
函数(默认是 emotion 中的 re-exported)来生成关键帧的样式表:
import styled from '@mui/material/styles';
import keyframes from '@mui/system';
const spin = keyframes`
from
transform: rotate(0deg);
to
transform: rotate(360deg);
`;
const RotatedBox = styled("div")(
backgroundColor: "pink",
width: 30,
height: 30,
animation: `$spin 1s infinite ease`
);
因为styled
/sx
属性在内部都使用了情感,所以可以将相同的样式对象传递给sx
属性:
<Box
sx=
backgroundColor: "pink",
width: 30,
height: 30,
animation: `$spin 1s infinite ease`
/>
V4
只是在@Ryan's answer 之上的一些注释。如果您使用makeStyles
定义keyframe
。请记住在动画名称前加上$
。我第一次错过了这个小细节,我的代码不起作用,在下面的示例中
const useStyles = makeStyles(
"@keyframes fadeIn":
"0%":
opacity: 0,
transform: "translateY(5rem)"
,
"100%":
opacity: 1,
transform: "translateY(0)"
,
selector:
animation: "$fadeIn .2s ease-in-out"
);
代替
animation: "fadeIn .2s ease-in-out"
应该是
animation: "$fadeIn .2s ease-in-out"
但是如果你在全局范围内定义keyframe
。这里不需要前缀
const useStyles = makeStyles(
"@global":
"@keyframes fadeIn":
"0%":
opacity: 0,
transform: "translateY(5rem)"
,
"100%":
opacity: 1,
transform: "translateY(0)"
,
selector:
animation: "fadeIn .2s ease-in-out" // --> this works
);
在 github 上关注 issue 以获取更多关于此的讨论。
【讨论】:
以上是关于如何在 MUI 中应用自定义动画效果@keyframes?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter CustomScrollView 自定义滑动效果