Históricamente, las aplicaciones web sufrían una limitación importante frente al software nativo de escritorio: en cuanto el usuario minimizaba el navegador o cambiaba a su editor de código, hoja de cálculo o documento de diseño, la interfaz de la aplicación web quedaba oculta en una pestaña de fondo. Para herramientas de gestión del tiempo como PomoTask, mantener el reloj visible sin ocupar espacio en el monitor principal es un requisito clave de ergonomía visual.
1. De Video Picture-in-Picture a Document Picture-in-Picture API
La primera generación de la API Picture-in-Picture solo permitía extraer un elemento <video> a una ventana flotante sin controles personalizados. Para mostrar un temporizador interactivo en esa época, era necesario dibujar cada fotograma en un <canvas> oculto, capturar un flujo de medios mediante canvas.captureStream(30) e inyectarlo en un elemento de video.
Hoy en día, los navegadores basados en Chromium soportan la Document Picture-in-Picture API (window.documentPictureInPicture), que abre una ventana flotante Always-on-Top con su propio árbol DOM completo donde podemos renderizar HTML, CSS e incluso botones interactivos (Pausar, Reiniciar, Saltar ciclo):
async function openFloatingTimerWidget() {
if ('documentPictureInPicture' in window) {
const pipWindow = await window.documentPictureInPicture.requestWindow({
width: 260,
height: 260,
});
// Copiar hojas de estilo o inyectar diseño compacto en forma de tomate
const style = pipWindow.document.createElement('style');
style.textContent = `
body {
margin: 0;
background: radial-gradient(circle at 30% 30%, #ef4444, #991b1b);
color: #fff;
font-family: system-ui, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
user-select: none;
}
.time { font-size: 3rem; font-weight: 800; letter-spacing: -0.03em; }
`;
pipWindow.document.head.appendChild(style);
// Insertar contenedor interactivo...
}
}
2. Estrategia Híbrida de Compatibilidad (Graceful Degradation)
En ingeniería de software de calidad, nunca debemos asumir que todos los usuarios ejecutan el mismo motor de navegador. En PomoTask implementamos una arquitectura de tres niveles para el mini-reloj flotante:
- Nivel 1 (Document PiP API): Ventana DOM interactiva con botones de control directo y animaciones vectoriales SVG.
- Nivel 2 (Canvas + Video PiP Fallback): Para navegadores que soportan PiP de video estándar (como Safari en macOS/iOS), un motor de renderizado 2D dibuja el reloj, el anillo de progreso y el estado actual en un
HTMLCanvasElementy lo transmite a unHTMLVideoElementmediante MediaSession API. - Nivel 3 (Popup Compacto / Notificaciones): En entornos sin soporte PiP, se ofrece una ventana emergente dimensionada sin barras de herramientas junto con actualización en vivo del
document.title.
3. Prevención de Apagado de Pantalla con Screen Wake Lock API
Cuando un usuario utiliza su teléfono móvil o tableta sobre el escritorio como reloj de estudio, el sistema operativo apaga la pantalla tras 30 o 60 segundos de inactividad táctil. Mediante la Screen Wake Lock API (navigator.wakeLock.request('screen')), podemos solicitar un bloqueo de pantalla activo únicamente mientras el temporizador está corriendo, liberándolo automáticamente en cuanto el usuario pausa la sesión o la pestaña pasa a segundo plano:
let wakeLockSentinel = null;
async function acquireWakeLock() {
if ('wakeLock' in navigator && document.visibilityState === 'visible') {
try {
wakeLockSentinel = await navigator.wakeLock.request('screen');
} catch (err) {
// El sistema puede rechazarlo si el modo de ahorro de batería extremo está activo
}
}
}
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible' && isTimerRunning) {
acquireWakeLock();
}
});
Esta gestión responsable de permisos asegura que la batería del dispositivo solo se utilice cuando el usuario realmente está en una sesión activa de concentración.