File size: 3,153 Bytes
9f48b33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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;