diff --git a/index.php b/index.php index e39c5d6..b94c010 100644 --- a/index.php +++ b/index.php @@ -82,6 +82,20 @@ $liveIndex = get_live_index($schedule); --bg-dark: #0f172a; --glass-bg: rgba(255, 255, 255, 0.03); --glass-border: rgba(255, 255, 255, 0.08); + --flash-color: #ffffff; + } + + .flash-effect { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 9999; + background-color: var(--flash-color); + opacity: 0; + mix-blend-mode: overlay; } body, html { @@ -604,6 +618,7 @@ $liveIndex = get_live_index($schedule);
+ @@ -707,6 +722,25 @@ $liveIndex = get_live_index($schedule); let waveColor = "rgba(56, 189, 248, 0.8)"; // Default primary let waveGlow = "rgba(56, 189, 248, 0.4)"; + function hexToRgb(hex) { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; + } + + function getComplementaryColor(rgbaStr) { + // Extract r, g, b from rgba(r, g, b, a) + const match = rgbaStr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/); + if (!match) return "#ffffff"; + const r = 255 - parseInt(match[1]); + const g = 255 - parseInt(match[2]); + const b = 255 - parseInt(match[3]); + return `rgb(${r}, ${g}, ${b})`; + } + const programColors = { "Amanecer Techno": { main: "rgba(0, 230, 118, 0.8)", glow: "rgba(0, 230, 118, 0.4)" }, "Sesiones de House Vocal": { main: "rgba(244, 114, 182, 0.8)", glow: "rgba(244, 114, 182, 0.4)" }, @@ -741,6 +775,20 @@ $liveIndex = get_live_index($schedule); const average = sum / 30; const boost = (average / 128.0); // Factor between 0 and 2 + // Flash Effect Detection (Drop detection) + const flashEl = document.querySelector(".flash-effect"); + if (boost > 1.6 && Math.random() > 0.96) { + const useWhite = Math.random() > 0.5; + const flashColor = useWhite ? "#ffffff" : getComplementaryColor(waveColor); + document.documentElement.style.setProperty("--flash-color", flashColor); + flashEl.style.opacity = "0.3"; + setTimeout(() => { + flashEl.style.transition = "opacity 0.4s ease-out"; + flashEl.style.opacity = "0"; + }, 40); + setTimeout(() => { flashEl.style.transition = ""; }, 500); + } + // Update CSS variables for background pulse document.body.style.setProperty("--pulse-intensity", (1 + boost * 0.15).toString()); floatingMics.forEach(mic => { @@ -749,12 +797,11 @@ $liveIndex = get_live_index($schedule); canvasCtx.clearRect(0, 0, canvas.width, canvas.height); - // --- Particle System (Fire/Sparks) --- - if (boost > 1.2) { // Threshold for intense bass - const particleCount = Math.floor(boost * 3); + // --- Particle System (Fire/Sparks with Smoke Trail) --- + if (boost > 1.2) { + const particleCount = Math.floor(boost * 2); for (let i = 0; i < particleCount; i++) { const x = Math.random() * canvas.width; - // Find approximate y of the wave at this x const dataIdx = Math.floor((x / canvas.width) * dataArray.length); const v = dataArray[dataIdx] / 128.0; const amplitude = (v - 1) * (1.5 + boost * 2) + 1; @@ -767,7 +814,8 @@ $liveIndex = get_live_index($schedule); vy: -Math.random() * 6 - (boost * 4), alpha: 1, size: Math.random() * 3 + 1, - color: waveColor.replace("0.8", "1") // More solid for sparks + color: waveColor.replace("0.8", "1"), + trail: [] }); } } @@ -775,16 +823,29 @@ $liveIndex = get_live_index($schedule); // Update and draw particles for (let i = particles.length - 1; i >= 0; i--) { const p = particles[i]; + + // Add to trail + p.trail.push({ x: p.x, y: p.y, alpha: p.alpha }); + if (p.trail.length > 10) p.trail.shift(); + p.x += p.vx; p.y += p.vy; - p.vy += 0.2; // Gravity - p.alpha -= 0.02; // Fade out + p.vy += 0.22; // Gravity + p.alpha -= 0.015; // Slower fade for smoke effect if (p.alpha <= 0) { particles.splice(i, 1); continue; } + // Draw Trail (Smoke) + p.trail.forEach((point, idx) => { + canvasCtx.beginPath(); + canvasCtx.arc(point.x, point.y, p.size * (idx / p.trail.length), 0, Math.PI * 2); + canvasCtx.fillStyle = p.color.replace("1)", `${point.alpha * 0.2})`); + canvasCtx.fill(); + }); + canvasCtx.save(); canvasCtx.globalAlpha = p.alpha; canvasCtx.fillStyle = p.color;