A Pen by Bob Wright on CodePen.
Created
February 2, 2026 00:19
-
-
Save Bob-Wright-the-reactor/c135a2447b0468bb4382922ea7a08725 to your computer and use it in GitHub Desktop.
ZENITH Reactor 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Zenith Reactor: Z-Command Mandala</title> | |
| <style> | |
| body { margin: 0; background: #000; overflow: hidden; font-family: 'Courier New', monospace; } | |
| #ui { | |
| position: absolute; top: 20px; right: 20px; z-index: 100; | |
| background: rgba(15, 0, 30, 0.9); padding: 15px; border: 2px solid #a0f; | |
| color: #a0f; pointer-events: none; width: 240px; text-align: right; | |
| box-shadow: 0 0 25px #a0f; | |
| } | |
| canvas { display: block; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="ui"> | |
| <div id="mode-text" style="font-size: 18px; font-weight: bold; letter-spacing: 2px;">FIELD ACTIVE</div> | |
| <div style="font-size: 10px; margin-top: 10px; opacity: 0.8;"> | |
| VIOLET SPECTRUM: 280nm<br> | |
| [ Z ]: TRIGGER ZENITH MANDALA<br> | |
| [ SPACE ]: TIME STASIS | |
| </div> | |
| </div> | |
| <canvas id="canvas"></canvas> | |
| <script> | |
| const canvas = document.getElementById('canvas'); | |
| const ctx = canvas.getContext('2d', { alpha: false }); | |
| let particles = []; | |
| let audioStarted = false; | |
| let audioCtx, analyser, dataArray; | |
| let isMandala = false; | |
| let isPaused = false; | |
| function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } | |
| window.addEventListener('resize', resize); | |
| resize(); | |
| // --- THE ZENITH KEY TRIGGER --- | |
| window.addEventListener('keydown', (e) => { | |
| if (e.key.toLowerCase() === 'z') { | |
| isMandala = !isMandala; | |
| } | |
| if (e.code === 'Space') isPaused = !isPaused; | |
| }); | |
| window.addEventListener('mousedown', () => { initAudio(); }); | |
| function initAudio() { | |
| if (audioStarted) return; | |
| audioStarted = true; | |
| audioCtx = new (window.AudioContext || window.webkitAudioContext)(); | |
| analyser = audioCtx.createAnalyser(); | |
| const audio = new Audio('https://upload.wikimedia.org/wikipedia/commons/e/e2/Mozart_-_Sonata_for_Two_Pianos_in_D%2C_K._448_-_I._Allegro_con_spirito.ogg'); | |
| audio.crossOrigin = "anonymous"; | |
| const source = audioCtx.createMediaElementSource(audio); | |
| source.connect(analyser); | |
| analyser.connect(audioCtx.destination); | |
| dataArray = new Uint8Array(analyser.frequencyBinCount); | |
| audio.play(); | |
| } | |
| class Particle { | |
| constructor(id) { | |
| this.id = id; | |
| this.init(); | |
| // Pre-calculate Mandala positions | |
| let points = 12; | |
| let angle = (this.id % points) * (Math.PI * 2 / points); | |
| let radius = (this.id / 450) * (canvas.height * 0.45); | |
| this.tx = canvas.width/2 + Math.cos(angle) * radius; | |
| this.ty = canvas.height/2 + Math.sin(angle) * radius; | |
| } | |
| init() { | |
| this.x = Math.random() * canvas.width; | |
| this.y = Math.random() * canvas.height; | |
| this.px = this.x; this.py = this.y; | |
| this.vx = (Math.random() - 0.5) * 4; | |
| this.vy = (Math.random() - 0.5) * 4; | |
| this.life = Math.random() * 100 + 50; | |
| this.hue = 270 + Math.random() * 30; | |
| } | |
| update(pulse) { | |
| if (isPaused) return; | |
| this.px = this.x; this.py = this.y; | |
| if (isMandala) { | |
| // "Z" Mode: Smooth spring-physics toward the Mandala grid | |
| let dx = (this.tx - this.x); | |
| let dy = (this.ty - this.y); | |
| this.vx += dx * 0.05; | |
| this.vy += dy * 0.05; | |
| this.vx *= 0.75; // Heavy damping for "locking" feel | |
| this.vy *= 0.75; | |
| } else { | |
| // Standard Quantum Flow | |
| let angle = (Math.sin(this.x * 0.005) + Math.cos(this.y * 0.005)) * 4; | |
| this.vx += Math.cos(angle) * 0.6; | |
| this.vy += Math.sin(angle) * 0.6; | |
| this.vx *= 0.95; this.vy *= 0.95; | |
| } | |
| this.x += this.vx; | |
| this.y += this.vy; | |
| if (!isMandala && (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height)) { | |
| this.init(); | |
| } | |
| } | |
| draw(pulse) { | |
| ctx.strokeStyle = `hsla(${this.hue}, 100%, ${60 + (pulse/5)}%, ${isMandala ? 0.9 : 0.4})`; | |
| ctx.lineWidth = isMandala ? 2 : 1; | |
| ctx.beginPath(); ctx.moveTo(this.px, this.py); ctx.lineTo(this.x, this.y); ctx.stroke(); | |
| } | |
| } | |
| for (let i = 0; i < 450; i++) particles.push(new Particle(i)); | |
| function animate() { | |
| let pulse = 0; | |
| if (audioCtx) { | |
| analyser.getByteFrequencyData(dataArray); | |
| pulse = dataArray[4] || 0; | |
| } | |
| document.getElementById('mode-text').textContent = isMandala ? "ZENITH POINT" : "FIELD ACTIVE"; | |
| document.getElementById('mode-text').style.color = isMandala ? "#fff" : "#a0f"; | |
| // Ghosting trails | |
| ctx.fillStyle = isMandala ? 'rgba(20, 0, 40, 0.15)' : 'rgba(0, 0, 0, 0.08)'; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| ctx.globalCompositeOperation = 'lighter'; | |
| particles.forEach(p => { p.update(pulse); p.draw(pulse); }); | |
| ctx.globalCompositeOperation = 'source-over'; | |
| requestAnimationFrame(animate); | |
| } | |
| animate(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment