// 432 Blue — cymatic blob spinner function CymaticBlob({ size = 260, speed = 1, mode = 0 }){ const ref = React.useRef(null); const N = 220; // path resolution const presets = [ // [base radius, modes...]: each mode is {n: harmonic, amp: amplitude, phaseSpeed: how fast its phase rotates} { base: 0.62, modes: [ { n: 3, amp: 0.06, phaseSpeed: 0.6 }, { n: 5, amp: 0.04, phaseSpeed: -0.9 }, { n: 8, amp: 0.025, phaseSpeed: 1.4 }, ]}, { base: 0.6, modes: [ { n: 4, amp: 0.07, phaseSpeed: 0.5 }, { n: 7, amp: 0.035, phaseSpeed: -1.1 }, { n: 11, amp: 0.018, phaseSpeed: 1.7 }, ]}, { base: 0.58, modes: [ { n: 2, amp: 0.09, phaseSpeed: 0.4 }, { n: 6, amp: 0.04, phaseSpeed: -0.8 }, { n: 13, amp: 0.015, phaseSpeed: 2.2 }, ]}, ]; React.useEffect(() => { let raf; const start = performance.now(); const cfg = presets[mode % presets.length]; function tick(now){ const t = (now - start) / 1000 * speed; const cx = 100, cy = 100; let d = ''; for (let i = 0; i <= N; i++){ const a = (i / N) * Math.PI * 2; let r = cfg.base * 100; for (const m of cfg.modes){ r += m.amp * 100 * Math.sin(m.n * a + t * m.phaseSpeed * Math.PI); } const x = cx + Math.cos(a) * r; const y = cy + Math.sin(a) * r; d += (i === 0 ? 'M' : 'L') + x.toFixed(2) + ' ' + y.toFixed(2) + ' '; } d += 'Z'; if (ref.current) { ref.current.querySelector('.blob-fill').setAttribute('d', d); ref.current.querySelector('.blob-stroke').setAttribute('d', d); ref.current.querySelector('.blob-stroke-2').setAttribute('d', d); ref.current.querySelector('.blob-stroke-3').setAttribute('d', d); } raf = requestAnimationFrame(tick); } raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, [mode, speed]); return ( {/* outer halo */} {/* magenta echo (slightly outside via stroke) */} {/* fill */} {/* crisp edge */} {/* internal cymatic rings */} {[20, 32, 44].map((r,i) => ( ))} {/* nodes around */} {Array.from({length:12}).map((_,i)=>{ const a = (i/12)*Math.PI*2; const r = 78; return ; })} ); } // Spinner card with frequency readout function SpinnerCard({ mode = 0, label = "TUNING" }){ const [hz, setHz] = React.useState(432.000); React.useEffect(() => { let raf; const start = performance.now(); function tick(now){ const t = (now - start) / 1000; // small oscillation around 432 setHz(432 + Math.sin(t * 1.3) * 0.34 + Math.sin(t * 3.1) * 0.08); raf = requestAnimationFrame(tick); } raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, []); return (
{label}
{hz.toFixed(3)} Hz
RESONANCE LOCK
); } // Bare inline spinner (small applications) function SpinnerInline(){ return (
); } window.CymaticBlob = CymaticBlob; window.SpinnerCard = SpinnerCard; window.SpinnerInline = SpinnerInline;