Diseñador de motion
El video generado por agentes tiene un aspecto característico que proviene de los valores por defecto: cada elemento aparece con un fade up de unos 24 px con power3.out durante 0.4 a 0.6 s, con 0.08 s de separación, y luego nada se mueve. La propia guía de animación de HyperFrames lo define como su configuración predeterminada (gsap.defaults({ duration: 0.6, ease: "power3.out" })). Este skill la anula. Cuando entre en conflicto con los valores de movimiento de otro skill, este tiene prioridad; toma la estructura de esos skills, nunca las curvas ni el tiempo.
Eres el diseñador de motion. Decide qué sensación debe transmitir la pieza y luego elige. Dos piezas no deben moverse igual.
Ciclo de trabajo
- Lee
LIBRARY.md(junto a este archivo): registros, curvas, resortes, tiempos, dispositivos, tratamientos de texto. - Elige un registro para la pieza (técnico, editorial, premium, expresivo, juguetón, calmado). Mezclar está bien; un momento expresivo en una pieza técnica es normal.
- Para cada elemento, decide qué es su movimiento antes de cómo se desacelera (sección 6 de LIBRARY): ¿esta línea aparece de golpe, se escribe, ajusta su tracking o se lanza? La mayoría del texto de apoyo aparece de golpe.
- Añade
motion-kit.jsa la composición (assets/motion-kit.js, cargado después de GSAP) y úsalo para animar. - Recorre el resultado fotograma a fotograma y ejecuta las comprobaciones de la sección 8 de LIBRARY.
Reglas
- Sin ajustes predefinidos con nombre como valores por defecto. Ni
power1apower4, ni CSSease, ni un valor por defecto del framework. Cada curva se elige para el movimiento:MotionKit.curve('kit.land'), una curva del sistema (m3.emphasizedDecelerate,carbon.expressive.entrance), o tu propiaMotionKit.bez(x1, y1, x2, y2). - Una curva por propiedad. x e y pueden ser diferentes (
arc), para que el recorrido se curve como lo haría un objeto lanzado. - Duración basada en distancia y peso, no en el hábito de 0.3 a 0.6 s:
MotionKit.dur(px, weight). - Las salidas son más rápidas que las entradas (aproximadamente 0.65x) y aceleran hacia fuera (
kit.leave,exitTo). - Un elemento líder y sus reacciones, con desplazamientos asimétricos (
MotionKit.react(i): 0, 4, 9, 15, 22, 30 fotogramas), nunca un escalonamiento uniforme. - Las pausas se mantienen vivas (un lento desplazamiento de cámara, un
wiggleen un contenedor, un detalle vivo) a menos que la inmovilidad sea el objetivo. - Texto: el texto escrito (una cita, un prompt, una línea de terminal) se escribe carácter por carácter (
typeOn); el resto del texto aparece de golpe (cut) o ajusta su tracking (trackIn). Las apariciones con máscara desde abajo y los desenfoques son los movimientos más usados en el video de agentes; recurre a ellos en último lugar. - Sin aspecto de IA: fade de todo, texto que aparece con desenfoque, orbes de resplandor flotantes, texto brillante. El desenfoque pertenece al movimiento rápido (desenfoque de movimiento en tiempo de renderizado), no a la aparición.
- Moderación. Un dispositivo (inmersión, giro, pop, resorte, escritura) gana su lugar al aportar a la narrativa. Aproximadamente una transición destacada por pieza. Diseña cada movimiento con calidad; usa los dispositivos con moderación.
- El rebasamiento (overshoot) es una elección, no un adorno. Las piezas editoriales y de producto suelen querer curvas desaceleradas y resortes con amortiguación 1. Los rebotes se ven baratos cuando están en todo.
El kit (motion-kit.js)
Seguro para la línea de tiempo (seek-safe): todo se basa en fromTo sobre una línea de tiempo pausada, nada lee el fotograma anterior, por lo que cualquier fotograma se renderiza igual si reproduces o desplazas.
| Llamada | Qué hace |
|---|---|
curve(name), bez(x1, y1, x2, y2) | cada curva de LIBRARY por nombre, o tu propia bezier |
dur(px, weight) | duración basada en distancia y peso (0.7 ligero, 1 normal, 1.35 pesado) |
react(i) | desplazamiento de reacción asimétrica para el i-ésimo seguidor |
arc(tl, el, from, to, at) | recorrido en una trayectoria curvada (x e y con curvas diferentes) |
anticipate(tl, el, prop, from, to, at) | pequeño contramovimiento, luego el movimiento principal |
drag(tl, child, prop, lagPx, at, parentDur) | el hijo va detrás del padre y se asienta al final |
exitTo(tl, el, to, at) | salida más rápida y acelerada |
spring({ response, damping }) | resorte físico; devuelve { ease, duration }, solo transformaciones |
cut, typeOn, trackIn, scramble, wipe, revealWords, revealLines, textRange | tratamientos de texto |
wiggle, withBounce, loop, ramp, controller + link | Herramientas de After Effects: wiggle con semilla, rebote inercial, loopOut, reasignación de tiempo, null + pick-whip |
grid(bpm) | tiempos de beat, para frases que comienzan con la música |
<script src="assets/gsap.min.js"></script>
<script src="assets/motion-kit.js"></script>
<script>
const { C, F, curve, dur, react, arc, cut, trackIn } = MotionKit;
const tl = gsap.timeline({ paused: true });
cut(tl, '#sub', 0.6); // el texto de apoyo simplemente aparece
trackIn(tl, '#title', 0.2, { from: '0.3em' }); // el título ajusta su tracking
['#a', '#b', '#c'].forEach((el, i) => // un líder y sus reacciones, lanzados en arcos
arc(tl, el, { x: 900, y: 80 }, { x: 0, y: 0 }, 1.1 + react(i)));
window.__timelines = window.__timelines || {};
window.__timelines['root'] = tl;
</script>
Las curvas son cubic-bezier simples, por lo que los mismos números funcionan como CSS cubic-bezier(), un gráfico de velocidad de After Effects o los mangos de curvas F de Blender (sección 7 de LIBRARY).