import React, { useEffect, useRef } from 'react'; interface FrequencyVisualizerProps { isPlaying: boolean; audioUrl?: string; } const FrequencyVisualizer: React.FC = ({ isPlaying, audioUrl }) => { const canvasRef = useRef(null); const audioContextRef = useRef(null); const analyzerRef = useRef(null); const requestRef = useRef(); useEffect(() => { if (!isPlaying) { if (requestRef.current) cancelAnimationFrame(requestRef.current); return; } const initAudio = async () => { if (!audioContextRef.current) { const AudioCtx = window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext; audioContextRef.current = new AudioCtx(); analyzerRef.current = audioContextRef.current.createAnalyser(); analyzerRef.current.fftSize = 256; } const draw = () => { if (!canvasRef.current || !analyzerRef.current) return; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); if (!ctx) return; const bufferLength = analyzerRef.current.frequencyBinCount; const dataArray = new Uint8Array(bufferLength); analyzerRef.current.getByteFrequencyData(dataArray); ctx.clearRect(0, 0, canvas.width, canvas.height); const barWidth = (canvas.width / bufferLength) * 2.5; let barHeight; let x = 0; for (let i = 0; i < bufferLength; i++) { barHeight = (dataArray[i] / 255) * canvas.height; // Gradient for "Monster WAV" feel const gradient = ctx.createLinearGradient(0, canvas.height, 0, 0); gradient.addColorStop(0, '#7c3aed'); // Primary violet gradient.addColorStop(1, '#a78bfa'); // Lighter violet ctx.fillStyle = gradient; ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight); x += barWidth + 1; } requestRef.current = requestAnimationFrame(draw); }; draw(); }; initAudio(); return () => { if (requestRef.current) cancelAnimationFrame(requestRef.current); }; }, [isPlaying]); return (
Monster WAV Monitor
); }; export default FrequencyVisualizer;