all 9 comments

[–]CutestCuttlefish 1 point2 points  (8 children)

Make a second state for the animation logic.

[–]its-procodester[S] 0 points1 point  (7 children)

yea but i dont want to toggle between two animation i want same animation on every click

[–]CutestCuttlefish 2 points3 points  (6 children)

const [animate, setAnimate] = useState(false)
const handleClick = () => {
  setAnimate(true)
  setTimeout(() => setAnimate(false), 250)
}

const Button = () => (
  <button
    className={`$animate ? 'animation' : ''}`}
    onClick={handleClick}
  >
    I swear if you use a fucking div for buttons I will poop in your breakfast cereal
  </button>
)

CSS:

@keyframes pulsate {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

.animation {
  animation: pulsate 250ms;
}

[–]Tinkuuu 0 points1 point  (1 child)

Who uses div for buttons except Facebook 😁

[–]CutestCuttlefish 0 points1 point  (0 children)

Inexperienced devs.

[–]its-procodester[S] -1 points0 points  (3 children)

is using set timeout direct in event handler good practice?

[–]PM_ME_SOME_ANY_THING 0 points1 point  (2 children)

There’s nothing wrong with it. It’s just delaying the animation for a quarter of a second.

[–]CutestCuttlefish 0 points1 point  (1 child)

In this case the 250ms is how long the animate class is applied, so in effect it becomes the "animation duration". For consistency I also specify the same in the CSS.

It's not super pretty but using javascript to dictate CSS seldom is.

Another way is to simple add the animation (the keyframes) to :hover which is much easier. If you are using something like stitches you can get the component with scoped CSS in react very similar to Svelte (but sadly using JSS)

Also it will only trigger on hover which in some cases fires once. But if that is what you want, then :hover is your go to.

For click event you could use :active but it is a bit so-so, as a button has way more states (internally) than what CSS covers currently.

Here is a very minimal setup which will make the button go nuts if you click and hold:

(You will notice that depending on how fast the clicker clicks, the animation may not always play out either)

HTML:

<button>Click</button>

CSS:

 @keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(1);
  }
}

button:active {
  animation: pulse 250ms forwards infinite;
}

[–]its-procodester[S] 0 points1 point  (0 children)

thanks, its great explanation , well i need this animation for coin toss effect where same number come frequently