All skills
heygen-com avatar

/hyperframes-animation

@ff6e210
by HeyGenheygen-com/hyperframes55k stars
4,998

All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.

Use this Skill: https://skilld.dev/gh/heygen-com/hyperframes/hyperframes-animation

This session only. Nothing lands on disk.

rulesparticle-burst.md

≈2.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Particle Burst

Discrete flying particles as a one-shot event: a confetti pop that erupts upward and drifts back down on gravity, a dot burst radiating from behind a landing word, or a glyph dissolve where text breaks into particles that scatter and die. Particles are ephemeral garnish — born from a beat, fly, gone; they never become layout.

Boundaries: css-marker-patterns.md's burst mode is radiating drawn lines — a static accent, no flight. press-release-spring.md's release burst is one blurred radial layer faking an explosion — enough when a single glow pop will do. center-outward-expansion.md moves real layout elements to final resting slots; particles have no destination, only physics and a death.

How It Works

The whole event is one driver tween and one formula:

  1. Seeded setup — a fixed pool of PARTICLE_COUNT small divs is created once at composition setup (a deterministic loop — setup-time generation is fine; per-frame DOM creation is not). Each particle i derives everything from a pure hash:

    // angle, speed, size, spin, color (palette[i % palette.length]) — all from prand(i * k)
    const prand = (n) => {
      const x = Math.sin(n * 127.1 + 311.7) * 43758.5453;
      return x - Math.floor(x); // 0..1, pure function of n
    };
  2. Ballistic formula — a proxy tween advances T: 0 → 1 over FLIGHT_DUR with ease: "none"; onUpdate positions every particle as a pure function of T:

    x(T) = vx · T·FLIGHT_DUR
    y(T) = vy · T·FLIGHT_DUR + ½ · G · (T·FLIGHT_DUR)²
    rot(T) = spin · T·FLIGHT_DUR

    Gravity G supplies the rise-decelerate-fall arc for free. Because position is computed from T (never accumulated per frame), a seek to any moment renders the exact mid-flight state — this is what makes DOM particles seek-safe. The driver's ease: "none" is load-bearing: the physics lives in the formula; an eased driver warps gravity and the arc stops reading as thrown objects.

  3. Death — an opacity tail inside the same formula (fade over the last FADE_FRAC of flight), or the confetti signature: a separate instant-shrink tween scaling the pool to 0 in a blink at flight end. Either way the particles end invisible and stay invisible.

Recipe

<!-- inside a standard scene clip (hyperframes-core) -->
<div class="burst-stage">
  <div class="particle-field" id="particle-field"></div>
  <div class="burst-hero" id="burst-hero">{heroWord}</div>
</div>
/* .burst-stage: position: relative; display: grid; place-items: center.
   .burst-hero: z-index: 2 — particles fly BEHIND the word. */
.particle-field {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 50%; /* the launch origin — offset to taste (e.g. the word's baseline) */
  width: 0;
  height: 0;
}
.particle {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 2px; /* confetti chip; 50% for dots */
  opacity: 0; /* invisible until the event fires */
  will-change: transform, opacity;
}
// Setup: deterministic pool, generated ONCE.
const field = document.getElementById("particle-field");
const palette = ["{accentA}", "{accentB}", "{accentC}"]; // 3-5 brand tokens
const parts = [];
for (let i = 0; i < PARTICLE_COUNT; i++) {
  const el = document.createElement("div");
  el.className = "particle";
  const size = SIZE_MIN + prand(i * 3 + 1) * (SIZE_MAX - SIZE_MIN);
  el.style.width = `${size}px`;
  el.style.height = `${size * 0.7}px`; // slightly oblong = confetti chip
  el.style.background = palette[i % palette.length];
  field.appendChild(el);
  // Index-seeded launch parameters — the particle's whole life, fixed here.
  const angle = -Math.PI / 2 + (prand(i * 5 + 2) * 2 - 1) * CONE; // upward cone
  const speed = SPEED_MIN + prand(i * 7 + 3) * (SPEED_MAX - SPEED_MIN);
  parts.push({
    el,
    vx: Math.cos(angle) * speed,
    vy: Math.sin(angle) * speed, // negative = up
    spin: (prand(i * 11 + 4) * 2 - 1) * SPIN_MAX,
  });
}

// Confetti pop — one driver, pure ballistic formula.
const drive = { T: 0 };
tl.fromTo(
  drive,
  { T: 0 },
  {
    T: 1,
    duration: FLIGHT_DUR,
    ease: "none", // physics lives in the formula, not the ease
    onUpdate: () => {
      const t = drive.T * FLIGHT_DUR; // seconds of flight — pure function of T
      const fade = Math.min(1, (1 - drive.T) / FADE_FRAC); // opacity tail
      parts.forEach((p) => {
        const x = p.vx * t;
        const y = p.vy * t + 0.5 * G * t * t; // rise, stall, drift down
        p.el.style.transform = `translate(${x}px, ${y}px) rotate(${p.spin * t}deg)`;
        p.el.style.opacity = String(drive.T === 0 ? 0 : fade); // T===0 guard covers seeks before the event
      });
    },
  },
  BURST_AT,
);

