<!-- image containers -->
<h2 class="animation-title">Frame by Frame Animation #2: Opacity (JavaScript)</h2>
<img class="eye-animation eye-animation-1" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-1.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-2" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-2.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-3" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-3.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-4" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-4.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-5" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-5.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-6" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-6.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-7" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-7.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-8" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-8.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-9" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-9.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-10" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-10.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-11" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-11.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-12" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-12.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-13" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-13.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-14" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-14.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-15" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-15.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-16" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-16.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-17" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-17.svg" alt="blinking eye animation"/>
<img class="eye-animation eye-animation-18" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-18.svg" alt="blinking eye animation"/>
.animation-title {
  font-family: sans-serif;
  text-align: center;
}

// image containers
.eye-animation {
  width: 300px;
  
  // we stack all image containers one above another 
  position: absolute;
  opacity: 0;
  
  // and place them in the middle of the screen
  left: 50%;
  transform: translateX(-50%);
}
View Compiled
const totalFrames = 18;
const animationDuration = 1300;
const timePerFrame = animationDuration / totalFrames;
let timeWhenLastUpdate;
let timeFromLastUpdate;
let frameNumber = 1;

// 'step' function will be called each time browser rerender the content
// we achieve that by passing 'step' as a parameter to 'requestAnimationFrame' function
function step(startTime) {
  // 'startTime' is provided by requestAnimationName function, and we can consider it as current time
  // first of all we calculate how much time has passed from the last time when frame was update
  if (!timeWhenLastUpdate) timeWhenLastUpdate = startTime;
  timeFromLastUpdate = startTime - timeWhenLastUpdate;

  // then we check if it is time to update the frame
  if (timeFromLastUpdate > timePerFrame) {
    // hide all frames
    $('.eye-animation').css('opacity', 0);
    // and show the required one
    $(`.eye-animation-${frameNumber}`).css('opacity', 1);
    // reset the last update time
    timeWhenLastUpdate = startTime;

    // then increase the frame number or reset it if it is the last frame
    if (frameNumber >= totalFrames) {
      frameNumber = 1;
    } else {
      frameNumber = frameNumber + 1;
    }        
  }

  requestAnimationFrame(step);
}

// wait for images to be downloaded and start the animation
$(window).on('load', () => {
  requestAnimationFrame(step);
});
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js