Files
hyperframes/skills/gsap/SKILL.md
T
Miguel Ángel 8662598a3a docs: add runtime adapter skills (#572)
* docs: add runtime adapter skills

* docs: address adapter skill review comments
2026-04-30 16:08:43 +02:00

241 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: gsap
description: GSAP animation reference for HyperFrames. Covers gsap.to(), from(), fromTo(), easing, stagger, defaults, timelines (gsap.timeline(), position parameter, labels, nesting, playback), and performance (transforms, will-change, quickTo). Use when writing GSAP animations in HyperFrames compositions.
---
# GSAP
## HyperFrames Contract
HyperFrames controls GSAP through its `gsap` runtime adapter. Create a paused timeline synchronously, register it on `window.__timelines` with the exact `data-composition-id`, and let HyperFrames seek it.
```html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script>
window.__timelines = window.__timelines || {};
const tl = gsap.timeline({ paused: true });
tl.from(".title", { y: 48, opacity: 0, duration: 0.6, ease: "power3.out" }, 0);
tl.to(".accent", { scaleX: 1, duration: 0.5, ease: "power2.out" }, 0.25);
window.__timelines["main"] = tl; // key must equal data-composition-id on the composition root
</script>
```
- The registry key must match the composition root's `data-composition-id`.
- Do not call `tl.play()` for render-critical motion.
- Do not build timelines inside async code, timers, or event handlers.
- Keep loops finite. HyperFrames renders finite video durations.
## Core Tween Methods
- **gsap.to(targets, vars)** — animate from current state to `vars`. Most common.
- **gsap.from(targets, vars)** — animate from `vars` to current state (entrances).
- **gsap.fromTo(targets, fromVars, toVars)** — explicit start and end.
- **gsap.set(targets, vars)** — apply immediately (duration 0).
Always use **camelCase** property names (e.g. `backgroundColor`, `rotationX`).
## Common vars
- **duration** — seconds (default 0.5).
- **delay** — seconds before start.
- **ease** — `"power1.out"` (default), `"power3.inOut"`, `"back.out(1.7)"`, `"elastic.out(1, 0.3)"`, `"none"`.
- **stagger** — number `0.1` or object: `{ amount: 0.3, from: "center" }`, `{ each: 0.1, from: "random" }`.
- **overwrite** — `false` (default), `true`, or `"auto"`.
- **repeat** — finite number; never `-1` in HyperFrames. Compute repeats from the visible duration. **yoyo** — alternates direction with repeat.
- **onComplete**, **onStart**, **onUpdate** — callbacks.
- **immediateRender** — default `true` for from()/fromTo(). Set `false` on later tweens targeting the same property+element to avoid overwrite.
## Transforms and CSS
Prefer GSAP's **transform aliases** over raw `transform` string:
| GSAP property | Equivalent |
| --------------------------- | ------------------- |
| `x`, `y`, `z` | translateX/Y/Z (px) |
| `xPercent`, `yPercent` | translateX/Y in % |
| `scale`, `scaleX`, `scaleY` | scale |
| `rotation` | rotate (deg) |
| `rotationX`, `rotationY` | 3D rotate |
| `skewX`, `skewY` | skew |
| `transformOrigin` | transform-origin |
- **autoAlpha** — prefer over `opacity`. At 0: also sets `visibility: hidden`.
- **CSS variables** — `"--hue": 180`.
- **svgOrigin** _(SVG only)_ — global SVG coordinate space origin. Don't combine with `transformOrigin`.
- **Directional rotation** — `"360_cw"`, `"-170_short"`, `"90_ccw"`.
- **clearProps** — `"all"` or comma-separated; removes inline styles on complete.
- **Relative values** — `"+=20"`, `"-=10"`, `"*=2"`.
## Function-Based Values
```javascript
gsap.to(".item", {
x: (i, target, targets) => i * 50,
stagger: 0.1,
});
```
## Easing
Built-in eases: `power1``power4`, `back`, `bounce`, `circ`, `elastic`, `expo`, `sine`. Each has `.in`, `.out`, `.inOut`.
## Defaults
```javascript
gsap.defaults({ duration: 0.6, ease: "power2.out" });
```
## Controlling Tweens
```javascript
const tween = gsap.to(".box", { x: 100 });
tween.pause();
tween.play();
tween.reverse();
tween.kill();
tween.progress(0.5);
tween.time(0.2);
```
## gsap.matchMedia() (Responsive + Accessibility)
Runs setup only when a media query matches; auto-reverts when it stops matching.
```javascript
let mm = gsap.matchMedia();
mm.add(
{
isDesktop: "(min-width: 800px)",
reduceMotion: "(prefers-reduced-motion: reduce)",
},
(context) => {
const { isDesktop, reduceMotion } = context.conditions;
gsap.to(".box", {
rotation: isDesktop ? 360 : 180,
duration: reduceMotion ? 0 : 2,
});
},
);
```
---
## Timelines
### Creating a Timeline
```javascript
const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2.out" } });
tl.to(".a", { x: 100 }).to(".b", { y: 50 }).to(".c", { opacity: 0 });
```
### Position Parameter
Third argument controls placement:
- **Absolute**: `1` — at 1s
- **Relative**: `"+=0.5"` — after end; `"-=0.2"` — before end
- **Label**: `"intro"`, `"intro+=0.3"`
- **Alignment**: `"<"` — same start as previous; `">"` — after previous ends; `"<0.2"` — 0.2s after previous starts
```javascript
tl.to(".a", { x: 100 }, 0);
tl.to(".b", { y: 50 }, "<"); // same start as .a
tl.to(".c", { opacity: 0 }, "<0.2"); // 0.2s after .b starts
```
### Labels
```javascript
tl.addLabel("intro", 0);
tl.to(".a", { x: 100 }, "intro");
tl.addLabel("outro", "+=0.5");
tl.play("outro");
tl.tweenFromTo("intro", "outro");
```
### Timeline Options
- **paused: true** — create paused; call `.play()` to start.
- **repeat**, **yoyo** — apply to whole timeline.
- **defaults** — vars merged into every child tween.
### Nesting Timelines
```javascript
const master = gsap.timeline();
const child = gsap.timeline();
child.to(".a", { x: 100 }).to(".b", { y: 50 });
master.add(child, 0);
```
### Playback Control
`tl.play()`, `tl.pause()`, `tl.reverse()`, `tl.restart()`, `tl.time(2)`, `tl.progress(0.5)`, `tl.kill()`.
---
## Performance
### Prefer Transform and Opacity
Animating `x`, `y`, `scale`, `rotation`, `opacity` stays on the compositor. Avoid `width`, `height`, `top`, `left` when transforms achieve the same effect.
### will-change
```css
will-change: transform;
```
Only on elements that actually animate.
### gsap.quickTo() for Frequent Updates
```javascript
let xTo = gsap.quickTo("#id", "x", { duration: 0.4, ease: "power3" }),
yTo = gsap.quickTo("#id", "y", { duration: 0.4, ease: "power3" });
container.addEventListener("mousemove", (e) => {
xTo(e.pageX);
yTo(e.pageY);
});
```
### Stagger > Many Tweens
Use `stagger` instead of separate tweens with manual delays.
### Cleanup
Pause or kill off-screen animations.
---
## References (loaded on demand)
- **[references/effects.md](references/effects.md)** — Drop-in effects: typewriter text, audio visualizer. Read when needing ready-made effect patterns for HyperFrames.
## Best Practices
- Use camelCase property names; prefer transform aliases and autoAlpha.
- Prefer timelines over chaining with delay; use the position parameter.
- Add labels with `addLabel()` for readable sequencing.
- Pass defaults into timeline constructor.
- Store tween/timeline return value when controlling playback.
## Do Not
- Animate layout properties (width/height/top/left) when transforms suffice.
- Use both svgOrigin and transformOrigin on the same SVG element.
- Chain animations with delay when a timeline can sequence them.
- Create tweens before the DOM exists.
- Skip cleanup — always kill tweens when no longer needed.
- Use infinite repeat values in HyperFrames compositions. Use finite repeat counts computed from the visible duration.
## Credits And References
- HyperFrames adapter source: `packages/core/src/runtime/adapters/gsap.ts`.
- GSAP documentation: https://gsap.com/docs/v3/
- GSAP timeline pause and seek behavior: https://gsap.com/docs/v3/GSAP/Timeline/pause%28%29/