rossark-motion-skill
Bring anything drawn to life with calm, believable motion. It covers characters and creatures (gliding pupils, blinks, breathing, head tilts), full-body acting (landing, waving, leaning, levitating, kicking a ball), plants, fabric, fire, smoke, water, weather, lights, machines, vehicles, icons, logos, charts and whole scenes. Use it whenever someone asks to animate an illustration, an icon, a mascot or a scene, to make something "feel alive", to add idle motion, to turn a static drawing into a living one, or to recreate the motion of a reference video. Comes with a small motion engine and templates for React Native (react-native-svg + Reanimated) and SwiftUI (TimelineView + Canvas), tools that measure a reference video frame by frame, and offline rendering to video, in a phone frame too. The method also works on the web.
Install
npx skills add https://github.com/rossark0/rossark-motion-skill --skill rossark-motion-skillMOTION.md: living illustrations in this project
Copy this file next to the project's art (for example
src/art/MOTION.md) and fill in Part 2 as you learn the project. Part 1 is the method and stays as it is. Therossark-motion-skillreads this file first, and Part 2 overrides the skill's defaults.
Part 1. The method
The goal: anything drawn (a character, a plant, a flame, a street, a logo, a chart) feels alive and calm. Nothing teleports, nothing bounces, nothing shouts.
Principles
- Never teleport: interpolate everything; never swap drawings.
- Calm by default: strong curves, no bouncy overshoot.
- Small amplitudes: when unsure, halve it.
- Arcs and pivots: each moving part is a layer rotating around its joint (stem base, hinge, neck, hook).
- Overlap and follow-through: tips and trailing parts move later and further; give each part the same wave with a growing phase delay.
- Variety without chaos:
- repeated items get a seeded phase, speed and size;
- nothing moves in sync, and there's no random value per frame.
- One main action per scene, plus two or three idle loops. Side things stay quiet.
- Opacity only to appear or disappear.
- The layout never moves: motion lives inside the drawing.
- Reduced motion: loops freeze on a good frame 0, and one-shots show their final frame.
- Nothing runs unseen: pause off screen, when hidden and in the background.
- Enough frames: anything under ~100 ms flickers at 30 fps; render and export at 60 when you can. Blinks close in ~110 ms and reopen in ~190 ms.
- Interface rules:
- frequency decides how much (often seen = barely moves; rare moments get the delight);
- every motion has a purpose;
- shared elements travel, never teleport;
- interface moves stay under 300 ms;
- exits are faster than entrances;
- nothing appears from scale 0;
- interruptions continue from the current value.
The engine
- Clocks: a loop clock for idle life, a one-shot clock for a scene that tells an action. One per character, group or scene.
- Tracks: keyframes
[ms, value, 'out'?]read withtrack(t, keys). The last key equals the first.trackstops at every key, so use it for one move (a blink, a lid). For acting (a chain of poses), useflow(t, keys), which passes through the keys without stopping and never overshoots. - Helpers:
wave(−1 to 1), for sway and breathing;loop(0 to 1), for drift and falling;bell, to fade in and out;seg, for one beat of a one-shot;seeded(i), for per-item variety.
- Curves:
- travel uses ease-in-out
(0.77, 0, 0.175, 1); - open and arrive use ease-out
(0.23, 1, 0.32, 1); - leaving uses ease-in;
- endless loops are linear.
- travel uses ease-in-out
Quick recipes
Acting (a whole character)
- Every channel: key pose (
flow) + idle (waves, never off while on stage) + follow-through (the parent read 90–140 ms earlier) + accents (awaveinside asegwindow). - Arms: an upper arm and a forearm share a round elbow; the forearm points at shoulder angle + elbow bend.
- Head turns: slide the face toward the turn (eyes 10, nose 13 in a 100-wide head) and the ears the other way. Blink on the turn.
- Weight: the hips shift and carry the upper body, and the legs angle to keep the feet under it.
- Landing: hover, then fall with gravity and stretch; squash hard (0.8) on contact and keep the volume (
width = 1 / height^0.6). - In the air: limp feet (toes down, one knee folded, trading slowly). The shadow stays on the floor and scales with the height.
- Props: enter from off screen already moving and roll by distance / radius. The eyes follow them. A kick hits at the middle of the swing; the prop leaves as a throw, spinning, with a short squash.
- Asymmetry: the arms never mirror each other.
- Camera: a view from a little above is a whole build, not a tweak: the head is 40–50% of the height, the torso is short and narrower than the head, the legs are short, the feet are round from above, and the shadow is a wide oval with the feet in its lower half. Keep it in one
buildobject. A flat view keeps a thin pill shadow. - Framing: on a phone, as big as the screen allows, with the feet low.
From a reference video
- Contact sheets at the full frame rate (
tools/sheet.sh). - Measure motion with numbers (
tools/track_edges.py): a 2% jiggle or a 5% float doesn't show to the eye. - Sample colors from pixels (
tools/sample_colors.py). - Go part by part: feet, shadow, hands, head.
- Compare proportions as ratios of one unit (head widths). "Stretched" means a ratio is far off.
- Compare your render with the reference at the same moments.
- Don't publish a copy of someone else's art.
Performance
- Everything is a function of one clock's time.
- Draw many items in one SVG or
Canvas. - Reset repeating animations to 0 before starting, and cancel them on cleanup.
- Declare curves at the top of the module.
Workflow
- Read Part 2 and the art file's header comments.
- List what could live in the drawing.
- Pick one main action and two or three idle loops.
- Split the art into layers at their pivots.
- Put the numbers in tokens.
- Check frame 0, the final frames and the loop seams. For a character, look at a contact sheet of every 4th frame of your own render.
- Run the checks.
- Hand off: what moves, and what hasn't been seen on a real device.
Part 2. This project
Fill these in. Delete the hints in italics as you go.
Where the code is
- Platform: React Native, SwiftUI, web
- Motion engine and live face: paths, or "copy
templates/react-native/ortemplates/swiftui/from the skill" - Art kit, characters, poses: paths, and the coordinate system (where the head centre or pivot is, units)
- Existing animated pieces to copy from: paths
The owner's rules
Quote them in their own words, with the date. They override Part 1.
- …
Rig limits
What can't move how (no separate head layer, eyes baked into the drawing, a hand on the face, one flat image).
- …
How changes are checked
Device or simulator, who tests, the type, lint and test commands, known pre-existing errors.
- …