3

I am trying to animate a button when hovered using styled from MUI 5 - but it is not working. I tried to find inspiration from:

.. with no luck.

Try and have a look and tell what I cannot see:

import Button from "@mui/material/Button";
import { styled } from "@mui/material/styles";
import { keyframes } from "@emotion/react";
const getAnimation = () => keyframes`
 0 % { transform: translate(1px, 1px) rotate(0deg) },
 10% { transform: translate(-1px, -2px) rotate(-1deg); },
 20% { transform: translate(-3px, 0px) rotate(1deg); },
 30% { transform: translate(3px, 2px) rotate(0deg); },
 40% { transform: translate(1px, -1px) rotate(1deg); },
 50% { transform: translate(-1px, 2px) rotate(-1deg); },
 60% { transform: translate(-3px, 1px) rotate(0deg); },
 70% { transform: translate(3px, 1px) rotate(-1deg); },
 80% { transform: translate(-1px, -1px) rotate(1deg); },
 90% { transform: translate(1px, 2px) rotate(0deg); },
 100% { transform: translate(1px, -2px) rotate(-1deg); }
`;
const StyledButton = styled((props) => {
 const { ...other } = props;
 return <Button {...other} />;
})(({ theme }) => ({
 ":hover": {
 animation: `${getAnimation} shake infinite`
 },
 backgroundColor: "#2699FB",
 color: "#FFFFFF"
}));
const App = () => {
 return (
 <StyledButton variant="contained">
 My button
 </StyledButton>
 )
}
export default App
NearHuscarl
83.1k24 gold badges322 silver badges292 bronze badges
asked Sep 29, 2021 at 8:32

2 Answers 2

4

Emotion's keyframe is a tag function. It accepts a template string as the first argument and returns the keyframe data. What you defined in your code is a function that just returns another function without doing anything:

const getAnimation = () => keyframes`
 0 % { transform: translate(1px, 1px) rotate(0deg) },
 ...
 100% { transform: translate(1px, -2px) rotate(-1deg); }
`;

You're supposed to change the code to this:

const myKeyframe = keyframes`
 0 % { transform: translate(1px, 1px) rotate(0deg) },
 ...
 100% { transform: translate(1px, -2px) rotate(-1deg); }
`;

Usage

const StyledButton = styled((props) => <Button {...props} />)(({ theme }) => ({
 ":hover": {
 backgroundColor: "#2699FB",
 // I also fixed the animation sub-property order of yours
 // See: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations#configuring_the_animation
 animation: `${myKeyframe} 1s infinite ease`
 },
 backgroundColor: "#2699FB",
 color: "#FFFFFF"
}));

Live Demo

Codesandbox Demo

answered Sep 29, 2021 at 8:46
Sign up to request clarification or add additional context in comments.

Comments

2

This s eem to work for me

  1. Inside sx prop
<Box
 sx={{
 animationName: "move", 
 "@keyframes move": {
 "0%": {
 opacity: 0,
 },
 "50%": {
 opacity: 1,
 },
 "100%": {
 opacity: 0,
 },
 }, 
 }}
>
 Content
</Box>

or

2)

import { keyframes } from "@mui/system";

...

const shake = keyframes`
 25% { transform: translateX(-1px); } 
 75% { transform: translateX(1px); }
`;

...

<Box
 sx={{
 animation: `${shake} .5s linear infinite;`,
 width: "75px",
 height: "75px",
 }}
>
...
</Box>
answered Feb 5, 2023 at 7:47

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.