Ankit Jaishwal
Ankit Jaishwal

Reputation: 526

How to animate refresh icon on Click in React?

In my react app, there is a refresh icon. I am using material UI for the icon. I want that after clicking on it, it should spin for a second. I have no idea how to do it.

I have tried this but it didn't work.

const useStyles = makeStyles((theme) => ({
refresh: {
    marginTop: "20px",
    cursor: "pointer",
    margin: "auto",
    animation: "spin 1s 1",
  },
  "@keyframes spin": {
    "0%": {
      transform: "translateY(-200%)",
    },
    "100%": {
      transform: "translateY(0)",
    },
  },
}));

function Refresh() {
    const [spin, setSpin] = React.useState(0);
    const classes= useStyles();
    
    const refreshCanvas = () => {
        setSpin(1);
        console.log("Refreshed");
    };
    return (
        <AutorenewIcon
            className={classes.refresh}
            onClick={refreshCanvas}
            onAnimationEnd={() => setSpin(0)}
            spin={spin}
        />
    )
    
}

Upvotes: 0

Views: 8151

Answers (3)

Ankit Jaishwal
Ankit Jaishwal

Reputation: 526

Got the answer... Thanx for both the answers I got here... I got the idea from those answers.

const useStyles = makeStyles((theme) => ({
      refresh: {
        margin: "auto",
      },
      spin: {
        margin: "auto",
        animation: "$spin 1s 1",
      },
      "@keyframes spin": {
        "0%": {
          transform: "rotate(0deg)",
        },
        "100%": {
          transform: "rotate(360deg)",
        },
      }
    }))
    
    function Refresh() {
    const [spin, setSpin] = React.useState(0);
    
const classes= useStyles();

const refreshCanvas = () => {
    setSpin(true);
    setTimeout(() => {
      setSpin(false);
    }, 1000);
    console.log("Refreshed");
};
return (
    <AutorenewIcon
        className={spin ? classes.spin : classes.refresh}
        onClick={refreshCanvas}
        spin={spin}
    />
  )
}

Upvotes: 0

Rajiv
Rajiv

Reputation: 3772

set the spin true on click and then add a setTimeout for 1000ms, which will set that spin state again false. And then add a class conditionally based on the value of the spin state and add the animation to that class.

const useStyles = makeStyles((theme) => ({
    refresh: {
        marginTop: "20px",
        cursor: "pointer",
        margin: "auto",
        "&.spin": {
            animation: "$spin 1s 1",
            // pointerEvents:'none'
        }
    },
    "@keyframes spin": {
        "0%": {
            transform: "rotate(0deg)"
        },
        "100%": {
            transform: "rotate(360deg)"
        }
    }
}));

function Refresh() {
    const [spin, setSpin] = React.useState(false);
    const classes = useStyles();

    const refreshCanvas = () => {
        setSpin(true);
        setTimeout(() => {
            setSpin(false);
        }, 1000);
    };

    return (
        <Autorenew
            className={clsx({
                [classes.refresh]: true,
                spin: spin
            })}
            onClick={refreshCanvas}
            spin={360}
        />
    );
}

Optional Update: Also you can add pointerEvents:"none" in spin class to disable the click for that period of time until the animation is going which is 1000ms here.

Here is the working demo:
Edit amazing-burnell-m9j4y

Upvotes: 1

Sangam Rajpara
Sangam Rajpara

Reputation: 678

Seprate the class of animaion let's assume it is refresh as of now and stored in classes.refresh.

You can do it by conditionally applying className to your element

function Refresh() {
const [spin, setSpin] = React.useState(0);

const classes= useStyles();

const refreshCanvas = () => {
    setSpin(1);
    console.log("Refreshed");
};
return (
    <AutorenewIcon
        className={spin === 1 ? classes.refresh : ''}
        onClick={refreshCanvas}
        onAnimationEnd={() => setSpin(0)}
        spin={spin}
    />
)
}

Upvotes: 0

Related Questions