Eyeball

by Douglas Ludlow

HTML

<div class="pagecontent">
    <div class='eye circle'>
        <div class='container circle'>
            <div class='sclera circle center'>
                <div class='iris circle center'>
                    <div class='pupil circle center'></div>
                </div>
            </div>
        </div>
        <div class='highlight circle'></div>
    </div>
</div>

CSS

.pagecontent {
    padding: 30px;
}

html, body {
  background: grey;
  text-align: center;
}

@-webkit-keyframes blink {
  0% {
    height: 80%;
  }

  50% {
    height: 0%;
    top: 50%;
  }

  100% {
    height: 80%;
  }
 }

.circle {
  border-radius: 100%;
  position: relative;
  overflow: hidden;
}

.center {
  position: absolute;
  left: 50%;
  top: 50%;
}

.eye {
  box-shadow: 0 20px 0 rgba(0,0,0,0.05);
  text-align: center;
  background: grey;
  display: inline-block;
  position: absolute;
  margin-left: -100px;
  margin-top: -120px;
  height: 200px;
  width: 200px;
  left: 50%;
  top: 50%;
  transition: background-color .5s;
}

.eye:hover {
    background: #f00;
}

.eye .highlight {
  box-shadow: inset 15px 60px rgba(255, 255, 255, 0.1);
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  transition: background-color 1s;
}

.eye:hover .highlight {
    background: rgba(200, 0, 0, .15);
}

.eye .container {
  position: absolute;
  height: 80%;
  width: 99%;
  top: 10%;
}
.eye .sclera {
    background: black;
    height: 100%;
    width: 100%;
    transition: background-color .5s;
}

.eye:hover .sclera {
    background: #aaa;
}

.eye .sclera .iris {
  background: red;
  height: 100px;
  width: 100px;
  transition: background-color .5s;
}

.eye:hover .sclera .iris {
  background: #0f0;
}

.eye .sclera .iris .pupil {
  background: black;
  height: 50%;
  width: 50%;
}

JavaScript

var centered = document.getElementsByClassName( 'center' );
var eyes = document.getElementsByClassName( 'eye' );
var eyeRadius = 100;
var mouseX = 0.0;
var mouseY = 0.0;

// Returns the pixel value of a number, e.g '42px'
function toPixels( number ) {
    return Math.round( number ) + 'px';
}

// Applies the CSS3 blink animation to the eyes
function blink() {
    
    for ( var i = 0; i < eyes.length; i++ ) {
        
        var eye = eyes[i];
        var container = eye.getElementsByClassName( 'container' )[0];
        container.style.webkitAnimation = '';
        
        // Since the animation property was already present on the element,
        // we need to wait until the next frame to add it back so that it
        // registers as a change
        setTimeout( function() {
            container.style.webkitAnimation = 'blink 500ms ease-in-out';
        }, 0);
    }
    
    //setTimeout( blink, 4000 + Math.random() * 5000 );
}

function updateEyes() {
    
    for ( var i = 0; i < eyes.length; i++ ) {
        
        var eye = eyes[i];
        var eyeBounds = eye.getBoundingClientRect();
        
        // Find the angle from the mouse to the center of the eye...
        
        // Then subract the eye center from them
        var deltaX = mouseX - eyeBounds.left - eyeRadius;
        var deltaY = mouseY - eyeBounds.top - eyeRadius;
        
        // Now find the angle
        var angle = Math.atan2( deltaY, deltaX );
        
        // Compute the distance using Pythagorean theorem: a^2 + b^2 = c^2
        var distance = Math.sqrt( deltaX * deltaX + deltaY * deltaY );
        
        // Limit the distance to the radius of the eye
        var offset = Math.min( distance, eyeRadius * 0.6 );
        
        // Now position the iris
        var xPos = Math.cos( angle ) * offset;
        var yPos = Math.sin( angle ) * offset;
        
        // Move the iris
        var iris = eye.getElementsByClassName( 'iris' )[0];
        iris.style.left = toPixels(...