Design Smiley Face Eyes that follow Mouse Cursor using CSS and JS

Creating animated smiley faces with eyes that follow the mouse cursor is an engaging way to learn CSS pseudo-elements and JavaScript event handling. This effect combines CSS animations with JavaScript mouse tracking to create interactive cartoon faces.

How It Works

The animation works by calculating the angle between the mouse position and each eye's center. JavaScript uses Math.atan2() to determine the rotation angle, then applies a CSS transform to rotate the eyeballs toward the cursor.

HTML Structure

We create multiple face containers, each containing two eyes represented by divs:

<div class="face">
   <div class="eyes">
      <div class="eye"></div>
      <div class="eye"></div>
   </div>
</div>
<div class="face">
   <div class="eyes">
      <div class="eye"></div>
      <div class="eye"></div>
   </div>
</div>

CSS Styling

CSS creates the smiley face appearance using border-radius for circular shapes and ::before pseudo-elements for the mouth and eyeballs. The hover effect changes the mouth from a smile to a closed expression:

<style>
* {
   margin: 0;
   padding: 0;
   box-sizing: border-box;
}

body {
   display: flex;
   justify-content: center;
   align-items: center;
   min-height: 100vh;
   background: #b37208;
}

.face {
   position: relative;
   width: 310px;
   height: 310px;
   border-radius: 50%;
   background-color: #ffcd00;
   display: flex;
   justify-content: center;
   align-items: center;
   margin: 10px;
}

.face::before {
   content: "";
   position: absolute;
   top: 190px;
   width: 160px;
   height: 80px;
   background: #c810dc;
   border-bottom-left-radius: 80px;
   border-bottom-right-radius: 80px;
   transition: 0.5s;
}

.face:hover::before {
   top: 210px;
   width: 150px;
   height: 20px;
   background: #c810dc;
   border-bottom-left-radius: 0px;
   border-bottom-right-radius: 0px;
}

.eyes {
   position: relative;
   top: -40px;
   display: flex;
}

.eyes .eye {
   position: relative;
   width: 90px;
   height: 90px;
   display: block;
   background: #fff;
   margin: 0 15px;
   border-radius: 50%;
}

.eyes .eye::before {
   content: "";
   position: absolute;
   top: 50%;
   left: 30px;
   transform: translate(-50%, -50%);
   width: 50px;
   height: 50px;
   background: #333;
   border-radius: 50%;
}
</style>

JavaScript Eye Tracking

The JavaScript tracks mouse movement and calculates the rotation angle for each eyeball. The getBoundingClientRect() method gets the eye's position, and Math.atan2() calculates the angle between the mouse and eye center:

<script>
document.querySelector("body").addEventListener("mousemove", trackEyes);

function trackEyes(event) {
   const eyes = document.querySelectorAll(".eye");
   
   eyes.forEach(function(eye) {
      // Calculate eye center coordinates
      let eyeX = eye.getBoundingClientRect().left + eye.clientWidth / 2;
      let eyeY = eye.getBoundingClientRect().top + eye.clientHeight / 2;
      
      // Calculate angle between mouse and eye center
      let radian = Math.atan2(event.pageX - eyeX, event.pageY - eyeY);
      
      // Convert to degrees and apply rotation
      let rotation = radian * (180 / Math.PI) * -1 + 270;
      eye.style.transform = "rotate(" + rotation + "deg)";
   });
}
</script>

Complete Example

<!DOCTYPE html>
<html>
<head>
   <title>Smiley Face Eyes Following Mouse Cursor</title>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <style>
      * {
         margin: 0;
         padding: 0;
         box-sizing: border-box;
      }

      body {
         display: flex;
         justify-content: center;
         align-items: center;
         min-height: 100vh;
         background: #b37208;
      }

      .face {
         position: relative;
         width: 310px;
         height: 310px;
         border-radius: 50%;
         background-color: #ffcd00;
         display: flex;
         justify-content: center;
         align-items: center;
         margin: 10px;
      }

      .face::before {
         content: "";
         position: absolute;
         top: 190px;
         width: 160px;
         height: 80px;
         background: #c810dc;
         border-bottom-left-radius: 80px;
         border-bottom-right-radius: 80px;
         transition: 0.5s;
      }

      .face:hover::before {
         top: 210px;
         width: 150px;
         height: 20px;
         background: #c810dc;
         border-bottom-left-radius: 0px;
         border-bottom-right-radius: 0px;
      }

      .eyes {
         position: relative;
         top: -40px;
         display: flex;
      }

      .eyes .eye {
         position: relative;
         width: 90px;
         height: 90px;
         display: block;
         background: #fff;
         margin: 0 15px;
         border-radius: 50%;
      }

      .eyes .eye::before {
         content: "";
         position: absolute;
         top: 50%;
         left: 30px;
         transform: translate(-50%, -50%);
         width: 50px;
         height: 50px;
         background: #333;
         border-radius: 50%;
      }
   </style>
</head>
<body>
   <div class="face">
      <div class="eyes">
         <div class="eye"></div>
         <div class="eye"></div>
      </div>
   </div>
   <div class="face">
      <div class="eyes">
         <div class="eye"></div>
         <div class="eye"></div>
      </div>
   </div>
   
   <script>
      document.addEventListener("mousemove", function(event) {
         const eyes = document.querySelectorAll(".eye");
         
         eyes.forEach(function(eye) {
            let eyeX = eye.getBoundingClientRect().left + eye.clientWidth / 2;
            let eyeY = eye.getBoundingClientRect().top + eye.clientHeight / 2;
            let radian = Math.atan2(event.pageX - eyeX, event.pageY - eyeY);
            let rotation = radian * (180 / Math.PI) * -1 + 270;
            
            eye.style.transform = "rotate(" + rotation + "deg)";
         });
      });
   </script>
</body>
</html>

Key Features

The animation includes several interactive elements:

  • Eye Tracking: Eyeballs rotate to follow mouse movement
  • Hover Effect: Mouth changes from smile to closed when hovering over faces
  • Smooth Transitions: CSS transitions create smooth mouth animations
  • Multiple Faces: Each face tracks the mouse independently

Conclusion

This smiley face animation demonstrates how CSS pseudo-elements and JavaScript event handling work together to create engaging interactive effects. The combination of mouse tracking, mathematical calculations, and CSS transforms provides an excellent foundation for learning web animation techniques.

Updated on: 2026-03-15T23:19:00+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements