givemotion: HTML como entrada, video como salida
Una composición es un único archivo HTML. Cada fotograma es esa página en un momento concreto del tiempo. Las animaciones CSS, transiciones, Web Animations, temporizadores, requestAnimationFrame, canvas y WebGL se ejecutan sobre un reloj virtual, por lo que lo que escribes se renderiza exacto por fotograma y de forma idéntica cada vez. No se necesita ninguna etiqueta script o import: el runtime (window.gm) y una hoja de estilo predefinida se inyectan automáticamente.
Este archivo es el núcleo (léelo completo). Luego lee solo las 1-3 recetas técnicas que tu video necesite (tabla al final): cada una muestra cómo un profesional construye ese efecto, con números y un ejemplo funcional. Consulta cualquier otra cosa cuando la necesites.
El bucle
- Directo. Antes de escribir código, decide cómo haría un gran estudio este encargo: investiga el género (busca en la web ejemplos reales cuando puedas, si no, recupéralos de memoria), luego escribe al inicio del HTML: el estilo en palabras, el sistema tipográfico, el lenguaje de movimiento (familias de easing, ritmo, cómo se entregan las escenas) y el guion de tomas (una línea por momento: tiempo, qué hay en pantalla, el movimiento, la entrega). Cómo:
references/direction.md. - Fotogramas de estilo. Construye primero las 2-3 poses clave, fijas, y evalúalas como pósters (un punto focal, jerarquía, márgenes). Luego anima.
- Escribe el movimiento; ejecuta
npx givemotion check video.htmlmientras avanzas: corrige cada ✖; ⚠ son fallos reales a menos que sean intencionados; ℹ son sugerencias de estilo. - Revisa dos veces.
npx givemotion review video.htmlescribe lo que ve un espectador (resumen, los fotogramas que la gente lee, tiras de movimiento en los momentos ajetreados) yreview/REVIEW.md: puntúa con dureza, corrige los cinco peores problemas, revisa de nuevo. Ojos frescos encuentran más: dale a un sub-agente solo el brief y la carpeta review. Pon los tiempos del brief endata-expect. - Renderiza:
npx givemotion render video.html -o out/video.mp4.
--json para salida de máquina, <comando> --help para opciones. still video.html -t 3.2 -o f.png renderiza un momento concreto; inspect --at 4.5 --el "#logo" dice dónde está un elemento.
Cómo se hace buen movimiento aquí
El motor te da cualquier HTML/CSS/SVG/canvas y una línea de tiempo exacta por fotograma; el aspecto viene de cómo lo coreografías. Los espectadores ciegos prefirieron videos donde cada elemento estaba coreografiado a mano frente a videos construidos con presets de una sola palabra.
- Coreografía a mano. Usa
gm.timelinepara todo lo que importe: tiempos de inicio explícitos, easing por movimiento (unexpo.outrápido, unsine.inOutsuave, unback.out(1.6)de aterrizaje), desplazamientos de 40-120 ms entre partes relacionadas. Los presets (data-enter,data-camera) están bien para cosas secundarias pequeñas. - Tres capas en cada momento heroico: el movimiento principal; un detalle secundario que lo venda (desenfoque mientras es rápido, un resplandor, una sombra que crece, seguimiento, un anillo o partículas en el impacto); y movimiento ambiental para que el fotograma nunca esté congelado (fondo que se desplaza, cámara lenta que se acerca).
- Contraste en el tiempo. Entrada rápida, asentamiento lento; pausas de 0.4-1 s después de que algo aterriza; salidas más cortas que las entradas. Nunca muevas todo a la misma velocidad con la misma curva.
- Sigue el brief exactamente en colores, fuentes, texto, tamaños y tiempos; tu oficio se aplica a cómo se mueven las cosas, no a contenido extra.
- El fotograma 0 es el gancho, nada queda cortado por el borde del fotograma, el texto es grande (títulos 96-200 px, cuerpo ≥ 36 px a 1080p), un héroe por momento, las escenas fluyen unas dentro de otras (empuje, látigo, morph, match cut) en lugar de fundirse.
- Las cosas vienen de cosas. Un nuevo elemento nace de uno ya en pantalla, no aparece de la nada: tres círculos salen exprimidos del círculo principal; uno de los rectángulos en pantalla se desliza y se convierte en el subrayado; una tarjeta crece desde el botón que se hizo clic; la marca del logotipo se convierte en la marca de la tarjeta final. Reutiliza y transforma antes de añadir. Planta el siguiente conjunto temprano: ya en el mundo (pequeño, atenuado) mientras este compás se reproduce, para que la cámara lo revele.
- Un movimiento de cámara significa "mira aquí". Acércate solo hacia algo que el espectador deba leer a continuación. Nunca hagas zoom a un espacio vacío o a la escena anterior como forma de transición: para salir de una escena, muévete lateralmente (empuje, látigo, barrido) o lleva un elemento a través (morph, la regla anterior).
- Anima
transform/translate/scale/rotate/opacity/filter/clip-path, nowidth/top/left. - Cada elemento tiene una vida planificada: entrada, una pausa legible (~1 s + 0.25 s por palabra), luego una salida o entrega. El guion de tomas da cada pausa.
Jerarquía: una cosa importa a la vez
Los espectadores prefirieron videos donde el ojo siempre sabía dónde mirar.
- Cada línea tiene una palabra clave. Dale a la palabra que lleva el significado contraste (color de acento, peso más grueso, tamaño mayor, o un resaltado dibujado); el resto se mantiene más discreto. Una por línea, como máximo dos por pantalla. Si todo es acento, nada lo es.
- Cada momento tiene un héroe: lo más grande, brillante y con más movimiento. El soporte es más pequeño (héroe ≥ 1.6× el tamaño siguiente; como máximo tres niveles), más tenue (apagado o 50-70% de opacidad), llega después del héroe y se mueve menos. Los efectos (anillos, chispas) enmarcan al héroe, nunca lo cruzan.
- Guía el ojo en orden: el héroe aterriza primero; la palabra clave obtiene su color o subrayado 0.2-0.4 s después de que la línea se asiente; el soporte sigue. Cuando la cámara o un señalamiento se enfoca en algo, atenúa el resto.
- Roles de paleta estrictos: acento solo para énfasis, apagado para texto secundario.
Easing: adapta la curva al movimiento
- Al entrar decelera (ease-out:
expo.out,power3.out, oback.out(1.4)cuando aterriza con peso). - Al salir acelera (ease-in:
power2.in), más corto que la entrada (60-70%). - Al moverse de A a B mientras es visible, movimientos de cámara, un cambio de escala de algo ya en pantalla: ease-in-out (
power2.inOut,sine.inOut): comienza suavemente y aterriza suavemente. - Deriva ambiental:
sine.inOutlargo;linearsolo para bucles (giros, tickers). Nada que empiece o termine en pantalla se mueve linealmente. - Deja
easefuera y el motor ya hace esto (las entradas entran con resorte, los movimientos entran y salen con facilidad, las salidas entran con facilidad); cuando establezcas uno, sigue las reglas anteriores.
Composición mínima
<!doctype html>
<html data-width="1920" data-height="1080" data-fps="30" data-duration="2.5">
<head>
<style>
:root { --bg: #0b0d12; --ink: #fff; --accent: #7c9cff; }
body { background: var(--bg); color: var(--ink); font-family: Inter, sans-serif; }
.scene { display: grid; place-items: center; } /* .scene ya es absolute + marco completo */
h1 { font-size: 160px; letter-spacing: -0.03em; margin: 0; }
.glow { position: absolute; width: 900px; height: 900px; border-radius: 50%; background: var(--accent); filter: blur(160px); opacity: .25; }
</style>
</head>
<body>
<section class="scene">
<div class="glow"></div>
<h1 id="t" data-split="chars">Hello</h1>
</section>
<script>
gm.timeline('.scene')
.from('.glow', { scale: 0.6, opacity: 0, duration: 1.2, ease: 'sine.out' }, 0) // ambiente: la luz florece…
.to('.glow', { x: 220, y: -90, duration: 2.5, ease: 'sine.inOut' }, 0) // …y sigue desplazándose
.from('#t .gm-char', { y: 140, opacity: 0, filter: 'blur(12px)', duration: 0.7, ease: 'expo.out', stagger: 0.05 }, 0.2) // principal: rápido de entrada, desenfoque mientras rápido
.fromTo('#t', { letterSpacing: '0.12em' }, { letterSpacing: '-0.03em', duration: 2.4, ease: 'expo.out' }, 0.2) // detalle: el tracking se aprieta
.to('#t', { scale: 1.06, duration: 1.9, ease: 'sine.inOut' }, 0.6); // la pausa sigue respirando
</script>
</body>
</html>
Fuentes integradas: Inter, JetBrains Mono, Playfair Display, Space Grotesk, Bebas Neue, Nunito, Caveat; otras mediante @font-face.
Modelo de tiempo (léelo)
- Los ajustes viven en
<html>:data-width,data-height(números pares),data-fps(por defecto 30),data-durationopcional,data-backgroundopcional. - Los tiempos son segundos:
1.5,1.5s,500ms,45f(fotogramas),1:02.5. - Clips. Un elemento con
data-start,data-durationodata-endsolo existe (se muestra) desde el inicio hasta inicio+duration. Los tiempos son relativos al clip padre. Los elementos sin tiempo están siempre presentes. - Duración del video =
data-durationen<html>, en caso contrario el final del último clip. - Secuencias.
data-sequenceen un contenedor reproduce sus hijos uno tras otro. Cada hijo necesitadata-duration, o dale al contenedordata-cuts="0 2.13 4.27"(cuándo empieza cada hijo; también"beats: 0 4 8"/"bars: 0 1 2").data-gap="0.2"(negativo = solapamiento).data-transition="<nombre> <segundos> [easing]"solapa vecinos y anima el cambio; un hijo puede establecer su propiodata-transition(cómo entra). Cada transición descuenta su duración del total: 3 escenas de 4s confade 0.5duran 11s. Cortes en el beat,data-cut-align, y dónde se sitúa el tiempo 0 de una escena:references/timeline.md. - Transiciones:
push-/cover-/whip-/wipe-+left/right/up/down(push: lo nuevo empuja lo viejo hacia fuera; cover: lo nuevo se desliza sobre; whip: rápido, desenfocado)diagonalclockiriszoomzoom-through(la escena antigua pasa volando)flip(3D)dip(a través de negro)blurfade-upfade, ymorph: elementos con el mismodata-morph="nombre"en ambas escenas vuelan y se redimensionan desde el lugar antiguo al nuevo mientras el resto se entrecruza. Lleva un logotipo, tarjeta o número a través; en una escena usagm.fly. - Las animaciones CSS se ejecutan en tiempo de clip.
animation: fade-up .6s .4s bothcomienza .4s después de que aparezca su clip. Usaboth(obackwards) fill para que el elemento esté oculto antes de su retardo. - Algo aparece más tarde dentro de una escena larga (un mundo de cámara, una pizarra): el retardo en
data-entercuenta desde el inicio del clip del elemento, así quedata-enter="write 0.8 11.9"escribe una etiqueta 11.9 s después del inicio de la escena y la mantiene oculta hasta entonces. No se necesita clip extra. gm.onFrame(fn)obtiene el tiempo del video, incluso dentro de una escena;gm.onFrame('#s', (local, info, el) => …)cuenta desde el inicio de#s, comogm.timeline('#s').- Los temporizadores,
requestAnimationFrame,Date.now(),performance.now()son virtuales yMath.random()está seedado. El código web normal funciona.
Línea de tiempo: coreografía precisa (estilo GSAP, integrado)
Para cualquier cosa con más de unas pocas piezas móviles, usa gm.timeline: la API de GSAP que conoces, calculada a partir del tiempo (exacta por fotograma, en paralelo). Los tiempos están en segundos relativos al clip que contiene el ámbito.
gm.timeline('#scene2') // ámbito: los selectores se buscan dentro de él
.from('.title .gm-word', { y: 120, opacity: 0, rotate: 8, stagger: 0.06 }) // sin ease: entra con resorte
.to('.card', { x: 400, y: -60, scale: 1.2 }, '+=0.3') // arcos, dimensionados a la distancia
.fromTo('.bar', { scaleY: 0 }, { scaleY: 1, stagger: { each: 0.08, from: 'center' } }, '<')
.to('#line', { draw: 1, duration: 1.5 }, 2) // dibuja un trazo SVG
.to('.price', { textContent: 249, duration: 1.5 }, 2.5); // cuenta un número
gm.fly('#event', { from: '#slot2', at: 7.5, duration: 0.8 }); // vuela desde la caja de otro elemento a su propio lugar
from()/fromTo() muestran sus valores iniciales desde el inicio del clip (ocultos hasta que entran). Superposición de tweens en una propiedad: gana el inicio más reciente. Posiciones, todas las propiedades y opciones, etiquetas, keyframes, gm.fly y advertencias de SVG: references/timeline.md.
También integrado (tablas en references/api.md): presets data-enter/data-exit, data-split, data-stagger, data-count (-roll), data-type (máquina de escribir), data-scramble, data-camera (push, float, shake…), data-parallax, data-morph, data-fit, data-pulse, nombres de easing (los nombres de GSAP funcionan), keyframes CSS predefinidos y var(--px), y bloques listos para usar (npx givemotion blocks: subtítulos, ventana de código, cursor, ventana de navegador, gráficos…).
Recetas técnicas (lee las que tu video necesite)
| Tu video tiene… | Lee |
|---|---|
| Un logotipo, una intro de marca, una intro o una tarjeta final | references/techniques/logo-reveal.md |
| Texto grande que golpea, se apila, rota; un titular como estrella | references/techniques/kinetic-type.md |
| Revelaciones de texto: palabras/caracteres, máquina de escribir, escritura, desorden, resaltado | references/techniques/text-reveals.md |
| Movimientos de cámara: acercarse, seguir, látigo, ladear, zoom a un detalle, sacudir | references/techniques/camera-moves.md |
| Varias escenas que se entregan (push, whip, morph, barridos de forma) | references/techniques/scene-transitions.md |
| Resplandor, barridos de luz, degradados, grano, desenfoque, profundidad | references/techniques/light-and-depth.md |
| Números, contadores, gráficos de barras/líneas, señalamientos | references/techniques/numbers-and-charts.md |
| Líneas que se dibujan, rutas, mapas, pines, algo que viaja por un camino | references/techniques/paths-and-maps.md |
| Formas planas: crecer, aplastar, dividir, orbitar, morph | references/techniques/shapes-and-motion-graphics.md |
| Una app/interfaz con un cursor, clics, escritura, listas | references/techniques/ui-demo.md |
| Código en un editor, escritura, resaltados de línea | references/techniques/code-on-screen.md |
| Impacto y energía: golpes, sacudidas, explosiones, beats musicales | references/techniques/impacts-and-energy.md |
| Subtítulos palabra por palabra, clips verticales 9:16 | references/techniques/captions-vertical.md |
| Pizarra, boceto, dibujado a mano | references/techniques/hand-drawn.md |
| Un fondo vivo detrás de todo | references/techniques/backgrounds-and-ambient.md |
Referencia de API (consulta cuando sea necesario)
| Cuando… | Lee |
|---|---|
| Un atributo, preset, nombre de easing, CSS predefinido o bloque | references/api.md |
gm.timeline completo: posiciones, keyframes, etiquetas, gm.fly, SVG | references/timeline.md |
Mundos de gm.camera, tomas, gm.path.travel, montar, parallax | references/camera.md |
gm.chart.*, bloques de gráficos | references/charts.md |
Diagramas, flechas, data-sketch, gm.connect, gm.shape, morphs de trazados | references/diagrams.md |
Música, beats, voz en off + givemotion words, clips de video, subtítulos | references/media-audio.md |
Datos/plantillas, <gm-in … | references/data-templates.md |
| Rendimiento, exportación, composición, capas, resolución, codecs | references/rendering.md |
Blocks listos para usar: npx givemotion blocks | references/blocks.md |
| Línea de comandos: check, review, still, inspect, render | references/cli.md |
Cómo trabajar con agentes
- Divide el trabajo. Un agente para la estructura HTML, otro para los estilos y otro para la animación (
gm.timeline). O dale a un agente la escena 1, a otro la 2.data-expectles dice cuándo ocurre cada parte. - Bucle de revisión.
npx givemotion reviewescribe una reseña y la puntuación; pásale la reseña al agente que la necesita. Sin reseña, no hay confirmación. - Usa
--jsonpara check, review, still e inspect para que un agente lea la salida.readel archivo de revisión para obtener contexto. - Un sub-agente que solo vea el brief y la carpeta
review/encuentra lo que el creador pasó por alto.