<!DOCTYPE html>
<html>
<head>
  <title>ASMR Audio Positioner</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #1c1c1c;
      color: #f1f1f1;
    }

    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 80vh;
      width: 100%;
      position: fixed;
      top: 0;
      left: 0;
    }

    .ear {
      width: 20vw;
      height: 20vw;
      max-width: 120px;
      max-height: 120px;
      background-color: #333;
      border-radius: 50%;
      margin: 0 5vw;
      display: flex;
      justify-content: center;
      align-items: center;
      overflow: hidden;
      position: relative;
    }

    .ear img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .right-ear {
      order: 1;
    }

    .left-ear {
      order: 3;
    }

    .center-ear {
      order: 2;
      width: 25vw;
      height: 25vw;
      max-width: 160px;
      max-height: 160px;
      background-color: #555;
      border-radius: 50%;
      margin: 0 3vw;
    }

    .audio-position {
      width: 8vw;
      height: 8vw;
      max-width: 40px;
      max-height: 40px;
      background-color: #888;
      border-radius: 50%;
      position: absolute;
      cursor: move;
      z-index: 1;
    }

    .button-container {
      position: fixed;
      bottom: 20px;
      left: 0;
      right: 0;
      text-align: center;
    }

    .record-btn {
      margin: 0 5px;
      padding: 10px 20px;
      font-size: 16px;
      background-color: #333;
      color: #f1f1f1;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }

    .record-btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    .config-menu {
      position: fixed;
      bottom: -200px;
      left: 0;
      right: 0;
      background-color: rgba(51, 51, 51, 0.9);
      padding: 20px;
      transition: bottom 0.3s ease;
      border-top-left-radius: 10px;
      border-top-right-radius: 10px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .config-menu.open {
      bottom: 0;
    }

    .config-option {
      margin-bottom: 10px;
      display: flex;
      align-items: center;
    }

    .config-option label {
      margin-right: 10px;
    }

    .transparency-line {
      position: absolute;
      left: 0;
      right: 0;
      height: 1px;
      background-color: rgba(255, 255, 255, 0.2);
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding-right: 10px;
      font-size: 12px;
    }

    .close-btn {
      margin-top: 20px;
      padding: 10px 20px;
      font-size: 16px;
      background-color: #555;
      color: #f1f1f1;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="ear right-ear">
      <img src="imagenes/derecho.jpg" alt="Right Ear">
    </div>
    <div class="ear center-ear">
      <img src="C:\Users\ACER\Desktop\Asmr\imagenes\muñeca.jpeg" alt="Center Ear">
    </div>
    <div class="ear left-ear">
      <img src="imagenes/izquierdo.jpg" alt="Left Ear">
    </div>
    <div class="audio-position" id="audioPosition"></div>
  </div>
  <div class="button-container">
    <button class="record-btn" id="recordBtn">Record</button>
    <button class="record-btn" id="stopBtn" disabled>Stop</button>
    <button class="record-btn" id="downloadBtn" disabled>Download</button>
    <button class="record-btn" id="configBtn">Config</button>
  </div>
  <div class="config-menu" id="configMenu">
    <div class="config-option">
      <label for="transparencyLines">Transparency Lines:</label>
      <input type="checkbox" id="transparencyLines">
    </div>
    <button class="close-btn" id="closeBtn">Close</button>
  </div>
  <script>
    const audioPosition = document.getElementById('audioPosition');
    const recordBtn = document.getElementById('recordBtn');
    const stopBtn = document.getElementById('stopBtn');
    const downloadBtn = document.getElementById('downloadBtn');
    const configBtn = document.getElementById('configBtn');
    const configMenu = document.getElementById('configMenu');
    const transparencyLinesCheckbox = document.getElementById('transparencyLines');
    const closeBtn = document.getElementById('closeBtn');
    
    let isDragging = false;
    let currentX;
    let currentY;
    let initialX;
    let initialY;
    let xOffset = 0;
    let yOffset = 0;
    
    let mediaRecorder;
    let recordedChunks = [];
    let audioContext;
    let sourceNode;
    let pannerNode;
    let gainNode;
    let destinationNode;
    let positions = [];
    
    audioPosition.addEventListener('mousedown', dragStart);
    audioPosition.addEventListener('touchstart', dragStart);
    document.addEventListener('mouseup', dragEnd);
    document.addEventListener('touchend', dragEnd);
    document.addEventListener('mousemove', drag);
    document.addEventListener('touchmove', drag);
    
    configBtn.addEventListener('click', toggleConfigMenu);
    transparencyLinesCheckbox.addEventListener('change', toggleTransparencyLines);
    closeBtn.addEventListener('click', closeConfigMenu);
    
    function dragStart(e) {
      if (e.type === 'touchstart') {
        initialX = e.touches[0].clientX - xOffset;
        initialY = e.touches[0].clientY - yOffset;
      } else {
        initialX = e.clientX - xOffset;
        initialY = e.clientY - yOffset;
      }
      isDragging = true;
    }
    
    function dragEnd() {
      isDragging = false;
    }
    
    function drag(e) {
      if (isDragging) {
        e.preventDefault();
        if (e.type === 'touchmove') {
          currentX = e.touches[0].clientX - initialX;
          currentY = e.touches[0].clientY - initialY;
        } else {
          currentX = e.clientX - initialX;
          currentY = e.clientY - initialY;
        }
        xOffset = currentX;
        yOffset = currentY;
        setTranslate(currentX, currentY, audioPosition);
        updateAudio();
      }
    }
    
    function setTranslate(xPos, yPos, el) {
      el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
    }
    
    recordBtn.addEventListener('click', startRecording);
    stopBtn.addEventListener('click', stopRecording);
    downloadBtn.addEventListener('click', downloadRecording);
    
    function startRecording() {
      recordedChunks = [];
      positions = [];
    
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
          audioContext = new AudioContext();
          sourceNode = audioContext.createMediaStreamSource(stream);
          pannerNode = audioContext.createPanner();
          gainNode = audioContext.createGain();
          destinationNode = audioContext.createMediaStreamDestination();
          sourceNode.connect(pannerNode);
          pannerNode.connect(gainNode);
          gainNode.connect(destinationNode);
          mediaRecorder = new MediaRecorder(destinationNode.stream);
          mediaRecorder.addEventListener('dataavailable', handleDataAvailable);
          mediaRecorder.start();
          recordBtn.disabled = true;
          stopBtn.disabled = false;
          updateAudio();
        })
        .catch(error => {
          console.error('Error accessing microphone:', error);
        });
    }
    
    function stopRecording() {
      mediaRecorder.stop();
      recordBtn.disabled = false;
      stopBtn.disabled = true;
      downloadBtn.disabled = false;
      sourceNode.disconnect();
      pannerNode.disconnect();
      gainNode.disconnect();
      destinationNode.disconnect();
      audioContext.close();
    }
    
    function handleDataAvailable(event) {
      if (event.data.size > 0) {
        recordedChunks.push(event.data);
      }
    }
    
    function downloadRecording() {
      const blob = new Blob(recordedChunks, { type: 'audio/webm' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'recording.webm';
      a.click();
      URL.revokeObjectURL(url);
      downloadBtn.disabled = true;
    }
    
    function updateAudio() {
      if (pannerNode && gainNode) {
        const containerWidth = document.querySelector('.container').offsetWidth;
        const containerHeight = document.querySelector('.container').offsetHeight;
        const earWidth = document.querySelector('.ear').offsetWidth;
        const centerX = currentX + initialX;
        const centerY = currentY + initialY;
        const normalizedX = (centerX - earWidth) / (containerWidth - 2 * earWidth);
        const normalizedY = 1 - (centerY / containerHeight);
    
        const panValue = normalizedX * 2 - 1;
        pannerNode.setPosition(panValue, 0, 1 - Math.abs(panValue));
    
        const gainValue = normalizedY;
        gainNode.gain.setValueAtTime(gainValue, audioContext.currentTime);
    
        positions.push({ x: normalizedX, y: normalizedY });
      }
    }
    
    function toggleConfigMenu() {
      configMenu.classList.toggle('open');
    }
    
    function toggleTransparencyLines() {
      if (transparencyLinesCheckbox.checked) {
        showTransparencyLines();
      } else {
        hideTransparencyLines();
      }
    }
    
    function closeConfigMenu() {
      configMenu.classList.remove('open');
    }
    
// Función para mostrar las líneas de transparencia
function showTransparencyLines() {
  const volumeLevels = [0, 20, 40, 60, 80, 100, 120, 140];
  const container = document.querySelector('.container');
  const containerHeight = container.offsetHeight;

  // Eliminar las líneas existentes para evitar duplicados
  hideTransparencyLines();

  volumeLevels.forEach(level => {
    const line = document.createElement('div');
    line.classList.add('transparency-line');
    // Calcula la posición de la línea basada en su nivel
    // El nivel más alto (140) se sitúa en la parte superior del contenedor (top = 0)
    // El nivel más bajo (0) se sitúa en la parte inferior del contenedor (top = containerHeight)
    line.style.top = `${containerHeight - (level / 140) * containerHeight}px`;
    line.textContent = level;
    container.appendChild(line);
  });
}

// Función para ocultar las líneas de transparencia
function hideTransparencyLines() {
  const lines = document.querySelectorAll('.transparency-line');
  lines.forEach(line => line.remove());
}
    
    function hideTransparencyLines() {
      const lines = document.querySelectorAll('.transparency-line');
      lines.forEach(line => line.remove());
    }
    </script>
    
</body>
</html>