← back to Model Arena

data/artifacts/1fd68f0d37b7/gemma3-12b.html

130 lines

<!DOCTYPE html>
<html>
<head>
  <title>Microphone Audio Visualizer</title>
  <style>
    body { margin: 0; overflow: hidden; background-color: #222; color: #eee; font-family: sans-serif; }
    #container { width: 100vw; height: 100vh; display: flex; flex-direction: column; }
    #controls { padding: 10px; background-color: rgba(34, 34, 34, 0.8); }
    button { margin-right: 10px; padding: 5px 10px; border: none; outline: none; color: #fff; background-color: #444; cursor: pointer; }
    #canvas { width: 100vw; height: calc(100vh - 40px); } /* Adjust for controls */

  </style>
</head>
<body>
  <div id="container">
    <div id="controls">
      <button id="toggleTheme">Light Theme</button>
    </div>
    <canvas id="canvas"></canvas>
  </div>

  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    const toggleThemeButton = document.getElementById('toggleTheme');

    let analyser;
    let audioContext;
    let microphone;
    let isRecording = false;
    let themeLight = true;


    function requestMicrophonePermission() {
      return navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
          microphone = stream;
          return stream;
        })
        .catch(err => {
          alert("Microphone permission denied. Please check your browser settings.");
          console.error("Error accessing microphone:", err);
          return Promise.reject(err); // Reject the promise to prevent further execution
        });
    }


    function init() {
      audioContext = new (window.AudioContext || window.webkitAudioContext)();

      requestMicrophonePermission()
        .then(stream => {
          const source = audioContext.createMediaStreamSource(stream);
          analyser = audioContext.createAnalyser();
          source.connect(analyser);
          analyser.fftSize = 256;  // Adjust FFT size for resolution

          drawWaveform();
          drawFrequencyBars();

        })
        .catch(error => { console.error("Initialization failed:", error); });
    }


    function drawWaveform() {
      const bufferLength = analyser.frequencyBinCount;
      const dataArray = new Uint8Array(bufferLength);

      analyser.getByteTimeDomainData(dataArray);

      ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas before drawing

      ctx.beginPath();
      let x = 0;
      let y = canvas.height / 2; // Center vertically
      ctx.moveTo(x, y - dataArray[0]);

      for (let i = 1; i < bufferLength; i++) {
        x += 1;
        y = canvas.height / 2;
        const value = dataArray[i];
        ctx.lineTo(x, y - value);
      }

      ctx.strokeStyle = themeLight ? '#fff' : '#000';
      ctx.lineWidth = 1; // Adjust line width as needed
      ctx.stroke();
    }


    function drawFrequencyBars() {
        const bufferLength = analyser.frequencyBinCount;
        const dataArray = new Uint8Array(bufferLength);

        analyser.getByteFrequencyData(dataArray);

        const barWidth = canvas.width / bufferLength;

        ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas before drawing

        for (let i = 0; i < bufferLength; i++) {
            const height = dataArray[i];
            const x = i * barWidth;
            const y = canvas.height - height;  // Invert for vertical bars
            const width = barWidth;
            const barHeight = y;

            ctx.fillStyle = themeLight ? 'rgba(0, 255, 255, 0.5)' : 'rgba(173, 216, 230, 0.5)'; // Light blue or gray
            ctx.fillRect(x, y, width, barHeight);

        }
    }


    toggleThemeButton.addEventListener('click', () => {
      themeLight = !themeLight;
      document.body.style.backgroundColor = themeLight ? '#222' : '#333';
      toggleThemeButton.textContent = themeLight ? 'Light Theme' : 'Dark Theme';

        drawWaveform(); // Redraw waveforms with updated color
        drawFrequencyBars(); //Redraw frequency bars with updated colors
    });



    init();
  </script>
</body>
</html>