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.

rulescontext-sensitive-cursor.md

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

Context-Sensitive Cursor

In a typewriter sequence, the cursor's color (and optionally height / blink behavior) matches the active text segment — brand accent while typing the brand name, dim on placeholders, success color on the completion mark. The eye lands on the keyword being typed because the cursor shifts with it; a fixed single-color cursor is visual noise by comparison. Layers on top of discrete-text-sequence's SEQUENCE pattern.

How It Works

The text is authored as a SEQUENCE of { t, text, segment, color } entries; a linear driver's onUpdate reverse-searches for the current entry and writes both the visible text and the cursor's background (the cursor is a colored block, so background, NOT color). A second linear tween sweeps a phase p through 2π × BLINK_CYCLES_PER_SCENE and gates cursor opacity on sin(p) > 0 — a deterministic square-wave blink on the timeline.

Recipe

<!-- inside a standard scene clip (hyperframes-core) -->
<div class="terminal">
  <div class="prompt">$</div>
  <div class="text-wrap">
    <span class="text" id="text"></span><span class="cursor" id="cursor">_</span>
  </div>
</div>
.terminal {
  font-family: {monoFont}; /* proportional fonts drift the cursor mid-segment */
  display: flex;
  align-items: baseline;
  white-space: pre; /* preserve trailing spaces — cursor sits at segment end */
}
.text {
  white-space: pre;
}
.cursor {
  display: inline-block; /* inline ignores width/height */
  width: {cursorWidth}px;
  height: {cursorHeight}px;
  background: {textColor}; /* default — overridden per segment in onUpdate */
  vertical-align: {cursorBaselineFix}px; /* small negative — anchor to baseline, not line-height */
}
// Adjacent entries usually share a text prefix but may differ in `segment` —
// that's what shifts the cursor color mid-line.
const SEQUENCE = [
  { t: 0, text: "", segment: "main", color: "{mainColor}" },
  { t: T_LEADIN_END, text: "{leadInChunk}", segment: "main", color: "{mainColor}" },
  { t: T_BRAND_IN, text: "{leadInBrandPrefix}", segment: "brand", color: "{brandColor}" },
  { t: T_BRAND_OUT, text: "{leadInBrandFull}", segment: "main", color: "{mainColor}" },
  { t: T_CMD_IN, text: "{leadInCmdPrefix}", segment: "cmd", color: "{cmdColor}" },
  { t: T_SUCCESS, text: "{leadInDone}", segment: "success", color: "{successColor}" },
];

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

const textEl = document.getElementById("text");
const cursorEl = document.getElementById("cursor");

const driver = { t: 0 };
tl.to(
  driver,
  {
    t: DURATION,
    duration: DURATION,
    ease: "none",
    onUpdate: () => {
      const entry = entryAt(driver.t);
      textEl.textContent = entry.text;
      cursorEl.style.background = entry.color;
    },
  },
  0,
);

// Deterministic square-wave blink
const blink = { p: 0 };
tl.to(
  blink,
  {
    p: Math.PI * 2 * BLINK_CYCLES_PER_SCENE,
    duration: DURATION,
    ease: "none",
    onUpdate: () => {
      cursorEl.style.opacity = Math.sin(blink.p) > 0 ? "1" : "0";
    },
  },
  0,
);

Variations

  • Non-blinking during active typing — suppress blink while letters are appearing (solid cursor), resume on idle. This MUST be a pure function of the driver's time: tracking a mutable lastChangeTime in onUpdate is not reverse-seek-safe (scrubbing backwards leaves the stale forward-pass value behind and the cursor blinks — or holds solid — at the wrong frames). Bake the change times from the SEQUENCE instead — every entry whose text differs from its predecessor is a typing event:
// Baked once at build time — no runtime state.
const CHANGE_TIMES = SEQUENCE.filter((e, i) => i > 0 && e.text !== SEQUENCE[i - 1].text).map(
  (e) => e.t,
);
// In onUpdate — identical result at any seek, either direction:
const isTyping = CHANGE_TIMES.some((t) => t <= driver.t && driver.t - t < TYPING_GRACE);
cursorEl.style.opacity = isTyping ? "1" : Math.sin(blink.p) > 0 ? "1" : "0";
  • Cursor HEIGHT shifts on segment — larger cursor on the brand segment: cursorEl.style.height = entry.segment === "brand" ? cursorHeightEmphasis : cursorHeight (1.1–1.25×; more reads as glitch).
  • Contrast reversal — a dark-text-on-light segment needs a dark cursor too; keep entry.color as the single source of truth and read from it.

Values

token range notes
DURATION 4–8s per typed line ≥ SEQUENCE[last].t + closing dwell
entry t spacing 0.2–0.5s micro-additions ascending, non-uniform — slow down on highlights
segment palette 3–4 colors max more reads as random; brand vs success should differ in saturation/luminance
cursorWidth / Height 8–24px / 0.85–1.0× fontSize too thin vanishes in render compression; too tall outranks the text
cursorBaselineFix small negative px drop the block to the text baseline
BLINK_CYCLES_PER_SCENE period ≈ 0.6–1.2s whole number — otherwise the sin sweep ends mid-cycle and the cursor pops on the last frame
TYPING_GRACE 0.15–0.3s < shortest dwell between adjacent entries — otherwise the cursor never blinks

Critical Constraints

  • Cursor color goes on background — it's a colored block, not a glyph.
  • Blink is timeline-driven sin, pure of any mutable tracker — the typing-grace variation shows the seek-safe form.
  • white-space: pre on text and container — collapsed trailing spaces park the cursor in the wrong column.
  • Monospace font + display: inline-block cursor — proportional faces drift the cursor mid-segment; inline ignores the block geometry.
  • BLINK_CYCLES_PER_SCENE is a whole number for the fixed DURATION.

See also

discrete-text-sequence (the underlying SEQUENCE pattern) · camera-cursor-tracking (camera follows the cursor) · press-release-spring (post-typing confirm press).

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