import { useEffect, useRef, type CSSProperties } from 'react'; import s from './Ambient.module.css'; /** * Ambient-фон (docs/design.md#1): три размытых дрейфующих пятна; третье — в цвете обложки текущего трека. * Отключается в настройках; при prefers-reduced-motion пятна неподвижны. */ export function Ambient({ color, readAudio }: { color: string; readAudio?: () => { bass: number; mid: number; treble: number }; }) { const root = useRef(null); useEffect(() => { if (!readAudio) return; const mq = window.matchMedia?.('(prefers-reduced-motion: reduce)'); let raf = 0; let last = performance.now(); let level = 0; const frame = (now: number) => { const dt = Math.min(0.05, (now - last) / 1000); last = now; const audio = !mq?.matches && !document.hidden ? readAudio() : undefined; const target = audio ? audio.bass * 0.65 + audio.mid * 0.25 + audio.treble * 0.1 : 0; level += (target - level) * (1 - Math.exp(-dt * 7)); root.current?.style.setProperty('--music-scale', String(1 + level * 0.16)); root.current?.style.setProperty('--music-light', String(1 + level * 0.3)); raf = requestAnimationFrame(frame); }; raf = requestAnimationFrame(frame); return () => cancelAnimationFrame(raf); }, [readAudio]); return (
); }