Supapinzi Supapinzi - 1 year ago 229
CSS Question

JavaScript blinking eye animation

I am currently trying to learn JavaScript and trying out a lot of stuff, but as for now, my JS skilly are still very limited.
I created a little game where there is a box with bunny heads which randomly appear and the user has to click them as fast as possible.

So I created the bunnies with an interval animation where the bunny closes and opens its eyes within every 2 seconds.
Now I feel kind of stupid, but i can't manage to get the animation working as I want it to. Now the bunny is just closing its eyes every 2 seconds and then opening them again every 2 seconds. However, I want it only to blink, meaning that the eyes should be closed just for an instant and then opened again, so that the bunny is blinking every 2 seconds.
And then I would also like it to randomly sometimes blink only once and sometimes blink twice.
Not sure if this is hella easy and I am just blind from hours of coding stuff and learning new things, but it seems that I might need your help here.

Here is a fiddle of the whole thing as it is right now.

You can see the complete code that was used inside the fiddle. I did not want to post the whole website here in the code section, but the parts I believe are of interest for my animation.

Here is the js code for the blinking eyes:

var eyeleft = document.getElementById("eyeleft");
var eyeright = document.getElementById("eyeright");

window.onload = setInterval(function() {
eyeleft.className = (eyeleft.className != 'closedeyeleft' ? 'closedeyeleft' : 'eyeleft');
eyeright.className = (eyeright.className != 'closedeyeright' ? 'closedeyeright' : 'eyeright');
}, 2000);

Next the HTML

<div id="shape" class="game-shapes">
<div class="ears left"></div>
<div class="ears right"></div>
<div id="eyeleft" class="eyeleft"></div>
<div id="eyeright" class="eyeright"></div>
<div id="mouth">
<div id="tooth"></div>
<div id="tongue"></div>

And now CSS

.game-shapes {
height: 80px;
width: 80px;
cursor: pointer;
opacity: 0;
position: relative;
transition: opacity ease-in-out .2s;
.game-shapes div {
position: absolute;
.eyeright {
background: #000;
border-radius: 50%;
width: 20px;
height: 20px;
top: 30px;
.eyeleft {
left: 4px;
.eyeright {
right: 4px;
.eyeright:after {
content: '';
background: #fff;
width: 7px;
height: 7px;
top: 4px;
left: 4px;
border-radius: 50%;
position: absolute;
z-index: 5;
.eyeright:after {
width: 4px;
height: 4px;
top: 10px;
left: 10px;
.closedeyeright {
background: transparent none repeat scroll 0 0;
border-color: #000;
border-radius: 5px;
border-style: solid;
border-width: 4px 4px 0;
height: 4px;
top: 35px;
width: 12px;
.closedeyeleft {
left: 3px;
.closedeyeright {
right: 3px;

Answer Source

Thanks for a well-formed question with plenty of details!

Here is a potential solution to provide both the quick blink as well as the random second blink.

//made blink a named function to improve readability a bit
var blink = function(isSecondBlink) {
  //got rid of the ternary expressions since we're always doing
  //open eyes -> close eyes -> delay -> open eyes

  //close both eyes
  eyeleft.className = "closedeyeleft";
  eyeright.className = "closedeyeright";

  //let's reopen those eyes after a brief delay to make a nice blink animation
  //as it happens, humans take ~250ms to blink, so let's use a number close to there
  setTimeout(function() {
      eyeleft.className = "eyeleft";
      eyeright.className = "eyeright";
  }, 200);

  if (isSecondBlink) { return; } //prevents us from blinking 3+ times

  //This provides a 40% chance of blinking twice, adjust as needed
  var blinkAgain = Math.random() <= 0.4;

  //if we need to blink again, go ahead and do it in 300ms
  if (blinkAgain) {
    setTimeout(function() { blink(true); }, 300);

//go ahead and blink every 2 seconds
window.onload = setInterval(blink, 2000);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download