← back to Model Arena

data/artifacts/1fd68f0d37b7/qwen3-14b.html

115 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Audio Visualizer</title>
  <style>
    body {
      margin: 0;
      background: #111;
      color: #fff;
      font-family: sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
      overflow: hidden;
    }
    canvas {
      display: block;
      margin: 0 auto;
      background: #000;
    }
    #toggle {
      position: absolute;
      top: 10px;
      right: 10px;
      padding: 8px 16px;
      background: #333;
      border: none;
      color: #fff;
      cursor: pointer;
      border-radius: 4px;
    }
    #message {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      text-align: center;
      font-size: 1.2em;
      opacity: 0;
      transition: opacity 0.5s;
    }
    #message.visible {
      opacity: 1;
    }
  </style>
</head>
<body>
  <button id="toggle">Toggle Theme</button>
  <canvas id="canvas" width="800" height="300"></canvas>
  <div id="message">Microphone access denied. Please allow access to use the visualizer.</div>

  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    const toggleBtn = document.getElementById('toggle');
    const message = document.getElementById('message');
    let isDarkTheme = true;

    let audioCtx;
    let analyser;
    let source;
    let dataArray;

    function initAudio() {
      audioCtx = new (window.AudioContext || window.webkitAudioContext)();
      analyser = audioCtx.createAnalyser();
      analyser.fftSize = 256;
      const bufferLength = analyser.frequencyBinCount;
      dataArray = new Uint8Array(bufferLength);

      navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
          source = audioCtx.createMediaStreamSource(stream);
          source.connect(analyser);
          draw();
        })
        .catch(err => {
          message.classList.add('visible');
          console.error('Microphone access denied:', err);
        });
    }

    function draw() {
      requestAnimationFrame(draw);
      analyser.getByteFrequencyData(dataArray);
      const width = canvas.width;
      const height = canvas.height;
      ctx.fillStyle = '#000';
      ctx.fillRect(0, 0, width, height);

      const barWidth = (width / dataArray.length) * 2.5;
      let x = 0;

      for (let i = 0; i < dataArray.length; i++) {
        const barHeight = dataArray[i];
        const bar = barHeight * 2.5;

        ctx.fillStyle = isDarkTheme ? `rgb(${barHeight}, ${barHeight}, ${255 - barHeight})` : `rgb(${255 - barHeight}, ${barHeight}, ${barHeight})`;
        ctx.fillRect(x, height - bar, barWidth, bar);
        x += barWidth + 1;
      }
    }

    toggleBtn.addEventListener('click', () => {
      isDarkTheme = !isDarkTheme;
      toggleBtn.textContent = isDarkTheme ? 'Toggle Theme' : 'Toggle Theme';
    });

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