SuperAPI AI Directory

motion-design

Design & creation

View repository

Updated 10-19 00:28

About this skill

Motion design (HyperFrames edition)

The HyperFrames docs teach you the API; this file is about taste. The numbers below come from a work that actually shipped—treat them as defaults: deviating is fine, but it must be deliberate, not just an oversight.

Adapted from whaleyxbt/claude-motion's motion-design skill (MIT, see LICENSEin the same folder). The original targets Remotion; this version is rewritten for HyperFrames (HTML + GSAP) and adds Traditional Chinese typography rules. Sections marked "(new in this version)" are not from the original.

When used within the motion-explainer series workflow (new in this version)

motion-explainer(and -images、-video、soil-motion-deck) using the official faceless-explainer workflow, the following three things follow that workflow; this file's approach does not apply:

  • Timing: beats come from STORYBOARD.md and audio_meta.json(the timing of narration clauses), and each frame's data-start/data-duration is written by assemble-index .Do not create a separate timeline.js/window.TL(Section 1).
  • Creating the project: use npx hyperframes init(see motion-explainer Section 3), not the "workflow" section's approach.
  • Fonts and colors: determined by the project's theme.json (default Source Han Sans Bold, three-color theme);theme.py overrides the fonts and palettes written in each frame. The font family suggestions in Sections 5 and 6 apply only when there is no theme.json .

The rest of the taste rules (easing, spring, reading dwell, composition, Chinese typography, accent color only for emphasis) apply as usual.

Division of labor with the official HyperFrames skills (new in this version)

HeyGen's official HyperFrames skills are also installed locally (hyperframes、hyperframes-core、hyperframes-animation etc.). The division of labor is as follows:

  • Official skills govern "how to do it": project structure,data-* attributes, API usage, workflow routing, ready-made registry components. When API usage conflicts with this file, the official one prevails.
  • This file governs "taste": easing, rhythm, dwell time, fonts, color, Chinese typography. When using the official hyperframes-animation rules / blueprints, the timing and easing numbers still default to this file.
  • Checking: always go through review-loop, which already includes the official hyperframes check。

0. Hard rules of HyperFrames (new in this version)

Violating these makes the picture flicker, misalign, or differ on every output:

  • Timing is determined by HTML: each scene is a class="clip" element, placed on the timeline with data-start、data-duration . The root element must have data-composition-id and an explicit data-duration。

  • Motion is handled by GSAP:gsap.timeline({ paused: true }), registered to window.__timelines["<composition-id>"], the key name must equal data-composition-id。

  • Give every important tween an explicit position (the third argument); when both ends matter, use fromTo(), because output seeks around skipping.

  • Only animate transform and opacity, do not repeatedly animate top/left/width/height。

  • Prohibited: CSS transition/@keyframes、Date.now()、requestAnimationFrame、setTimeout, no seeded Math.random(), resources fetched only midway through the output.

  • Do not use script to play, pause, or seek audio/video, and do not use script to show or hide clips based on time. Leave all of that to data attributes. To move a video, move the outer wrapper element.

  • Always use a seeded function for randomness:

    function rand(seed) { let t = (seed += 0x6D2B79F5); t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }
    

1. Time in one place

  • Every beat is a named point in time (seconds), grouped by scene (s1、s2…), written in timeline.js:

    window.TL = {
      s1: { start: 0, title: 0.3, items: [1.2, 1.45, 1.7], exit: 3.6 },
      s2: { start: 3.4, drawOn: 3.5, hook: 5.2, end: 8 },
    };
    

    in index.html , loaded with <script src="timeline.js"></script> before all composition scripts.

  • Always take GSAP position parameters from TL (TL.s1.title、TL.s1.exit + 0.05 relative notation like this is fine); do not hardcode seconds in scenes.

  • The scene wrapper's data-start/data-duration must match the scene boundaries of TL . When retiming, first change timeline.js, then update these two attributes to match.

  • Place sound effects and narration with <audio data-start="…"> on the same set of beats. The review-loop screenshot times are also taken from TL , so picture, sound, and checks move together.

  • All visuals must be determined solely by time; see section 0.

2. Easing

The original's four curves are precisely rebuilt in GSAP with CustomEase . To load more gsap@3/dist/CustomEase.min.js, then register with gsap.registerPlugin(CustomEase) :

CustomEase.create("enter", "0.16,1,0.3,1");   // easeOut
CustomEase.create("exit",  "0.6,0,0.9,0.35"); // easeIn
CustomEase.create("move",  "0.65,0,0.35,1");  // easeInOut
CustomEase.create("land",  "0.55,0,0.2,1.12"); // overshoot
Curve Use Closest built-in name
enter = bezier(0.16, 1, 0.3, 1) Entrances, reveals, any "arrival" expo.out(nearly identical)
exit = bezier(0.6, 0, 0.9, 0.35) Exits: fast, no dragging approx. power3.in
move = bezier(0.65, 0, 0.35, 1) Movement between two states (flip, dock, morph) power2.inOut(identical)
land = bezier(0.55, 0, 0.2, 1.12) Values that "settle" (slider climbing to a slot) No good built-in substitute; use CustomEase

ease: "none"(linear) only for continuous motion: rotation, drift, particles, second hand.

To make one animation follow another value (for example, subtitles following slider position), use the same tween to drive a proxy object, deriving in onUpdate ; do not give it another independent clock.

3. Spring

The original uses Remotion's physical springs; GSAP has no spring physics. The table below shows the approximations chosen for this version (added in this version, not the original's numbers). After output, use review-loop to confirm the feel:

Feel GSAP setting Use for
Default settle back.out(1.2),0.6 s General UI entrance
Heavy, steady power3.out,0.8–1.0 s Large panels, flip back
Knob snapping back.out(1.7),0.35 s Controls jumping to a slot
Pop back.out(2.2),0.45 s Callouts, badges, success dots
Spring accent elastic.out(1, 0.4),0.9 s The climax moment used only once per video

Use springs for things with physicality (UI, objects); use Bezier curves for text and camera-like movement.

4. Rhythm

  • Stagger: English words about 0.09 s; Chinese character by character about 0.04–0.05 s, word by word about 0.09 s (the Chinese part is new in this version); list items and labels about 0.2–0.25 s; rings and dots about 0.06 s.
  • Text revealAbout 0.8 s, with a mask: outer layer overflow: hidden, inner layer yPercent: 100 → 0 , plus a bit of rotation (rotation: 3 → 0)。
  • The exit is about half the entrance(0.35–0.55 s vs. 0.7–1.25 s); for the exit use the exit curve.
  • Scenes must overlap: the next scene starts drawing in before the previous one has fully left (e.g. s2.drawOn 4.02 s is earlier than s1.flipEnd 4.4 s). A hard cut to blank looks like it's "loading."
  • TypingEach character takes about 0.035 s; when idle, the cursor blinks at about 2.4 Hz (use steps or set scheduled on the timeline, don't use a timer).
  • Reading dwell: every state meant to be read must hold once it settles. At least 1 s for a short sentence; about 0.25 s more for each word beyond three; for Chinese, about 0.25 s more for each 4 additional characters (new in this version). The final closing line must be at least 2 s. The original 22-second version exists precisely because the 15-second version flashed its text too fast: when in doubt, hold longer and move less.

5. Fonts

  • At most three type families: a display serif, a UI sans-serif, and a monospace (for labels, prompts, numbers).
    • English (original): Instrument Serif / Inter / JetBrains Mono.
    • Traditional Chinese (new in this version): Noto Serif TC / Noto Sans TC, with JetBrains Mono for numbers and labels. Put the font files in the project's assets/fonts/, load them with @font-face , and don't rely on system fonts (they'll differ on another computer).
  • English display type should be large (about 138 px on a 1080-wide canvas), with tighter tracking (-0.02em),line-height: 1。
  • Chinese display type (new in this version): about 96–120 px at 1080 wide, no more than about 12 characters per line, tracking from 0 to 0.02em(no negative tracking for Chinese),line-height: 1.15–1.25。
  • one focal point per line: in English, use a single italic word in the accent color; Chinese has no true italics, so carry the emphasis with the accent color plus heavier weight (new in this version).
  • Monospace labels: uppercase,letter-spacing: 0.2–0.24em, color muted. They're just decoration; make anything the audience must read big.
  • Mobile test: at 360 px wide (the size actually seen in social feeds), the key message must still be legible. Check with a contact sheet.

6. Color

  • (new in this version) Set the tone for the whole video withthree colors, decided by the user like a presentation template: background color bg, primary color fg(text and line art), accent color accent, written in the project's theme.json, applied with the motion-explainer series skill's theme.py . Use the accent color only for "answers, conclusions, key numbers, section cards."
  • Define the palette as CSS variables in :root (--bg、--ink、--muted、--accent…); don't let new color codes appear in scenes.
  • There's only one accent color, and it means something: the thing that changed, the answer, the winner. If everything is accent, nothing is.
  • Glow is driven by state, not time (glow = effort): light must tell the story.

7. Texture: nothing is completely still

  • Film grain: overlay an SVG feTurbulence filter at about 0.09 opacity, changing seedevery two frames (scheduled on the timeline with set , seed computed from the frame number).
  • Vignette + dotted grid, drifting a few px per second:radial-gradient vignette, with the grid using a single linear tween spanning the whole video.
  • Hand-drawn "line jitter" (feTurbulence + feDisplacementMap, also changing the seed every two frames): use it for a draft-like, low-completion feel, and fade it out as quality improves.
  • Idle elements should breathe: a clock that ticks, a blinking cursor, a slow rotation.

8. Continuity and transitions

  • Prefer letting objects persist over hard cuts. In the original, the cue bar, sparks, and slider travel across scenes and change roles; that is the difference between "designed" and "cobbled together." In HyperFrames, cross-scene objects go in the root composition, not inside any one scene.
  • Every transition should be carried by an object on screen (five result dots merging into one, then becoming a halo). No stock wipe transitions.
  • Use velocity: derive motion trails and squash from "the difference between this frame's value and the previous frame's," don't fake it.
  • One climax moment per video (halo + impact). Build all the way up to it, don't use it up too early.

9. Anti-patterns

  • Everything fading in at once, or everything using the same duration.
  • Using linear easing on things that start and stop.
  • Text still moving when it should be read.
  • More than one focal point in a single frame.
  • Content less than about 60 px from the frame edge (safe area), unless it's a deliberate crop.
  • Frame 0 is blank or all black: when social platforms autoplay muted, frame 0 is the thumbnail.
  • (New in this version) Controlling audio/video playback or clip visibility in script, using CSS animations, using unseeded randomness, see Section 0.

Workflow

  1. First write the beats into timeline.js(a storyboard written in numbers), then confirm the rhythm with the user before starting.
  2. Use npx hyperframes init <專案資料夾> to create the project; each scene is a composition in compositions/ , and shared components and cross-scene objects go in index.html。
  3. After every meaningful change, run the review-loop skill.
  4. Handle audio only after the visual timing is locked: sound effects and music should match the beats of <audio data-start> with TL . Leave the accent and emotion of Chinese narration for the user to judge by ear; don't substitute ASR or similarity scores (new in this version).