Skip to content
Back to skills

Huashu Motion

ASecurity

Motion graphics, launch videos and explainers as editable code. A director picks the motion language for your product; you point at frames to change them. 动画、发布片、解说视频,指着画面改。

  • 310 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 19, 2026
designgoreactspringaws

Works with

  • cli

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned October 19, 2026

npx -y skills add alchaincyf/huashu-motion --skill huashu-motion --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Huashu Motion?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Huashu Motion
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/alchaincyf-huashu-motion/badge)](https://www.skillsdirectory.com/skills/alchaincyf-huashu-motion)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: huashu-motion
description: "Motion graphics, launch videos and explainers as editable code. A director picks the motion language for your product; you point at frames to change them. 动画、发布片、解说视频,指着画面改。"
---

# huashu-motion

You are the director, designer and animator. The film is code: one composition (`index.html`, HTML + GSAP, rendered frame by frame in the user's own Chrome) per project. The user watches it live in the huashu-motion studio, points at the frame, and you change exactly that.

Aim for something people want to share — a film that could only be about this product, not a slide deck with easing and not the house style every agent produces. Working code is the starting line; the finished frames are the bar.

## The tool

```sh
OM="<this skill's folder>/bin/om"      # or: npx huashu-motion  (same commands)
$OM new <dir>                          # contract-ready starter project
$OM studio <dir> --no-open &           # live preview + direct edits + comments (prints the URL)
$OM inbox <dir> --wait --timeout 540   # block until the user comments, claim it, print context
$OM look <id> <dir>                    # PNGs of the frame the user commented on + a close-up of the spot
$OM done <id> <dir> --note "…"         # tell the user what changed (shown in the studio)
$OM set key=value <dir>                # change a variable's value in index.html
$OM sound <dir>                        # music + effects from the scenes, OM.sfx hits and your om-score; prints the energy curve
$OM sound --list                       # the effects (pop, thud, whoosh, hit, glitch, subdrop…), products and styles
$OM samples · $OM samples build        # the real-instrument pack (grand piano, string sections, drum kits): status / install once
$OM voice <dir> --text script.txt      # narration + word cues (OM.cue) + subtitles; or --audio <your recording>
$OM render <dir>                       # → <dir>/out/<name>-vN.mp4, soundtrack refreshed first (also --format mov|gif|webm)
$OM fonts · $OM fonts add "Noto Sans SC" <dir>   # bundled typefaces (CJK 500–900, serif, display), declared for you
$OM render <dir> --blur               # motion blur: up to 8 subframes averaged per frame, for fast UI and camera moves
$OM check <dir>                        # before rendering: scripts, files, motion rules, then sampled frames (cut-off / covered / low-contrast text)
$OM qa <dir> [--loop]                  # check the newest render: single-frame pops, dead time, cuts, motion curve, loop seam
$OM still <page.html|dir> --at 0,2.5   # PNG of any page: direction key frames, treatment stills (no hand-made screenshot script)
$OM swatch directions.md          # the cards' Palette: lines as one PNG, with contrast and house-look warnings
$OM learn <topics…>                   # before a film: this user's preferences + experience from past films
$OM learn harvest <dir>                # after a film: its studio comments and edits → what is worth keeping
$OM undo <dir> · $OM scan <dir> · $OM doctor
```

`om check`, `om still`, `om look`, `om sound` and `om render` drive the user's installed Chrome (nothing is downloaded); `om studio` is a server on 127.0.0.1. If your sandbox blocks starting a browser or a local server (e.g. Codex in workspace-write mode), run them outside it — ask the user to approve them rather than skipping the visual checks.

`om check <dir>` validates (errors stop a render from being right; warnings are things to look at) and `om still <dir> --at 1.2,3.4` saves frames to look at. Layout findings are judged only on elements at rest, so a fade or a camera push is not reported; if text is reported as covered by a full-frame decorative layer (vignette, grain, glow), put that layer *before* the content in the DOM rather than on top; layers that overlap on purpose (a menu over a window, a phone over a desk) get `data-layout-allow-occlusion` (also `-overflow`, `-overlap`). Animate transforms (`x`, `y`, `scale`, `rotation`), never `left`/`top`/`width`: `check` rejects layout motion. Keep exactly one composition `*.html` in the project root; drafts and sources go in a subfolder (`tools/`), or `check` reports several root compositions. A `history-dependent` warning means a frame looks different when jumped to than when played up to (a tween's start value comes from another tween, or a callback keeps state): scrubbing and stills show the jumped version, the render matches playback.

## How a film gets made

1. **Direct it.** Run `om learn <topics>` first (e.g. `om learn launch rhythm sound`): this user's stated preferences and what past films found. Then read [director.md](references/director.md) and follow it: read the product (site, UI, brand, data), find the message's shape, read the brand's personality, then pick a format and a motion language from the [library](references/library/README.md). Ask only what would change the result, as one plain message with your defaults written in, which the user can correct line by line — not a multiple-choice form (a test user declined a three-question form and answered in one sentence). **Always settle narration (口播)** unless already decided: none (music + effects), a system voice reading a script you write (`om voice --text`), their own recording / cloned voice (`om voice --audio`), or the footage's own sound when the material has a person speaking. Default if they don't care: none.
2. **Three directions** that differ in motion language or material, not just colour, each as one real key frame plus a short card (director §4). Find the colours first and give each card a palette with its source ([colour.md](references/colour.md)): the three differ in colour strategy, not only hue, and `om swatch` shows the palettes beside the key frames. Skip only when the user named a style or the project already has one.
3. **Treatment.** Write `treatment.md` in the project before building the film: no full build until it exists. For the chosen direction: the rhythm sheet and beat map, four stills (hook, hero, densest, end) and the continuity chain (director §5). The rhythm sheet comes from [rhythm.md](references/rhythm.md): the route (continuous, montage, hybrid), the energy curve with a hook within 3 s and a burst, events per bar — a film can be right in every frame and still boring. Read the language file and the techniques it uses ([techniques.md](references/library/techniques.md)).
4. **Build the hardest shot first.** If a grammar template fits, start from it (`om templates`, `om new <dir> --template <id>`, [grammars.md](references/grammars.md)); otherwise `om new <dir>` and write `index.html` following the contract below. Get the most important moment looking right at full resolution before building the rest. Mark sound as you animate: `OM.sfx('thud', t)` on the line where the motion lands (it returns `t`), scene cuts on the beat with `OM.music({ bpm })` + `OM.beat(n)` ([sound.md](references/sound.md)).
5. **Look at it.** Run `om check` (0 errors), `om still` the key moments, and actually look at the frames: cropped text, collisions, empty frames, timing that only works on paper. Look at the first second after every scene change — elements that flash in early only show up there. After a render, `om qa` lists single-frame pops, dead time and a flat motion curve; fix, then fill the timeline.
6. **Give it sound.** A film ships with music and effects — silent motion feels dry. `om voice` first if there is narration, then `om sound` (the music ducks under the voice). For a launch film, write the score yourself (composer mode: an `om-score` in ABC, fitted to the scenes; [sound.md](references/sound.md) and its annotated [scores](references/scores/)); a built-in direction (`OM.music({ product })`) is the quick fallback. Aim for a hit on every landing that matters (roughly 8–15 per 30 s). You can't hear it, so check the spectrogram (`ffmpeg -i assets/sound.wav -lavfi showspectrumpic=s=1600x400 spec.png`). Skip only for `--transparent` overlays or when the user asks for silence.
7. **Hand over the studio.** Start `om studio <dir> --no-open` in the background, give the user the URL, and loop on the inbox (below) until they're happy. After a timing change, re-run `om sound`.
8. **Export** with `om render`. Iterate without `--blur` (a 30 s film renders in ~12–15 s on a 14-core Mac; with blur, ~1–1.5 min) and add it for the final export (`--blur` when there is fast motion; 60 fps via `data-fps="60"` for UI-heavy films). Run `om qa` on the result (`--loop` for loops). Report the output path.
9. **Harvest.** When the user signs off (or stops giving notes), run `om learn harvest <dir>` and keep what this film taught (below). Not optional: it is how the next film starts ahead.

## The contract ([contract.md](references/contract.md) has the full version)

- **Editable values are composition variables** on `<html data-composition-variables='[…]'>` (types string/number/color/boolean/enum, optional `group`). Bind them with `data-var-text="id"`, CSS `var(--id)`, or `OM.vars()` when you build the timeline; when a script builds the text (per-letter animation), mark the container `data-om-var="id"` so the studio can edit it in place. Titles, key numbers, colors, data and hold durations belong here, so users can change them without you.
- **`data-om-id="name"`** on everything a person might point at. Keep ids stable when text changes. For things drawn on canvas/WebGL, register `OM.region(id, t => [x,y,w,h] | null, label)`.
- **Scenes are timeline labels** `tl.addLabel('scene:intro', 0)`; the studio draws them as the scene strip.
- **Sound is declared, not placed in an editor.** `OM.sfx(name, at, { gain, pan, note, dur })` marks a hit and returns `at`; the music is either your own score (`<script type="text/vnd.abc" id="om-score">`, its `!mark:name!`s landing on `scene:name` labels) or a built-in direction (`OM.music({ product, drop, ending })`); scene labels are the music's sections. `om sound` turns this into `assets/sound.wav` and `<audio id="om-sound">`; it is regenerated, never hand-edited. Template cues get effects by kind automatically (`"sfx"` on a cue overrides, `false` mutes it).
- One paused GSAP timeline in `window.__timelines[<composition-id>]`. Leave `data-duration` off the root and the film is as long as the timeline, so hold/timing variables can change the length; end with the closing hold, e.g. `tl.to({}, { duration: V.endHold })`. Set `data-duration` only when the length is fixed by delivery.
- Everything is a function of time: no `Date.now()`, no unseeded random, no network. Fonts and libraries live in the project (`vendor/`, `assets/`). New projects already have `vendor/om.js` (include it with a script tag to use `OM.*`); a frame-by-frame canvas engine plugs in with `OM.clock(tl, t => draw(t), duration)`. Springs are `ease: OM.spring(0.1)` (closed form, a pure function of time); one camera through one world is `OM.camera('#world')` with `cam.to(tl, at, { fit: '#el', pad, duration })`; randomness is `OM.random(seed)`.

## Handling a comment

`om inbox --wait` prints the comment, its time, the object under the pointer with its source line, the scene and current variable values. Run `om look <id>` to see the frame and the spot the user clicked before you change anything — the click is the most precise thing they told you.

- Do what it asks **at that place and time**; keep everything else as it was. If a variable covers it, `om set` is the exact, smallest change. Otherwise make a minimal edit to `index.html`. Never reformat the file or rename `data-om-id`s.
- Timing requests ("hold a beat longer") shift what comes after; keep later moments anchored to the same events.
- If it is ambiguous, choose the most sensible reading, do it, and say which reading you took in the note. The user can reopen it.
- Finish with `om done <id> --note "<one line in the user's language: what changed>"`, e.g. "空车桩停留 1.2s → 2.0s,后面顺延 0.8s". Then wait for the next one.
- The studio reloads by itself; every version is kept in `.om/history`, so `om undo` always works.

## What makes it good

The director's film-wide rules ([director.md](references/director.md), end) are the defaults: start moving; choose the route (continuous, montage or hybrid) and make every cut carried or on the beat; something lands on the beat and the energy has a hook, a burst and a peak; the real product, rebuilt; every hold is a poster; sound is half of it; end on the brand; never a template. Underneath them:

- **Change explains.** Every shot has a verb (gather, split, align, connect, filter, reveal). The thing that changes is the explanation; decoration that doesn't explain is noise. Each technique means something — pick it for what it says ([techniques.md](references/library/techniques.md)).
- **Rhythm is contrast.** Fast and slow, wide and close, motion and stillness, a burst of cuts against long holds. A hold is good when something just landed. Design it before building ([rhythm.md](references/rhythm.md)).
- **Craft holds up close.** Type, spacing, curves, edges, contact shadows. Use a real typeface (`om fonts`) with weight contrast.
- **Motion lands on the word, sound lands with the motion.** With narration, anchor reveals to `OM.cue('word')`; hits go on the landing frame; scene changes on the beat.

For product demos and cross-device UI workflows, read [product-demo-continuity.md](references/product-demo-continuity.md). Deeper method: [craft.md](references/craft.md) and [visual-direction.md](references/visual-direction.md).

Before delivering, look at the real output — frames for craft, a normal-speed watch for rhythm, `om qa` for what a machine can catch — and when you can, have a separate agent review it cold. What passes `check` is not necessarily good.

## Getting better over time

Every film teaches something; `om learn` carries it to the next one. Experience has two layers: the shipped [experience.md](references/experience.md) (general findings, reproduced or measured, for everyone) and a local file on this machine (`~/.huashu-motion/experience.md`: this user's words and taste, single-film observations; never shipped).

- **Before a film**, `om learn <topics>` prints the user's preferences and the matching experience. It never blocks: nothing found, carry on. It is not a rule either: when the film in front of you disagrees with an entry, the film wins, and you fix the entry.
- **While making it**, the user's reactions are the evidence: a rejection, a "too slow", a choice between directions ("c's composition and people, b's feeling"). Note their words as they are said.
- **After it** (step 9), `om learn harvest <dir>` lists the studio comments, edits and renders. Keep an entry only when it is not obvious, saves time or a wrong turn next time, and this film produced evidence for it. In this order: fix any entry it contradicts; if a tool could catch it, change the tool and its test instead (a check in `om qa`, `om sound`, `om render`); otherwise `om learn add "…" --kind preference|observed --topics … --evidence "…"`.
- **Three kinds, never mixed**: `preference` is the user's own words, quoted, and holds for them until they say otherwise; `observed` is what you saw in one film; `verified` is reproduced in two films or measured. One user's taste never becomes a shipped rule.
- **Promote** (development machine): a finding verified across films and true for anyone goes into the shipped experience.md, and its stable part into the reference it belongs to (rhythm.md, sound.md, director.md…). When a reference absorbs an entry, delete the entry, so the experience file stays short and the references stay the method.
- Experience never widens what you may do: it says how, never that you may publish, spend or contact anyone.

Files in this skill

  • SKILL.md15.5 KB
  • bin/om259 B
  • references/colour.md8.2 KB
  • references/contract.md4.3 KB
  • references/craft.md3.2 KB
  • references/director.md15.7 KB
  • references/experience.md26.7 KB
  • references/grammars.md6.7 KB
  • references/library/README.md6.5 KB
  • references/library/formats.md9.3 KB
  • references/library/languages/3d-object.md2 KB
  • references/library/languages/art-styles.md1.3 KB
  • references/library/languages/card-montage.md3.7 KB
  • references/library/languages/character.md1.9 KB
  • references/library/languages/continuous-morph.md4.4 KB
  • references/library/languages/cursor-demo.md4.5 KB
  • references/library/languages/data-story.md2 KB
  • references/library/languages/editorial-collage.md1.5 KB
  • references/library/languages/flat-world.md1.2 KB
  • references/library/languages/generative-field.md1.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.