<div id="container">
  <svg class="shape" id="circle">
    <circle cx="75" cy="75" r="60" class="shape-inner">
      <animateTransform attributeName="transform"
                        begin="0s"
                        dur="4s"
                        type="rotate"
                        from="0 90 90"
                        to="360 90 90"
                        repeatCount="indefinite"
                        />
    </circle>
  </svg>

  <svg class="shape" id="square">
    <rect x="35" y="35" width="120" height="120"
          class="shape-inner">
      <animateTransform attributeName="transform"
                        begin="0s"
                        dur="4s"
                        type="rotate"
                        from="0 95 95"
                        to="360 95 95"
                        repeatCount="indefinite"
                        />
    </rect>
  </svg>

  <svg class="shape" id="triangle">
    <polygon points="85 10, 160 140, 10 140" class="shape-inner">
      <animateTransform attributeName="transform"
                        begin="0s"
                        dur="4s"
                        type="rotate"
                        from="0 100 100"
                        to="360 100 100"
                        repeatCount="indefinite"
                        />    
    </polygon>
  </svg>

  <svg class="shape" id="pentagon">
    <polygon class="shape-inner" style="stroke: rgb(0, 0, 0); fill: none; stroke-width: 3px;" points="10.98 59.371 76.741 10.205 141.97 59.371 116.944 137.114 36.184 136.669">
      <animateTransform attributeName="transform"
                        begin="0s"
                        dur="4s"
                        type="rotate"
                        from="0 90 90"
                        to="360 90 90"
                        repeatCount="indefinite"
                        /> 
    </polygon>
  </svg>
</div>
body {
  margin: 0;
}

#container {
  width: 100vw;
  max-width: 100vw;
  height: 200px;
  max-height: 200px;
  overflow: hidden;
  border-bottom: 1px solid black;
  position: absolute;
  background: #a1c1b5;
}

.shape {
  position: absolute;
  left: 0px;
  top: 0px;
  height: 200px;
  width: 200px;
  fill: transparent;
}

.shape-inner {
  fill: transparent;
  stroke: black;
  stroke-width: 3;
  opacity: 0.25
}
function App() {
  var container = document.getElementById('container');
  
  // get the shape elements
  var circle = document.getElementById('circle');
  var square = document.getElementById('square');
  var triangle = document.getElementById('triangle');
  var pentagon = document.getElementById('pentagon');

  // animate function
  function animate(elem, startX, startY, bounce, duration) {
    
    // set and store the start positions (they'll need to be the same for the end position too)
    let posStartX;
    if (startX === 'left') {
      posStartX = 0;
    } else {
      posStartX = 100;
    }
    
    // posX is the X position variable we'll update
    let posX = startX;
    
    // array for storing the keyframes
    let keyframes = [];
    
    // we're going to push a transform into the keyframes array for each bounce
    for (let i = 1; i <= bounce; i++) {
      let translateX;
      let translateY;
      if (i === 1 || i === bounce) {
        // if we're on the right side we need to do an additional translate to account for the size of the shape div
        translateX = startX === 'right' ? `translateX(${posStartX}vw) translateX(-180px)` : `translateX(${posStartX}vw)`;
        translateY = `translateY(${startY}px)`;
      } else {
        // if we're on the right side we need to do an additional translate to account for the size of the shape div
        translateX = posX === 'right' ? `translateX(100vw) translateX(-180px)` : `translateX(0vw)`;
        // for randomly picking Y, we want to translate up or down so pick randomly from '-' or '' first, then pick the pixels randomly
        translateY = `translateY(${['-', ''][Math.floor(Math.random() * 2)]}${Math.floor(Math.random() * 200)}px)`;
      }
      
      // store the transformation
      let transform = `${translateX} ${translateY}`;
      keyframes.push({transform: transform});
      
      // change the X position
      posX = posX === 'right' ? 'left' : 'right';
    }
    var options = {
        duration: duration,
        iterations: Infinity
      };
    elem.animate(keyframes, options);
  };
  
  // animate!
  animate(circle, 'left', 12, 5, 36000);
  animate(square, 'left', 60, 7, 37000);
  animate(triangle, 'right', 27, 5, 38000);
  animate(pentagon, 'right', 99, 7, 39000);
}

App();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.