Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

217
Vistas
¿Cómo animar el cambio de color (fotogramas clave) hacia adelante y hacia atrás al hacer clic con useState sin iniciar la animación durante la primera carga de la página?

Tengo un pequeño problema complicado.

Tengo un contenedor que se está coloreando al hacer clic en él. Al hacer clic en él, se enviarán datos a la matriz, pero ese no es el problema.

Al hacer clic en él, también se animará el cambio de color. La animación se activará hacia adelante al hacer clic y hacia atrás si se vuelve a hacer clic en el contenedor.

El problema es que la animación se activa condicionalmente con el uso de useState (booleano) y, por lo tanto, la segunda animación ya se ejecutará cuando se cargue la página, incluso antes de hacer clic en el contenedor. Me preguntaba sobre el estilo de estado de reproducción de animación, pero no parece ser suficiente.

Aquí está la demostración editable https://qeevsk.csb.app/ ¿Alguna idea, tal vez hay un mejor enfoque?

El código en sí:

 const [activeDiv, setDivState] = useState(false); const BigDiv = styled("div")( ({ theme, activeDiv }) => css` min-width: 220px; height: 100%; position: relative; padding: ${theme.spacing(2, 0)}; border-bottom: red 4px solid; background-color: transparent; cursor: pointer; text-align: center; transition-delay: 0.5s; will-change: transform; ::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; background-color: ${activeDiv ? "red" : "transparent"}; animation: ${activeDiv ? setColor("red") : unsetColor("red")} 0.5s ease ; transform-origin: bottom center}; } ` ); const setColor = (colorTo) => keyframes` 0% {transform: scaleY(0); } 100% {transform: scaleY(1); background-color: ${colorTo}} `; const unsetColor = (colorFrom) => keyframes` 0% {transform: scaleY(1); background-color: ${colorFrom}} 100% {transform: scaleY(0); background-color: transparent;} `; const SecondDiv = styled("div")( ({ theme, activeDiv, color }) => css` display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; position: relative; z-index: 1; ` ); return ( <> <BigDiv activeDiv={activeDiv} onClick={(e) => { setDivState(!activeDiv); }} > <SecondDiv> <p>Click to animate</p> </SecondDiv> </BigDiv> </> ); }
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Ya obtuvo algunas respuestas válidas, pero si está buscando un enfoque diferente, puede administrar el estado de la animación con un tercer valor como "IDLE":

 const AnimStatus = { IDLE: -1, INACTIVE: 0, ACTIVE: 1 }; // the status will be handled like this: const [divStatus, setDivStatus] = useState(AnimStatus.IDLE); <BigDiv divStatus={divStatus} onClick={(e) => { setDivStatus((prev) => prev === AnimStatus.INACTIVE || prev === AnimStatus.IDLE ? AnimStatus.ACTIVE : AnimStatus.INACTIVE ); }} /> // in the css animation const BigDiv = styled("div")( ({ theme, divStatus }) => css` /* BigDiv CSS properties */ ::after { /* Other ::after CSS properties */ width: 100%; height: 100%; transform-origin: bottom center; ${ divStatus !== AnimStatus.IDLE ? css` background-color: ${divStatus === AnimStatus.ACTIVE ? "red" : "transparent"}; animation: ${divStatus === AnimStatus.ACTIVE ? setColor("red") : unsetColor("red")} 0.5s ease; ` : "" } }; } ` );

La ventaja de este enfoque es que puede reutilizar este AnimStatus en todas sus animaciones como una interfaz y agregar fácilmente efectos específicos para "IDLE".

Aquí está mi demostración: https://codesandbox.io/s/animate-divs-forked-u2oltp

about 4 years ago · Juan Pablo Isaza Denunciar

0

Puede definir una variable de estado similar a startAnimation y configurarla como falsa de forma predeterminada.

Cuando el usuario haga clic en click it to continue , luego configúrelo en verdadero y aplique la animación en consecuencia

estado definido

 const [startAnimation, setStart] = useState(false);

Pásalo en componente

 <BigDiv activeDiv={activeDiv} startAnimation={startAnimation} onClick={(e) => { setStart(true); setDivState(!activeDiv); }} > <SecondDiv> <p>Click to animate</p> </SecondDiv> </BigDiv> </>

Úselo en un componente como este

 const BigDiv = styled("div")( ({ theme, activeDiv, startAnimation }) => css` min-width: 220px; height: 100%; position: relative; padding: ${theme.spacing(2, 0)}; border-bottom: red 4px solid; background-color: transparent; cursor: pointer; text-align: center; transition-delay: 0.5s; will-change: transform; ::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; background-color: ${activeDiv ? "red" : "transparent"}; animation: ${ startAnimation ? (activeDiv ? setColor("red") : unsetColor("red")) : "" } 0.5s ease ; transform-origin: bottom center}; } ` );
about 4 years ago · Juan Pablo Isaza Denunciar

0

La solución más fácil que se me ocurrió fue establecer el estado inicial de activeDiv en null y cambiar la regla de animación a:

 animation: ${activeDiv ? setColor("red") : unsetColor("red")} ${activeDiv === null ? "0" : "0.5s ease"} ;

Ahora no habrá ninguna animación al inicio, pero se animará si activeDiv es todo menos nulo.

Aquí está mi bifurcación: https://codesandbox.io/s/animate-divs-forked-gth814

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda