Search code examples
htmlcsssasskeyframe

Circles "waves" animations with CSS keyframes


I'm trying to animate circles to achieve an infinite effect of colliding waves.

I laid the base but I can't make the order of the animations smooth and linear.

Codepen available here.

<div class="circles-container"
    <!-- 1er circle -->
    <svg width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" style="z-index: 1;">
      <path class="circle-1" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
    </svg>
    <!-- 2eme circle -->
    <svg width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" style="z-index: 2;">
      <path class="circle-2" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
    </svg>
    <!-- 3eme circle -->
    <svg width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" style="z-index: 3;">
      <path class="circle-3" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
    </svg>
</div>


.circles-container { position: relative; }

.circles-container svg {
  position: absolute;
  top: 0;
  left: 0;
}

.circle-1 {
  animation: scaleCircle 7.5s ease-in-out infinite;
  transform: scale(0);
  transition: all 2s ease-in-out;
  color: #1D1D28;
}

.circle-2 {
  animation: scaleCircle 5s ease-in-out infinite 2.5s;
  transform: scale(0);
  transition: all 2s ease-in-out;
  color: #420DC4;
}

.circle-3 {
  animation: scaleCircle 5s ease-in-out infinite;
  transform: scale(0);
  transition: all 2s ease-in-out;
  color: #1D1D28;
}

@keyframes scaleCircle {
  0% {
    transform: scale(0);
  }

  100% {
    transform: scale(2);
  }
}

Here is the scenario:

When loading, a first blue circle is displayed.

  1. A first black circle grows until it crushes the blue circle
  2. at 50% of step's 1 animation, a new blue circle is displayed and enlarged until it overwrites the black circle created during step 1
  3. back to step 1

In my render, you can see that the circles are showing but some are hiding too soon, etc. The circles should display one after the other in a linear fashion.

Is it possible to do this in full CSS with keyframes ?


Solution

  • Not sure if this is exactly what you are going for but maybe you can tinker with it.

    So with 4 circles you can animate the scale basically the way you have it. And then for their svg container, you animate the z-index so whenever a wave starts it gets its highest z-index and then it deceases before the next wave starts.

    <div class="circles-container">
      
      <!-- 1er cercle -->
      <svg class="circle-parent-1" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg">
        <path class="circle-1" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
      </svg>
    
      <!-- 2eme cercle -->
      <svg  class="circle-parent-2" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" >
        <path class="circle-2" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
      </svg>
      
      <svg  class="circle-parent-3" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" >
        <path class="circle-3" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
      </svg>
      
    
      <svg  class="circle-parent-4" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" >
        <path class="circle-4" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
      </svg>
      
    body {
      margin: 0;
      padding: 0;
    }
    
    .circles-container { position: relative; }
    
    .circles-container svg {
      position: absolute;
      top: 0;
      left: 0;
    }
    
    .circle-parent-1 {
      animation: zIndexCircle 8s ease-in-out infinite;
      animation-delay: 0s;
    }
    
    .circle-parent-2 {
      animation: zIndexCircle 8s ease-in-out infinite;
      animation-delay: 2s;
    }
    
    .circle-parent-3 {
      animation: zIndexCircle 8s ease-in-out infinite;
      animation-delay: 4s;
    }
    
    .circle-parent-3 {
      animation: zIndexCircle 8s ease-in-out infinite;
      animation-delay: 4s;
    }
    .circle-parent-4 {
      animation: zIndexCircle 8s ease-in-out infinite;
      animation-delay: 6s;
    }
    
    
    .circle-1 {
      animation: scaleCircle 8s ease-in-out infinite;
      animation-delay:0s;
      transform: scale(0);
      color: #1D1D28;
    }
    
    .circle-2 {
      animation: scaleCircle 8s ease-in-out infinite;
      animation-delay:2s;
      transform: scale(0);
      color: #420DC4;
    }
    
    .circle-3 {
      animation: scaleCircle 8s ease-in-out infinite;
      animation-delay:4s;
      transform: scale(0);
      color: #1D1D28;
    }
    
    .circle-4 {
      animation: scaleCircle 8s ease-in-out infinite;
      animation-delay:6s;
      transform: scale(0);
      color: #420DC4;
    }
    
    @keyframes zIndexCircle {
        0% {
        z-index:5;
      }
      25% {
        z-index: 4;
      }
      50% {
        z-index:3;
      }
      75% {
        z-index:2;
      }
      
      100% {
        z-index:1;
      }
    }
    @keyframes scaleCircle {
      0% {
        transform: scale(0);
      }
      75% {
         transform: scale(2);
      } 
      100% {
        transform: scale(2);
      }
    }
    

    https://codepen.io/todilo-the-vuer/pen/XWEmdXL