const container = document.getElementById('stars-container'); // Create Canvas const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); container.appendChild(canvas); let width, height; let stars = []; let comets = []; function resize() { width = window.innerWidth; height = window.innerHeight; canvas.width = width; canvas.height = height; initStars(); } class Star { constructor() { this.reset(); this.y = Math.random() * height; // Initial random y } reset() { this.x = Math.random() * width; this.y = Math.random() * height; this.z = Math.random() * 2 + 0.5; // Depth/Size/Speed this.baseSize = Math.random() * 1.5; this.alpha = Math.random() * 0.5 + 0.1; this.twinkle = Math.random() * 0.05; } update() { this.alpha += this.twinkle; if (this.alpha > 0.8 || this.alpha < 0.1) this.twinkle = -this.twinkle; } draw() { ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`; ctx.beginPath(); const size = this.baseSize * (this.z / 2); ctx.arc(this.x, this.y, size, 0, Math.PI * 2); ctx.fill(); } } class Comet { constructor() { this.reset(); } reset() { this.x = Math.random() * width; this.y = Math.random() * height * 0.5; this.len = Math.random() * 80 + 20; this.speed = Math.random() * 5 + 2; this.angle = Math.PI / 4 + (Math.random() - 0.5) * 0.2; // 45 degrees this.active = false; this.wait = Math.random() * 200 + 50; } update() { if (!this.active) { this.wait--; if (this.wait <= 0) { this.active = true; this.x = Math.random() * width - 200; // Start off screen slightly this.y = Math.random() * height * 0.5; } return; } this.x += Math.cos(this.angle) * this.speed; this.y += Math.sin(this.angle) * this.speed; if (this.x > width + 100 || this.y > height + 100) { this.active = false; this.reset(); this.wait = Math.random() * 500 + 100; // Wait longer before next } } draw() { if (!this.active) return; // Gradient tail const grad = ctx.createLinearGradient( this.x, this.y, this.x - Math.cos(this.angle) * this.len, this.y - Math.sin(this.angle) * this.len ); grad.addColorStop(0, 'rgba(255, 255, 255, 0.8)'); grad.addColorStop(1, 'rgba(99, 102, 241, 0)'); // Fade to purple blue ctx.strokeStyle = grad; ctx.lineWidth = 2; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(this.x, this.y); ctx.lineTo( this.x - Math.cos(this.angle) * this.len, this.y - Math.sin(this.angle) * this.len ); ctx.stroke(); // Head ctx.fillStyle = 'white'; ctx.beginPath(); ctx.arc(this.x, this.y, 2, 0, Math.PI * 2); ctx.fill(); // Glow ctx.shadowBlur = 10; ctx.shadowColor = '#6366f1'; ctx.fill(); ctx.shadowBlur = 0; } } function initStars() { stars = []; comets = []; for (let i = 0; i < 150; i++) stars.push(new Star()); for (let i = 0; i < 3; i++) comets.push(new Comet()); } function animate() { ctx.clearRect(0, 0, width, height); // Background gradient for depth // ctx.fillStyle = 'rgba(5, 5, 16, 0.2)'; // ctx.fillRect(0,0,width,height); stars.forEach(s => { s.update(); s.draw(); }); comets.forEach(c => { c.update(); c.draw(); }); requestAnimationFrame(animate); } window.addEventListener('resize', resize); resize(); animate();