Audio_Deepfake_Detection / frontend /src /components /WaveformBackground.tsx
vipan-kumar's picture
Initial commit: Audio Deepfake Detector with 8 detectors trained on jay15k
e6a1f55
Raw
History Blame Contribute Delete
2.99 kB
import { useEffect, useRef } from "react";
/** Full-screen animated SVG sine waves morphing between clean & corrupted forms. */
export default function WaveformBackground() {
const ref = useRef<SVGSVGElement | null>(null);
useEffect(() => {
const svg = ref.current;
if (!svg) return;
let frame = 0;
let raf = 0;
const paths = svg.querySelectorAll<SVGPathElement>("path[data-wave]");
const buildPath = (
width: number,
height: number,
amp: number,
freq: number,
noise: number,
phase: number
) => {
const points: string[] = [];
const step = 6;
for (let x = 0; x <= width; x += step) {
const base = Math.sin((x / width) * Math.PI * 2 * freq + phase) * amp;
const jitter =
noise *
(Math.sin((x / width) * Math.PI * 2 * (freq * 4.7) + phase * 1.3) * 0.5 +
Math.sin((x / width) * Math.PI * 2 * (freq * 11.3) + phase * 0.7) * 0.5);
const y = height / 2 + base + jitter;
points.push(`${x},${y.toFixed(2)}`);
}
return `M${points.join(" L")}`;
};
const tick = () => {
frame += 1;
const w = svg.viewBox.baseVal.width || 1600;
const h = svg.viewBox.baseVal.height || 600;
const t = frame / 60;
paths.forEach((p, i) => {
const layer = i + 1;
const noiseRamp = 4 + 8 * Math.sin(t * 0.25 + layer * 0.7); // morph clean ↔ corrupted
const d = buildPath(
w,
h,
18 + layer * 6,
1.3 + layer * 0.4,
Math.max(0, noiseRamp),
t * (0.4 + layer * 0.15)
);
p.setAttribute("d", d);
});
raf = requestAnimationFrame(tick);
};
raf = requestAnimationFrame(tick);
return () => cancelAnimationFrame(raf);
}, []);
return (
<div className="pointer-events-none fixed inset-0 z-0 overflow-hidden">
{/* Faint grid */}
<div className="absolute inset-0 grid-bg opacity-[0.45]" />
{/* Animated waves */}
<svg
ref={ref}
className="absolute inset-0 h-full w-full"
viewBox="0 0 1600 600"
preserveAspectRatio="none"
aria-hidden
>
<defs>
<linearGradient id="waveGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stopColor="rgb(var(--cyber))" stopOpacity="0.04" />
<stop offset="50%" stopColor="rgb(var(--cyber))" stopOpacity="0.18" />
<stop offset="100%" stopColor="rgb(var(--danger))" stopOpacity="0.08" />
</linearGradient>
</defs>
<path data-wave stroke="url(#waveGrad)" strokeWidth="1.2" fill="none" />
<path data-wave stroke="url(#waveGrad)" strokeWidth="1" fill="none" />
<path data-wave stroke="url(#waveGrad)" strokeWidth="0.8" fill="none" />
</svg>
{/* Soft scan-line vignette */}
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-bg/60" />
</div>
);
}