How to rotate material-ui icon
Asked Answered
W

3

12

I'm trying to rotate material-ui icon using css property animation but not getting the desired result. Can somebody please help me identify what's going wrong here?

https://codesandbox.io/s/nifty-nightingale-v8sqh?file=/App.tsx

my expectation is a continuous rotating icon.

Weaponry answered 3/5, 2021 at 9:35 Comment(0)
S
5

You're almost there! You can keep both the rotateIcon style as the @keyframes spin style in the createStyles definition. The trick is to prefix spin with a $-sign so it comes $sign. Then it will work:

import React from "react";
import { Container, createStyles, makeStyles } from "@material-ui/core";
import LoopIcon from "@material-ui/icons/Loop";

export const useStyles = makeStyles(() =>
  createStyles({
    rotateIcon: {
      animation: "$spin 2s linear infinite"
    },
    "@keyframes spin": {
      "0%": {
        transform: "rotate(360deg)"
      },
      "100%": {
        transform: "rotate(0deg)"
      }
    }
  })
);

export default function App() {
  const classes = useStyles();
  return (
    <Container maxWidth="sm">
      <LoopIcon className={classes.rotateIcon} />
    </Container>
  );
}

Saddlery answered 24/11, 2021 at 13:53 Comment(1)
The '$' before spin: brilliant. thank you.Disfranchise
Y
20

Here's an alternative way with the new sx prop, which is new to MUI v5

import LoopIcon from '@mui/icons-material/Loop';
<LoopIcon
  sx={{
    animation: "spin 2s linear infinite",
    "@keyframes spin": {
      "0%": {
        transform: "rotate(360deg)",
      },
      "100%": {
        transform: "rotate(0deg)",
      },
    },
  }}
/>
Yvor answered 18/4, 2022 at 0:9 Comment(0)
S
5

You're almost there! You can keep both the rotateIcon style as the @keyframes spin style in the createStyles definition. The trick is to prefix spin with a $-sign so it comes $sign. Then it will work:

import React from "react";
import { Container, createStyles, makeStyles } from "@material-ui/core";
import LoopIcon from "@material-ui/icons/Loop";

export const useStyles = makeStyles(() =>
  createStyles({
    rotateIcon: {
      animation: "$spin 2s linear infinite"
    },
    "@keyframes spin": {
      "0%": {
        transform: "rotate(360deg)"
      },
      "100%": {
        transform: "rotate(0deg)"
      }
    }
  })
);

export default function App() {
  const classes = useStyles();
  return (
    <Container maxWidth="sm">
      <LoopIcon className={classes.rotateIcon} />
    </Container>
  );
}

Saddlery answered 24/11, 2021 at 13:53 Comment(1)
The '$' before spin: brilliant. thank you.Disfranchise
S
4

The animation name ("spin" in your initial sandbox) must refer to a set of keyframes.

A direct solution is to define the keyframes directly (not ideal, not neat, not extensible, etc.), see the keyframes in the style tag below.

You might want to check https://styled-components.com/docs/api#keyframes for a more neat solution.

import React from "react";
import { Container, createStyles, makeStyles } from "@material-ui/core";
import LoopIcon from "@material-ui/icons/Loop";

export const useStyles = makeStyles(() =>
  createStyles({
    rotateIcon: {
      animation: "spin 4s linear infinite"
    }
  })
);

export default function App() {
  const classes = useStyles();

  return (
    <Container maxWidth="sm">
      <LoopIcon className={classes.rotateIcon} />
      <style>{`
            @keyframes spin {
                 0% { transform: rotate(360deg); }
                 100% { transform: rotate(0deg); }
            }
        `}</style>
    </Container>
  );
}

https://codesandbox.io/s/practical-fire-6k3cx?file=/App.tsx

Snowplow answered 3/5, 2021 at 10:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.