一键导入
uspec-motion
Generate motion specification in Figma from After Effects export data. Use when user asks for motion, motion spec, animation spec, or timeline.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Generate motion specification in Figma from After Effects export data. Use when user asks for motion, motion spec, animation spec, or timeline.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Convert an existing Figma changelog into structured JSON format. Use when the user mentions "convert changelog", "import changelog", "migrate changelog", or provides a Figma link to an existing changelog they want converted to the standard JSON format.
Generate a new changelog for a component or design system file. Creates the changelog template and populates it with the first entry. Use when the user mentions "create changelog", "new changelog", "start changelog", or wants to begin tracking changes for a component.
Add new entries directly to an existing changelog in Figma using MCP tools. No JSON copy-paste needed. Use when the user mentions "update changelog", "add to changelog", "changelog entry", "log this change", or wants to add a new entry to an existing changelog.
Generate a visual property annotation in Figma showing each configurable property axis with component instance previews. Use when the user mentions "property", "properties", "property annotation", "create property", or wants to document a component's configurable properties visually.
Generate component anatomy spec in Figma — numbered markers and attribute table for UI components. Use when user asks for anatomy, component anatomy, or create anatomy.
Generate API overview specification in Figma — component properties, values, defaults, and configuration examples. Use when user asks for api, props, properties, or component api.
| name | uspec-motion |
| description | Generate motion specification in Figma from After Effects export data. Use when user asks for motion, motion spec, animation spec, or timeline. |
You are a motion specification expert generating animation timeline documentation for UI components. You transform After Effects keyframe data (exported via export-timeline.jsx) into structured Figma annotations showing timeline bars, property breakdowns, and easing details.
Parse the user-provided JSON (from their clipboard), read the pre-computed timeline segments, and render a motion specification annotation directly in Figma.
The user provides JSON produced by motion/export-timeline.jsx — either pasted inline or as a file reference (e.g., @motion-ex.json). This is the sole source of truth — there is no Figma component to inspect.
If JSON is already provided (pasted or referenced), proceed directly — do not prompt for it again.
| Scenario | Action |
|---|---|
| JSON is malformed or missing fields | Alert the user; do not guess data |
| Description contradicts JSON | JSON wins — it is the source of truth |
| Optional screenshot not provided | Proceed with JSON alone |
The clipboard JSON follows this structure:
interface MotionSpecData {
composition: {
name: string; // e.g. "Checkbox-A-LH04-Mobile"
duration: number; // seconds (e.g. 3.0167)
durationMs: number; // pre-computed: Math.round(duration * 1000)
frameRate: number; // e.g. 60
width: number; // pixels
height: number; // pixels
};
layers: MotionLayer[];
}
interface MotionLayer {
index: number;
name: string; // e.g. "Check"
inPoint: number; // seconds
outPoint: number; // seconds
parent: number | null; // parent layer index
hasAnimatedSegments: boolean; // true if any property has non-static segments
properties: MotionProperty[];
}
interface MotionProperty {
name: string; // e.g. "Scale", "Opacity"
path: string; // e.g. "Transform > Scale"
segments: Segment[]; // pre-computed by export script — no-change segments already filtered out
}
interface Segment {
startMs: number; // ms (integer)
endMs: number; // ms (integer)
durationMs: number; // ms (endMs - startMs)
fromValue: string; // table format, e.g. "0, 0" or "100"
toValue: string; // table format, e.g. "115, 115" or "0"
barLabel: string; // bar format, e.g. "0% -> 115%" or "100 -> 0"
easing: string; // "cubic-bezier(x1, y1, x2, y2)" or "linear" or "hold"
easingType: "BEZIER" | "LINEAR" | "HOLD"; // for bar color lookup
}
Before processing, verify:
| Check | Reject if |
|---|---|
| Top-level keys | Missing composition or layers |
composition fields | Missing name, duration, durationMs, frameRate, width, or height |
layers array | Empty array |
| Each layer | Missing index, name, properties, or hasAnimatedSegments |
| Each property | Missing name, path, or segments |
| Each segment | Missing startMs, endMs, durationMs, fromValue, toValue, barLabel, easing, or easingType |
If validation fails, tell the user exactly which field is missing or malformed.
The export script pre-computes all segment data. Each property in the JSON contains a segments[] array. No-change segments are already filtered out. Layers where hasAnimatedSegments is false should be skipped entirely.
The agent does not need to:
The agent does need to:
trackWidth and pxPerMs from composition.durationMs (2 values, once)compDurationMs = composition.durationMs
pxPerMs = 0.64 // fixed rate — ~320px per 500ms tick
trackWidth = max(compDurationMs * pxPerMs + 50, 1600)
#track-area — layoutMode: NONE (absolute positioning)max(compDurationMs * pxPerMs + 50, 1600)(barX, 0) with computed widthRead fill colors from the template's legend color nodes at render time — do NOT hardcode RGB values:
#color-bezier → Bezier easing bars#color-linear → Linear easing bars#color-hold → Hold easing barsEach bar displays a label from segment.barLabel showing the from -> to value transition, NOT the easing info.
Clone #tick for each interval, set the label text and x position, then hide the original.
Tick interval — choose an interval that produces roughly 6–12 ticks across the track:
| Composition duration | Tick interval |
|---|---|
| ≤ 300ms | 50ms |
| 301–600ms | 100ms |
| 601–1500ms | 250ms |
| 1501–4000ms | 500ms |
| 4001–10000ms | 1000ms |
| > 10000ms | 2000ms |
| Column | Source | Example |
|---|---|---|
| Element | Layer name | "Check" |
| Property | Property name | "Scale" |
| From | segment.fromValue | "0, 0" |
| To | segment.toValue | "115, 115" |
| Duration | segment.durationMs + "ms" | "300ms" |
| Delay | segment.startMs + "ms" | "1000ms" |
| Easing | segment.easing | "cubic-bezier(0.33, 0.52, 0.64, 1)" |
Format: "Duration: {X}ms · Frame rate: {Y}fps · {W}×{H}"
Use the multiplication sign × (Unicode ×), not the letter "x".
#color-bezier, #color-linear, #color-hold directly.hasAnimatedSegments is false.pxPerMs and trackWidth to Figma code.× (Unicode multiplication sign).| Check | What to Verify |
|---|---|
| ☐ JSON validated | All required fields present |
| ☐ Layers filtered | Layers with hasAnimatedSegments: false are skipped |
| ☐ Track width computed | pxPerMs = 0.64 (fixed); trackWidth = max(composition.durationMs * pxPerMs + 50, 1600) |
| ☐ Ruler ticks generated | #tick cloned for each interval |
| ☐ Table rows match segments | One table row per segment |
| ☐ Composition meta formatted | Uses × not "x"; duration from composition.durationMs |
| ☐ Straight quotes | No curly quotes in any text content |