smooth-motion-choreography
Skill0 starsChanged 2 months agoMITView on GitHub
Choreographs smooth motion for existing Remotion vector scenes - enter, hold, emphasis, camera and exit moves, ease and spring presets (settle, overshoot, no bounce), stagger, draw-on, transitions, loop seams, a flicker linter. Use when the user asks to animate scenes or icons, ease something in, smooth jerky, flickering or popping motion, or fix a loop that jumps. Not for CSS, web UI, or export.
In this repository10 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-skillSkill
- publish-repoSkill
- animation-export-presetsSkill
- animation-frame-qaSkill
- animation-storyboardSkill
- storytelling-animationSkill
- vector-asset-sourcingSkill
- vector-scene-layoutSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 17
Use when the scenes exist and need animating, when motion feels jerky, mechanical, floaty or flickery, when transitions or a loop seam need …
- Very specific: line 21
Do NOT use for: beats and timing of the story (animation-storyboard), building or sizing scenes (vector-scene-layout), encoding and presets …
- Very specific: line 62
Every scene animated from useCurrentFrame() with the helpers or the easing tokens.
- Distinctive: line 65
No text moves during its readable window.
- Very specific: line 84
Never animate font-size, width, left: text reflows and line breaks jump.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
smooth-motion-choreography
Adds motion to the static scenes of a Remotion project so the result reads as one calm system on a muted phone feed. It fixes the failures agents produce by default: springs that bounce text, CSS transitions that flicker in the parallel render, staggers that read as one pop, pans that strobe at 30 fps, text that moves while it should be read, exits that vanish before the cut, and loops with a visible seam.
When to use / when NOT to use
Use when the scenes exist and need animating, when motion feels jerky, mechanical, floaty or flickery, when transitions or a loop seam need fixing, or when someone asks which easing or spring to use in Remotion.
Do NOT use for: beats and timing of the story (animation-storyboard), building or
sizing scenes (vector-scene-layout), encoding and presets (animation-export-presets),
judging a finished render (animation-frame-qa), web UI hover effects, CSS or GSAP
questions, or Remotion API detail (remotion-dev/skills).
Workflow
- Read the contract:
storyboard.jsongives each beat'smotionintent, transition type and overlap;src/timeline.tsgives frames. Readreferences/motion-vocabulary.mdonce: five moves, easing tokens, springs, stagger. - Copy the helpers:
assets/templates/motion.tsintosrc/. Ifsrc/Video.tsxis still the layout template, replace it withassets/templates/Video.tsx(same series plus the loop wrap); if it was customised, patch the wrap in by hand (recipe inreferences/loops-and-transitions.md).assets/templates/scenes/TextCard.tsxshows an animated card. - Animate each scene from the local frame:
const frame = useCurrentFrame(); const { fps } = useVideoConfig();thenpresence()/enter()/exit()for cards,settle()for icons,evolvePathfor draw-on,clamp01()with an easing token for travel. Map each beat'smotionintent to the vocabulary; grouped items useenterGroup()(≤ 4 items, whole cascade inside 0.5 s); keep every text card still for its readable window; passskipExitwhen an overlapping transition does the handoff; animatetransform,opacityand SVG geometry (dash offset, path, fill), never layout properties (font-size,width,left, padding). - Transitions and loops: the storyboard's
transitionper beat drivesTransitionSeries; forloop: truethe template appends the hook copy and shifts the series (recipe inreferences/loops-and-transitions.md). - Lint, then look:
Lint must report 0 errors. Render 10–15 frames around every transition and the loop seam (python3 "${CLAUDE_SKILL_DIR}/scripts/lint_motion.py" src npx remotion render src/index.ts <target> out/frames --sequence --image-format=png --frames=<a>-<b>P-5toP-1, then0to4), tile them (ffmpeg -pattern_type glob -i 'out/frames/*.png' -vf "scale=160:-2,tile=11x1" strip.png) and open the strip. Fix anything that pops, jumps, strobes or moves under text. - Hand off: the list of moves per beat and anything the intent asked for that
was toned down (and why). Next:
animation-export-presets.
Output spec
- Every scene animated from
useCurrentFrame()with the helpers or the easing tokens;lint_motion.py srcexits 0. - Transition strips and, for loops, the wrap strip rendered and reviewed.
- No text moves during its readable window; the CTA beat is still.
Gotchas
- Remotion renders frames in parallel tabs: CSS
transition/animation, timers,Date.now,Math.random, GSAP/Motion do not animate or differ per frame. Userandom(seed); derive everything from the frame. useCurrentFrame()is local inside a<Sequence>; subtracting the beat's start again is the most common timing bug.spring()defaults overshoot; text takesdamping: 200. Always passfps.interpolatewithoutextrapolateRight: "clamp"keeps going after the range.- Enter from
scale(0.92)or a short rise; neverscale(0)or a hard pop. - Stagger 2 frames at 30 fps for grouped items and cap the group at 4 so the whole cascade lands inside 0.5 s; one frame is a pop, five is a sequence of events. A text card never staggers.
- A full-frame pan under ~7 s strobes at 24–30 fps, and an eased pan peaks at about
twice its average speed, so budget half of
maxPanPxPerFramefor eased moves; shorten the travel or use<CameraMotionBlur>on that beat only (render time multiplies bysamples). - Never animate
font-size,width,left: text reflows and line breaks jump. - A loop is a period, not "last frame equals first": the last beat cross-fades into a hook copy and the series is shifted by the wrap; the wrap must be > 0 and ≥ the hook's complete entrance including any stagger (the template throws otherwise), and the wrap is always a fade.
- 60 fps doubles render time and most feeds play 30; keep the storyboard's fps.
Pointers
scripts/lint_motion.py— anti-pattern lint with line numbers;--self-test.assets/templates/motion.ts—EASE,SPRING,enter,enterGroup,exit,presence,rise,scaleIn,settle,clamp01,maxPanPxPerFrame.assets/templates/Video.tsx— TransitionSeries with the loop wrap;scenes/TextCard.tsx— animated card.references/motion-vocabulary.md— moves, tokens, springs, stagger, smoothness rules, determinism, sources.references/loops-and-transitions.md— series arithmetic, morphs, the loop recipe, strobing and motion blur.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

