AudViz

Follow for updates

Installation

Components

Circle Anim

Circular Animation

import { useRef, useEffect } from "react"
  import { AudioVisComponentProps } from "../visualizarRegistery";
  
  export function CircleAnim({ stream }: AudioVisComponentProps) {
    const canvasRef = useRef<HTMLCanvasElement | null>(null);
    const animationRef = useRef<number | null>(null);
    const analyserRef = useRef<AnalyserNode | null>(null)
    const freqArrayRef = useRef<Uint8Array | null>(null);
  
    useEffect(() => {
      if(!canvasRef.current) return;
  
      const canvas = canvasRef.current;
      const ctx = canvas.getContext("2d");
      if(!ctx) return;
  
      const draw = () =>
    
                ctx.clearRect(0, 0, canvas.width, canvas.height);
    
                let average = 0;
                if(analyserRef.current && freqArrayRef.current) {
                    analyserRef.current.getByteFrequencyData(freqArrayRef.current);
                    const bufferLength = analyserRef.current.frequencyBinCount;
                    average = freqArrayRef.current.reduce((sum, value) => sum + value, 0) / bufferLength;
                }
    
                const centerX = canvas.width / 2;
                const centerY = canvas.height / 2;
                const radius = canvas.width/3 + average / 3;
    
                // Create radial gradient
                const gradient = ctx.createRadialGradient(
                    centerX, centerY, 50, // Inner circle
                    centerX, centerY, radius ,  // Outer edge for blur
                );
    
                // Define gradient color stops
                gradient.addColorStop(0.4, "rgb(0, 0, 0)"); // Center solid color
                gradient.addColorStop(0.7, "rgba(128, 217, 255, 0.93)"); // Mid-opacity
                gradient.addColorStop(1, "rgba(255, 255, 255, 0)"); // Transparent edge
                // gradient.addColorStop(1, "rgba(0, 0, 0, 0.92)"); // Center solid color
                
    
                ctx.beginPath();
                ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
                ctx.fillStyle = gradient;
                ctx.fill();
    
                animationRef.current = requestAnimationFrame(draw);
            }
    
            draw();
    
            return () => {
                cancelAnimationFrame(animationRef.current!);
            }
    
        }, []);
    
        useEffect(() => {
            if (!stream) return;
    
            const audioContext = new AudioContext();
            const audioSource = audioContext.createMediaStreamSource(stream);
    
            analyserRef.current = audioContext.createAnalyser();
            analyserRef.current.fftSize = 32;
            const bufferLength = analyserRef.current.frequencyBinCount;
            freqArrayRef.current = new Uint8Array(bufferLength);
    
            audioSource.connect(analyserRef.current);
    
            return () => {
                audioContext.close();
            }
            
        }, [stream]);
    
        return (
            <div className=''>
                <canvas ref={canvasRef} width={200} height={200} ></canvas>
            </div>
        )
    }