@pixerate/editor 0.114.0 → 0.115.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.114.0",
3
+ "version": "0.115.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -197,6 +197,7 @@
197
197
  "@types/dagre": "^0.7.54",
198
198
  "@types/markdown-it": "^14.2.0",
199
199
  "@types/node": "^26.6.5",
200
+ "assemblyscript": "0.28.20",
200
201
  "fast-check": "^3.23.2",
201
202
  "mermaid": "12.0.0",
202
203
  "tiptap-markdown": "^0.8.10",
@@ -218,6 +219,7 @@
218
219
  "build": "tsup",
219
220
  "typecheck": "tsc --noEmit",
220
221
  "test": "vitest run",
221
- "test:corpus": "node scripts/fetch-psd-corpus.mjs && PSD_CORPUS=1 vitest run tests/psd-corpus.test.ts"
222
+ "test:corpus": "node scripts/fetch-psd-corpus.mjs && PSD_CORPUS=1 vitest run tests/psd-corpus.test.ts",
223
+ "build:wasm": "node scripts/build-wet-wasm.mjs"
222
224
  }
223
225
  }
@@ -378,6 +378,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
378
378
  | `assign_profile` | Make the document's numbers mean colours in `profile` (built-in id or `icc:<base64>`; RGB only). The look changes, pixels do not. One undo step. Returns the profile. |
379
379
  | `convert_to_profile` | Convert pixel layers into `profile` keeping their look (`intent`, `bpc`), then assign it. One undo step. Returns the profile, `convertedLayerIds` and `unconvertedLayerIds` (shape, type, effects, smart objects). |
380
380
  | `set_proof_setup` | Soft-proof the viewport through `profile` (`intent`, `bpc`, `simulatePaper`, `gamutWarning`), or `off: true`. View state. Returns the setup. |
381
+ | `set_color_mode` | Image › Mode: `rgb`, `cmyk` (with the press `profile`, default coated-cmyk, and the separation `intent`) or `lab`. Pixels stay RGB; CMYK documents proof through their profile and `export_psd` writes CMYK / Lab channels. One undo step. Returns the profile summary with `mode`. |
381
382
  | `convert_colors` | Read-only. `colors` #rrggbb from the document's profile (or `from`) to `to`: channel `values` 0..1 (CMYK, RGB, grey), `hex` for RGB, and `lab`. |
382
383
  | `clone_stamp` | Copy pixels from the clone source along `points`: each point paints what is at point + offset (source − first point, whole px). `source` `{x, y}` sets the source for this stroke (else the current one, see `set_clone_source`); `aligned` keeps the offset for later strokes; `sample` current \| current-below \| all; `brush` `{size, hardness, spacing, opacity, flow, smoothing, pressureSize, pressureOpacity}`; `layerId`, `channel` (a mask clones from itself). One undo step. Returns the layer, channel, `bounds`, dabs and `clone` `{offset, source, aligned}`. Call `set_clone_source` or pass `source` first. |
383
384
  | `heal_brush` | As `clone_stamp`, then blends the cloned texture into the colour and light around the stroke (Poisson seamless cloning, when the stroke ends). Use for blemishes, wrinkles, dust and seams where the surroundings have the right tone. Returns as `clone_stamp`. |
@@ -20,13 +20,18 @@ means sRGB. The viewport assumes an sRGB display and converts other working spac
20
20
  4. **Soft proof before printing**: `set_proof_setup` with `coated-cmyk` (or the printer's
21
21
  profile as `icc:<base64>`), `gamutWarning: true` to grey out colours the press cannot hit;
22
22
  look with `capture_view`; adjust (lower saturation in the greyed areas); then `off: true`.
23
- 5. **Numbers for a print brief**: `convert_colors` gives CMYK percentages (values × 100) and
23
+ 5. **Print documents**: `set_color_mode` `cmyk` with the press profile makes the document a
24
+ CMYK one: you keep editing RGB, the viewport proofs through the press, and `export_psd`
25
+ writes a CMYK PSD (the separation uses `intent`). Opening a CMYK PSD does this for you. Check
26
+ out-of-gamut colours with `set_proof_setup` `gamutWarning` before exporting.
27
+ 6. **Numbers for a print brief**: `convert_colors` gives CMYK percentages (values × 100) and
24
28
  Lab for any `#rrggbb`, without changing the document.
25
29
 
26
30
  ## Pitfalls
