Bird Cursor Game
Bird Cursor Game is a fun interactive animation where a small animated bird follows the user’s mouse cursor across the screen. As the cursor moves, the bird smoothly flies toward it while flapping its wings, creating a playful and dynamic visual experience.
This project is built using HTML, CSS, and JavaScript, making it a great beginner-friendly project for learning web animations, event handling, and interactive UI design.
🎮 What is the Bird Cursor Game?
The Bird Cursor Game is a simple interactive web animation where a bird character behaves like a virtual pet that follows the user’s cursor. When the mouse moves, the bird flies toward it with smooth motion and animated wings.
Unlike traditional games with levels or scores, this project focuses on interactive motion and visual engagement.
This type of animation can be used in:
• Coding blogs
• Educational websites
• Portfolio websites
• Kids learning platforms
• Fun landing pages
The main goal is to create a natural flying effect that reacts to the user’s movements and makes the website feel more interactive.
🧩 Technologies Used
1️⃣ HTML – Structure of the Bird
HTML provides the basic structure of the animation. The bird itself is created using SVG graphics, which allows the shapes to remain sharp and scalable on any screen size.
The bird design typically consists of:
• A body
• Two wings
• Eyes and a beak
• Decorative highlights
SVG graphics are ideal for this type of project because they are lightweight, scalable, and easy to animate using CSS or JavaScript.
2️⃣ CSS – Styling and Wing Animation
CSS controls the appearance and animation of the bird, making it look more lively and interactive.
Positioning
The bird is placed using position: fixed, which allows it to move freely across the entire screen without being affected by scrolling.
Wing Animation
The wings flap using CSS keyframe animations, giving the bird a natural flying effect.
Shadow Effects
A subtle drop shadow is added to the bird so it appears slightly lifted from the page, creating a more visually appealing animation.
These CSS effects together make the bird feel alive and responsive.
🖱️ JavaScript – Making the Bird Follow the Cursor
JavaScript controls the interactive behavior of the bird and ensures it reacts to the user’s cursor movements.
Cursor Tracking
The browser continuously tracks the mouse position using the pointermove event. Whenever the user moves the cursor, the X and Y coordinates are updated.
Smooth Movement
Instead of jumping directly to the cursor, the bird follows it using a smooth easing motion. This creates a more natural flying effect where the bird gradually approaches the cursor.
Direction Rotation
To enhance realism, the bird slightly rotates in the direction it is moving. This is calculated using basic mathematical functions so that the bird always faces the direction of flight.
✨ Features of the Bird Cursor Game
✔ Bird smoothly follows the cursor
✔ Wings continuously flap during flight
✔ The bird rotates toward the direction of movement
✔ Works on both mouse and touch devices
✔ Lightweight and fast animation
✔ Built entirely using front-end technologies
Since this project does not require external libraries, it can easily be integrated into almost any website.
🚀 Learning Benefits
Building this project helps beginners understand several important web development concepts, including:
• DOM manipulation
• JavaScript event listeners
• CSS animations
• Mouse position tracking
• Smooth motion effects
• Basic game-style interactivity
These concepts are widely used in modern web interfaces, interactive websites, and browser-based games.
💻 Complete Code – Copy and Try It Yourself
You can copy the complete code below and paste it into an index.html file to run the Bird Cursor Game on your computer or website.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Cursor Bird</title>
<style>
html, body {
height: 100%;
margin: 0;
overflow: hidden;
background: radial-gradient(1200px 800px at 70% 20%, #e6f6ff 0%, #cfeeff 40%);
}
.bird {
position: fixed;
left: 0;
top: 0;
width: 64px;
height: 64px;
transform: translate(-50%, -50%);
transform-origin: 50% 50%;
will-change: transform;
filter: drop-shadow(0 6px 10px rgba(0,0,0,0.15));
pointer-events: none;
z-index: 10;
}
.bird-svg, .wing { position: absolute; }
.wing {
width: 32px;
height: 20px;
left: 6px;
top: 18px;
transform-origin: right center;
animation: flap 0.35s ease-in-out infinite;
opacity: 0.95;
}
.wing.right {
left: auto;
right: 6px;
transform-origin: left center;
animation-delay: 0.05s;
}
@keyframes flap {
0%, 100% { transform: rotate(6deg) translateY(0); }
50% { transform: rotate(-18deg) translateY(1px); }
}
</style>
</head>
<body>
<div class="bird" id="bird">
<svg class="wing left" viewBox="0 0 32 20">
<path d="M1,10 C8,1 20,1 31,10 C20,13 8,18 1,10 Z"
fill="#ffd37a" stroke="#d39e3a" stroke-width="1"/>
</svg>
<svg class="wing right" viewBox="0 0 32 20">
<path d="M1,10 C8,1 20,1 31,10 C20,13 8,18 1,10 Z"
fill="#ffd37a" stroke="#d39e3a" stroke-width="1"/>
</svg>
<svg class="bird-svg" viewBox="0 0 64 64" width="64" height="64">
<ellipse cx="32" cy="34" rx="20" ry="16" fill="#ffcc66" stroke="#c7932a" stroke-width="2"/>
<circle cx="44" cy="24" r="10" fill="#ffcc66" stroke="#c7932a" stroke-width="2"/>
<circle cx="47" cy="22" r="2.6" fill="#1e293b"/>
<circle cx="46.2" cy="21.2" r="0.8" fill="#fff"/>
<polygon points="54,24 46,28 46,20" fill="#ff9c2b" stroke="#c57915" stroke-width="1"/>
<path d="M14,34 L6,30 L8,38 Z" fill="#e6a848" stroke="#b07a24" stroke-width="1"/>
<ellipse cx="28" cy="38" rx="10" ry="8" fill="rgba(255,255,255,0.35)"/>
</svg>
</div>
<script>
(function () {
const bird = document.getElementById('bird');
const half = 32;
const ease = 0.06;
const snapDist = 0.75;
let targetX = innerWidth / 2;
let targetY = innerHeight / 2;
let x = targetX;
let y = targetY;
let lastX = x;
let lastY = y;
addEventListener('pointermove', (e) => {
targetX = e.clientX;
targetY = e.clientY;
}, { passive: true });
function clamp(nx, ny) {
const minX = half;
const minY = half;
const maxX = innerWidth - half;
const maxY = innerHeight - half;
nx = Math.max(minX, Math.min(maxX, nx));
ny = Math.max(minY, Math.min(maxY, ny));
return { nx, ny };
}
function tick() {
let nx = x + (targetX - x) * ease;
let ny = y + (targetY - y) * ease;
const dx = targetX - nx;
const dy = targetY - ny;
if ((dx*dx + dy*dy) <= snapDist * snapDist) {
nx = targetX;
ny = targetY;
}
({ nx, ny } = clamp(nx, ny));
const angle =
Math.atan2(ny - lastY, nx - lastX) * 180 / Math.PI;
bird.style.transform =
`translate(${nx - half}px, ${ny - half}px) rotate(${angle}deg)`;
lastX = x;
lastY = y;
x = nx;
y = ny;
requestAnimationFrame(tick);
}
bird.style.transform =
`translate(${x - half}px, ${y - half}px)`;
requestAnimationFrame(tick);
})();
</script>
</body>
</html>
