Svg animate
Skill ChanMeng666/svg-animation-studio/.claude/skills/svg-animate
A composable SVG animation system driven by Claude Code. Describe an animation in natural language; get a production-ready .svg file. 25 motion/shape/filter primitives, 4 skills, 3 subagents, snapshot-tested, Next.js preview.
npx -y skills add ChanMeng666/svg-animation-studio --skill svg-animateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Create, edit, or remix an animated SVG file from a natural-language description. Use this whenever the user asks you to make, build, design, generate, animate, or "draw something that moves" — mascots, logos, loaders, badges, icons, characters, brand marks, or any visual asset that should animate. Always prefer this skill over hand-writing SVG strings. Trigger phrases (use this skill even on subtle variants): "做一个X动画", "给我画个会动的Y", "搞一个跳跃/旋转/脉动的Z", "make me an animated X", "create a bouncing/spinning/pulsing X", "build a logo that does Y", "design a loader that ...", "I need an SVG mascot for ...". Also use when the user provides a reference image or sketch and asks to "animate this" or "make this lively". When the user says they want output "as an SVG file" or asks for something to drop into output/, this skill is the right entry point.
SKILL.md
8.8 KB, as published. Nobody here has run it
You are the entry point for SVG animation requests in this repository.
The repository (svg-animation-studio) is a compounding system: every animation
reuses primitives from lib/primitives/, every new primitive earns the right
to be added through /svg-add-primitive. Your job is to translate one
sentence of natural language into a working output/<slug>.svg that visually
delights — without breaking that compounding discipline.
Why this skill exists
LLMs that template-literal SVG strings end up with subtly broken markup,
inconsistent IDs, and no way to evolve. This skill funnels everything through
lib/composer.js so the system stays composable, snapshot-testable, and
reusable across sessions. If you find yourself wanting to write <svg ...>
inline anywhere, stop — composer.composeSVG exists for exactly that need.
Step 1 — Understand what's being asked
- Read any user-provided reference from
ref/(sketches, sample SVGs, screenshots). - Identify the asset class: character mascot, logo mark, loader/spinner, notification badge, ambient background, or icon.
- Identify the motion verbs: jumping, bobbing, pulsing, spinning, waving, talking, glowing, drifting, flickering.
- Identify the style cues: pixel-art, gradient-smooth, flat, neon, comic.
If the request is vague ("make it cool"), ask one clarifying question — pick the highest-leverage one (usually: "what shape/character?" or "what motion?"). Don't grill the user.
Step 2 — Read the catalog before composing
Open lib/presets/index.js to see what already exists. Look at each
candidate's compose() (~30 lines each) to learn the patterns. Decide one of:
- Fork — closest existing preset is 80%+ right. Copy its file to a new slug, adjust params/colors.
- Compose from primitives — no existing preset fits, but the needed
primitives all exist in
lib/primitives/. Build a new preset. - Stop and request a primitive — a needed motion / shape / filter doesn't
exist. Output a one-line summary plus:
"I need a
<primitive-name>primitive inlib/primitives/<category>.js. Please run/svg-add-primitive <name>." Do NOT add primitives inline. Seedocs/extension-protocol.mdrule 1.
For inspiration mapping ("user wants X → reach for Y"), open
references/preset-cookbook.md.
For the full lib API (signatures + defaults), open references/lib-api.md.
For any branded / multi-layer asset (cover, banner, logo, loader), use the modern composition path (it's how the quality bar is reproduced):
- Pull a palette with
getPalette(opts.palette || '<default>')fromlib/palettes.jsand reference accents by index (pal.accents[0]) — never hardcode hex. - Build the body with
composeScene({ layers, defs, style })fromlib/scene.js: it orders layers back-to-front and auto-nests a layer's statictransform+ animatedclassName(so the CSS transform can't clobber positioning — Gotcha 2). - Then fork the closest family template:
brandCover.js/gradientCover.js(covers),heroStrip.js/repoHero.js(banners),orbitLogo.js/pulseMonoLogo.js/spinBadge.js(logos/badges),dotLoader.js/rippleLoader.js/bounceChar.js(loaders/characters).chan-coveris the FROZEN reference — forkbrand-coverinstead.
For why timing / squash / staggering matter, open
references/animation-principles.md. The 5-point quality checklist there is
the same one /svg-verify will grade against — design with it in mind.
Step 3 — Write the preset
A preset file lives at lib/presets/<slugCamelCase>.js and exports:
module.exports = {
name: '<slug-kebab>',
viewBox: '0 0 W H',
width: W, height: H,
compose(opts = {}) {
motion.resetIdCounter(); // mandatory first line
// pull primitives, compose body + style, return composeSVG({...})
}
};
Add the new slug to lib/presets/index.js.
Constraints, in priority order:
composeSVGis the only allowed way to assemble the root<svg>document.- Call
motion.resetIdCounter()as the first line ofcompose()so class names are deterministic across calls — this is what makes snapshots stable. - Default colors and durations should match the source's intent; allow the
user to override via
opts. - Re-use existing primitives wherever possible. Each new preset that re-uses ≥ 1 primitive validates the compounding contract.
Step 4 — Render
node lib/render-cli.js <slug>
This writes to output/<slug>.svg. Inspect file size — if it's < 200 bytes,
something is wrong (probably an empty body); if it's > 20 KB without good
reason (heavy gradients or many elements), something is duplicated.
Step 5 — Snapshot
npm run test:snapshot
First time for a new preset → snapshot is created. Subsequent runs → diff is shown. If diff is intentional (you tuned params), update with:
npm run snapshot:update
Always re-verify visually after a snapshot update.
Step 6 — Visually verify
Invoke /svg-verify <slug> — it runs in an isolated subagent context, opens
the SVG in chrome-devtools MCP, scores against the 5-point rubric, and
returns ≤ 100 words. The screenshots and console messages stay in the
subagent's context so this main thread doesn't drown in image data.
Step 7 — Iterate or finalize
If the verdict is tweak: adjust params (duration, easing, magnitude,
stagger), re-render, re-verify. Cap at 3 rounds before pausing to ask the
user. If fail: probably a structural issue — re-read the source primitives
and reconsider composition rather than tweaking magnitudes.
If pass: report to the user with:
- Path:
output/<slug>.svg - Primitives used:
motion.foo,shapes.bar, ... - The verdict's one-line summary
- (Optional) Whether to run
/svg-export <slug>to optimize and ship.
Anti-patterns
- ❌ Writing
<svg ...>markup directly in a skill or preset. Always go throughcomposer.composeSVG. - ❌ Adding a function to
lib/primitives/*.jswithout going through/svg-add-primitive. The protocol exists to keep JSDoc, snapshot coverage, and lib-api.md in sync. - ❌ Calling
npm run snapshot:updatewithout a visual recheck. Snapshots are the only thing protecting you from silent regressions. - ❌ Burning the user's time on > 3 silent iterations. After three rounds without a pass, pause and ask.
- ❌ Hand-writing keyframe values when a
motion.*primitive already covers the motion. Composability is the whole point.
When the user wants multiple variants
If the user asks for "a few options", "show me 3 styles", "give me variants",
or "compare different approaches", delegate to the svg-explorer subagent
instead of running variants serially in this thread. The Agent dispatch
pattern:
Use the svg-explorer agent to produce <N> variants of
"<user's description>" varying along axis <timing|palette|style|energy>.
It returns a comparison block with file paths + a recommendation. Then run
/svg-verify <recommended-slug> on the chosen winner, and /svg-export if
the user accepts.
Why delegate? Generating N presets in parallel + rendering N SVGs + reading N preset diffs would pump verbose intermediate output into this thread. The fork keeps the comparison clean: you only see the final summary.
When something goes wrong
npm testfails on a preset you didn't touch → you broke a primitive signature. Diff your primitive changes and either fix them or update the snapshot deliberately after visual recheck.compose()throws → almost certainly a missing or renamed primitive. Opendocs/lib-api.mdand grep for the function you tried to call.- Visual verification keeps failing on stagger → check
animation-principles.mdsection "Staggering"; the magnitude is probably outside 0.05–0.15 s.