diff --git a/index.php b/index.php index dde0b20..baf70b4 100644 --- a/index.php +++ b/index.php @@ -312,23 +312,44 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489"; .visualizer-container { width: 100%; - height: 100px; + height: 120px; margin-bottom: 1rem; display: flex; align-items: flex-end; justify-content: center; + gap: 4px; overflow: hidden; border-bottom: 1px solid rgba(255, 255, 255, 0.1); - background: radial-gradient(circle at center, rgba(56, 189, 248, 0.1) 0%, transparent 70%); + background: radial-gradient(circle at center, rgba(56, 189, 248, 0.05) 0%, transparent 70%); position: relative; + padding: 0 10px; } - #visualizer { + .audio-visualizer { + display: flex; + align-items: flex-end; + justify-content: center; + gap: 4px; width: 100%; height: 100%; - filter: drop-shadow(0 0 8px rgba(0, 230, 118, 0.5)); } + .visualizer-bar { + width: 18px; + height: 5px; + border-radius: 4px 4px 0 0; + background: var(--primary-color); + transition: height 0.05s ease; + min-height: 5px; + } + + /* Colores vibrantes para las barras */ + .visualizer-bar:nth-child(5n+1) { background: linear-gradient(to top, #00e676, #69f0ae); } + .visualizer-bar:nth-child(5n+2) { background: linear-gradient(to top, #38bdf8, #7dd3fc); } + .visualizer-bar:nth-child(5n+3) { background: linear-gradient(to top, #facc15, #fde047); } + .visualizer-bar:nth-child(5n+4) { background: linear-gradient(to top, #f472b6, #fb923c); } + .visualizer-bar:nth-child(5n+5) { background: linear-gradient(to top, #818cf8, #a5b4fc); } + /* Playing Animations */ body.is-playing .glass-card { animation: card-pulse 4s infinite ease-in-out; @@ -657,7 +678,7 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
- +
@@ -780,40 +801,42 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489"; const playBtn = document.getElementById('play-pause'); const playIcon = document.getElementById('play-icon'); const trackTitle = document.getElementById('track-title'); - const canvas = document.getElementById('visualizer'); - const ctx = canvas.getContext('2d'); + const visualizerContainer = document.getElementById('audio-visualizer'); let audioCtx; let analyzer; let source; let animationId; - let bars = []; + const BAR_COUNT = 16; + let visualizerBars = []; function initVisualizer() { if (audioCtx) return; + // Create bars + visualizerContainer.innerHTML = ''; + visualizerBars = []; + for (let i = 0; i < BAR_COUNT; i++) { + const bar = document.createElement('div'); + bar.className = 'visualizer-bar'; + visualizerContainer.appendChild(bar); + visualizerBars.push(bar); + } + audioCtx = new (window.AudioContext || window.webkitAudioContext)(); analyzer = audioCtx.createAnalyser(); source = audioCtx.createMediaElementSource(audio); source.connect(analyzer); analyzer.connect(audioCtx.destination); - analyzer.fftSize = 256; + analyzer.fftSize = 128; const bufferLength = analyzer.frequencyBinCount; const dataArray = new Uint8Array(bufferLength); - function resizeCanvas() { - canvas.width = canvas.offsetWidth * window.devicePixelRatio; - canvas.height = canvas.offsetHeight * window.devicePixelRatio; - ctx.scale(window.devicePixelRatio, window.devicePixelRatio); - } - resizeCanvas(); - window.addEventListener('resize', resizeCanvas); - let colorOffset = 0; function draw() { if (audio.paused) { - ctx.clearRect(0, 0, canvas.width, canvas.height); + visualizerBars.forEach(bar => bar.style.height = '5px'); document.documentElement.style.setProperty('--dynamic-glow', 'rgba(56, 189, 248, 0.7)'); document.documentElement.style.setProperty('--dynamic-glow-dim', 'rgba(56, 189, 248, 0.4)'); return; @@ -821,51 +844,23 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489"; animationId = requestAnimationFrame(draw); analyzer.getByteFrequencyData(dataArray); - ctx.clearRect(0, 0, canvas.width, canvas.height); + colorOffset += 1; - const barCount = 40; // Número de barras fijas para un look más limpio - const logicalWidth = canvas.width / window.devicePixelRatio; - const logicalHeight = canvas.height / window.devicePixelRatio; - const gap = 4; - const barWidth = (logicalWidth / barCount) - gap; - - colorOffset += 2; - - for (let i = 0; i < barCount; i++) { - // Mapear el índice de la barra a la frecuencia (usando una escala logarítmica para mejor visual) - const frequencyIndex = Math.floor(Math.pow(i / barCount, 1.5) * (bufferLength / 2)); - const barHeight = (dataArray[frequencyIndex] / 255) * logicalHeight * 0.8 + 5; + for (let i = 0; i < BAR_COUNT; i++) { + // Map frequency data to bars + const freqIndex = Math.floor((i / BAR_COUNT) * (dataArray.length * 0.8)); + const val = dataArray[freqIndex]; + const height = (val / 255) * 100 + 5; - const x = i * (barWidth + gap); - const barHue = (colorOffset + (i / barCount) * 200) % 360; - - const gradient = ctx.createLinearGradient(0, logicalHeight, 0, logicalHeight - barHeight); - gradient.addColorStop(0, `hsla(${barHue}, 100%, 50%, 0.2)`); - gradient.addColorStop(0.5, `hsla(${barHue}, 100%, 50%, 0.8)`); - gradient.addColorStop(1, `hsla(${(barHue + 60) % 360}, 100%, 70%, 1)`); - - ctx.fillStyle = gradient; - - // Dibujar barra con bordes redondeados superiores - ctx.beginPath(); - if (ctx.roundRect) { - ctx.roundRect(x, logicalHeight - barHeight, barWidth, barHeight, [5, 5, 0, 0]); - } else { - ctx.rect(x, logicalHeight - barHeight, barWidth, barHeight); + if (visualizerBars[i]) { + visualizerBars[i].style.height = `${height}%`; } - ctx.fill(); - - // Añadir un "cap" o punto brillante arriba de la barra - ctx.fillStyle = `hsla(${(barHue + 60) % 360}, 100%, 80%, 1)`; - ctx.beginPath(); - ctx.arc(x + barWidth/2, logicalHeight - barHeight, barWidth/3, 0, Math.PI * 2); - ctx.fill(); } - // Efecto de brillo dinámico en la tarjeta basado en el volumen medio + // Dynamic glow effect based on average volume let sum = 0; - for(let i=0; i