Variations

  • Confetti pop, then instant-shrink — the playful signature: full burst, gravity drift, then every chip scales to 0 in a blink: FADE_FRAC near 0, plus tl.to(".particle", { scale: 0, duration: SHRINK_DUR, ease: "power2.in" }, BURST_AT + FLIGHT_DUR - SHRINK_DUR) with SHRINK_DUR 0.15–0.25s. Keep the whole event tiny relative to the subject — a garnish measured in a few dozen pixels, not a screen-filling cannon.
  • Dot burst behind a landing word — radial instead of a cone: angle = prand(i) * Math.PI * 2, G near 0, short flight (0.4–0.7s), round dots (border-radius: 50%), pool z-indexed behind the word. Fire at the word's settle frame.
  • Glyph dissolve — seed each particle's origin across the glyph block's box (ox = (prand(i*13) - 0.5) * BLOCK_W, same for oy, added inside the transform), gentle outward drift with low G; text fades out over the first ~30% of flight while particles fade in from its silhouette. Color every particle {textColor} so the swarm reads as the text's own material. (True per-pixel dissolves are Canvas-2D territory — techniques.md; this DOM version sells it up to ~40 particles.)
  • Two-stage burst (pop + stragglers) — split the pool: 70% on the main driver, 30% on a second driver ~0.12s later with lower speeds; the split is index-derived (i % 10 < 3). Same formula, two windows.

Values

| token | range | notes | | --------------------- | -------------------------------------------- | ------------------------------------------------------------------------------- | --- | ----------------------- | | PARTICLE_COUNT | 10–18 pop/dots; 24–40 dissolve | cap ~40 — per-frame style writes; past that, seek perf and register degrade | | G | 900–1600 px/s² confetti; 0–200 dots/dissolve | natural fall vs drift | | SPEED_MIN / SPEED_MAX | 250–700 px/s | per-particle via prand, never uniform | | CONE | 0.35–0.8 rad (~20–45°) | wider = splash, narrower = fountain | | FLIGHT_DUR | 0.7–1.4s | arc should peak ~35–45% of flight: check | vy | / G ≈ 0.4 × FLIGHT_DUR | | SIZE_MIN / SIZE_MAX | 5–14px chips; 4–8px dots | on a 1080p frame | | SPIN_MAX | 180–720 deg/s confetti; 0 dots | tumble | | FADE_FRAC | 0.2–0.35 | near 0 when using instant-shrink | | BURST_AT | on a cause | the word's settle, a click, a lockup completing — an uncaused burst is noise |

Critical Constraints

  • Position is a pure function of time, driver ease "none" — x(T), y(T), rot(T) computed from the driver value every frame, never accumulated (+=) per tick (accumulation breaks the moment the renderer seeks); gravity is the ease — an eased driver bends the parabola.
  • Fixed pool, no per-frame DOM — all particles exist after setup with opacity: 0; the event only writes transform / opacity. PARTICLE_COUNT ≤ ~40 — per-frame style writes scale linearly; keep the event cheap.
  • Particles start AND end at opacity: 0 — the drive.T === 0 guard covers seeks to before the event; the tail/shrink covers after. A chip frozen mid-air at driver end is a bug every subsequent frame.
  • Particles are punctuation — one event per beat, fired on a cause, small relative to the subject, dead before the next beat; z-ordered behind or around the word it celebrates, never over it. A persistent particle system is a background, and that's not this rule.

See also

spring-pop-entrance (confetti fires on the hero's settle frame) · kinetic-beat-slam (one beat earns the confetti payoff) · press-release-spring (single-layer glow alternative, or compose both) · css-marker-patterns (drawn-line burst when the accent should feel hand-annotated) · scale-swap-transition (glyph dissolve covers the exit).

Source: SKILL.md on GitHub

No alerts3d3 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    The skill is a comprehensive knowledge base and utility set for HyperFrames animations. It includes an auditing tool that dynamically installs vendor-specific dependencies from the NPM registry to analyze project timelines. The behavior is documented, tested, and follows established development patterns for CLI utilities.

  • Socket3d

    No alerts

  • Snyk3d

    Risk: LOW · No issues

Signed by skilld at ff6e210. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 16 hours ago.

Activeupdated 4 days ago

README badge

README badge for heygen-com/hyperframes/hyperframes-animation