@pixerate/editor 0.79.0 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/dist/agent/index.cjs +102 -6
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -2
- package/dist/agent/index.d.ts +4 -2
- package/dist/agent/index.js +101 -5
- package/dist/agent/index.js.map +1 -1
- package/dist/{builtins-BKYlHH1s.d.ts → builtins-CV1fDj64.d.ts} +5 -1
- package/dist/{builtins-1kqwLUnb.d.cts → builtins-c4w0eAYl.d.cts} +5 -1
- package/dist/{chunk-2CJ3LPYQ.js → chunk-424H3P4I.js} +13 -295
- package/dist/chunk-424H3P4I.js.map +1 -0
- package/dist/{chunk-UN33YOXW.cjs → chunk-PA5S7KPC.cjs} +293 -2
- package/dist/chunk-PA5S7KPC.cjs.map +1 -0
- package/dist/{chunk-IB3ZHQAX.js → chunk-PTYWCFFW.js} +29 -4
- package/dist/chunk-PTYWCFFW.js.map +1 -0
- package/dist/{chunk-JQ3BB3E6.js → chunk-PXDEFEG2.js} +293 -2
- package/dist/chunk-PXDEFEG2.js.map +1 -0
- package/dist/{chunk-YU4WQE5M.cjs → chunk-TAPXWP2B.cjs} +95 -377
- package/dist/chunk-TAPXWP2B.cjs.map +1 -0
- package/dist/{chunk-HXDMZQTD.cjs → chunk-TPOT575P.cjs} +29 -4
- package/dist/{chunk-IB3ZHQAX.js.map → chunk-TPOT575P.cjs.map} +1 -1
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.d.cts +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.js +1 -1
- package/dist/generation/index.cjs +932 -791
- package/dist/generation/index.cjs.map +1 -1
- package/dist/generation/index.d.cts +266 -240
- package/dist/generation/index.d.ts +266 -240
- package/dist/generation/index.js +926 -785
- package/dist/generation/index.js.map +1 -1
- package/dist/image-editor/index.cjs +266 -2
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +12 -1
- package/dist/image-editor/index.d.ts +12 -1
- package/dist/image-editor/index.js +265 -1
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +16 -16
- package/dist/spreadsheet/index.cjs +3 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.js +16 -16
- package/dist/video-editor/index.cjs +461 -101
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +67 -3
- package/dist/video-editor/index.d.ts +67 -3
- package/dist/video-editor/index.js +426 -66
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +3 -1
- package/skills/README.md +55 -0
- package/skills/pixerate-agent-tools/SKILL.md +75 -0
- package/skills/pixerate-animation-editor/SKILL.md +155 -0
- package/skills/pixerate-animation-editor/references/commands.md +123 -0
- package/skills/pixerate-canvas/SKILL.md +230 -0
- package/skills/pixerate-chart/SKILL.md +190 -0
- package/skills/pixerate-diagram/SKILL.md +134 -0
- package/skills/pixerate-generation/SKILL.md +109 -0
- package/skills/pixerate-image-editor/SKILL.md +139 -0
- package/skills/pixerate-parameters/SKILL.md +83 -0
- package/skills/pixerate-rich-text/SKILL.md +160 -0
- package/skills/pixerate-spreadsheet/SKILL.md +146 -0
- package/skills/pixerate-vector/SKILL.md +191 -0
- package/skills/pixerate-vector/references/commands.md +138 -0
- package/skills/pixerate-video-editor/SKILL.md +173 -0
- package/dist/chunk-2CJ3LPYQ.js.map +0 -1
- package/dist/chunk-HXDMZQTD.cjs.map +0 -1
- package/dist/chunk-JQ3BB3E6.js.map +0 -1
- package/dist/chunk-UN33YOXW.cjs.map +0 -1
- package/dist/chunk-YU4WQE5M.cjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.81.0",
|
|
4
4
|
"description": "UI-agnostic rich text and media editing core library",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
},
|
|
141
141
|
"files": [
|
|
142
142
|
"dist",
|
|
143
|
+
"skills",
|
|
143
144
|
"THIRD_PARTY_NOTICES.md"
|
|
144
145
|
],
|
|
145
146
|
"sideEffects": false,
|
|
@@ -176,6 +177,7 @@
|
|
|
176
177
|
"@types/dagre": "^0.7.54",
|
|
177
178
|
"@types/markdown-it": "^14.2.0",
|
|
178
179
|
"@types/node": "^24.0.0",
|
|
180
|
+
"fast-check": "^3.23.2",
|
|
179
181
|
"mermaid": "12.0.0",
|
|
180
182
|
"tiptap-markdown": "^0.8.10",
|
|
181
183
|
"tsup": "^8.4.0",
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Agent skills
|
|
2
|
+
|
|
3
|
+
Each editor domain in `@pixerate/editor` ships an [Agent Skill](https://agentskills.io): a
|
|
4
|
+
`SKILL.md` that teaches a model when and how to use that domain's tools, and the practice an
|
|
5
|
+
expert in the domain would follow. They are published with the package, so an app or agent
|
|
6
|
+
that uses the tools can load the matching skill.
|
|
7
|
+
|
|
8
|
+
| Skill | Covers |
|
|
9
|
+
| --- | --- |
|
|
10
|
+
| [`pixerate-agent-tools`](pixerate-agent-tools/SKILL.md) | What every editor has in common: the MCP bridge, tool naming and namespaces, `list_commands` / `run_command` / `run_commands`, errors, undo. Load it with any domain skill. |
|
|
11
|
+
| [`pixerate-rich-text`](pixerate-rich-text/SKILL.md) | Documents and prompts: text, tables, find and replace, charts in documents, prompt variables. |
|
|
12
|
+
| [`pixerate-spreadsheet`](pixerate-spreadsheet/SKILL.md) | Cells, ranges, rows and columns, filters, merges. |
|
|
13
|
+
| [`pixerate-canvas`](pixerate-canvas/SKILL.md) | Node-graph canvas, components and variants, arranging, shape booleans, keyframe animation. |
|
|
14
|
+
| [`pixerate-vector`](pixerate-vector/SKILL.md) | Vector paths, styles, gradients, effects, blends, Pathfinder, SVG. |
|
|
15
|
+
| [`pixerate-chart`](pixerate-chart/SKILL.md) | Chart specs, data, series, presets, trendlines, Office and Mermaid charts. |
|
|
16
|
+
| [`pixerate-diagram`](pixerate-diagram/SKILL.md) | Mermaid diagrams: nodes, edges, groups, layout. |
|
|
17
|
+
| [`pixerate-image-editor`](pixerate-image-editor/SKILL.md) | Adjustments, adjustment layers, selections and masks. |
|
|
18
|
+
| [`pixerate-animation-editor`](pixerate-animation-editor/SKILL.md) | Vector animation: shots, commands, timing, Flair and Lottie. |
|
|
19
|
+
| [`pixerate-video-editor`](pixerate-video-editor/SKILL.md) | Non-linear video editing: tracks, clips, transitions, export. |
|
|
20
|
+
| [`pixerate-generation`](pixerate-generation/SKILL.md) | Planning, estimating and running paid media generation. |
|
|
21
|
+
| [`pixerate-parameters`](pixerate-parameters/SKILL.md) | Effect parameters, presets and keyframes. |
|
|
22
|
+
|
|
23
|
+
## Using them
|
|
24
|
+
|
|
25
|
+
Copy or symlink the directories into your agent's skills folder, for example for Claude Code:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cp -R node_modules/@pixerate/editor/skills/* .claude/skills/
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Skills use bare tool names (`get_chart`). A host that namespaces providers exposes them as
|
|
32
|
+
`<namespace>__get_chart`.
|
|
33
|
+
|
|
34
|
+
## Maintaining them
|
|
35
|
+
|
|
36
|
+
A skill is part of its domain's agent path (see section 4 of `AGENTS.md`). When you add,
|
|
37
|
+
rename or remove a tool or command, or change how one should be used, update the skill in the
|
|
38
|
+
same change.
|
|
39
|
+
|
|
40
|
+
- **Format.** YAML frontmatter with `name` (the directory name) and `description` (what the
|
|
41
|
+
skill covers and when to use it, at most 1024 characters), then: a mental model, a working
|
|
42
|
+
method, best practices, a tool reference, commands (if any) and pitfalls. Keep `SKILL.md`
|
|
43
|
+
under 500 lines and move long reference material to `references/*.md`.
|
|
44
|
+
- **Tool tables.** Every tool and command id the domain exposes is the first cell of exactly
|
|
45
|
+
one table row: `` | `get_chart` | when and how to use it | ``. Say when to reach for it, what
|
|
46
|
+
it returns, the arguments that matter (with units and defaults) and what to call before or
|
|
47
|
+
after.
|
|
48
|
+
- **The test.** `packages/core/tests/agent-skills.test.ts` builds every provider and command
|
|
49
|
+
set and fails when a skill misses a tool, lists one that no longer exists, or a new
|
|
50
|
+
`create*ToolProvider` / `create*Commands` factory is not mapped to a skill. A new domain
|
|
51
|
+
gets a new skill directory, an entry in `expectedBySkill()` and `FACTORIES`, and a row in
|
|
52
|
+
the table above.
|
|
53
|
+
- **Workflows and practice.** The test cannot check advice. When a feature changes the best
|
|
54
|
+
way to do something (a new batch tool, a new check, a better default), update the working
|
|
55
|
+
method and best practices too.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-agent-tools
|
|
3
|
+
description: How to drive any Pixerate editor (rich text, spreadsheet, canvas, vector, chart, diagram, image, animation, video, generation) through its agent tools - finding the right editor over the MCP bridge, reading tool names and namespaces, running editor commands with list_commands / run_command / run_commands, batching with result references, undo, and recovering from tool errors. Use whenever Pixerate editor tools are available, before the domain skill for the editor at hand.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Driving Pixerate editors with agent tools
|
|
7
|
+
|
|
8
|
+
Every Pixerate editor exposes the same kind of tool surface: a strict, one-tool-per-operation
|
|
9
|
+
set of MCP tools from its tool provider, plus (where the host registers them) its commands
|
|
10
|
+
through three generic command tools. This skill covers what is common to all of them. Each
|
|
11
|
+
editor domain has its own skill for its tools: `pixerate-rich-text`, `pixerate-spreadsheet`,
|
|
12
|
+
`pixerate-canvas`, `pixerate-vector`, `pixerate-chart`, `pixerate-diagram`,
|
|
13
|
+
`pixerate-image-editor`, `pixerate-animation-editor`, `pixerate-video-editor`,
|
|
14
|
+
`pixerate-generation` and `pixerate-parameters`.
|
|
15
|
+
|
|
16
|
+
## How tools are named
|
|
17
|
+
|
|
18
|
+
- Tool names are `snake_case` verbs on a noun: `get_*` / `list_*` / `find_*` / `render_*` read,
|
|
19
|
+
everything else writes.
|
|
20
|
+
- When several editors register a tool with the same name, or a host gives a provider a
|
|
21
|
+
namespace, the name is prefixed: `chart__get_chart`, `doc-1__find_text`. Skills use the bare
|
|
22
|
+
name; match on the suffix after `__`.
|
|
23
|
+
- The annotations are reliable: `readOnlyHint: true` never changes anything, `destructiveHint:
|
|
24
|
+
true` removes content, `idempotentHint: true` is safe to retry.
|
|
25
|
+
- The tool list changes while you work (an editor mounts, a chart becomes read-only and its
|
|
26
|
+
write tools disappear). If a tool you used before is gone, list tools again rather than guess.
|
|
27
|
+
|
|
28
|
+
## Working method
|
|
29
|
+
|
|
30
|
+
1. **Read before you write.** Start with the domain's `get_*` tool. Write tools take the ids,
|
|
31
|
+
ranges and positions that read tools return; never invent an id.
|
|
32
|
+
2. **Prefer the specific tool.** A dedicated tool (`set_chart_values`, `add_video_clip`) has a
|
|
33
|
+
strict schema and a precise error; use generic commands only for what has no tool.
|
|
34
|
+
3. **Batch related edits.** Use the domain's batch tool (`edit_animation`, `edit_video`,
|
|
35
|
+
`run_commands` with `atomic: true`) so a multi-step change is one undo step and either all
|
|
36
|
+
applies or none does. Use `dry_run` where offered when you are unsure.
|
|
37
|
+
4. **Use what writes return.** Writes return what they created or changed (new ids, the
|
|
38
|
+
resulting range or value). Chain on those rather than re-reading the whole state.
|
|
39
|
+
5. **Check, then look.** Run the domain's `check_*` tool and fix every error and warning.
|
|
40
|
+
Render (`render_*`, `view_editor`) after a batch of edits, not after every edit: images cost
|
|
41
|
+
tokens, so use them for what text cannot tell you (overlap, legibility, balance).
|
|
42
|
+
6. **Undo your own mistakes** with the domain's `undo_*` tool or the `history.undo` command, not
|
|
43
|
+
by hand-reverting with more edits.
|
|
44
|
+
|
|
45
|
+
## Errors
|
|
46
|
+
|
|
47
|
+
A failed call comes back as an `isError` result whose text says what was wrong and how to fix
|
|
48
|
+
it, with `structuredContent.error.code`:
|
|
49
|
+
|
|
50
|
+
- `invalid_arguments`: the arguments do not match the schema; `details` names each bad path.
|
|
51
|
+
Fix the arguments and call again.
|
|
52
|
+
- `tool_failed`: the editor refused the change (unknown id, out-of-range position, read-only
|
|
53
|
+
target). Nothing was applied. Read the state again, then retry with valid input.
|
|
54
|
+
- `unknown_tool`: the tool is not registered now (the editor closed, or it is read-only).
|
|
55
|
+
|
|
56
|
+
Never repeat an identical failing call. Never work around a read-only refusal; tell the user.
|
|
57
|
+
|
|
58
|
+
## Tool reference
|
|
59
|
+
|
|
60
|
+
| Tool | Use it to |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| `list_editors` | See which editors are open in the browser and connected to the MCP bridge (id, name, kind, tool count, last activity). Call it first when tools come through the bridge; pass an id or part of a name as `editor` to any tool to pick one when several are open, otherwise the most recently active editor with that tool answers. If none is connected, ask the user to open the app and connect it. |
|
|
63
|
+
| `list_commands` | Discover the commands an editor registers: id, label, group, params JSON Schema, shortcuts, and whether each is enabled now (with the reason when it is not). Filter with `query`; pass `enabledOnly: true` to see only what you can run now. |
|
|
64
|
+
| `run_command` | Run one command by `id` with `params` matching its schema. Disabled commands and unknown params fail with a reason; read it before retrying. |
|
|
65
|
+
| `run_commands` | Run several commands in order as `steps`. A param string `"$0.id"` or `"$last.id"` is replaced by that path of an earlier step's result, so a step can use an id an earlier step created. Pass `atomic: true` and a `label` to make the batch one undo step that rolls back entirely on failure; without it, steps before a failure stay applied. |
|
|
66
|
+
|
|
67
|
+
## Commands
|
|
68
|
+
|
|
69
|
+
These history commands are registered wherever a host shares a history with its command
|
|
70
|
+
registry. Domain editors also have their own `undo_*` / `redo_*` tools.
|
|
71
|
+
|
|
72
|
+
| Command | Use it to |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| `history.undo` | Revert the last change (one tool call or one atomic batch is one step). |
|
|
75
|
+
| `history.redo` | Re-apply the change you just undid. |
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-animation-editor
|
|
3
|
+
description: How to author and edit vector animations (motion graphics, logo reveals, animated icons, explainer scenes, UI micro-interactions) in the Pixerate animation editor through its agent tools - artwork SVG with ids, shots of commands (enter, exit, draw, move, rotate, scale, fade, morph, Smart Animate match, follow a path, pulse, shake, wiggle), easing and springs, stagger, camera, beat and voiceover cues, drivers, reusable clips, checking, rendering frames and contact sheets, and exporting to Flair or Lottie. Use when animation tools such as get_animation, insert_shots or edit_animation are available, or when asked to animate, time, ease, stagger or export vector motion.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pixerate animation editor
|
|
7
|
+
|
|
8
|
+
A scene is **artwork** (an SVG parsed into vector paths and groups, each with an id) plus an
|
|
9
|
+
ordered list of **shots**. A shot optionally moves the camera, plays its `run` of commands,
|
|
10
|
+
then holds (default 600 ms). Commands play one after another unless `"with": "previous"`;
|
|
11
|
+
each has a default length taken from the content (enter 600 ms, exit 450, move 700, draw
|
|
12
|
+
follows the path length), so leave `duration` out unless you mean to change the pace. Every
|
|
13
|
+
frame is a pure function of time.
|
|
14
|
+
|
|
15
|
+
Ids: element ids come from `get_animation` (`elements`) or `find_animation_elements`; shot ids
|
|
16
|
+
are ones you choose (`"intro"`); commands are addressed by shot id plus their index in the run.
|
|
17
|
+
Times are milliseconds, positions are document units of the artwork. Anything that enters
|
|
18
|
+
later is hidden until its `enter`; anything that never enters is visible from the start.
|
|
19
|
+
|
|
20
|
+
For errors, namespaced tool names and the generic command tools, see `pixerate-agent-tools`.
|
|
21
|
+
The full command vocabulary (every type, option and default) is in
|
|
22
|
+
[references/commands.md](references/commands.md).
|
|
23
|
+
|
|
24
|
+
## Working method
|
|
25
|
+
|
|
26
|
+
1. **Read.** `get_animation` for elements, shots with timing, clips, drivers and issues. If
|
|
27
|
+
there is no artwork, `set_animation_artwork_svg` first (give every element you will animate
|
|
28
|
+
an id), or start from `import_flair_effect` / `import_pptx_animation`. For outlined text,
|
|
29
|
+
`get_text_layout` shows the letter, word and line units.
|
|
30
|
+
2. **Plan shots, one idea each.** Write down what the viewer should notice in each shot and in
|
|
31
|
+
what order, then map each beat to a command. Hidden end states (morph / match targets,
|
|
32
|
+
follow paths) must exist in the artwork before you reference them.
|
|
33
|
+
3. **Write in batches.** `insert_shots` for whole shots; `edit_animation` for several related
|
|
34
|
+
edits as one undo step (`dry_run: true` first when unsure; `"$0.indexes[0]"` and
|
|
35
|
+
`"$last.shot"` refer to earlier ops). Refine with `add_commands`, `update_command`,
|
|
36
|
+
`move_command`, `delete_commands`. Use `write_animation` only to replace every shot.
|
|
37
|
+
4. **Fit and cue.** `fit_animation` to hit a length (keep shots whose pace matters). For music
|
|
38
|
+
or voiceover, `set_animation_settings` with `beat` or `narration`, read cues with
|
|
39
|
+
`get_timing_grid`, and give shots `"at": { "beat": n }` or `{ "word": i }`.
|
|
40
|
+
5. **Check.** `check_animation`; fix every error and warning (codes such as `too-fast`,
|
|
41
|
+
`overlap`, `out-of-frame`, `enter-visible`, `cue-missed`). Use `get_motion_path` for
|
|
42
|
+
spacing and arcs as numbers.
|
|
43
|
+
6. **Look.** `render_animation_frame` with `shot` + `at: "end"`, or `times` for a contact sheet,
|
|
44
|
+
plus `onion_skin` / `motion_paths` to see motion in one picture. Render after a batch, not
|
|
45
|
+
after every edit. `seek_animation` shows the person a moment.
|
|
46
|
+
7. **Export** when asked: `export_flair_motion`, `export_flair_effect` (after
|
|
47
|
+
`set_animation_controls`) or `export_lottie`; read the returned notes on what was sampled
|
|
48
|
+
or dropped.
|
|
49
|
+
|
|
50
|
+
## Best practices
|
|
51
|
+
|
|
52
|
+
- **One idea per shot, one focal motion at a time.** Stage the action so the eye knows where
|
|
53
|
+
to look; secondary elements move less, later, or not at all. Use the camera (`frame` a
|
|
54
|
+
node) to direct attention rather than moving everything.
|
|
55
|
+
- **Ease every change.** Arrivals ease out (decelerate into place; the default for `enter`),
|
|
56
|
+
exits ease in (`exit` with `ease: "ease-in"`), moves ease in-out (the default). Use `linear`
|
|
57
|
+
only for mechanical motion (a constant spin, a progress bar) or loops.
|
|
58
|
+
- **Timing by size and distance.** Small UI changes 150-300 ms, element entrances 300-600 ms,
|
|
59
|
+
large moves and camera moves 600-1200 ms. Nothing under 120 ms (`too-fast`). Big things
|
|
60
|
+
move slower than small things.
|
|
61
|
+
- **Anticipation and follow-through.** `ease-in-back` for a wind-up before a fast exit;
|
|
62
|
+
`pop`, `rise`, `ease-out-back` or a spring preset (`spring-gentle`, `spring-quick`) for
|
|
63
|
+
overshoot and settle on arrival. Use `spring-bouncy` sparingly; it reads as playful.
|
|
64
|
+
- **Overlapping action.** Stagger related items 40-120 ms (`stagger`, or `split` with
|
|
65
|
+
`cascade` for text) instead of moving them in lockstep; start secondary motion with
|
|
66
|
+
`"with": "previous"` plus a small `delay` so it trails the lead.
|
|
67
|
+
- **Arcs.** Natural movement curves: use `move` with `via` waypoints (one smooth path) instead
|
|
68
|
+
of chained moves that stop at each point, or `follow` a path node.
|
|
69
|
+
- **Hold long enough to read.** Leave each result on screen (shot `hold`, default 600 ms);
|
|
70
|
+
roughly 250 ms per word for text that must be read, longer for the final frame or logo.
|
|
71
|
+
- **Exaggeration with restraint.** Emphasis (`pulse`, `shake`, `teeter`, `color-pulse`) is for
|
|
72
|
+
one thing that needs attention, once; it returns to rest on its own.
|
|
73
|
+
- **Motion blur** only for genuinely fast motion (`motionBlur: { shutter: 180 }`); it affects the
|
|
74
|
+
stage and rendered frames, not Flair or Lottie exports.
|
|
75
|
+
- **Accessibility.** Avoid flashing: never more than three flashes a second (WCAG 2.3.1), so
|
|
76
|
+
keep `color-pulse` and fades on large areas slow and few. Avoid large-scale parallax, zooms
|
|
77
|
+
and spinning for essential UI motion; ship a reduced-motion alternative (the host should
|
|
78
|
+
swap in a fade or the end state under `prefers-reduced-motion`; this editor does not
|
|
79
|
+
generate one). Loops that run longer than 5 s need a way to pause (WCAG 2.2.2).
|
|
80
|
+
- **Interactive pieces.** For a button or toggle set `trigger` (`click`, `hover`, `press`,
|
|
81
|
+
`scroll`); for a click toggle, make the last shot restore the starting state.
|
|
82
|
+
|
|
83
|
+
## Tool reference
|
|
84
|
+
|
|
85
|
+
### Read
|
|
86
|
+
|
|
87
|
+
| Tool | Use it to |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| `get_animation` | Start here. Returns name, artwork size, length (ms), loop, elements (id, type, name, parent, bounds, solid paints, live effects with numeric params), every shot with each command's index, start, end and `flairPrimitive`, clips, drivers, controls and an issue summary, plus `readOnly` when edits are refused. `includeElements: false` (default true) skips the element list on large artwork. |
|
|
90
|
+
| `get_shot` | Read one shot as stored (`shot` id) with its start/end and each command's start/end in ms; cheaper than `get_animation` while refining one shot. |
|
|
91
|
+
| `find_animation_elements` | Find elements whose id or name contains `query` (case-insensitive; `limit` default 20, max 200) when the artwork is large. Returns id, type, name, parent, bounds, paints, effects. |
|
|
92
|
+
| `get_text_layout` | Before animating outlined text with `split`: returns the `group`'s lines, words and letter ids in reading order. Errors if the element is not a group of paths (convert text to outlines, one path a letter, and group it). |
|
|
93
|
+
| `get_motion_path` | Check spacing, arcs and landing points as numbers: samples a `node`'s centre (document units) from `from` to `to` ms every `step` ms (default 33, at most 400 samples), with where each moving change starts and ends. |
|
|
94
|
+
| `get_timing_grid` | List beats (number, ms, bar, beat in bar) and narration words (index, text, start, end) between `from` and `to` (`limit` default 200), and which shot plays at each, to choose `at` cues. Empty, with a hint, when no beat grid or narration is set. |
|
|
95
|
+
| `check_animation` | After every batch of writes. Lists issues with a code, severity, shot, command index, node ids, measured vs needed values and how to fix it. Fix errors and warnings; notes are advisory. |
|
|
96
|
+
| `render_animation_frame` | Look at the result: `time` (ms) or `shot` + `at` (`start`, `middle`, `end`; default end). `times` (2-16 moments) makes a labelled contact sheet (`columns` 1-8). `onion_skin` adds ghost frames (`before` default 2, `after` 0, `spacing` ms or `"commands"`); `motion_paths` (true or ids) draws travel paths. SVG by default; `format: "png"` only when the host can rasterize. |
|
|
97
|
+
| `export_flair_motion` | Get the scene as a Flair SvgMotion `{ svg, animate }` with hold, sampled-step count and notes. `fps` (default scene fps, else 30), `curves` and `behaviors` (default true), `flair` target version (default 0.39; older versions get springs, steps, behaviours and curves sampled). |
|
|
98
|
+
| `export_flair_effect` | Get a Flair catalog vector effect (`id` kebab-case, `name`, `description`, `category` default icon, `tags`, plus `curves` / `behaviors` / `flair` as above). Call `set_animation_controls` first so colours become `{{name: color}}` controls. |
|
|
99
|
+
| `export_lottie` | Get Lottie (Bodymovin v5) JSON for lottie-web and mobile players, with a marker per shot, `fps` (default scene fps, else 30), the sampled keyframe count and notes on what was not carried over (gradients, dashes, reveal clips, morphs that change point counts). |
|
|
100
|
+
|
|
101
|
+
### Write
|
|
102
|
+
|
|
103
|
+
| Tool | Use it to |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `seek_animation` | Show the person a moment: `time` (ms) or the start of a `shot`, with `play` true or false. Does not change the scene. |
|
|
106
|
+
| `set_animation_artwork_svg` | Replace the artwork with a standalone `svg` (with a viewBox) as one undo step. Put an id on every element you will animate; refused if existing shots name ids the new artwork lacks. Returns the elements. |
|
|
107
|
+
| `import_pptx_animation` | Replace the whole scene with a PowerPoint slide's shapes and animation pane (`data` base64 .pptx, `slide` default 1): one shot per click, delays, repeats and acceleration kept; text, pictures and charts are left out with notes. Run with `dry_run: true` first. |
|
|
108
|
+
| `set_animation_drivers` | Replace all drivers (empty list clears): a target's `x`, `y`, `rotation`, `scaleX`, `scaleY` or `opacity` follows a source node's property as change · `factor` + `offset`, optionally `clamp`ed. For parallax, wheels that turn as they roll, shadows that fade as something rises. |
|
|
109
|
+
| `set_animation_clip` | Define, replace or (with `clip: null`) delete a named reusable clip whose `run` targets `"$"`; play it with a `play` command on any nodes. Prefer a clip over repeated identical commands. |
|
|
110
|
+
| `copy_animation` | Give the nodes in `to` every command that animates `from` (all shots or `shots`), each copy starting with its original, optionally `stagger`ed (ms). Quick for one-off duplication; use a clip for motion you will reuse. |
|
|
111
|
+
| `fit_animation` | Make the scene last `seconds` by setting shot `speed`, keeping proportions; shots in `keep` play as written. `dry_run: true` reports the new length and speeds first. |
|
|
112
|
+
| `import_flair_effect` | Replace the whole scene with a Flair vector `effect` or SvgMotion `motion` (give exactly one; optional `name`). Placeholders become colour controls; each Flair step becomes a shot. Use `dry_run: true` first. |
|
|
113
|
+
| `insert_shots` | Add one or more complete shots (`id`, `run`, optional `label`, `camera`, `hold`, `speed`, `at`) at position `at` (default the end). Returns every shot's timing and issues. |
|
|
114
|
+
| `update_shot` | Change one shot's `label`, `camera`, `run`, `hold`, `speed`, `at` or `id` via `set`, and clear `label`, `camera`, `hold`, `speed` or `at` via `remove`. |
|
|
115
|
+
| `delete_shots` | Remove shots by id (one undo step). |
|
|
116
|
+
| `move_shot` | Reorder a shot to index `to` (0 = first). |
|
|
117
|
+
| `add_commands` | Add commands to a shot's run at index `at` (default the end). Returns the indexes they got and their timing; use those indexes for later updates. |
|
|
118
|
+
| `update_command` | Change one command (by `shot` and `command` index): fields in `set` replace, names in `remove` clear (e.g. `"delay"`). Returns the command and its timing. |
|
|
119
|
+
| `delete_commands` | Remove commands from a shot by index; later commands move up, so re-read indexes afterwards. |
|
|
120
|
+
| `move_command` | Move one command to index `to` in its run; a `"with": "previous"` command then starts with its new neighbour. |
|
|
121
|
+
| `set_animation_settings` | Set `name`, `description`, `loop` (none, loop, ping-pong), `trigger` (click, hover, press, scroll, or null), export `fps` (default 30), scene `steps` (12 = on twos; null smooth), `motionBlur`, `beat` (`bpm`, `offset`, `meter`), `narration` word timings, or `target` length [min, max] seconds. |
|
|
122
|
+
| `set_animation_controls` | Set the colour controls (`name`, `type: "color"`, `default` #rrggbb used in the scene, `label`) and `presets` a Flair effect exposes. Replaces existing controls; an empty list clears. |
|
|
123
|
+
| `edit_animation` | Apply several ops (`set_settings`, `insert_shots`, `update_shot`, `delete_shots`, `move_shot`, `add_commands`, `update_command`, `move_command`, `delete_commands`, `set_controls`) as one all-or-nothing undo step; refer to earlier outcomes with `"$0.indexes[0]"`, `"$last.shot"`. `dry_run: true` validates without applying. The default for multi-step changes. |
|
|
124
|
+
| `write_animation` | Replace every shot (and optionally settings, controls, presets) while keeping the artwork. Only for a full rewrite; per-operation tools give better errors. |
|
|
125
|
+
| `undo_animation` | Undo your last edit (one tool call or one `edit_animation` batch). |
|
|
126
|
+
| `redo_animation` | Redo the edit you just undid. |
|
|
127
|
+
|
|
128
|
+
## Pitfalls
|
|
129
|
+
|
|
130
|
+
- **Unknown ids are refused** with a "did you mean" suggestion. Take ids from `get_animation` or
|
|
131
|
+
the elements `set_animation_artwork_svg` returns; never guess them.
|
|
132
|
+
- **`enter-visible`**: an element that enters while already showing blinks out first. Give an
|
|
133
|
+
element that should appear later an `enter` before anything else moves it; do not `enter` an
|
|
134
|
+
element that should be visible from the start. `exit-hidden` is the reverse: enter it first.
|
|
135
|
+
- **`overlap`**: two commands changing the same property at once; the later takes over. Sequence
|
|
136
|
+
them, or use `"blend": "add"` on move, rotate or scale to stack. Emphasis already stacks.
|
|
137
|
+
- **Reveals need a box**: `wipe`, `iris`, `split` on a lone straight line fade instead
|
|
138
|
+
(`reveal-no-box`); use `draw` / `undraw` for lines.
|
|
139
|
+
- **Morph and match targets stay hidden.** Draw the end state as a separate hidden node or group;
|
|
140
|
+
for `match`, parts the end state adds need a partner (same name) in the start group, or they
|
|
141
|
+
never appear (`match-unpaired`).
|
|
142
|
+
- **Draw a group one way.** Do not mix per-stroke drawing (`order`, `pace`, `comet`) with a plain
|
|
143
|
+
`draw` on the same group in one scene.
|
|
144
|
+
- **Indexes shift.** After `delete_commands` or `move_command`, indexes change; use what the write
|
|
145
|
+
returned or `get_shot` before the next index-based edit.
|
|
146
|
+
- **Springs set their own length.** Leave `duration` out with a spring; a short `duration` cuts it
|
|
147
|
+
off (`spring-cut-short`).
|
|
148
|
+
- **Click triggers** play nothing until the first click; each click plays the next shot. A
|
|
149
|
+
triggered scene ignores `loop` (`trigger-loop`), and clicks decide when shots start, so do not
|
|
150
|
+
give its shots `at` cues (`click-cue`).
|
|
151
|
+
- **Exports approximate.** Motion blur is never exported; Lottie drops gradients, dashes and reveal
|
|
152
|
+
clips; back eases on colours or opacity are sampled for Flair. Read the notes and tell the
|
|
153
|
+
user what changed.
|
|
154
|
+
- **Read-only**: when `get_animation` returns `readOnly`, write tools are hidden; read, render and
|
|
155
|
+
export still work. Tell the user rather than working around it.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Animation command vocabulary
|
|
2
|
+
|
|
3
|
+
Every command is an object with a `type` and (except `wait`) `targets`: element ids from
|
|
4
|
+
`get_animation`. A group animates as one. Times are ms, distances document units, angles
|
|
5
|
+
degrees clockwise. Commands share names and defaults with Flair's motion primitives
|
|
6
|
+
(`get_animation` shows each command's `flairPrimitive`).
|
|
7
|
+
|
|
8
|
+
## Fields every command takes
|
|
9
|
+
|
|
10
|
+
- `targets`: element ids (at least one).
|
|
11
|
+
- `duration`: length per target. Leave it out: each type has a default (below) and `draw`
|
|
12
|
+
follows the path length. With `repeat`, it is one cycle.
|
|
13
|
+
- `delay`: wait before starting (default 0).
|
|
14
|
+
- `stagger`: start each further target this much later (default 0).
|
|
15
|
+
- `with`: `"after"` (default) starts when the commands before it finish; `"previous"` starts
|
|
16
|
+
together with the command before.
|
|
17
|
+
- `ease`: a preset (`linear`, `ease`, `ease-in`, `ease-out`, `ease-in-out`, `ease-in-back`,
|
|
18
|
+
`ease-out-back`, `ease-out-elastic`, `ease-in-elastic`, `ease-in-out-elastic`, `elastic`,
|
|
19
|
+
`spring`, `spring-gentle`, `spring-quick`, `spring-bouncy`, `spring-slow`, `hold`), or
|
|
20
|
+
`{ "type": "cubic-bezier", x1, y1, x2, y2 }`, `{ "type": "spring", stiffness (170),
|
|
21
|
+
damping (26), mass (1), velocity (0) }`, `{ "type": "elastic", amplitude (1), period (0.3),
|
|
22
|
+
mode (out | in | in-out) }`. Default: cubic ease-out for entrances, ease-in-out for moves.
|
|
23
|
+
A spring with no `duration` lasts until it settles.
|
|
24
|
+
- `note`: why the command is there, in a few words.
|
|
25
|
+
- `split`: `letter`, `word` or `line` for outlined text (a group of letter paths), staggered
|
|
26
|
+
40 / 120 / 300 ms per unit; `cascade`: `forward` (default), `backward`, `center`, `edges`,
|
|
27
|
+
`random` (deterministic).
|
|
28
|
+
- `repeat` (1-1000, not for enter or exit) and `repeatMode`: `loop` (default), `mirror`
|
|
29
|
+
(every other cycle backwards), `offset` (carry on: rotate by 90 with repeat 4 is a full turn).
|
|
30
|
+
- `steps`: hold poses on a grid of this many frames per second (12 = on twos).
|
|
31
|
+
|
|
32
|
+
## Default lengths (ms)
|
|
33
|
+
|
|
34
|
+
enter 600, exit 450, move 700 (+400 per `via` point), rotate 700, scale 500, fade 400,
|
|
35
|
+
style 500, morph 900, match 900, follow 1400, pulse 600, shake 500, teeter 600, wave 1000,
|
|
36
|
+
wiggle 1500, color-pulse 600, effect 900, play (the clip's own length). Shot hold 600,
|
|
37
|
+
camera move 1000.
|
|
38
|
+
|
|
39
|
+
## Entrances and exits
|
|
40
|
+
|
|
41
|
+
- `enter` brings hidden targets in. `style`:
|
|
42
|
+
- `fade` (default); `pop` (scales up past full size and settles; `scale` start, default 0.5);
|
|
43
|
+
`grow` (from nothing); `slide` (`direction` of travel, default up; `distance` default 40);
|
|
44
|
+
`draw` (outline drawn on, then the fill fades in); `zoom` (settles from larger; `scale`
|
|
45
|
+
default 1.6); `rise` (rises a short way, overshooting a touch; `distance` default 20).
|
|
46
|
+
- Reveals through a clip over the target's box: `wipe` (edge travels `direction`, default
|
|
47
|
+
right), `iris` (from the centre; `shape` circle or box), `split` (from a line through the
|
|
48
|
+
middle; `orientation` horizontal or vertical). Need a box with width and height.
|
|
49
|
+
- Drawing options for groups: `order` (`together` default, or `sequence`), `pace` (`time`
|
|
50
|
+
or `speed`), `align` (`start` / `end`, with speed), `sortBy` (`document` or `distance`,
|
|
51
|
+
with sequence), `origin` { x, y } for a radial reveal.
|
|
52
|
+
- `exit` takes targets out. `style`: `fade` (default), `shrink`, `slide` (default down,
|
|
53
|
+
`distance` 40), `undraw`, `wipe`. Same drawing options as enter.
|
|
54
|
+
|
|
55
|
+
## Pose and paint
|
|
56
|
+
|
|
57
|
+
- `move`: `by` { x, y } offset or `to` { x, y } for the centre. `via`: up to 64 waypoints the
|
|
58
|
+
centre passes through smoothly without overshoot; `pacing` `even` (default, steady speed)
|
|
59
|
+
or `equal` (same time per stretch). `blend` default replace.
|
|
60
|
+
- `rotate`: `by` degrees or `to` degrees from rest. `blend` default replace.
|
|
61
|
+
- `scale`: `to` a factor or { x, y } (required); `geometric: true` for an even-rate zoom.
|
|
62
|
+
- `fade`: `to` opacity 0-1 (required).
|
|
63
|
+
- `style`: blends solid `fill`, `stroke` (CSS colours, mixed in OKLab) and `strokeWidth`. On a
|
|
64
|
+
group it changes every path in it.
|
|
65
|
+
- `draw`: draws strokes to `to` (default 1) from `from` (default what is drawn now);
|
|
66
|
+
`comet`: a travelling stroke this fraction long that runs off the end. Drawing options as
|
|
67
|
+
enter.
|
|
68
|
+
|
|
69
|
+
## Shape change and paths
|
|
70
|
+
|
|
71
|
+
- `morph`: each target takes the shape and paint of node `into` (keep `into` hidden).
|
|
72
|
+
- `match` (Smart Animate): tweens a group into group `into`, part by part. Parts pair by name,
|
|
73
|
+
then by id with the group ids taken out (`card-a-title` and `card-b-title`), then by kind in
|
|
74
|
+
order. Unpaired parts fade out; parts of `into` with no partner never appear.
|
|
75
|
+
- `follow`: moves targets along path node `path` (it can be hidden), `from` / `to` fractions
|
|
76
|
+
(default 0 / 1); `rotate: true` turns with the path, and moves or shakes made meanwhile turn
|
|
77
|
+
with it.
|
|
78
|
+
|
|
79
|
+
## Emphasis (returns to rest; `blend` default add, so it stacks on other motion)
|
|
80
|
+
|
|
81
|
+
- `pulse`: scales up and back; `amount` extra scale (0.15), `count` (1).
|
|
82
|
+
- `shake`: side to side, settling; `amount` (8), `count` (3), `axis` horizontal or vertical.
|
|
83
|
+
- `teeter`: rocks about the centre; `angle` (8), `count` (3).
|
|
84
|
+
- `wave`: bobs without settling; `amount` (6), `count` (2).
|
|
85
|
+
- `wiggle`: smooth seeded noise; `amount` (6), `frequency` Hz (3), `octaves` (2), `rotate`
|
|
86
|
+
degrees (0), `seed` (default from the target id; the same seed wanders the same way).
|
|
87
|
+
- `color-pulse`: tints `fill` or `stroke` (`paint`) toward `color` (default #f59e0b) and back;
|
|
88
|
+
`count` (1).
|
|
89
|
+
|
|
90
|
+
`blend: "add"` on move, rotate or scale makes them a stacking layer too (what they add stays);
|
|
91
|
+
`blend: "replace"` on emphasis makes it take over instead.
|
|
92
|
+
|
|
93
|
+
## Other
|
|
94
|
+
|
|
95
|
+
- `effect`: tweens numeric `param` of live path effect `effect` (ids from the element's
|
|
96
|
+
`effects` in `get_animation`) `to` a value.
|
|
97
|
+
- `play`: plays clip `clip` (defined with `set_animation_clip`, commands targeting `"$"`) on
|
|
98
|
+
the targets; `speed` (0.05-20, default 1), `delay`, `stagger`, `with`. Clips cannot play clips.
|
|
99
|
+
- `wait`: waits `duration` ms (no targets).
|
|
100
|
+
|
|
101
|
+
## Shots
|
|
102
|
+
|
|
103
|
+
`{ id, run, label?, camera?, hold?, speed?, at? }`
|
|
104
|
+
|
|
105
|
+
- `id` matches `^[A-Za-z0-9_][\w.-]*$` and is unique.
|
|
106
|
+
- `camera`: `{ x, y, width, height }` or `{ frame: "<node id>", padding (24) }`, with `ms`
|
|
107
|
+
(default 1000), `ease`, `geometric`. The first shot cuts to its camera.
|
|
108
|
+
- `hold`: ms after the commands (default 600).
|
|
109
|
+
- `speed`: plays the whole shot this many times as fast (0.05-20; `fit_animation` sets it).
|
|
110
|
+
- `at`: `{ beat: n }` (2.5 is the "and" of beat 3), `{ word: i }` or `{ ms: t }`; the shot
|
|
111
|
+
before holds until the cue. Needs a `beat` grid or `narration` set with
|
|
112
|
+
`set_animation_settings`; `check_animation` reports `cue-missed` when the previous shot runs
|
|
113
|
+
past it.
|
|
114
|
+
|
|
115
|
+
## Drivers
|
|
116
|
+
|
|
117
|
+
`set_animation_drivers({ drivers: [{ target, property, source: { node, property }, factor (1),
|
|
118
|
+
offset (0), clamp: [min, max] }] })`, properties `x`, `y`, `rotation`, `scaleX`, `scaleY`,
|
|
119
|
+
`opacity`. The target's change from rest = source change · factor + offset, added to offsets
|
|
120
|
+
and turns, multiplied into scales and opacity, on top of the target's own commands. Examples:
|
|
121
|
+
parallax (`x` follows `x` · 0.5), a rolling wheel (`rotation` follows `x` · 360 / (2π · radius)),
|
|
122
|
+
a shadow that fades as a ball rises (`opacity` follows `y` · 0.005). Cycles are reported by
|
|
123
|
+
`check_animation` (`driver-cycle`).
|