// Original stars.js code modified with AI in the following order: // 1) Microsoft Copilot // 2) Deepseek AI // 3) Qwen3 Coder (() => { const canvas = document.getElementById("starfield"); const ctx = canvas.getContext("2d"); let width, height; let bgCanvas, bgCtx; let starSprites = []; let layers = []; let comets = []; let pulses = []; let particles = []; let mouse = { x: 0, y: 0, active: false }; // Layer configurations: count, base speed, draw size const layerConfigs = [ { count: 500, speed: 1.5, size: 2.5 }, { count: 400, speed: 3.0, size: 4.0 }, { count: 300, speed: 6.0, size: 5.5 }, { count: 200, speed: 10.0, size: 8.0 }, ]; const rand = (min, max) => min + Math.random() * (max - min); // Handle resize function resize() { width = window.innerWidth; height = window.innerHeight; canvas.width = width; canvas.height = height; // Create background with enhanced nebula effect bgCanvas = document.createElement("canvas"); bgCanvas.width = width; bgCanvas.height = height; bgCtx = bgCanvas.getContext("2d"); // Base gradient - pure black background const bgGrad = bgCtx.createRadialGradient( width / 2, height / 2, 0, width / 2, height / 2, width * 0.8 ); bgGrad.addColorStop(0, "#000000"); bgGrad.addColorStop(0.5, "#000000"); bgGrad.addColorStop(1, "#000000"); bgCtx.fillStyle = bgGrad; bgCtx.fillRect(0, 0, width, height); // Enhanced nebula effect with multiple layers - more vibrant const nebulaCount = Math.floor(width * height / 30000); bgCtx.globalCompositeOperation = "screen"; for (let i = 0; i < nebulaCount; i++) { const x = rand(0, width); const y = rand(0, height); const radius = rand(100, 400); const hue = rand(220, 280); const alpha = rand(0.03, 0.08); const grd = bgCtx.createRadialGradient( x, y, 0, x, y, radius ); grd.addColorStop(0, `hsla(${hue}, 100%, 100%, ${alpha})`); grd.addColorStop(0.3, `hsla(${hue + 20}, 100%, 80%, ${alpha * 0.8})`); grd.addColorStop(1, `hsla(${hue - 20}, 100%, 50%, 0)`); bgCtx.beginPath(); bgCtx.fillStyle = grd; bgCtx.arc(x, y, radius, 0, Math.PI * 2); bgCtx.fill(); } // Add subtle star clusters - brighter bgCtx.globalCompositeOperation = "lighter"; for (let i = 0; i < nebulaCount / 3; i++) { const x = rand(0, width); const y = rand(0, height); const clusterSize = rand(20, 60); const clusterGrad = bgCtx.createRadialGradient( x, y, 0, x, y, clusterSize ); clusterGrad.addColorStop(0, `rgba(255, 255, 255, 0.2)`); clusterGrad.addColorStop(1, `rgba(200, 220, 255, 0)`); bgCtx.beginPath(); bgCtx.fillStyle = clusterGrad; bgCtx.arc(x, y, clusterSize, 0, Math.PI * 2); bgCtx.fill(); } bgCtx.globalCompositeOperation = "source-over"; } // Pre-render enhanced star sprites with glow function createStarSprites() { starSprites = layerConfigs.map(cfg => { const r = cfg.size; const sz = Math.ceil(r * 8); const off = document.createElement("canvas"); off.width = off.height = sz; const octx = off.getContext("2d"); // Core glow with gradient - brighter for black background const gradient = octx.createRadialGradient( sz/2, sz/2, 0, sz/2, sz/2, r * 3 ); gradient.addColorStop(0, "#ffffff"); gradient.addColorStop(0.3, "#a0c0ff"); gradient.addColorStop(1, "rgba(50, 100, 255, 0)"); octx.fillStyle = gradient; octx.beginPath(); octx.arc(sz/2, sz/2, r * 3, 0, Math.PI * 2); octx.fill(); // Bright core with corona - enhanced brightness octx.shadowColor = "#ffffff"; octx.shadowBlur = r * 3; octx.globalCompositeOperation = "lighter"; octx.fillStyle = "#ffffff"; octx.beginPath(); octx.arc(sz/2, sz/2, r * 0.8, 0, Math.PI * 2); octx.fill(); // Secondary corona - enhanced brightness octx.shadowColor = "#a0c0ff"; octx.shadowBlur = r * 5; octx.fillStyle = "rgba(180, 220, 255, 0.9)"; octx.beginPath(); octx.arc(sz/2, sz/2, r * 0.6, 0, Math.PI * 2); octx.fill(); return off; }); } // Initialize star layers with enhanced twinkle parameters function initStars() { layers = layerConfigs.map((cfg, idx) => { const stars = []; for (let i = 0; i < cfg.count; i++) { stars.push({ x: rand(-width/2, width/2), y: rand(-height/2, height/2), z: rand(1, width), twPhase: rand(0, Math.PI * 2), twFreq: rand(0.01, 0.05), twRange: rand(0.3, 0.9), sprIndex: idx, hue: rand(180, 220), // Blue-ish stars saturation: rand(80, 100), brightness: rand(90, 100), pulsePhase: rand(0, Math.PI * 2), pulseSpeed: rand(0.02, 0.08), originalSize: cfg.size }); } return { ...cfg, stars }; }); } // Spawn comets with enhanced effects function maybeComet() { if (Math.random() < 0.003) { const angle = Math.PI * 0.25 + rand(-0.5, 0.5); comets.push({ x: rand(-100, width + 100), y: rand(-100, height * 0.4), len: 0, maxLen: rand(100, 250), angle: angle, speed: rand(12, 20), segments: [], alpha: 1.0, hue: rand(180, 220), size: rand(2, 5) }); } } // Create particle explosion function createParticles(x, y, count, color) { for (let i = 0; i < count; i++) { particles.push({ x: x, y: y, vx: rand(-3, 3), vy: rand(-3, 3), life: 1.0, decay: rand(0.01, 0.03), size: rand(1, 3), color: color || `hsl(${rand(180, 220)}, 100%, ${rand(80, 100)}%)` }); } } // Click creates enhanced warp pulse with particles canvas.addEventListener("click", e => { // Create main pulses for (let i = 0; i < 5; i++) { pulses.push({ x: e.clientX, y: e.clientY, r: i * 15, maxR: 200 + i * 60, thickness: 20 - i * 2, alpha: 0.9 - i * 0.15, speed: 10 - i * 1.5, hue: rand(180, 220) }); } // Create particle explosion createParticles(e.clientX, e.clientY, 50, `hsl(${rand(180, 220)}, 100%, 90%)`); }); // Mouse move for star attraction canvas.addEventListener("mousemove", e => { mouse.x = e.clientX; mouse.y = e.clientY; mouse.active = true; }); canvas.addEventListener("mouseleave", () => { mouse.active = false; }); // Update positions and effects function update() { const now = Date.now(); // Update stars with mouse attraction layers.forEach(layer => { layer.stars.forEach(s => { s.z -= layer.speed; // Mouse attraction effect if (mouse.active) { const dx = (mouse.x - width/2) - s.x; const dy = (mouse.y - height/2) - s.y; const dist = Math.sqrt(dx*dx + dy*dy); if (dist < 300) { const force = (300 - dist) / 300 * 0.5; s.x += dx * force * (s.z / width); s.y += dy * force * (s.z / width); } } if (s.z <= 0) { s.z = width; s.x = rand(-width/2, width/2); s.y = rand(-height/2, height/2); } // Update twinkle and pulsing s.twPhase += s.twFreq; s.pulsePhase += s.pulseSpeed; }); }); // Update comets comets = comets.filter(c => c.alpha > 0.05); comets.forEach(c => { c.len += c.speed; const headX = c.x + Math.cos(c.angle) * c.len; const headY = c.y + Math.sin(c.angle) * c.len; // Add new segment c.segments.push({ x: headX, y: headY, alpha: 1.0, size: c.size * (0.5 + 0.5 * Math.random()) }); // Fade old segments c.segments.forEach(seg => seg.alpha -= 0.015); // Remove old segments if (c.segments.length > 30) c.segments.shift(); // Fade entire comet c.alpha -= 0.002; // Occasionally create particles if (Math.random() < 0.3) { createParticles(headX, headY, 1, `hsl(${c.hue}, 100%, 80%)`); } }); // Update pulses pulses = pulses.filter(p => p.r < p.maxR); pulses.forEach(p => { p.r += p.speed; p.alpha -= 0.006; }); // Update particles particles = particles.filter(p => p.life > 0); particles.forEach(p => { p.x += p.vx; p.y += p.vy; p.vy += 0.05; // Gravity p.life -= p.decay; p.vx *= 0.98; // Friction p.vy *= 0.98; }); maybeComet(); } // Draw the enhanced scene function draw() { // Background with subtle movement ctx.clearRect(0, 0, width, height); ctx.drawImage(bgCanvas, 0, 0); // Subtle motion blur effect ctx.fillStyle = "rgba(0, 0, 0, 0.05)"; ctx.fillRect(0, 0, width, height); // Draw particles particles.forEach(p => { ctx.globalAlpha = p.life; ctx.fillStyle = p.color; ctx.beginPath(); ctx.arc(p.x, p.y, Math.max(0.1, p.size * p.life), 0, Math.PI * 2); ctx.fill(); }); // Stars with enhanced effects layers.forEach((layer, li) => { const sprite = starSprites[li]; ctx.globalCompositeOperation = "lighter"; layer.stars.forEach(s => { const k = (width/2) / s.z; const x = s.x * k + width/2; const y = s.y * k + height/2; if (x < -100 || x > width+100 || y < -100 || y > height+100) return; // Calculate twinkle with pulsing const twinkle = 0.5 + 0.5 * Math.sin(s.twPhase); const pulse = 0.8 + 0.2 * Math.sin(s.pulsePhase); const alpha = (s.twRange + (1 - s.twRange) * twinkle) * pulse; const ds = Math.max(0.1, (1 - s.z/width) * s.originalSize * 2 * pulse); ctx.globalAlpha = alpha; const drawSize = Math.max(0.1, ds * 2); ctx.drawImage(sprite, x - ds, y - ds, drawSize, drawSize); }); }); ctx.globalCompositeOperation = "source-over"; ctx.globalAlpha = 1; // Comets with enhanced particle trails comets.forEach(c => { ctx.lineCap = "round"; for (let i = 1; i < c.segments.length; i++) { const seg1 = c.segments[i-1]; const seg2 = c.segments[i]; const gradient = ctx.createLinearGradient( seg1.x, seg1.y, seg2.x, seg2.y ); const segAlpha = Math.min(seg1.alpha, seg2.alpha) * c.alpha; gradient.addColorStop(0, `hsla(${c.hue}, 100%, 100%, ${segAlpha})`); gradient.addColorStop(0.5, `hsla(${c.hue - 20}, 100%, 80%, ${segAlpha * 0.8})`); gradient.addColorStop(1, `hsla(${c.hue - 40}, 100%, 60%, ${segAlpha * 0.3})`); ctx.strokeStyle = gradient; ctx.lineWidth = Math.max(0.1, seg2.size * (i/c.segments.length) * c.alpha); ctx.beginPath(); ctx.moveTo(seg1.x, seg1.y); ctx.lineTo(seg2.x, seg2.y); ctx.stroke(); } }); // Warp pulses with enhanced rings pulses.forEach(p => { ctx.beginPath(); ctx.arc(p.x, p.y, Math.max(0.1, p.r), 0, Math.PI * 2); const gradient = ctx.createRadialGradient( p.x, p.y, Math.max(0.1, p.r - p.thickness/2), p.x, p.y, Math.max(0.1, p.r + p.thickness/2) ); gradient.addColorStop(0, `hsla(${p.hue}, 100%, 100%, ${p.alpha})`); gradient.addColorStop(0.3, `hsla(${p.hue - 10}, 100%, 90%, ${p.alpha * 0.9})`); gradient.addColorStop(0.7, `hsla(${p.hue - 20}, 100%, 70%, ${p.alpha * 0.5})`); gradient.addColorStop(1, `hsla(${p.hue - 30}, 100%, 50%, 0)`); ctx.strokeStyle = gradient; ctx.lineWidth = Math.max(0.1, p.thickness); ctx.stroke(); // Add inner glow if (p.alpha > 0.3) { const innerRadius = Math.max(0.1, p.r * 0.3); ctx.beginPath(); ctx.arc(p.x, p.y, innerRadius, 0, Math.PI * 2); const innerGradient = ctx.createRadialGradient( p.x, p.y, 0, p.x, p.y, innerRadius ); innerGradient.addColorStop(0, `hsla(${p.hue + 20}, 100%, 100%, ${p.alpha * 0.7})`); innerGradient.addColorStop(1, `hsla(${p.hue}, 100%, 80%, 0)`); ctx.fillStyle = innerGradient; ctx.fill(); } }); } // Animation loop function loop() { update(); draw(); requestAnimationFrame(loop); } // Initialize function init() { resize(); createStarSprites(); initStars(); window.addEventListener("resize", () => { resize(); initStars(); }); // Add some initial particles for visual interest for (let i = 0; i < 100; i++) { setTimeout(() => { createParticles(rand(0, width), rand(0, height), 3, `hsl(${rand(180, 220)}, 100%, ${rand(70, 90)}%)`); }, i * 100); } loop(); } init(); })();