27
31
 
28
- - The working space must be RGB: CMYK, grey and Lab profiles are for proofing and
29
- `convert_colors` here.
32
+ - The working space must be RGB: CMYK and Lab are document modes (`set_color_mode`) for
33
+ output, not spaces you edit numbers in. Adjustment layers keep their RGB settings in a CMYK or
34
+ Lab PSD, where Photoshop applies them to its own channels; `export_psd` warns.
30
35
  - `convert_to_profile` converts pixel layers (and the source image). Shape and type colours,
31
36
  layer effects and smart objects keep their numbers and are listed in `unconvertedLayerIds`:
32
37
  check them and recolour if the look matters.
@@ -14,15 +14,17 @@
14
14
  `list_layer_effects.patterns`) and its global light. An effects block the editor cannot read
15
15
  is kept and written back by `export_psd`, but not drawn; the warnings say so.
16
16
  3. **`import_psd` replaces the document** (one undo step). 16- and 32-bit files keep their
17
- depth (`get_image_info.bitDepth`); CMYK, Lab, grayscale and indexed files are converted to
18
- RGB; an RGB file's ICC profile becomes the document's colour profile. The warnings say what
19
- changed. `export_psd` writes at the document's depth and embeds its profile. Change the depth
20
- with `set_bit_depth`: 16-bit for smooth gradients and strong grades, 32-bit for linear-light
21
- HDR (layers blend in linear light there). Adjustment layers, blend modes, merges and the
22
- exported merged image keep the depth; layer effects, layer filters, painting and transforms
23
- still work in 8 bits on what they change, so grade a deep file with adjustment layers rather
24
- than repainting it when the depth matters. Afterwards work with `list_layers` as usual: there
25
- is no Background source image, every pixel comes from the layers.
17
+ depth (`get_image_info.bitDepth`). CMYK files are converted to RGB through their embedded (or
18
+ the default coated) CMYK profile and stay in CMYK mode, Lab files stay in Lab mode, so
19
+ `export_psd` writes them back as they came (`set_color_mode`); grayscale and indexed files are
20
+ converted to RGB; an RGB file's ICC profile becomes the document's colour profile. The
21
+ warnings say what changed. `export_psd` writes at the document's depth, mode and profile.
22
+ Change the depth with `set_bit_depth`: 16-bit for smooth gradients and strong grades, 32-bit
23
+ for linear-light HDR (layers blend in linear light there). Adjustment layers, blend modes,
24
+ merges and the exported merged image keep the depth; layer effects, layer filters, painting
25
+ and transforms still work in 8 bits on what they change, so grade a deep file with adjustment
26
+ layers rather than repainting it when the depth matters. Afterwards work with `list_layers` as
27
+ usual: there is no Background source image, every pixel comes from the layers.
26
28
  4. **Smart objects come in live**: embedded contents (a PSB opens as a nested document you can
27
29
  edit with `edit_smart_object_contents`, a PNG as raster contents), the placement and warp, the
28
30
  smart filters and the filter mask; the layer shows Photoshop's own pixels until you change it.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pixerate-paint-editor
3
- description: How to make a picture in the Pixerate paint editor (natural media in the spirit of Painter, Rebelle and ArtRage) through its agent tools - canvas and paper (generated grain, depth, families from cold pressed watercolour to canvas), layers with painterly blend modes (watercolor, tint, highlight, shadow), dry-media brushes (pencil, pastel, charcoal, airbrush, marker, ink, erasers) with pressure, tilt, barrel rotation and velocity, blending tools (blender, smudge, Mixer Brush), brush behaviours (pick-up and mix ratios, dirty and multi-coloured brushes), the brush library, strokes that replay and vary, symmetry and perspective guides, tracing and reference images, harmonies, swatches, a mixing pad and pigment mixing, and PNG, JPEG, WebP, PSD and JSON output. Use when asked to paint, sketch, shade, blend, smudge, glaze, mix colours, paint symmetric or in perspective, trace an image, or when paint_stroke, set_paper, replay_strokes or mix_colors are available.
3
+ description: How to paint in the Pixerate paint editor (natural media) through its agent tools - canvas and paper (generated grain, depth, families from cold pressed watercolour to canvas), layers with painterly blend modes (watercolor, tint, highlight, shadow), dry media (pencil, pastel, charcoal, airbrush, marker, ink) with pen dynamics, wet media (watercolour, gouache and oil that flow, bloom, granulate and dry), thick impasto paint lit by a movable light, blending tools (blender, smudge, Mixer Brush), brush behaviours (pick-up and mix ratios, dirty and multi-coloured brushes), the brush library, replayable strokes, symmetry and perspective guides, tracing and reference images, harmonies, swatches, a mixing pad and pigment mixing, and PNG, JPEG, WebP, PSD and JSON output. Use when asked to paint, sketch, paint in watercolour, shade, blend, smudge, glaze, mix colours, paint symmetric or in perspective, trace an image, or when paint_stroke, set_paper, replay_strokes or mix_colors are available.
4
4
  ---
