Spaces:
Sleeping
Sleeping
| <div id="hexa-container" style="width: 100%; height: 100%; min-height: 300px; background: #000; border-radius: 12px; overflow: hidden; position: relative; border: 1px solid #222; box-shadow: 0 0 30px rgba(0,0,0,0.8);"> | |
| <canvas id="defragCanvas" style="width: 100%; height: 100%; display: block;"></canvas> | |
| <div id="overlay" style="position: absolute; top: 20px; left: 20px; color: rgba(255,255,255,0.4); font-family: 'Courier New', monospace; font-size: 10px; pointer-events: none;"> | |
| SYSTEM: ONLINE<br> | |
| AUDIO: ENABLED | |
| </div> | |
| </div> | |
| <script> | |
| class HexaMandala { | |
| constructor(canvasId) { | |
| this.canvas = document.getElementById(canvasId); | |
| if (!this.canvas) return; | |
| this.ctx = this.canvas.getContext('2d'); | |
| // Default State | |
| this.hexCode = [1,0,1,0,1,0]; | |
| this.petalCount = 5; | |
| this.element = 'water'; | |
| this.stability = 1.0; | |
| this.speaking = false; // New: React to audio | |
| this.time = 0; | |
| this.resize(); | |
| this.initColors(); | |
| this.animate(); | |
| window.addEventListener('resize', () => this.resize()); | |
| } | |
| resize() { | |
| const parent = this.canvas.parentElement; | |
| this.canvas.width = parent.clientWidth * window.devicePixelRatio; | |
| this.canvas.height = parent.clientHeight * window.devicePixelRatio; | |
| this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio); | |
| this.width = parent.clientWidth; | |
| this.height = parent.clientHeight; | |
| } | |
| initColors() { | |
| this.colors = { | |
| fire: { h: 10, s: 80, l: 50 }, | |
| earth: { h: 35, s: 60, l: 40 }, | |
| air: { h: 200, s: 70, l: 80 }, | |
| water: { h: 220, s: 90, l: 30 } | |
| }; | |
| } | |
| updateParams(hex, petals, elem, stab, isSpeaking) { | |
| this.hexCode = hex || [1,1,1,1,1,1]; | |
| this.petalCount = petals || 5; | |
| this.element = elem || 'water'; | |
| this.stability = stab !== undefined ? stab : 1.0; | |
| if (isSpeaking !== undefined) this.speaking = isSpeaking; | |
| } | |
| drawHexRing(radius, index, isYang) { | |
| this.ctx.beginPath(); | |
| if (isYang) { | |
| this.ctx.arc(0, 0, radius, 0, Math.PI * 2); | |
| this.ctx.lineWidth = 3; | |
| this.ctx.strokeStyle = `rgba(255, 255, 255, ${0.15 + (index * 0.05)})`; | |
| this.ctx.stroke(); | |
| } else { | |
| this.ctx.setLineDash([5, 10]); | |
| this.ctx.arc(0, 0, radius, 0, Math.PI * 2); | |
| this.ctx.lineWidth = 2; | |
| this.ctx.strokeStyle = `rgba(255, 255, 255, ${0.1 + (index * 0.05)})`; | |
| this.ctx.stroke(); | |
| this.ctx.setLineDash([]); | |
| } | |
| } | |
| animate() { | |
| this.time += 0.01; | |
| this.ctx.fillStyle = "#050505"; | |
| this.ctx.fillRect(0, 0, this.width, this.height); | |
| this.ctx.save(); | |
| this.ctx.translate(this.width/2, this.height/2); | |
| // Audio Reactivity (Pulse when speaking) | |
| let audioPulse = this.speaking ? Math.sin(this.time * 10) * 5 : 0; | |
| // Glitch Shake | |
| if (this.stability < 0.5) { | |
| let shake = (1.0 - this.stability) * 3; | |
| this.ctx.translate((Math.random()-0.5)*shake, (Math.random()-0.5)*shake); | |
| } | |
| let baseR = Math.min(this.width, this.height) * 0.12; | |
| // Draw Rings | |
| this.hexCode.forEach((val, i) => { | |
| let r = baseR + (i * 15) + audioPulse; | |
| this.drawHexRing(r, i, val === 1); | |
| }); | |
| // Draw Petals | |
| let c = this.colors[this.element] || this.colors.water; | |
| let count = this.petalCount; | |
| for (let i = 0; i < count; i++) { | |
| this.ctx.save(); | |
| let angle = (i / count) * Math.PI * 2 + (this.time * 0.1); | |
| this.ctx.rotate(angle); | |
| this.ctx.beginPath(); | |
| this.ctx.moveTo(0, 0); | |
| this.ctx.quadraticCurveTo(baseR*1.5, baseR, 0, baseR*3 + audioPulse); | |
| this.ctx.quadraticCurveTo(-baseR*1.5, baseR, 0, 0); | |
| let alpha = 0.6 * this.stability; | |
| this.ctx.fillStyle = `hsla(${c.h}, ${c.s}%, ${c.l}%, ${alpha})`; | |
| this.ctx.fill(); | |
| this.ctx.restore(); | |
| } | |
| this.ctx.restore(); | |
| requestAnimationFrame(() => this.animate()); | |
| } | |
| } | |
| // Initialize on load | |
| setTimeout(() => { | |
| window.hexa = new HexaMandala('defragCanvas'); | |
| }, 500); | |
| </script> |