Skip to content

June 10, 2017

Adding Infinite Loop to the Cool CSS Smiley Animation

by Joe Kuan

There is a very cool pure CSS smiley animation created by Tiago Alexandre Lopes. The animation begins as soon as one of the smiley radio buttons is checked. However, the nice animation doesn’t repeat. It would be nice to have the animation repeated every 5 seconds.

TL;DR Here is the demo.

I know very little of CSS. After reading some tutorial on CSS animation, here is how I do it.

Before we convert the smiley animation into infinite loop, we first need to understand the CSS animation construct. Below is part of the animation definitions of the happy face.

.smiley.happy .eye:nth-of-type(2),
#happy[type=radio]:checked ~ .smiley .eye:nth-of-type(2) {
  height: 20px;
  margin-top: 0;
  animation: wink .8s;
  animation-delay: .3s;
}

@keyframes wink {
  0% {
   height: 20px;
    margin-top: 0;
  }
  30% {
    height: 3px;
    margin-top: 8px;
  }
  70% {
    height: 3px;
    margin-top: 8px;
  }
  100% {
    height: 20px;
    margin-top: 0;
  }
}

Basically, the above code means that when the happy radio button is checked, animation ‘wink’ is performed on the 2nd eye of the face. The animation wink will last 0.8 second and the animation will start in 0.3 second after the radio button is checked. The keyframes keyword defines the frame details of wink animation. The percentage represent the timing portion within the whole 0.8 second animation.

For changing the animation into infinite loop, we add animation-iteration-count into the animation configuration as follows:

  ...
  animation: wink .8s;
  animation-delay: .3s;
  animation-iteration-count: infinite;
}

Since the whole animation only last 1.1 seconds (0.8s + 0.3s), by repeating the animation indefinitely will loop the whole animation sequence too fast and the smiley face will look like suffering from an electric shock. To maintain the smooth animation and space between 5 seconds interval, we need to include the 5 seconds delay as a whole animation sequence.

We set the animation-delay as the amount of delay between each sequence. For the sake of simplicity, we round the original animation to 1 second. Hence the whole new animation will last 6 seconds. Here are the new configurations:

.smiley.happy .eye:nth-of-type(2),
#happy[type=radio]:checked ~ .smiley .eye:nth-of-type(2) {
  height: 20px;
  margin-top: 0;
  animation: wink 6s;
  animation-delay: 5s;
  animation-iteration-count: infinite;
}

As for maintaining the animation sequence, we copy the last frame and append it to the end. The percentage gap between the last and the new frames should be proportional to the 5 seconds delay. So the new percentage for the whole animation excluding the 5 seconds delay is – (0.8 / 6) * 100% ≈ 13%. Then based on the original proportion of the frames, we can recalculate for each frame section as 13% * 0.3 ≈ 3.9 and 13% * 0.7 ≈ 9.1%. Here is the new configuration for keyframes:

@keyframes wink
{
  0%
  {
   height: 20px;
    margin-top: 0;
  }
  3.9% {
    height: 3px;
    margin-top: 8px;
  }
  9.1% {
    height: 3px;
    margin-top: 8px;
  }
  13% {
    height: 20px;
    margin-top: 0;
  }
  /* 5 seconds delay gap */
  100% {
    height: 20px;
    margin-top: 0;
  }
}

Repeats the same operation to the rest of animation definitions and we get a continuous lively smiley face.

The downside of this change is that the very first animation doesn’t appear until the 5 seconds delay after clicking the radio button.

Advertisements
Read more from CSS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: