UNPKG

laif-ds

Version:

Design System di Laif con componenti React basati su principi di Atomic Design

99 lines (98 loc) 3 kB
"use client"; import { jsx as p } from "react/jsx-runtime"; import { useRef as i, useEffect as R, useCallback as f } from "react"; const c = { FFT_SIZE: 512, SMOOTHING: 0.8, MIN_BAR_HEIGHT: 2, MIN_BAR_WIDTH: 2, BAR_SPACING: 1, COLOR: { MIN_INTENSITY: 100, // Minimum gray value (darker) MAX_INTENSITY: 255, // Maximum gray value (brighter) INTENSITY_RANGE: 155 // MAX_INTENSITY - MIN_INTENSITY } }; function F({ stream: a, isRecording: s, onClick: B }) { const u = i(null), d = i(null), I = i(null), h = i(null), N = i(null), A = () => { h.current && cancelAnimationFrame(h.current), d.current && d.current.close(); }; R(() => A, []); const T = f((e) => { const t = Math.floor(e * c.COLOR.INTENSITY_RANGE) + c.COLOR.MIN_INTENSITY; return `rgb(${t}, ${t}, ${t})`; }, []), _ = f( (e, t, n, o, r, l) => { e.fillStyle = l, e.fillRect(t, n - r, o, r), e.fillRect(t, n, o, r); }, [] ), m = f(() => { if (!s) return; const e = u.current, t = e?.getContext("2d"); if (!e || !t || !I.current) return; const n = window.devicePixelRatio || 1; t.scale(n, n); const o = I.current, r = o.frequencyBinCount, l = new Uint8Array(r), C = () => { h.current = requestAnimationFrame(C), o.getByteFrequencyData(l), t.clearRect(0, 0, e.width / n, e.height / n); const S = Math.max( c.MIN_BAR_WIDTH, e.width / n / r - c.BAR_SPACING ), g = e.height / n / 2; let E = 0; for (let w = 0; w < r; w++) { const M = l[w] / 255, O = Math.max( c.MIN_BAR_HEIGHT, M * g ); _( t, E, g, S, O, T(M) ), E += S + c.BAR_SPACING; } }; C(); }, [s, _, T]), y = f(async () => { try { const e = new AudioContext(); d.current = e; const t = e.createAnalyser(); t.fftSize = c.FFT_SIZE, t.smoothingTimeConstant = c.SMOOTHING, I.current = t, e.createMediaStreamSource(a).connect(t), m(); } catch (e) { console.error("Error starting visualization:", e); } }, [a, m]); return R(() => { a && s ? y() : A(); }, [a, s, y]), R(() => { const e = () => { if (typeof window > "u" || !u.current || !N.current) return; const t = N.current, n = u.current, o = window.devicePixelRatio || 1, r = t.getBoundingClientRect(); n.width = (r.width - 2) * o, n.height = (r.height - 2) * o, n.style.width = `${r.width - 2}px`, n.style.height = `${r.height - 2}px`; }; if (typeof window < "u") return window.addEventListener("resize", e), e(), () => window.removeEventListener("resize", e); }, []), /* @__PURE__ */ p( "div", { ref: N, className: "bg-d-background/80 h-full w-full cursor-pointer rounded-lg backdrop-blur", onClick: B, children: /* @__PURE__ */ p("canvas", { ref: u, className: "h-full w-full" }) } ); } export { F as AudioVisualizer };