laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
99 lines (98 loc) • 3 kB
JavaScript
"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
};