🌟 Starfield Zoom Flythrough Tutorial

Learn to create a classic 3D starfield effect using HTML5 Canvas

Step 1: Understanding the Concept

A starfield effect simulates flying through space by:

Key Concept: We use perspective projection. Stars closer (smaller Z) appear larger and move faster. Stars farther away (larger Z) appear smaller and move slower, creating the illusion of stars rushing toward you as you fly backward through space.

Step 2: HTML Canvas Setup

<canvas id="starfield" width="800" height="600"></canvas>

<script>
const canvas = document.getElementById('starfield');
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
const centerX = width / 2;
const centerY = height / 2;
</script>

Step 3: Create the Star Class

class Star {
    constructor() {
        this.reset();
    }
    
    reset() {
        // Random position in 3D space
        this.x = Math.random() * 1600 - 800; // -800 to 800
        this.y = Math.random() * 1200 - 600; // -600 to 600
        this.z = Math.random() * 1000;       // 0 to 1000
    }
    
    update(speed) {
        // Move star toward camera (decrease z)
        this.z -= speed;
        
        // Reset if star passes camera
        if (this.z < 1) {
            this.reset();
            this.z = 1000;
        }
    }
    
    draw(ctx, centerX, centerY) {
        // Perspective projection
        const k = 128 / this.z;
        const px = this.x * k + centerX;
        const py = this.y * k + centerY;
        
        // Star size based on depth
        const size = (1 - this.z / 1000) * 2;
        
        // Brightness based on depth
        const brightness = (1 - this.z / 1000) * 255;
        
        ctx.fillStyle = `rgb(${brightness}, ${brightness}, ${brightness})`;
        ctx.fillRect(px, py, size, size);
    }
}
Perspective Formula: screenX = (x * focalLength / z) + centerX
The focal length (128) controls field of view. Smaller = wider, larger = narrower.

Step 4: Initialize Stars Array

const numStars = 500;
const stars = [];

for (let i = 0; i < numStars; i++) {
    stars.push(new Star());
}

Step 5: Animation Loop

let speed = 5;
let paused = false;

function animate() {
    // Clear canvas with fade effect for trails
    ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
    ctx.fillRect(0, 0, width, height);
    
    if (!paused) {
        // Update and draw each star
        stars.forEach(star => {
            star.update(speed);
            star.draw(ctx, centerX, centerY);
        });
    }
    
    requestAnimationFrame(animate);
}

animate();
Trail Effect: Instead of clearing the canvas completely, we draw a semi-transparent black rectangle. This creates motion trails behind stars.

Step 6: Add Interactivity (Optional)

// Pause/Resume
document.getElementById('pauseBtn').addEventListener('click', () => {
    paused = !paused;
});

// Speed control
document.getElementById('speedUpBtn').addEventListener('click', () => {
    speed += 2;
});

document.getElementById('slowDownBtn').addEventListener('click', () => {
    speed = Math.max(1, speed - 2);
});

Enhancements You Can Try

Key Takeaways

Check out these programming tutorials:

JavaScript:

Optical illusion (18 lines)

Oldschool fire effect (20 lines)

Fireworks (60 lines)

Animated fractal (32 lines)

Physics engine for beginners

Yin Yang with a twist (4 circles and 20 lines)

Tile map editor (70 lines)

Interactive animated sprites