# Mambo DVD Salvapantallas tipo logo de DVD: Mambo rebota en bucle por la pantalla, cambia de color y suena en cada rebote. Cuando cae justo en una esquina, esa esquina se queda encendida con el color exacto del golpe. ## Cómo abrirlo Doble clic en `index.html`. No necesita servidor ni instalar nada. El navegador no deja reproducir audio sin una interacción previa, por eso la portada pide un clic en **Iniciar** antes de arrancar. ## Controles | Tecla | Acción | |---|---| | `Espacio` | Pausar y reanudar (también funciona haciendo clic) | | `S` | Probar el sonido | | `E` | Precisión de esquina: Normal · Generosa · Real | | `C` | Modo de color: Tinte · Sólido · Original | | `F` | Pantalla completa | | `+` / `−` | Velocidad, de 0.25× a 4× | | `R` | Reiniciar contadores y trayectoria | | `H` | Ocultar el HUD | ## Modos de color - **Tinte** — gira el matiz del peluche conservando la ilustración. - **Sólido** — silueta plana de un color, que es lo que hacía el logo original. - **Original** — sin recoloreo. ## Precisión de esquina Una esquina exacta significa rebotar en los dos ejes en el mismo fotograma, y eso casi nunca pasa: en pruebas a 1920×1080 con margen fijo de 15 px salieron 0 esquinas en 60 segundos. Por eso la tolerancia es un porcentaje del lado menor de la ventana y no un valor en píxeles. - **Real** (0.8 %) — purista, pueden pasar muchos minutos. - **Normal** (4.5 %) — por defecto, una esquina cada pocos minutos. - **Generosa** (11 %) — para verlo seguido. ## Archivos | Archivo | Qué hace | |---|---| | `index.html` | Estructura: escenario, sprite, HUD y portada | | `styles.css` | Paleta OSD de reproductor de DVD, animaciones de impacto | | `app.js` | Física del rebote, detección de esquina, color y audio | | `Mambo_png.png` | El sprite | | `mambo_audio.ogg` | El sonido del rebote | ## Detalles de implementación - El movimiento va por **delta de tiempo**, no por fotograma, así que se ve igual a 60 Hz que a 144 Hz. El delta se acota a 50 ms para que volver de una pestaña en segundo plano no provoque un salto. - El modo Sólido se pinta en **canvas con `source-in`**, no con `mask-image`. Las máscaras CSS pasan por CORS y en `file://` (origen `null`) el sprite quedaba invisible. El canvas solo compone y nunca lee píxeles, así que el *taint* no molesta. - El desbloqueo de audio reproduce en silencio y **deja terminar** el clip. La versión con `pause()` abortaba el golpe real que cayera dentro de esa ventana y lo perdía con un `AbortError`. - El color avanza con el **ángulo áureo** (137.508°) para que dos rebotes seguidos nunca den colores parecidos.