Create fun and interactive Googly Eyes that follow your mouse using just HTML, CSS, and JavaScript! 🐭👀
In this tutorial, you’ll learn how to:
- Design cute eyes with HTML & CSS
- Track mouse movement with JavaScript
- Animate pupil movement dynamically
Perfect for beginners who want to add a playful UI touch to their websites or learn more about DOM interaction.
💻 Source code included in the video!
🧠 Great for creative portfolios, Halloween effects, or quirky designs.
❤️🔥 Don’t forget to 👍 like, 🔁 share, and 🔔 subscribe for more fun frontend projects!
▶️ YouTube: 📺
HTML:
Create an HTML file and add the following code:
<svg id="eyes" width="128" height="128" viewBox="0 0 128 128">
<defs>
<linearGradient id="a" x1="0" x2="0" y1="46.676" y2="82.083" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#424242"/>
<stop offset="1" style="stop-color:#212121"/>
</linearGradient>
<g id="eye-shape">
<path style="fill:#fafafa" d="M34.16 106.51C18.73 106.51 6.19 87.44 6.19 64s12.55-42.51 27.97-42.51S62.13 40.56 62.13 64s-12.55 42.51-27.97 42.51"/>
<path style="fill:#b0bec5" d="M34.16 23.49c6.63 0 12.98 4 17.87 11.27 5.22 7.75 8.1 18.14 8.1 29.24s-2.88 21.49-8.1 29.24c-4.89 7.27-11.24 11.27-17.87 11.27s-12.98-4-17.87-11.27C11.06 85.49 8.19 75.1 8.19 64s2.88-21.49 8.1-29.24c4.89-7.27 11.23-11.27 17.87-11.27m0-4C17.61 19.49 4.19 39.42 4.19 64s13.42 44.51 29.97 44.51S64.13 88.58 64.13 64 50.71 19.49 34.16 19.49"/>
</g>
<path id="pupil-shape" style="fill:url(#a)" d="M25.63 59.84c-2.7-2.54-2.1-7.58 1.36-11.26.18-.19.36-.37.55-.54-1.54-.87-3.23-1.36-5.01-1.36-7.19 0-13.02 7.93-13.02 17.7s5.83 17.7 13.02 17.7 13.02-7.93 13.02-17.7c0-1.75-.19-3.45-.54-5.05-3.24 2.33-7.11 2.64-9.38.51"/>
</defs>
<use href="#eye-shape" id="eye-left"/>
<use href="#pupil-shape" id="pupil-left"/>
<g transform="translate(59.68 0)">
<use href="#eye-shape" id="eye-right" />
<use href="#pupil-shape" id="pupil-right"/>
</g>
</svg>
CSS:
Create a CSS file and add the following code:
#eyes {
--size: clamp(64px, 30vi, 256px);
block-size: var(--size);
inline-size: var(--size);
}
body {
background: #f5deb3;
block-size: 100vb;
display: grid;
grid-template-rows: 2fr 1fr;
place-items: center;
text-align: center;
}
a {
font-family: sans-serif;
font-size: 2rem;
color: #333;
}
JavaScript:
Create a JavaScript file and add the following code:
const eyesSVG = document.querySelector('#eyes');
const eyes = [
{
eye: eyesSVG.querySelector('#eye-left'),
offsetX: 0,
pupil: eyesSVG.querySelector('#pupil-left')
},
{
eye: eyesSVG.querySelector('#eye-right'),
offsetX: 0,
pupil: eyesSVG.querySelector('#pupil-right')
}
];
const updateEye = (ev, {eye, pupil, offsetX}) => {
const eyeRect = eye.getBoundingClientRect();
const centerX = eyeRect.left + eyeRect.width / 2;
const centerY = eyeRect.top + eyeRect.height / 2;
const distX = ev.clientX - centerX;
const distY = ev.clientY - centerY;
const pupilRect = pupil.getBoundingClientRect();
const maxDistX = pupilRect.width / 2;
const maxDistY = pupilRect.height / 2;
const angle = Math.atan2(distY, distX);
const newPupilX = offsetX + Math.min(maxDistX, Math.max(-maxDistX, Math.cos(angle) * maxDistX));
const newPupilY = Math.min(maxDistY, Math.max(-maxDistY, Math.sin(angle) * maxDistY));
const svgCTM = eyesSVG.getScreenCTM();
const scaledPupilX = newPupilX / svgCTM.a;
const scaledPupilY = newPupilY / svgCTM.d;
pupil.setAttribute('transform', `translate(${scaledPupilX}, ${scaledPupilY})`);
}
// Pupil position starts off-centre on the X axis
const calcOffset = () => {
for (const props of eyes) {
props.pupil.removeAttribute('transform');
const eyeRect = props.eye.getBoundingClientRect();
const pupilRect = props.pupil.getBoundingClientRect();
props.offsetX = ((eyeRect.right - pupilRect.right) - (pupilRect.left - eyeRect.left)) / 2;
}
}
calcOffset();
globalThis.addEventListener('resize', () => {
calcOffset();
});
let frame = 0;
globalThis.addEventListener('mousemove', (ev) => {
cancelAnimationFrame(frame);
frame = requestAnimationFrame(() => {
for (const eye of eyes) {
updateEye(ev, eye);
}
});
});
Happy coding!
GooglyEyes #JavaScriptFun #MouseTracking #CSSAnimation #WebDevelopment #FrontendProject #LearnJavaScript #HTMLCSSJS #CreativeCoding #MiniProject