HyperFrames
¿Es tu primera vez? Ejecuta la comprobación del entorno antes de empezar:
python3 /var/minis/skills/hyperframes-cli/scripts/check-env.pyEsto verifica que
minis-browser-use,ffmpeg, y las habilidades requeridas estén instaladas. Si la habilidadhyperframes-clino está, instálala:python3 /var/minis/skills/hyperframes-cli/scripts/install-skill.py \ hyperframes-cli --repo heygen-com/hyperframes --subdir skills
El HTML es la fuente de verdad para el vídeo. Una composición es un archivo HTML con atributos data-* para la temporización, una línea de tiempo de GSAP para la animación y CSS para la apariencia. El framework maneja la visibilidad de los clips, la reproducción de medios y la sincronización de la línea de tiempo.
Enfoque
Antes de escribir HTML, piensa a un alto nivel:
- Qué — ¿qué debería experimentar el espectador? Identifica el arco narrativo, los momentos clave y los puntos emocionales.
- Estructura — cuántas composiciones, cuáles son sub-composiciones vs. en línea, qué pistas transportan qué (vídeo, audio, superposiciones, subtítulos).
- Temporización — qué clips impulsan la duración, dónde caen las transiciones, cuál es el ritmo.
- Diseño — construye primero el estado final. Consulta "Diseño Antes de la Animación" más abajo.
- Animar — luego añade movimiento siguiendo las reglas de abajo.
Para ediciones pequeñas (corregir un color, ajustar la temporización, añadir un elemento), ve directamente a las reglas.
Puerta de Identidad Visual
Verifica en este orden:
- ¿Existe DESIGN.md en el proyecto? → Léelo. Usa sus colores, fuentes, reglas de movimiento y restricciones de "Lo que NO se debe hacer" exactos.
- ¿Existe visual-style.md? → Léelo. Aplica su
style_prompt_fully campos estructurados. (Nota:visual-style.mdes un archivo específico del proyecto.visual-styles.mdes la biblioteca de estilos con 8 presets con nombre — archivos diferentes). - ¿El usuario nombró un estilo (ej., "Swiss Pulse", "oscuro y tecnológico", "marca de lujo")? → Lee visual-styles.md para los 8 presets con nombre. Genera un DESIGN.md mínimo con:
## Style Prompt(un párrafo),## Colors(3-5 valores hex con roles),## Typography(1-2 familias de fuentes),## What NOT to Do(3-5 anti-patrones). - ¿Ninguno de los anteriores? → Haz 3 preguntas antes de escribir cualquier HTML:
- ¿Cuál es el ambiente? (explosivo / cinematográfico / fluido / técnico / caótico / cálido)
- ¿Lienzo claro u oscuro?
- ¿Algún color de marca, fuente o referencia visual específica? Luego genera un DESIGN.md mínimo a partir de las respuestas.
Cada composición debe rastrear su paleta y tipografía hasta un DESIGN.md, visual-style.md o una dirección explícita del usuario. Si estás usando #333, #3b82f6 o Roboto — te saltaste este paso.
Para valores predeterminados de movimiento, tamaño, patrones de entrada y suavizado — sigue house-style.md. El estilo de casa maneja CÓMO se mueven las cosas. El DESIGN.md maneja QUÉ aspecto tienen las cosas.
Diseño Antes de la Animación
Posiciona cada elemento donde debería estar en su momento más visible — el fotograma donde ha entrado completamente, está colocado correctamente y aún no está saliendo. Escríbelo como HTML+CSS estático primero. Sin GSAP todavía.
Por qué esto es importante: Si colocas los elementos en su estado de inicio animado (fuera de pantalla, escalados a 0, opacidad 0) y los interpolas hacia donde crees que deberían aterrizar, estás adivinando el diseño final. Las superposiciones son invisibles hasta que el vídeo se renderiza. Al construir el estado final primero, puedes ver y solucionar problemas de diseño antes de añadir cualquier movimiento.
El proceso
- Identifica el fotograma principal para cada escena — el momento en que la mayoría de los elementos son visibles simultáneamente. Este es el diseño que construyes.
- Escribe CSS estático para ese fotograma. El contenedor
.scene-contentDEBE llenar la escena completa usandowidth: 100%; height: 100%; padding: Npx;condisplay: flex; flex-direction: column; gap: Npx; box-sizing: border-box. Usa el padding para empujar el contenido hacia adentro — NUNCA usesposition: absolute; top: Npxen un contenedor de contenido. Los contenedores de contenido posicionados absolutamente se desbordan cuando el contenido es más alto que el espacio restante. Reservaposition: absolutesolo para elementos decorativos. - Añade entradas con
gsap.from()— anima DESDE fuera de pantalla/invisible HASTA la posición CSS. La posición CSS es la verdad fundamental; la interpolación describe el viaje para llegar allí. - Añade salidas con
gsap.to()— anima HASTA fuera de pantalla/invisible DESDE la posición CSS.
Ejemplo
/* scene-content llena la escena, el padding posiciona el contenido */
.scene-content {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 100%;
padding: 120px 160px;
gap: 24px;
box-sizing: border-box;
}
.title {
font-size: 120px;
}
.subtitle {
font-size: 42px;
}
/* El contenedor llena cualquier tamaño de escena (1920x1080, 1080x1920, etc.).
El padding posiciona el contenido. Flex + gap maneja el espaciado. */
INCORRECTO — dimensiones fijas y posicionamiento absoluto:
.scene-content {
position: absolute;
top: 200px;
left: 160px;
width: 1920px;
height: 1080px;
display: flex; /* ... */
}
// Paso 3: Animar HACIA esas posiciones
tl.from(".title", { y: 60, opacity: 0, duration: 0.6, ease: "power3.out" }, 0);
tl.from(".subtitle", { y: 40, opacity: 0, duration: 0.5, ease: "power3.out" }, 0.2);
tl.from(".logo", { scale: 0.8, opacity: 0, duration: 0.4, ease: "power2.out" }, 0.3);
// Paso 4: Animar FUERA de esas posiciones
tl.to(".title", { y: -40, opacity: 0, duration: 0.4, ease: "power2.in" }, 3);
tl.to(".subtitle", { y: -30, opacity: 0, duration: 0.3, ease: "power2.in" }, 3.1);
tl.to(".logo", { scale: 0.9, opacity: 0, duration: 0.3, ease: "power2.in" }, 3.2);
Composiciones multi-escena: un contenedor por escena
Cuando una composición tiene múltiples escenas que aparecen secuencialmente (A sale, luego B entra), nunca pongas todos los elementos de todas las escenas en un único contenedor flex compartido. Aunque cada elemento comienza con opacity: 0, flex aún asigna altura para cada hijo. Con contenido de 5 escenas en un solo contenedor, la altura total del contenedor supera con creces la altura del escenario — flex justify-content: center luego centra el contenido en relación con ese contenedor sobredimensionado, empujando el contenido visible fuera del recorte de la captura de pantalla.
INCORRECTO — todas las escenas en un contenedor flex:
<div class="scene-content"> <!-- flex column, height:100% -->
<!-- Elementos de la Escena A -->
<div id="title-a" style="opacity:0">Título A</div>
<div id="body-a" style="opacity:0">Cuerpo A</div>
<!-- Elementos de la Escena B — también ocupan altura flex incluso cuando son invisibles -->
<div id="title-b" style="opacity:0">Título B</div>
<div id="body-b" style="opacity:0">Cuerpo B</div>
<!-- Escena C ... -->
</div>
CORRECTO — cada escena es su propia capa absoluta:
<!-- Escena A -->
<div class="scene" id="scene-a">
<div id="title-a" style="opacity:0">Título A</div>
<div id="body-a" style="opacity:0">Cuerpo A</div>
</div>
<!-- Escena B — impacto de altura cero en la Escena A -->
<div class="scene" id="scene-b">
<div id="title-b" style="opacity:0">Título B</div>
<div id="body-b" style="opacity:0">Cuerpo B</div>
</div>
/* Cada escena llena el escenario de forma independiente */
.scene {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 80px 120px;
box-sizing: border-box;
z-index: 2;
gap: 24px;
}
Este es el único patrón correcto para escenas secuenciales. El position: absolute; inset: 0 en cada contenedor de escena NO entra en conflicto con la guía "Diseño Antes de la Animación" — esa guía prohíbe posicionar absolutamente elementos de contenido (títulos, tarjetas, estadísticas) en desplazamientos de píxeles fijos. Los contenedores de escena que llenan el escenario completo mediante inset: 0 son correctos y necesarios.
Cuando los elementos comparten espacio a lo largo del tiempo
Si el elemento A sale antes de que el elemento B entre en la misma área, ambos deben tener posiciones CSS correctas para sus respectivos fotogramas principales. El orden de la línea de tiempo garantiza que nunca coexistan visualmente — pero si te saltas el paso de diseño, no detectarás el caso en que se superpongan accidentalmente debido a un error de temporización.
Qué cuenta como superposición intencional
Los efectos en capas (brillo detrás del texto, elementos de sombra, patrones de fondo) y los diseños apilados en z (pilas de tarjetas, capas de profundidad) son intencionales. El paso de diseño se trata de detectar superposiciones no intencionales — dos titulares cayendo uno sobre otro, una estadística cubriendo una etiqueta, contenido desbordándose del fotograma.
Atributos de Datos
Todos los Clips
| Atributo | Requerido | Valores |
|---|---|---|
id | Sí | Identificador único |
data-start | Sí | Segundos o referencia al ID del clip ("el-1", "intro + 2") |
data-duration | Requerido para img/div/composiciones | Segundos. Vídeo/audio por defecto a la duración del medio. |
data-track-index | Sí | Entero. Los clips en la misma pista no pueden solaparse. |
data-media-start | No | Desplazamiento de recorte dentro de la fuente (segundos) |
data-volume | No | 0-1 (por defecto 1) |
data-track-index NO afecta la superposición visual — usa CSS z-index.
Clips de Composición
| Atributo | Requerido | Valores |
|---|---|---|
data-composition-id | Sí | Identificador único de la composición |
data-start | Sí | Tiempo de inicio (composición raíz: usa "0") |
data-duration | Sí | Tiene prioridad sobre la duración de la línea de tiempo de GSAP |
data-width / data-height | Sí | Dimensiones en píxeles (1920x1080 o 1080x1920) |
data-composition-src | No | Ruta al archivo HTML externo |
Estructura de la Composición
Las sub-composiciones cargadas mediante data-composition-src usan un envoltorio <template>. Las composiciones independientes (el index.html principal) NO usan <template> — colocan el div con data-composition-id directamente en <body>. Usar <template> en un archivo independiente oculta todo el contenido del navegador y rompe el renderizado.
Estructura de sub-composición:
<template id="my-comp-template">
<div data-composition-id="my-comp" data-width="1920" data-height="1080">
<!-- contenido -->
<style>
[data-composition-id="my-comp"] {
/* estilos con ámbito */
}
</style>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<script>
window.__timelines = window.__timelines || {};
const tl =