【问题标题】:JSS keyframes not working when passing props传递道具时JSS关键帧不起作用
【发布时间】:2021-05-09 11:15:23
【问题描述】:

我有一个 Spinner 组件,它基本上是一个加载图标。我正在尝试将道具传递给 JSS 样式,以便可以对其进行自定义。但是如果我将道具传递给关键帧,动画似乎不起作用。

下面是组件。当我使用动画$spinnertest 时,它工作正常。如果我使用$spinners,它不会加载动画(检查元素时,animation-name 甚至不会出现在类中,这让我相信它不会生成。)。

**问题的示例 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,
}

【问题讨论】:

    标签: reactjs jss


    【解决方案1】:

    我有一个周转解决方案,它有效(不是那么漂亮)。你可以把你的withStyles 变成一个柯里化函数,它接受keyframesProps,在你的关键帧定义中你会使用一个返回对象及其属性的 IIFE:

    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);
    

    【讨论】:

      【解决方案2】:

      听起来 MUI 在 makeStyles @keyframes 中存在关于 props 的错误 #16673 正如 Olivier Tassinari 所说,这个错误将在 v5 中修复,MUI 将使用新的样式解决方案styled-componentsRCF #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)`,
          },
        },
      }
      

      【讨论】:

      • 当我这样做时,JSS 只渲染 to 框架,因为它没有道具。
      • 是的@cclloyd,我更新了这些为什么会发生的简要介绍
      猜你喜欢
      • 1970-01-01
      • 2019-12-29
      • 2020-05-14
      • 1970-01-01
      • 2022-06-19
      • 2014-12-05
      • 2023-04-03
      • 1970-01-01
      • 2021-08-04
      相关资源
      最近更新 更多