Aprendí a usar animación en CSS usando @keyframe . Sin embargo, quiero escribir mi código de animación personalizado en mi proyecto React (usando MUI). Mi desafío es cómo puedo escribir el código Javascript para personalizar mis animaciones usando makeStyle() en MUI.
Quiero poder personalizar los procesos de transición en porcentajes esta vez en MUI. Necesito poder escribir códigos como este en makeStyle() pero parece que no sé cómo hacerlo.
@keyframes myEffect { 0%{ opacity:0; transform: translateY(-200%); } 100% { opacity:1; transform: translateY(0); } }Aquí hay un ejemplo que demuestra la sintaxis de keyframes dentro de makeStyles :
import React from "react"; import ReactDOM from "react-dom"; import { makeStyles } from "@material-ui/core/styles"; import Button from "@material-ui/core/Button"; import clsx from "clsx"; const useStyles = makeStyles(theme => ({ animatedItem: { animation: `$myEffect 3000ms ${theme.transitions.easing.easeInOut}` }, animatedItemExiting: { animation: `$myEffectExit 3000ms ${theme.transitions.easing.easeInOut}`, opacity: 0, transform: "translateY(-200%)" }, "@keyframes myEffect": { "0%": { opacity: 0, transform: "translateY(-200%)" }, "100%": { opacity: 1, transform: "translateY(0)" } }, "@keyframes myEffectExit": { "0%": { opacity: 1, transform: "translateY(0)" }, "100%": { opacity: 0, transform: "translateY(-200%)" } } })); function App() { const classes = useStyles(); const [exit, setExit] = React.useState(false); return ( <> <div className={clsx(classes.animatedItem, { [classes.animatedItemExiting]: exit })} > <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> <Button onClick={() => setExit(true)}>Click to exit</Button> </div> {exit && <Button onClick={() => setExit(false)}>Click to enter</Button>} </> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);Documentación: https://cssinjs.org/jss-syntax/?v=v10.0.0#keyframes-animation
Para aquellos que han comenzado a usar Material-UI v5 y quieren saber cómo hacerlo usando Emotion en lugar de makeStyles , a continuación hay un ejemplo de una forma de hacer los estilos equivalentes usando Emotion.
/** @jsxImportSource @emotion/react */ import React from "react"; import ReactDOM from "react-dom"; import { css, keyframes } from "@emotion/react"; import { useTheme } from "@mui/material/styles"; import Button from "@mui/material/Button"; const myEffect = keyframes` 0% { opacity: 0; transform: translateY(-200%); } 100% { opacity: 1; transform: translateY(0); } `; const myEffectExit = keyframes` 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-200%); } `; function App() { const theme = useTheme(); const animatedItem = css` animation: ${myEffect} 3000ms ${theme.transitions.easing.easeInOut}; `; const animatedItemExiting = css` animation: ${myEffectExit} 3000ms ${theme.transitions.easing.easeInOut}; opacity: 0; transform: translateY(-200%); `; const [exit, setExit] = React.useState(false); return ( <> <div css={exit ? animatedItemExiting : animatedItem}> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> <Button onClick={() => setExit(true)}>Click to exit</Button> </div> {exit && <Button onClick={() => setExit(false)}>Click to enter</Button>} </> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);Documentación de fotogramas clave de emoción: https://emotion.sh/docs/keyframes
V5
En v5, puede usar la función de keyframes (que se vuelve a exportar de emoción de forma predeterminada) para generar la hoja de estilo para el fotograma clave:
import { styled } from '@mui/material/styles'; import { keyframes } from '@mui/system'; const spin = keyframes` from { transform: rotate(0deg); } to { transform: rotate(360deg); } `; const RotatedBox = styled("div")({ backgroundColor: "pink", width: 30, height: 30, animation: `${spin} 1s infinite ease` }); Debido a que ambos props styled / sx usan emoción internamente, puedes pasar el mismo objeto de estilo al prop sx :
<Box sx={{ backgroundColor: "pink", width: 30, height: 30, animation: `${spin} 1s infinite ease` }} />V4
Solo algunas notas además de la respuesta de @Ryan . Si define el keyframe usando makeStyles . Recuerde anteponer el nombre de la animación con $ . Me perdí este pequeño detalle la primera vez y mi código no funcionó, en el siguiente ejemplo
const useStyles = makeStyles({ "@keyframes fadeIn": { "0%": { opacity: 0, transform: "translateY(5rem)" }, "100%": { opacity: 1, transform: "translateY(0)" } }, selector: { animation: "$fadeIn .2s ease-in-out" } });En lugar de
animation: "fadeIn .2s ease-in-out"Debería ser
animation: "$fadeIn .2s ease-in-out" Pero si define el keyframe en el ámbito global. El prefijo es innecesario aquí
const useStyles = makeStyles({ "@global": { "@keyframes fadeIn": { "0%": { opacity: 0, transform: "translateY(5rem)" }, "100%": { opacity: 1, transform: "translateY(0)" } } }, selector: { animation: "fadeIn .2s ease-in-out" // --> this works } });Siga este problema en github para obtener más información sobre esto.