5
5
 
6
6
  # Paint editor
@@ -16,7 +16,19 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
16
16
  (pressure, tilt, velocity, jitter), a **rotation** mode (`fixed`, `stroke`, `barrel`) and an
17
17
  engine: `dab` (most media), `eraser`, `mixer` (the Mixer Brush: a reservoir of paint plus paint
18
18
  it picks up), `blender` (mixes the colours under and near the tip) or `smudge` (drags paint
19
- along the stroke).
19
+ along the stroke), `wet` (watercolour, gouache, oil and the wet tools, below), `impasto`
20
+ (thick paint with relief and material, below), `particle` (procedural particle brushes),
21
+ `bristle` (a tuft of bristles) or `sticker` (sprays editable stickers).
22
+ - **Wet media** (`engine: "wet"`, categories `watercolor` and `wet-tool`): a stroke lays water
23
+ and pigment on the layer's **wet layer**, a fluid simulation that keeps running after the
24
+ stroke: the water spreads until its edge is pinned by the paper, carries pigment out to the
25
+ rim as it dries (edge darkening), drops pigment into the paper's valleys (granulation), pushes
26
+ pigment back where new water flows in (blooms), bleeds between touching wet colours and runs
27
+ downhill on a tilted canvas. Paint stays wet until it dries by itself (a few thousand steps)
28
+ or `dry_paint` dries it; a dried wash is fixed, so the next wash **glazes** over it. A wet
29
+ brush's `wet.tool` is `paint`, `water`, `dry`, `blow`, `blend`, `smudge` or `blot`; `water`,
30
+ `pigment` (concentration), `body` (0 transparent watercolour .. 1 opaque gouache), `strength`
31
+ and `rewet` set it up. Every result says whether paint is still wet (`wet` / `stillWet`).
20
32
  - **Behaviour** (`behavior`, dab and mixer brushes) is how a brush treats paint already on the
