This webpage itself is a masterpiece of procedural generation!
Live Procedural Generation
Every refresh regenerates the starfield with new star positions, sizes, and planetary configurations—no two visits are the same.
- Procedural Star Generation: 400+ stars randomly positioned and sized using mathematical algorithms.
- Dynamic Parallax Animation: Stars move with depth-based speed—smaller stars move faster, creating realistic 3D depth.
- Planetary Bodies with Atmospheres: Large stars become planets with atmospheric gradients, surface stripes, and swirling storms.
- Procedural Ring Systems: 40% of large planets receive randomly generated ring systems with elliptical transformations.
- Color-Coded Star Types: Jupiter orange, Saturn yellow-brown, Uranus blue, Mars red-brown—each with unique atmospheric effects.
- Real-time 60fps Rendering: Smooth animation using the Canvas 2D context with optimized render loops.
- Responsive Universe: Starfield adapts to any screen size, orientation, and device capabilities.
- Flickering Star Effects: Smaller stars twinkle via sine-wave driven opacity.
Implementation
Star Generation
The heart of the system - each star is generated with unique properties using mathematical randomness. The algorithm creates a realistic distribution where most objects are small stars, with occasional large planetary bodies that have atmospheric effects and ring systems.
▼ Click to see the detailed Code
// Add twinkling effect using sine wave functions
const flicker = s.size <= 1.8 ? Math.sin(Date.now() * s.speed * 0.005) * 0.7 + 0.8 : 1;
const alpha = 0.5 + flicker * 0.5;ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.size * 0.4, 0, Math.PI * 2);
ctx.fill()
This creates the illusion of 3D depth by making smaller stars move faster than larger ones. The mathematical relationship sizeFactor = 1 / (s.size + 0.5) ensures that distant stars (smaller) move faster, while nearby planets (larger) move slower, mimicking real-world perspective.
▼ Click to see the detailed Code
// Parallax movement - smaller stars move faster for depth effect
stars.forEach(s => {
const sizeFactor = 1 / (s.size + 0.5); // Smaller stars = faster movement
s.x += s.speed * sizeFactor * 0.3;
s.y += s.speed * sizeFactor * 0.15;
// Seamless boundary wrapping
if (s.x < 0) s.x = canvas.width;
if (s.x > canvas.width) s.x = 0;
});
Large celestial bodies are rendered with realistic atmospheric effects using radial gradients. The gradient creates a soft glow that extends beyond the planet's surface, simulating atmospheric scattering of light. Each planet type has its own color palette based on real astronomical observations.
▼ Click to see the detailed Code
// Create atmospheric glow using radial gradients
const gradient = ctx.createRadialGradient(s.x, s.y, 0, s.x, s.y, s.size * 8);
gradient.addColorStop(0, `rgba(${baseColor[0]}, ${baseColor[1]}, ${baseColor[2]}, 0.9)`);
gradient.addColorStop(0.3, `rgba(${baseColor[0]}, ${baseColor[1]}, ${baseColor[2]}, 0.8)`);
gradient.addColorStop(0.6, `rgba(${baseColor[0]}, ${baseColor[1]}, ${baseColor[2]}, 0.6)`);
gradient.addColorStop(1, 'rgba(0, 0, 0, 0)'); // Fade to transparent
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(s.x, s.y, s.size * 3, 0, Math.PI * 2);
ctx.fill();Smaller stars have a subtle twinkling effect achieved through sine wave functions. The Math.sin(Date.now() * s.speed * 0.005) creates a smooth, time-based oscillation that varies the star's opacity and creates the classic "twinkling star" effect seen in real night skies.
▼ Click to see the detailed Code
// Add twinkling effect using sine wave functions
const flicker = s.size <= 1.8 ? Math.sin(Date.now() * s.speed * 0.005) * 0.7 + 0.8 : 1;
const alpha = 0.5 + flicker * 0.5;
ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.size * 0.4, 0, Math.PI * 2);
ctx.fill();