Spaces:
Paused
Paused
| import React, { useRef, useEffect } from 'react'; | |
| const AudioVisualizer = ({ audioData }) => { | |
| const canvasRef = useRef(null); | |
| useEffect(() => { | |
| if (!audioData) return; | |
| const canvas = canvasRef.current; | |
| const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); | |
| const analyser = audioCtx.createAnalyser(); | |
| // Daha yumuşak geçişler için | |
| analyser.smoothingTimeConstant = 0.85; | |
| analyser.fftSize = 256; | |
| const source = audioCtx.createMediaStreamSource(audioData); | |
| source.connect(analyser); | |
| const bufferLength = analyser.frequencyBinCount; | |
| const dataArray = new Uint8Array(bufferLength); | |
| const canvasCtx = canvas.getContext('2d'); | |
| const draw = () => { | |
| requestAnimationFrame(draw); | |
| analyser.getByteFrequencyData(dataArray); | |
| const width = canvas.width; | |
| const height = canvas.height; | |
| const centerX = width / 2; | |
| const centerY = height / 2; | |
| canvasCtx.clearRect(0, 0, width, height); | |
| // Ortalama ses seviyesini hesapla | |
| let average = 0; | |
| for (let i = 0; i < bufferLength; i++) { | |
| average += dataArray[i]; | |
| } | |
| average = average / bufferLength; | |
| // Glow efekti | |
| const glowRadius = average * 1.5; | |
| const gradient = canvasCtx.createRadialGradient(centerX, centerY, 5, centerX, centerY, 100); | |
| gradient.addColorStop(0, 'rgba(79, 70, 229, 0.8)'); // Primary | |
| gradient.addColorStop(0.5, 'rgba(236, 72, 153, 0.4)'); // Secondary | |
| gradient.addColorStop(1, 'rgba(255, 255, 255, 0)'); | |
| // Merkezi daire (sürekli var olan) | |
| canvasCtx.beginPath(); | |
| canvasCtx.arc(centerX, centerY, 20 + (average / 5), 0, 2 * Math.PI); | |
| canvasCtx.fillStyle = gradient; | |
| canvasCtx.fill(); | |
| // Dış halkalar (frekansa göre) | |
| // Bass | |
| const bass = dataArray[10]; | |
| if (bass > 0) { | |
| canvasCtx.beginPath(); | |
| canvasCtx.arc(centerX, centerY, 30 + (bass / 2), 0, 2 * Math.PI); | |
| canvasCtx.strokeStyle = `rgba(139, 92, 246, ${bass / 255 * 0.5})`; | |
| canvasCtx.lineWidth = 4; | |
| canvasCtx.stroke(); | |
| } | |
| // Mid | |
| const mid = dataArray[50]; | |
| if (mid > 0) { | |
| canvasCtx.beginPath(); | |
| canvasCtx.arc(centerX, centerY, 40 + (mid / 2), 0, 2 * Math.PI); | |
| canvasCtx.strokeStyle = `rgba(236, 72, 153, ${mid / 255 * 0.4})`; | |
| canvasCtx.lineWidth = 3; | |
| canvasCtx.stroke(); | |
| } | |
| // High | |
| const high = dataArray[100]; | |
| if (high > 0) { | |
| canvasCtx.beginPath(); | |
| canvasCtx.arc(centerX, centerY, 50 + (high / 2), 0, 2 * Math.PI); | |
| canvasCtx.strokeStyle = `rgba(79, 70, 229, ${high / 255 * 0.3})`; | |
| canvasCtx.lineWidth = 2; | |
| canvasCtx.stroke(); | |
| } | |
| }; | |
| draw(); | |
| return () => { | |
| source.disconnect(); | |
| analyser.disconnect(); | |
| }; | |
| }, [audioData]); | |
| return ( | |
| <canvas | |
| ref={canvasRef} | |
| width={400} | |
| height={300} | |
| style={{ | |
| marginTop: '20px', | |
| maxWidth: '100%', | |
| filter: 'drop-shadow(0 0 10px rgba(79, 70, 229, 0.5))' | |
| }} | |
| /> | |
| ); | |
| }; | |
| export default AudioVisualizer; |