Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

220
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!