frame animation

by lemon kazi

HTML

<img class="eye-animation eye-animation-1" 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-2" 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-3" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Eye-18.svg" alt="blinking eye animation"/>

SCSS

.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%);
}

Babel + JSX

const totalFrames = 3;
const animationDuration = 1000;
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);
});