Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different timing functions for different parts of css3 keyframe animation? (accurate bounce)

Tags:

css

animation

Is this possible? I'm trying to recreate a ball dropping onto the screen, and I have an animation like this:

@keyframes bounce {
  20%, 40%, 60%, 74%, 84%, 92%, 100% {
    transform: translate(0, 0);
  }
  0% {
    transform: translate(0, -100vh);
  }
  30% {
    transform: translate(0, -40vh);
  }
  50% {
    transform: translate(0, -20vh);
  }
  68% {
    transform: translate(0, -10vh);
  }
  80% {
    transform: translate(0, -5vh);
  }
  88% {
    transform: translate(0, -2vh);
  }
  96% {
    transform: translate(0, -1vh);
  }
}

and this, when implemented like this:

.ball {
  animation: bounce 3s cubic-bezier(0.895, 0.03, 0.685, 0.22) 0s 1 normal forwards;
}

produces something that looks like this:

bounce!

This is.. okay, but not ideal. I'd prefer to do something like:

actual bounce

But in order to do this I need to have a different timing function for the initial 0-> 20% compared to the rest of them. Is there a way to do different timing functions for different parts of a keyframe animation? Or perhaps a different way to get an accurate bouncing animation that I'm not thinking of? Any help would be appreciated!

edit: added a fiddle here.

like image 854
shan Avatar asked Mar 11 '23 19:03

shan


1 Answers

Rather than specifying a timing function for the entire animation, you can specify for each key frame. The function represents how the the values are interpolated from the beginning to end of the respective key frame.

Here's an example by adding an ease function to the keyframes 20%, 40%, 60%, 74%, 84%, 92%, 100%.

@keyframes bounce {
  20%, 40%, 60%, 74%, 84%, 92%, 100% {
    transform: translate(0, 0);
    animation-timing-function: ease;
  }
  0% {
    transform: translate(0, -100vh);
  }
  30% {
    transform: translate(0, -40vh);
  }
  50% {
    transform: translate(0, -20vh);
  }
  68% {
    transform: translate(0, -10vh);
  }
  80% {
    transform: translate(0, -5vh);
  }
  88% {
    transform: translate(0, -2vh);
  }
  96% {
    transform: translate(0, -1vh);
  }
}

.ball {
  background: #ff0000;
  border-radius: 50%;
  position: absolute;
  top: 500px;
  width: 50px;
  height: 50px;
  animation: bounce 3s cubic-bezier(0.895, 0.03, 0.685, 0.22) 0s 1 normal forwards;
}
<div class="ball"> </div>
like image 90
Austin Brunkhorst Avatar answered Apr 14 '23 05:04

Austin Brunkhorst