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.

rulesdynamic-content-sequencing.md

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

Dynamic Content Sequencing

A utility pattern (not a motion rule in itself) for scenes that show a SEQUENCE of items (cards, phrases, stats): each item's duration is computed from its content length + per-item config, and the sequencer assigns absolute start/end times automatically — no hardcoded offsets per item. Distinct from discrete-text-sequence (one text element changing states) — this rule swaps between distinct content blocks.

How It Works

A content array of { eyebrow, title, body, speedFactor, hold } entries is reduced once at build time into a flat TIMELINE of { …entry, start, end } — duration per entry is BASE_DURATION + body.length × SEC_PER_CHAR + hold, so longer text earns more reading time. A single linear driver's onUpdate reverse-searches the active entry and swaps the DOM only on transitions (a lastTitle guard — per-frame textContent writes flicker in render); an optional progress bar fills 0→100% across the whole run.

Recipe

<!-- inside a standard scene clip (hyperframes-core) -->
<div class="display">
  <div class="eyebrow" id="eyebrow"></div>
  <div class="title" id="title"></div>
  <div class="body" id="body"></div>
  <div class="progress-bar"><div class="progress-fill" id="progress-fill"></div></div>
</div>
.body {
  min-height: 160px; /* reserve space — content height varies; without this, layout jumps */
}
.progress-fill {
  height: 100%;
  width: 0%;
}
// N entries, each with its own pacing (optionally a speedFactor multiplier);
// the final entry uses a larger hold (closing beat).
const CONTENT = [
  { eyebrow: "{eyebrow1}", title: "{title1}", body: "{body1}", hold: HOLD_MID },
  // …
  { eyebrow: "{eyebrowN}", title: "{titleN}", body: "{bodyN}", hold: HOLD_FINAL },
];

// Pre-compute absolute start/end ONCE — never in onUpdate.
let cumulative = 0;
const TIMELINE = CONTENT.map((entry) => {
  const dur = BASE_DURATION + entry.body.length * SEC_PER_CHAR + entry.hold;
  const start = cumulative;
  cumulative += dur;
  return { ...entry, start, end: cumulative };
});

function entryAt(time) {
  for (let i = TIMELINE.length - 1; i >= 0; i--) {
    if (time >= TIMELINE[i].start) return TIMELINE[i];
  }
  return TIMELINE[0];
}

const eyebrowEl = document.getElementById("eyebrow");
const titleEl = document.getElementById("title");
const bodyEl = document.getElementById("body");
const progressEl = document.getElementById("progress-fill");

const TOTAL_DURATION = cumulative + TAIL_PAD;
const driver = { t: 0 };
let lastTitle = "";

tl.to(
  driver,
  {
    t: TOTAL_DURATION,
    duration: TOTAL_DURATION,
    ease: "none",
    onUpdate: () => {
      const entry = entryAt(driver.t);
      // Swap content only on transitions — no per-frame DOM thrash
      if (entry.title !== lastTitle) {
        eyebrowEl.textContent = entry.eyebrow;
        titleEl.textContent = entry.title;
        bodyEl.textContent = entry.body;
        lastTitle = entry.title;
      }
      progressEl.style.width = `${(driver.t / TOTAL_DURATION) * 100}%`;
    },
  },
  0,
);

Variations

  • Crossfade between items — return BOTH adjacent entries during an overlap window (time ≥ e.start − overlap && time ≤ e.end + overlap, overlap ≈ 0.3s) and render them with opacities computed from distance to the boundary.
  • Per-item motion variation — map an entry.style key to an existing rule per chapter (e.g. 3d-text-depth-layers → hacker-flip-3d → counting-dynamic-scale); the sequencer only orchestrates timing.
  • Auto-extend composition duration — you can set data-duration from the computed TOTAL_DURATION in script, but HF reads data-duration at composition load and setting it after init may not take effect — author the duration manually from a rough total.

Accelerating cadence (geometric hold decay)

For rhetorical escalation — "everyone says…", a roll-call, a praise flurry — the beat grid itself accelerates: early entries hold ~1s (read speed), then windows shrink geometrically into a ~0.15–0.3s flurry, braking on an emphasis state before the resolve. The acceleration is pre-computed into the same flat TIMELINE — still content-driven, still deterministic, no speed-up tween anywhere:

// Geometric decay on the hold, clamped at a flurry floor; the brake state holds longest.
const HOLDS = CONTENT.map((entry, i) => Math.max(FLURRY_FLOOR, HOLD_START * Math.pow(DECAY, i)));
HOLDS[CONTENT.length - 1] = HOLD_FINAL;

let cumulative = 0;
const TIMELINE = CONTENT.map((entry, i) => {
  // Past ~0.5s states are glanced as motion texture, not read —
  // drop the per-char term or you never reach flurry speed.
  const readable = HOLDS[i] >= READ_THRESHOLD;
  const dur = HOLDS[i] + (readable ? entry.body.length * SEC_PER_CHAR : 0);
  const start = cumulative;
  cumulative += dur;
  return { ...entry, start, end: cumulative };
});

Worked example — praise-chip flurry: ~16 short quotes hard-cut through a chip beside a pinned wordmark. First 3 states at HOLD_START = 1.0 (each reads fully); DECAY = 0.8 shrinks every following window until FLURRY_FLOOR = 0.2 catches it (≈12 states over ~2.5s — a churn of acclaim, individually glanced); the longest phrase takes HOLD_FINAL ≈ 1.6 as the brake before the closing lockup.

Values: HOLD_START 0.8–1.2s; DECAY 0.75–0.88 (higher = longer runway before the flurry bites); FLURRY_FLOOR 0.15–0.3s (below ~0.15s swaps strobe); READ_THRESHOLD ~0.5s; brake ≥ 4× the floor or the stop doesn't register as a beat. The 3–6 entry guidance relaxes here — 12–18 states are legal precisely because flurry states aren't individually read. The hard-cut discipline (lastTitle guard, instant swaps) is what lets 0.2s states render clean.

Values

token range notes
BASE_DURATION 0.6–1.5s minimum per entry regardless of length — even one-word entries get read time
SEC_PER_CHAR 0.03–0.06 s/char ≈17–33 chars/sec; uniform across the sequence so the pace reads as one engine; lean high for wide-character languages
HOLD_MID 0.5–1.0s dwell on a non-final entry; < HOLD_FINAL
HOLD_FINAL 1.0–2.0s climax dwell — must exceed HOLD_MID by a clear margin so the close reads as a beat
SPEED_FACTOR 0.5–2.0 (default 1.0) per-entry only; if every entry shares a factor, fold it into SEC_PER_CHAR
TAIL_PAD 0.0–1.0s quiet beat after the last entry; prefer 0 when the next composition owns the breath
CONTENT N 3–6 entries <3 isn't a sequence; >6 drags (accelerating cadence relaxes this — see above)

Reference: ../examples/messaging-multi-phrase.html.

Critical Constraints

  • Pre-compute the TIMELINE once at build — never recompute in onUpdate; the reverse search over the flat array is the whole per-frame cost.
  • DOM swap only on entry transition (lastTitle/key guard) — per-frame textContent assignment flickers in HF render.
  • min-height on the body element — without reservation, downstream elements (progress bar, brand) jitter as content height varies.
  • Sequential only — for parallel tracks use a different reduction.
  • Titles fit one line at the chosen size; bodies fit inside min-height after wrapping.

See also

discrete-text-sequence (per-entry typewriter on the body) · context-sensitive-cursor (cursor color per chapter) · vertical-spring-ticker (animated word swap instead of hard cut) · scale-swap-transition (visual morph between entries).

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