Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS/SVG Animation Effect - Three Bouncing Squares - Correct Timing

Tags:

css

svg

I'm essentially trying to recreate the timing of these jumping circles:

https://dribbble.com/shots/2991038-Typing-Status

All three circles are jumping at the same speed, but the first circle does not begin again until the third circle lands. For the life of me, I cannot correctly delay each circle to get the timing right. I have it to where the second circle jumps when the first one is half way through a jump, but I cannot get it to where the first one begins after the third one lands. Perhaps my easing needs to be adjusted as well as timing?

Source: https://jsfiddle.net/88ybodjk/

@keyframes jump {
  0% {
    transform: translateY(0px);
  }
  33% {
    transform: translateY(-12px);
  }
  100% {
    transform: translateY(0px);
  }
}

.square-1 {
  animation: jump 2s ease infinite;
}

.square-2 {
  animation: jump 2s .6s ease infinite;
}

.square-3 {
  animation: jump 2s 1.2s ease infinite;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 190 50" style="padding-top: 100px;">
      <rect class="square-1" x="0" width="50" height="50" style="fill:tomato"/>
    
      <rect class="square-2" x="60" width="50" height="50" style="fill:tomato"/>
      
      <rect class="square-3" x="120" width="50" height="50" style="fill:tomato"/>
    
    </svg>
like image 984
Tim Avatar asked Feb 16 '26 05:02

Tim


1 Answers

Let's say that you want only a circle "in the air" at the same time.

Then, the key frames with a transition applied must cover only 33%.

This gives :

@keyframes jump {
  0% {
    transform: translateY(0px);
  }
  16.5% {
    transform: translateY(-12px);
  }
  33%, 100% {
    transform: translateY(0px);
  }
}

.square-1 {
  animation: jump 2s ease infinite;
}

.square-2 {
  animation: jump 2s .6s ease infinite;
}

.square-3 {
  animation: jump 2s 1.2s ease infinite;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 190 50" style="padding-top: 100px;">
      <rect class="square-1" x="0" width="50" height="50" style="fill:tomato"/>
    
      <rect class="square-2" x="60" width="50" height="50" style="fill:tomato"/>
      
      <rect class="square-3" x="120" width="50" height="50" style="fill:tomato"/>
    
    </svg>

However, due to the easing, this doesn't gives the correct illusion.

May be better would be to increase a little the duration of the transitioned part

@keyframes jump {
  0% {
    transform: translateY(0px);
  }
  25% {
    transform: translateY(-12px);
  }
  50%, 100% {
    transform: translateY(0px);
  }
}

.square-1 {
  animation: jump 2s ease infinite;
}

.square-2 {
  animation: jump 2s .6s ease infinite;
}

.square-3 {
  animation: jump 2s 1.2s ease infinite;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 190 50" style="padding-top: 100px;">
      <rect class="square-1" x="0" width="50" height="50" style="fill:tomato"/>
    
      <rect class="square-2" x="60" width="50" height="50" style="fill:tomato"/>
      
      <rect class="square-3" x="120" width="50" height="50" style="fill:tomato"/>
    
    </svg>
like image 93
vals Avatar answered Feb 17 '26 22:02

vals