21
33
  canvas: a **pick-up ratio** (how much paint each dab lifts and carries), a **mix ratio** (how
22
34
  much of the carried paint goes into what it lays down), **dirty** (keep the carried colour into
@@ -70,7 +82,9 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
70
82
  `repeat` for hatching, grass, foliage, rows, fans or spirals, in one undo step.
71
83
  8. **Check** with `render_preview` after each block of work, not after each stroke.
72
84
  `pick_color` reads exact values. Undo what made it worse.
73
- 9. **Deliver**: `export_image` (PNG, or JPEG / WebP in a browser), `export_psd` for Photoshop,
85
+ 9. **Watercolour** is its own way of working (see "Wet media" below): wet the paper or not,
86
+ lay washes light to dark, let them flow (`advance_wet_paint`), dry them (`dry_paint`), glaze.
87
+ 10. **Deliver**: `export_image` (PNG, or JPEG / WebP in a browser), `export_psd` for Photoshop,
74
88
  `save_document` to keep the painting with its strokes.
75
89
 
76
90
  ## Best practices
@@ -122,6 +136,77 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
122
136
  - **Save brushes you build** (`set_brush` then `save_brush`), and share them with
123
137
  `export_brushes` / `import_brushes`.
124
138
 
139
+ ## Wet media
140
+
141
+ 1. **Choose a watercolour paper** (`cold-pressed`, `rough-watercolor` for granulation and broken
142
+ edges, `hot-pressed` for smooth washes). Absorption, permeability and roughness of the paper
143
+ drive the simulation.
144
+ 2. **Plan light to dark.** Watercolour is transparent: you cannot paint light over dark (use
145
+ `gouache`, body 1, for that). Lay the lightest washes first.
146
+ 3. **Wet-in-wet or wet-on-dry.** `wet_paper` over an area first for soft, feathered, blooming
147
+ colour (skies, backgrounds); paint on dry paper for crisp edges with a darker rim.
148
+ 4. **Paint washes** with `watercolor-wash` (large, flat, very wet) in a few long strokes, then
149
+ shapes with `watercolor-round`, details with `watercolor-detail`. Colours touching while wet
150
+ bleed into each other; that is the point.
151
+ 5. **Let it flow, then dry.** `advance_wet_paint` (`seconds` 1..5) to let water spread, run and
152
+ bloom; `render_preview` shows the paint as it is now (wet paper looks a little darker).
153
+ `dry_paint` sets it where it is. Dry before glazing a second wash over a first, or the two
154
+ mix instead of layering.
155
+ 6. **Steer the water** with the wet tools: `add-water` (softens and lifts with `rewet`),
156
+ `hair-dryer` (stops a wash spreading), `blow` (pushes the water along the stroke),
157
+ `wet-blend` (evens out a wash), `wet-drag` (drags wet paint), `blot` (lifts wet paint: clouds,
158
+ highlights). `set_canvas_tilt` makes washes run downhill and very wet paint drip;
159
+ `set_flow_map` pushes water in a swirl, a direction or eddies.
160
+ 7. **Tune the medium** per layer with `set_wet_settings`: `granulation` (grainy pigment, needs a
161
+ rough paper), `edgeDarkening`, `bloom`, `bleed`, `viscosity` (runny .. thick), `evaporation`,
162
+ `pigmentWeight`, `pickup` (how easily dried paint lifts), `fixture` (staining).
163
+
164
+ - **Saving dries the paint** (deterministically): the saved file and every export hold dried
165
+ pixels; the editor keeps painting wet. A dry brush, fill, merge or duplicate on a wet layer
166
+ dries it first (in the same undo step).
167
+ - **Time** runs by itself in an editor on screen (`pause_wet_paint` stops it); for an agent with
168
+ no screen, nothing moves until `advance_wet_paint` or `dry_paint`.
169
+
170
+ ## Oils and thick paint
171
+
172
+ - **Wet oil** (`oil-round`, `oil-flat`; any wet brush with `wet.medium: "oil"`) runs on the wet
173
+ simulation as a thick, slow-drying medium: it barely flows, stays wet for minutes of simulated
174
+ time, and the brush picks up and mixes the wet oil it meets (`behavior.pickup` / `mix`), so
175
+ colours blend on the canvas. A layer takes the medium's wet settings the first time it holds
176
+ wet paint; keep oil and watercolour on separate layers. `set_instant_dry` on makes every wet
177
+ stroke dry as it ends (strokes stay exactly as laid).
178
+ - **Thick paint** (`engine: "impasto"`, category `impasto`) gives a layer relief (height) and
179
+ material (gloss, metallic) next to its colour, lit at render time by `set_lighting`
180
+ (azimuth, elevation, relief). Tools: `impasto-brush` (bristle ridges), `paint-tube` (blobs),
181
+ `palette-knife` (scrapes the relief flat and smears the paint), `paint-roller` (flat stippled
182
+ band), `gloop-pen` (glossy bead), `metallic-paint` (highlights in the paint's colour).
183
+ - **Loading and thinner**: `wet.load` / `impasto.load` below 1 make the brush run out along a
184
+ long stroke (dry-brush ends); `thinner` makes paint flatter and more transparent.
185
+ - **Light** is a view of the relief, not paint: move it (`set_lighting`) to read the texture
186
+ (a low elevation, 15..30°, shows brushwork best) and pick the final light before exporting.
187
+ `get_relief` reads a layer's relief; `flatten_relief` removes it but keeps the colour.
188
+ - **Metallic paper**: `set_paper` `metallic` 0..1 makes the grain sparkle under the light.
189
+
190
+ ## Procedural brushes, bristles, stickers and stencils
191
+
192
+ - **Particle brushes** (category `procedural`): `hair-strands` (strings of masses dragged behind
193
+ the pen: hair, fur, grass), `spring-ink` (springs that overshoot: lively ink lines),
194
+ `orbit-curls` (particles circling the pen: curls and spirals), `flow-fur` and `sparkle-dust`
195
+ (particles thrown into a swirling flow), `bead-trail` (beads along a springy path). Tune with
196
+ `particle` (kind, render dot / line / sequence, count, stiffness, damping, speed, gravity).
197
+ Draw slowly and with varying direction: the particles react to movement.
198
+ - **Bristle brushes** (category `bristle`): `bristle-round`, `bristle-flat`, `dry-brush`. Every
199
+ bristle draws its own line: press harder to splay the tuft, tilt to flatten it; soft bristles
200
+ bend into curves at turns; a low `bristle.load` runs dry into broken streaks.
201
+ - **Sticker spray** (category `sticker`): stamps (`star`, `leaf`, `confetti`, `flower`, `heart`,
202
+ `splat`, `sparkle`, `ring`, `dot`) sprayed along the stroke onto an **empty layer**, where each
203
+ stays an object: `list_stickers`, `update_sticker` (move, turn, resize, recolour, restamp),
204
+ `arrange_stickers`, `remove_stickers`. A sticker layer takes no other paint.
205
+ - **Stencils**: `add_stencil` lays a `ruler` or `arc` (strokes that start within `snap` px follow
206
+ it exactly: straight lines, circles, rainbows) or a `line` / `shape` mask (paint lands only on
207
+ one side or inside a rect, ellipse or polygon; `invert` for outside). Stencils stay until
208
+ removed (`remove_stencils`); masks are recorded with each stroke so replays keep them.
209
+
125
210
  ## Tool reference
126
211
 
127
212
  ### Canvas and paper
@@ -195,9 +280,41 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
195
280
  | `paint_stroke` | Paint one stroke through `points` (document px; `pressure` 0..1, `t` ms, `tiltX` / `tiltY` or `altitude` / `azimuth`, `twist`) with `brushId` (default the active brush), optional per-stroke `brush` changes, `color`, `layerId`, `seed`, `snapToPerspective`. The symmetry guide adds its copies; a sampling tracing image supplies the colour when `color` is missing. Returns `layerId`, `bounds`, `dabs`, `strokeId` and, for brushes that pick up paint, `mixerLoad` (what the brush carries now). Refused on locked, hidden or group layers, with the fix in the message. |
196
281
  | `list_strokes` | Read the recorded strokes, oldest first (default the last 100): id, layer, brush, colour, point count, seed, bounds. With `ids`, their points too. |
197
282
  | `replay_strokes` | Paint recorded `strokeIds` again: exactly, or varied by `dx` / `dy` (px), `rotate` (degrees clockwise), `scale` (brush size follows), `flipX`, `origin`, `pressureScale`, `color`, `brushId`, `layerId`, `repeat` (each copy applies the variation again). One undo step. Returns the new stroke ids, bounds and layers. |
198
- | `undo_paint` | Undo the last step. Returns what was undone and what is next. |
283
+ | `undo_paint` | Undo the last step (a wet stroke's undo puts the wet paint back as it was before it). Returns what was undone and what is next. |
199
284
  | `redo_paint` | Redo the step just undone. |
200
285
 
286
+ ### Wet media
287
+
288
+ | Tool | Use |
289
+ | --- | --- |
290
+ | `get_wet_paint` | Read the wet paint: `wet`, the clock, `paused`, `speed`, `tilt`, the kernel (`backend`, `message` when it runs slower than it could) and each wet layer (`wetCells`, `wetBounds`, `activeTiles`, settings, flow map). Call after wet strokes. |
291
+ | `advance_wet_paint` | Let time pass: `steps` (120 = one second at the default speed) or `seconds`. The paint spreads, blooms, runs and dries. Not an undo step. Returns `steps`, `clock`, `stillWet`, `layers`. Call after a group of wet strokes, before `render_preview`. |
292
+ | `dry_paint` | Dry wet paint at once where it is (one layer with `layerId` or all, optionally inside `rect`). One undo step. Returns `dried` (layer ids and rectangles) and `stillWet`. Dry before glazing over a wash. |
293
+ | `wet_paper` | Pre-wet the paper with clear water over `rect` (default the canvas) on a layer, `amount` 0..1, for wet-in-wet. One undo step. Returns the rectangle and `wet`. Then paint into it. |
294
+ | `set_wet_settings` | A layer's wet settings 0..1: `viscosity`, `evaporation`, `edgeDarkening`, `pigmentWeight`, `granulation`, `pickup`, `fixture`, `bloom`, `bleed`. Saved with the document, not an undo step. Returns `params`, `stillWet`. |
295
+ | `set_flow_map` | Push a layer's water in a pattern: `kind` linear (`angle`), swirl (`center`, `clockwise`), radial, turbulent (`scale`, `seed`) or none, at `strength`. Returns `flow`, `stillWet`. |
296
+ | `set_canvas_tilt` | Tilt the canvas (`angle` 0..90°, `direction` downhill clockwise from the bottom): wet paint runs downhill, very wet paint drips. Returns `tilt`, `stillWet`. |
297
+ | `pause_wet_paint` | Stop or resume time (`paused`) and set `speed` (steps per second). Editor state. |
298
+ | `set_water_overlay` | Show where the water is (`visible`), view only. |
299
+ | `set_instant_dry` | `on`: every wet stroke dries as it ends (same undo step); off (default) wet paint keeps moving. Returns `instantDry`. |
300
+
301
+ ### Thick paint and light
302
+
303
+ | Tool | Use |
304
+ | --- | --- |
305
+ | `set_lighting` | Move the light for thick paint and metallic paper: `azimuth` (degrees clockwise from the top), `elevation` (5..90), `relief` (0..1). Nothing is repainted; not an undo step. Returns the lighting. Use a low elevation to show brushwork. |
306
+ | `get_relief` | Read a layer's relief (`bounds`, `maxHeight` 0..255, null when flat) and the lighting. Changes nothing. |
307
+ | `flatten_relief` | Remove a layer's relief and material, keeping its colour. One undo step. Returns whether anything was flattened. |
308
+
309
+ ### Stickers
310
+
311
+ | Tool | Use |
312
+ | --- | --- |
313
+ | `list_stickers` | Read a layer's stickers bottom first: id, stamp, x, y, size, rotation, color, opacity. |
314
+ | `update_sticker` | Change one sticker by `id`: `stamp`, `x`, `y`, `size`, `rotation`, `color`, `opacity`. One undo step. Returns it. |
315
+ | `arrange_stickers` | Move stickers (`ids`) to the `front` or `back` of their layer. One undo step. |
316
+ | `remove_stickers` | Delete stickers by `ids`, or all on the layer. One undo step. |
317
+
201
318
  ### Guides
202
319
 
203
320
  | Tool | Use |
@@ -212,6 +329,9 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
212
329
  | `list_reference_images` | Read the reference images: id, name, size, placement, visibility. |
213
330
  | `update_reference_image` | Move, resize, rename, show or hide a reference panel. |
214
331
  | `remove_reference_image` | Remove a reference image. |
332
+ | `add_stencil` | Lay a stencil: `kind` ruler (`from`, `to`) or arc (`center`, `radius`, `startAngle`, `endAngle`) to guide strokes, line (`from`, `to`) or shape (`shape` rect / ellipse with `rect`, polygon with `points`) to mask; `mode` guide or mask, `invert`, `snap`, `feather`. Returns it with its id. |
333
+ | `update_stencil` | Move, reshape, switch or hide (`enabled`) a stencil by `id`. |
334
+ | `remove_stencils` | Remove stencils by `ids`, or all. |
215
335
  | `pick_reference_color` | Read a reference image's colour at its own pixel `x`, `y`; `setColor` makes it the paint colour. |
216
336
 
217
337
  ### View, input and output
@@ -223,6 +343,8 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
223
343
  | `render_preview` | See the painting (or `layerIds`) as a PNG, longest side `maxSide` (16..2048, default 512), with or without the `paper`. Render after each block of work. |
224
344
  | `export_image` | Export PNG (default), JPEG or WebP as base64, at `quality` and `scale` (≤ 1); `paper: false` gives a transparent PNG. JPEG / WebP need a browser canvas. |
225
345
  | `export_psd` | Export a PSD with every layer, the paper as a locked bottom layer, and the composite. Pigment and painterly modes are written as their nearest standard mode (`list_blend_modes` `psd`). Returns base64, size, `psb` and `warnings`. |
346
+ | `export_time_lapse` | Repaint the painting from its recorded strokes and events as a time-lapse: `frames` (about how many), `fps`, `maxSide`, `wetStepsPerFrame` (frames while wet paint flows), `holdMs`. Returns a contact sheet image, the frame count, size, duration, a video project of the frames and the ffmpeg command that renders `timelapse.mp4`; `includeFrames` adds every frame as base64 PNG. Changes nothing. |
347
+ | `export_high_res` | Repaint the painting from its strokes at `scale` 1..8 (brushes, grain, fills and wet events scaled): a PNG with real detail instead of upscaled pixels. Returns base64, size. Layers not painted with strokes come out empty. |
226
348
  | `save_document` | Get the document JSON (canvas, paper, layers as PNG data URLs, strokes unless `strokes: false`). |
227
349
  | `open_document` | Open a saved document JSON, replacing the painting and clearing the undo history. Returns the canvas, layers and any `problems`. |
228
350
 
@@ -255,5 +377,15 @@ is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y do
255
377
  `replay_strokes` move the cursor first. Results and undo are the same; it is one more reason to
256
378
  paint a few long strokes and replay them rather than many short ones. A stroke fails with "A
257
379
  stroke is in progress" while the user is painting; try it again afterwards.
380
+ - **Wet paint keeps changing.** A preview right after a wet stroke shows it before it has
381
+ flowed; `advance_wet_paint` first. Paint that should stay exactly where it was laid needs
382
+ `dry_paint` (or a dry medium).
383
+ - **Wet strokes on one layer interact**; washes that must not mix go on separate layers, or dry
384
+ the first before painting the second (glazing). At most 8 layers hold wet paint at once.
385
+ - **Undoing far back** past the wet undo memory (512 MB by default) leaves that paint dry as it
386
+ looked, rather than wet.
387
+ - **Replays repeat what was recorded**: strokes, fills, clears, flattened relief and wet events.
388
+ Imported pixels, merges and layer moves are not data, so `export_time_lapse` and
389
+ `export_high_res` start those layers empty; paint with strokes when the replay matters.
258
390
  - **Recorded strokes are kept in saved documents**; `save_document` with `strokes: false` when
259
391
  only the pixels matter (smaller JSON).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pixerate-vector
3
- description: How to draw and edit vector artwork in the Pixerate vector editor through its vector.* commands - adding shapes and SVG paths, text (point, area, on a path, styles, Create Outlines), symbols and instances, CAD constraints (parallel, tangent, dimensions, auto-constrain), artboards and frames with resizing constraints, connectors, fills, strokes, stacked fills and strokes with blend modes, drop shadows, glows and blurs, clipping masks and opacity masks, gradients (linear, radial, conic, Oklab), stroke alignment, arrowheads, variable-width and tapered strokes, live corner radii, boolean operations and Pathfinder (unite, subtract, divide, trim), Shape Builder, paint bucket, path effects (trim, repeater, zig zag, offset), envelope warps and free distort, blends and morphing, anchor editing (join, smooth, simplify, knife, eraser), align, distribute, group, and SVG import and export. Use when creating an icon, logo, illustration, glyph, badge or any Bezier path artwork, or editing an SVG in a Pixerate vector editor.
3
+ description: How to draw and edit vector artwork in the Pixerate vector editor through its vector.* commands - adding shapes and SVG paths, text (point, area, on a path, styles, Create Outlines), symbols and instances, CAD constraints, artboards and frames with resizing constraints, connectors, fills, strokes, stacked fills and strokes with blend modes, drop shadows, glows and blurs, clipping and opacity masks, gradients (linear, radial, conic, mesh, freeform), stroke alignment, arrowheads, variable-width and tapered strokes, live corner radii, boolean operations and Pathfinder (unite, subtract, divide, trim), Shape Builder, paint bucket, path effects (trim, repeater, zig zag, offset), envelope warps and free distort, blends and morphing, anchor editing (join, smooth, simplify, knife, eraser), align, distribute, group, and SVG import and export. Use when creating an icon, logo, illustration, glyph, badge or any Bezier path artwork, or editing an SVG in a Pixerate vector editor.
4
4
  ---
5
5
 
6
6
  # Pixerate vector editor
@@ -170,6 +170,7 @@ Parameter details (gradient fields, effect parameters, width profiles, envelopes
170
170
 
171
171
  | Command | Use it to |
172
172
  | --- | --- |
173
+ | `vector.traceImage` | Turn a PNG (data URL) into vector paths in one group: `threshold` mode for one-colour art (logos, scans, silhouettes; `channel: "alpha"` for cut-outs), `color` mode for a stacked path per colour (`colors` 2–32). Raise `tolerance` for fewer anchors, `cornerRoundness` 0 for sharp polygons. Place it with `x`, `y`, `width`. Returns `{ id, paths }`; check `subpaths` counts and simplify or delete specks after. |
173
174
  | `vector.addPathByDimensions` | Draw a path the way a CAD user types it: from `start`, each step `{ length, angle }` (degrees counter-clockwise on the page: 0 right, 90 up), `{ dx, dy }` or `{ x, y }`; `closed` joins the ends. Use it for exact technical outlines (brackets, floor plans, given lengths and angles) instead of computing coordinates by hand. Returns `{ id, anchors }`. |
174
175
  | `vector.addShape` | Add a `kind` `rect`, `ellipse`, `polygon` (`sides`, at least 3), `star` (`points`, `innerRatio` 0 to 1) or `line` at `x`, `y`, `width`, `height` (all required; for a line, width and height are the end's offset). `cornerRadius` and `cornerKind` give live corners; any style field and `name` apply. Uses the editor's default style for anything not given. Returns `{ id }`. |
175
176
  | `vector.addPath` | Add a path from SVG path data `d` (absolute or relative M, L, H, V, C, S, Q, T, A, Z; arcs and quadratics become cubics) in document units, with `name` and style fields; unset style comes from the editor defaults. Fails when `d` has no points. Returns `{ id }`. |
@@ -186,6 +187,19 @@ Parameter details (gradient fields, effect parameters, width profiles, envelopes
186
187
  | `vector.setWidthProfile` | Give strokes a variable width: a `preset` (uniform, taperStart, taperEnd, taperBoth, bulge, pinch, teardrop, wave, pressure; `uniform` removes it), explicit `points`, or a parametric `taper` and / or `wave`. Returns the profile points. |
187
188
  | `vector.setWidthPoint` | Set one width point of path `id`: `index` of an existing point (from the profile `vector.setWidthProfile` returns) or none to add one at `t` (0 to 1); `left` / `right` are side widths in document units. Returns the profile. |
188
189
 
190
+ ### Gradient meshes and freeform gradients
191
+
192
+ | Command | Use it to |
193
+ | --- | --- |
194
+ | `vector.setMeshGradient` | Fill paths with a gradient mesh: `rows` × `columns` smooth patches over their bounds, coloured per point (`colors`, row by row) or by four `corners`. Use for realistic shading (fruit, metal, skin, soft folds). Returns `{ meshes: [{ id, shading }] }`. |
195
+ | `vector.setMeshPoint` | Move a mesh point (`index`, row by row; `x`, `y` in document units) and / or set its `color` and `opacity`; neighbouring patches bend smoothly. Returns `{ id, shading }`. |
196
+ | `vector.setFreeformGradient` | Fill paths with a freeform gradient: colour `points` anywhere (with `spread` for pure-colour discs) and `lines` carrying colour along curves, or, with no points, four or more placed inside each path along `colors`. Use for soft, organic colour that a linear or radial gradient cannot make. Returns `{ gradients }`. |
197
+ | `vector.addFreeformPoint` | Add a colour point at `x`, `y` (default colour: what shows there). Returns `{ id, index, shading }`. |
198
+ | `vector.setFreeformPoint` | Move a freeform point or change its `color`, `opacity`, `spread`. Returns `{ id, shading }`. |
199
+ | `vector.removeFreeformPoint` | Remove a freeform point (never the last); later indices shift down. Returns `{ id, shading }`. |
200
+ | `vector.setFreeformLines` | Replace the freeform lines (point indices each curve runs through; `[]` removes them). Returns `{ id, shading }`. |
201
+ | `vector.getShading` | Read a path's mesh or freeform fill with points in document units (the indices the edit commands take). Call it before editing points. |
202
+
189
203
  ### Appearance: fill and stroke stacks, blend modes, filters
190
204
 
191
205
  | Command | Use it to |
@@ -356,6 +370,10 @@ contents whole while you work, without losing the mask.
356
370
 
357
371
  ## Pitfalls
358
372
 
373
+ - Mesh and freeform fills draw as fine tiles, not SVG gradients: they cannot be edited with
374
+ `vector.setGradient` or as stops, and other tools see them as SVG patterns. Point indices
375
+ shift after `vector.removeFreeformPoint`; read them again with `vector.getShading`.
376
+
359
377
  - A connector's geometry is regenerated after every edit while an end is glued: editing its
360
378
  anchors directly does not stick. Unglue the end (`vector.setConnector` with `null`) or change
361
379
  `route` instead. Connectors cannot be glued to connectors.