传递道具时 JSS 关键帧不起作用
JSS keyframes not working when passing props
我有一个 Spinner 组件,它基本上是一个加载图标。我正在尝试将道具传递给 JSS 样式,以便可以对其进行自定义。但是如果我将道具传递给关键帧,动画似乎不起作用。
下面是组件。当我使用动画 $spinnertest
时,效果很好。如果我使用 $spinners
,它不会加载动画(在检查元素时,animation-name
甚至不会出现在 class 中,这让我相信它没有得到生成。).
**问题的CodeSandBox示例(只需将动画更改为spinners
):https://codesandbox.io/s/exciting-shirley-pqt1o?fontsize=14&hidenavigation=1&theme=dark
const useStyles = makeStyles(theme => ({
root: props => ({
width: props.size,
height: props.size,
position: 'relative',
contain: 'paint',
display: 'inline-block',
}),
spinner: props => ({
width: props.size*0.3125,
height: props.size*0.3125,
background: props.color,
position: 'absolute',
animationDuration: props.duration,
animationIterationCount: 'infinite',
animationTimingFunction: 'ease-in-out',
}),
spinnerAnimation: {
animationName: '$spinners',
},
square2: props => ({
animationDelay: -props.duration/2,
}),
'@keyframes spinnertest': {
'25%': {
transform: 'translateX(22px) rotate(-90deg) scale(.5)',
},
'50%': {
transform: 'translateX(22px) translateY(22px) rotate(-180deg)',
},
'75%': {
transform: 'translateX(0) translateY(22px) rotate(-270deg) scale(.5)',
},
'to': {
transform: 'rotate(-1turn)',
},
},
'@keyframes spinners': props => ({
'25%': {
transform: `translateX(${props.translate}px) rotate(-90deg) scale(.5)`,
},
'50%': {
transform: `translateX(${props.translate}px) translateY(${props.translate}px) rotate(-180deg)`,
},
'75%': {
transform: `translateX(0) translateY(${props.translate}px) rotate(-270deg) scale(.5)`,
},
'to': {
transform: `rotate(-1turn)`,
},
}),
}));
export default function Spinner(props) {
const {duration, size, color} = props;
const classes = useStyles({
duration: duration,
size: size,
color: color,
translate: size*(1-0.3125),
});
return (
<Box className={classes.root}>
<Box className={clsx(classes.spinner, classes.spinnerAnimation)} />
<Box className={clsx(classes.spinner, classes.square2, classes.spinnerAnimation)} />
</Box>
)
}
Spinner.defaultProps = {
duration: 1800,
size: 32,
color: #fff,
}
我有一个有效的周转解决方案(不是那么好)。你会把你的 withStyles
变成一个柯里化函数,它接受 keyframesProps
,并且在你的关键帧定义中你会使用一个 IIFE returns 对象及其属性:
const useStyles = keyframesProps => makeStyles((theme) => ({
... all other styles,
// you need to call an IIFE because keyframes doesn't receive a function
"@keyframes spinners": ((props) => ({
"25%": {
transform: `translateX(${props.translate}px) rotate(-90deg) scale(.5)`
},
"50%": {
transform: `translateX(${props.translate}px) translateY(${props.translate}px) rotate(-180deg)`
},
"75%": {
transform: `translateX(0) translateY(${props.translate}px) rotate(-270deg) scale(.5)`
},
to: {
transform: `rotate(-1turn)`
}
}))(keyframesProps)
}));
在您的组件中,您可以将 classes
定义为:
const styleProps = {
duration: duration,
size: size,
color: color
}
const framesProps = {
translate: size * (1 - 0.3125)
}
const classes = useStyles(framesProps)(styleProps);
听起来 MUI 在 makeStyles 中有一个关于道具的错误 @keyframes
#16673
正如 Olivier Tassinari 所说,此错误将在 v5 中修复,其中 MUI 将使用新的样式解决方案 styled-components
RCF #22342.
问题更笼统:
箭头函数(有或没有道具)在 makeStyles 中不起作用
#21011
将道具传递给您定义的关键帧中的规则将修复它(希望 v5 可用后)
"@keyframes spinners": {
"25%": {
transform: (props) =>
// console.log(props) and template generation will be created correctly.
`translateX(${props.translate}px) rotate(-90deg) scale(.5)`
},
// ...
}
在那之前,您可以按照@buzatto 的建议使用高阶 useStyle 创建器来嵌入关键帧。
或者在您的主题对象中定义您的动画预设并在您的项目中全局使用它们。
const theme = createMuiTheme({
animation: {
presets: {
duration: 180,
// or even function
rotateDeg: (angle) => `{angle}deg`
//...
}
}
});
// usage
const useStyles = makeStyles(theme => ({
"@keyframes spinners": {
"25%": {
transform: `translateX(${
theme.animation.presets.duration * 10
}px) rotate(${theme.animation.presets.rotateDeg(-90)}) scale(.5)`,
},
},
}
我有一个 Spinner 组件,它基本上是一个加载图标。我正在尝试将道具传递给 JSS 样式,以便可以对其进行自定义。但是如果我将道具传递给关键帧,动画似乎不起作用。
下面是组件。当我使用动画 $spinnertest
时,效果很好。如果我使用 $spinners
,它不会加载动画(在检查元素时,animation-name
甚至不会出现在 class 中,这让我相信它没有得到生成。).
**问题的CodeSandBox示例(只需将动画更改为spinners
):https://codesandbox.io/s/exciting-shirley-pqt1o?fontsize=14&hidenavigation=1&theme=dark
const useStyles = makeStyles(theme => ({
root: props => ({
width: props.size,
height: props.size,
position: 'relative',
contain: 'paint',
display: 'inline-block',
}),
spinner: props => ({
width: props.size*0.3125,
height: props.size*0.3125,
background: props.color,
position: 'absolute',
animationDuration: props.duration,
animationIterationCount: 'infinite',
animationTimingFunction: 'ease-in-out',
}),
spinnerAnimation: {
animationName: '$spinners',
},
square2: props => ({
animationDelay: -props.duration/2,
}),
'@keyframes spinnertest': {
'25%': {
transform: 'translateX(22px) rotate(-90deg) scale(.5)',
},
'50%': {
transform: 'translateX(22px) translateY(22px) rotate(-180deg)',
},
'75%': {
transform: 'translateX(0) translateY(22px) rotate(-270deg) scale(.5)',
},
'to': {
transform: 'rotate(-1turn)',
},
},
'@keyframes spinners': props => ({
'25%': {
transform: `translateX(${props.translate}px) rotate(-90deg) scale(.5)`,
},
'50%': {
transform: `translateX(${props.translate}px) translateY(${props.translate}px) rotate(-180deg)`,
},
'75%': {
transform: `translateX(0) translateY(${props.translate}px) rotate(-270deg) scale(.5)`,
},
'to': {
transform: `rotate(-1turn)`,
},
}),
}));
export default function Spinner(props) {
const {duration, size, color} = props;
const classes = useStyles({
duration: duration,
size: size,
color: color,
translate: size*(1-0.3125),
});
return (
<Box className={classes.root}>
<Box className={clsx(classes.spinner, classes.spinnerAnimation)} />
<Box className={clsx(classes.spinner, classes.square2, classes.spinnerAnimation)} />
</Box>
)
}
Spinner.defaultProps = {
duration: 1800,
size: 32,
color: #fff,
}
我有一个有效的周转解决方案(不是那么好)。你会把你的 withStyles
变成一个柯里化函数,它接受 keyframesProps
,并且在你的关键帧定义中你会使用一个 IIFE returns 对象及其属性:
const useStyles = keyframesProps => makeStyles((theme) => ({
... all other styles,
// you need to call an IIFE because keyframes doesn't receive a function
"@keyframes spinners": ((props) => ({
"25%": {
transform: `translateX(${props.translate}px) rotate(-90deg) scale(.5)`
},
"50%": {
transform: `translateX(${props.translate}px) translateY(${props.translate}px) rotate(-180deg)`
},
"75%": {
transform: `translateX(0) translateY(${props.translate}px) rotate(-270deg) scale(.5)`
},
to: {
transform: `rotate(-1turn)`
}
}))(keyframesProps)
}));
在您的组件中,您可以将 classes
定义为:
const styleProps = {
duration: duration,
size: size,
color: color
}
const framesProps = {
translate: size * (1 - 0.3125)
}
const classes = useStyles(framesProps)(styleProps);
听起来 MUI 在 makeStyles 中有一个关于道具的错误 @keyframes
#16673
正如 Olivier Tassinari 所说,此错误将在 v5 中修复,其中 MUI 将使用新的样式解决方案 styled-components
RCF #22342.
问题更笼统:
箭头函数(有或没有道具)在 makeStyles 中不起作用
#21011
将道具传递给您定义的关键帧中的规则将修复它(希望 v5 可用后)
"@keyframes spinners": {
"25%": {
transform: (props) =>
// console.log(props) and template generation will be created correctly.
`translateX(${props.translate}px) rotate(-90deg) scale(.5)`
},
// ...
}
在那之前,您可以按照@buzatto 的建议使用高阶 useStyle 创建器来嵌入关键帧。
或者在您的主题对象中定义您的动画预设并在您的项目中全局使用它们。
const theme = createMuiTheme({
animation: {
presets: {
duration: 180,
// or even function
rotateDeg: (angle) => `{angle}deg`
//...
}
}
});
// usage
const useStyles = makeStyles(theme => ({
"@keyframes spinners": {
"25%": {
transform: `translateX(${
theme.animation.presets.duration * 10
}px) rotate(${theme.animation.presets.rotateDeg(-90)}) scale(.5)`,
},
},
}