@pixerate/editor 0.224.0 → 0.225.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.
@@ -17233,6 +17233,19 @@ function createVectorCommands(controller, options = {}) {
17233
17233
  return { ok: true };
17234
17234
  }
17235
17235
  },
17236
+ {
17237
+ ...base,
17238
+ id: `${prefix}rename`,
17239
+ label: "Rename Layer\u2026",
17240
+ keywords: ["rename", "name", "layer", "label"],
17241
+ description: "Renames node `id` (a path, group, text or any layer) to `name`, as the Layers panel shows it. One undo step. Returns { id, name }.",
17242
+ params: { type: "object", properties: { id: { type: "string", description: "The node (from vector.list)." }, name: { type: "string", minLength: 1, description: "Its new name." } }, required: ["id", "name"], additionalProperties: false },
17243
+ undoable: true,
17244
+ run: (_ctx, params) => {
17245
+ check2(controller.rename(params.id, params.name));
17246
+ return { id: params.id, name: params.name };
17247
+ }
17248
+ },
17236
17249
  {
17237
17250
  ...base,
17238
17251
  id: `${prefix}boolean`,
@@ -17233,6 +17233,19 @@ function createVectorCommands(controller, options = {}) {
17233
17233
  return { ok: true };
17234
17234
  }
17235
17235
  },
17236
+ {
17237
+ ...base,
17238
+ id: `${prefix}rename`,
17239
+ label: "Rename Layer\u2026",
17240
+ keywords: ["rename", "name", "layer", "label"],
17241
+ description: "Renames node `id` (a path, group, text or any layer) to `name`, as the Layers panel shows it. One undo step. Returns { id, name }.",
17242
+ params: { type: "object", properties: { id: { type: "string", description: "The node (from vector.list)." }, name: { type: "string", minLength: 1, description: "Its new name." } }, required: ["id", "name"], additionalProperties: false },
17243
+ undoable: true,
17244
+ run: (_ctx, params) => {
17245
+ check2(controller.rename(params.id, params.name));
17246
+ return { id: params.id, name: params.name };
17247
+ }
17248
+ },
17236
17249
  {
17237
17250
  ...base,
17238
17251
  id: `${prefix}boolean`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.224.0",
3
+ "version": "0.225.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -63,8 +63,15 @@ the pitfalls, and uses the tools below.
63
63
  (`select_subject`, or a `select_polygon`, then `refine_selection`), then `layer_via_copy`.
64
64
  3. **Shape layers non-destructively**: masks (`add_layer_mask` from the selection, or
65
65
  reveal-all / hide-all, softened with `density` / `feather`) instead of deleting pixels;
66
- `clipped: true` (via `set_layer_properties`) to limit a layer or adjustment to the layer below;
67
- `blend`, `opacity` and `fillOpacity` instead of baking.
66
+ `clipped: true` to limit a layer or adjustment to the layer below (pass it to
67
+ `add_adjustment_layer` / `add_effect_layer` with `aboveId` so it is clipped in the same step,
68
+ or set it later with `set_layer_properties`); `blend`, `opacity` and `fillOpacity` instead of
69
+ baking.
70
+ **To affect one layer only:** a filter effect from `apply_effect` keeps that layer's
71
+ transparency by default (`preserveTransparency`), so it changes only the layer's own pixels;
72
+ pass `preserveTransparency: false` only when the effect should fill the empty area too. A
73
+ generator or overlay goes on its own layer with `add_effect_layer` `aboveId` + `clipped: true`;
74
+ an adjustment with `add_adjustment_layer` `aboveId` + `clipped: true`.
68
75
  4. **Organise** with `group_layers` (pass-through by default: blend modes inside still see the
69
76
  layers below; give the group a blend mode to isolate them), `move_layer` and
70
77
  `offset_layer`.
@@ -176,7 +183,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
176
183
  | `export_smart_object_contents` | Export Contents: the contents as a file (`name`, `mimeType`, `byteLength`, `base64`): the file they came from while unedited, else a PNG (raster) or PSD / PSB (nested document). Changes nothing. |
177
184
  | `search_effects` | Find provider effects (when the host registered an effects provider; else `available: false`): `query`, `kind`, `category`, `use` (filter for smart filters; generator, overlay, title for effect layers). See `references/provider-effects.md`. |
178
185
  | `describe_effect` | Read an effect's `controls` (strict JSON Schema with ranges and units), `defaults`, `presets` and `inputs` before applying it. |
179
- | `list_applied_effects` | Read the provider effects per layer: effect smart filters (`role: smart filter`, with blend and opacity) and an effect layer's own effect (`generator`), with `available` false when the provider lacks one. Works without a provider. |
186
+ | `list_applied_effects` | Read the provider effects per layer: effect smart filters (`role: smart filter`, with blend, opacity and `preserveTransparency`) and an effect layer's own effect (`generator`), with `available` false when the provider lacks one. Works without a provider. |
180
187
  | `capture_view` | Inspect detail in natural image pixels (the space of `get_selection` and the select tools, before crop and rotation): `region` `content` (whole image, default), `selection` or `rect`; small regions are enlarged up to 8× with hard pixel edges, so a 64 px rect shows real pixels. `includeOverlays: true` shades unselected pixels and outlines the crop: use it to check a mask's edge before `apply_selection_as_mask`. Returns the `rect` and `scale`. Use `render_preview` for the final framed result. |
181
188
 
182
189
  ### Write
@@ -184,7 +191,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
184
191
  | Tool | Use it to |
185
192
  | --- | --- |
186
193
  | `set_adjustments` | Set base controls and existing layer parameters in one undo step: `values` is a map of control id or `layers.<layerId>.<controlId>` path to number; `label` is echoed. Values are clamped to range; returns `applied` and `clamped` (and a note when `tint` is set on a process 1 edit). Unknown ids fail and change nothing. Cannot set curves points, booleans or colours. |
187
- | `add_adjustment_layer` | Add a layer above the other adjustment layers and below annotations (or directly above `aboveId`, or at the top of group `parentId`): `kind` (curves, levels, hueSaturation, vibrance, colorBalance, blackWhite, photoFilter, invert, posterize, threshold), optional `params` merged with neutral defaults, `opacity` 0..1 (default 1), `blend` (default normal), `name`. With a selection the layer is masked by it (`useSelection`, default true; `false` for a global layer; `masked` in the result). Returns the layer (with its new id) and its stack index. The only tool that sets curves points, `colorize`, `preserveLuminosity`, a black and white `tint` or a photo filter `color`. |
194
+ | `add_adjustment_layer` | Add a layer above the other adjustment layers and below annotations (or directly above `aboveId`, or at the top of group `parentId`): `kind` (curves, levels, hueSaturation, vibrance, colorBalance, blackWhite, photoFilter, invert, posterize, threshold), optional `params` merged with neutral defaults, `opacity` 0..1 (default 1), `blend` (default normal), `name`. With a selection the layer is masked by it (`useSelection`, default true; `false` for a global layer; `masked` in the result). `clipped: true` (with `aboveId`) clips it to the layer below in the same undo step so it adjusts only that layer; refused when nothing is below. Returns the layer (with its new id), its stack index, `masked` and `clipped`. The only tool that sets curves points, `colorize`, `preserveLuminosity`, a black and white `tint` or a photo filter `color`. |
188
195
  | `select_all` | Select › All. Returns the selection summary (`empty`, `bounds`, `area`, `percent`). |
189
196
  | `deselect` | Clear the selection so edits apply to the whole layer. Returns the empty summary. |
190
197
  | `invert_selection` | Select › Inverse (soft edges stay soft; with nothing selected, selects all). Returns the summary. |
@@ -332,10 +339,10 @@ in the source frame at the document's bit depth, colour mode and profile. Read
332
339
  | `mix_colors` | Read-only. Mix 1 to 16 `colors` (`{color: #rrggbb, weight, strength?}`) like paint (Kubelka-Munk over reflectance spectra). Returns `mixed` (#rrggbb), `rgbLerp` (the plain RGB average, for comparison) and the normalised `weights`. Call it before `paint_stroke` / `fill_pixels` to pick a paint colour. |
333
340
  | `clear_pixels` | Remove the selected pixels (alpha to 0; a transparency-locked layer or a mask gets the background colour). Returns the changed bounds. |
334
341
  | `import_psd` | Open a PSD / PSB (`data` base64, a `data:` URL is fine) as the document, replacing the layers, crop and rotation (one undo step). Returns the new `layers` tree with ids, `layerIds`, size and `warnings` naming the affected layers. Call `inspect_psd` first when losses matter. |
335
- | `apply_effect` | Run a provider filter effect on a layer as a smart filter (`target`, `effect`, `values`, `index`, `enabled`, `opacity`); a pixel, shape or type layer becomes a smart object in the same undo step (`converted`). With a selection the filter mask is set from it (`masked`): deselect first to filter the whole layer. Returns the filter id. |
336
- | `update_effect` | Change an effect smart filter (`values` merged, `null` resets; `enabled`, `opacity`, `index`) or redraw an effect layer (`effect: "generator"`, values only). |
342
+ | `apply_effect` | Run a provider filter effect on a layer as a smart filter (`target`, `effect`, `values`, `index`, `enabled`, `opacity`, `blend`); a pixel, shape or type layer becomes a smart object in the same undo step (`converted`). It keeps the layer's transparency (`preserveTransparency`, default true: the result is drawn over the layer and takes its alpha); `false` lets a shader fill transparent pixels. With a selection the filter mask is set from it (`masked`): deselect first to filter the whole layer. Returns the filter id and `preserveTransparency`. |
343
+ | `update_effect` | Change an effect smart filter (`values` merged, `null` resets; `enabled`, `opacity`, `blend`, `preserveTransparency`, `index`) or redraw an effect layer (`effect: "generator"`, values only). Returns the filter as it is now. |
337
344
  | `remove_effect` | Remove an effect smart filter, or (`generator`) keep an effect layer's pixels as a plain layer. |
338
- | `add_effect_layer` | Add a layer drawn by a generator, overlay or title effect at the document's size and bit depth (`values`, `time`, `animate`, `name`, `aboveId` / `belowId`, `opacity`, `blend`). An effect with its own background (`backgroundOpacity` in `describe_effect`) starts with it transparent when there are layers below. Returns the layer id. |
345
+ | `add_effect_layer` | Add a layer drawn by a generator, overlay or title effect at the document's size and bit depth (`values`, `time`, `animate`, `name`, `aboveId` / `belowId`, `opacity`, `blend`, `clipped`). `clipped: true` clips it to the layer directly below in the same undo step, so it shows only over that layer's pixels (refused when nothing is below it in its group). An effect with its own background (`backgroundOpacity` in `describe_effect`) starts with it transparent when there are layers below. Returns the layer id and `clipped`. |
339
346
  | `set_effect_layer` | Change an effect layer: swap its `effect` (its defaults plus `values`), pick the still frame (`time`, ms), or make it play in an animation (`animate: { duration }`; `null` for a still frame). The longest animating layer sets the animation's length. |
340
347
  | `apply_selection_as_mask` | Mask a layer with the current selection: pass `layerId` to mask an existing layer, or `kind` (plus optional `params`) to create a new masked layer in one step. `density` 0..1 and `feather` px soften the mask non-destructively. Returns `layerId`, kind, mask info and the selection summary. |
341
348
  | `stroke_selection` | Edit › Stroke: a band `width` px (≤ 250) `outside` (default), `inside` or `center` on the selection edge, with `color`, `opacity`, `blend`, on a layer's pixels or mask (`channel`). One undo step. Returns the changed `bounds`. |
@@ -22,6 +22,13 @@ user where to find what you changed.
22
22
  ## Best practices
23
23
 
24
24
  - Prefer smart filters to baking: they stay editable, reorderable and maskable.
25
+ - **To affect one layer only,** apply the filter to that layer: `apply_effect` keeps its
26
+ transparency by default (`preserveTransparency: true`), so the effect only recolours the
27
+ layer's own pixels and follows later edits to them. Set `preserveTransparency: false`
28
+ (`apply_effect` or `update_effect`) only when the effect should draw into the empty area, such
29
+ as a glow or background around a cutout.
30
+ - For a generator or overlay limited to one layer, `add_effect_layer` with `aboveId` that layer
31
+ and `clipped: true`: one undo step, no `set_layer_properties` call needed.
25
32
  - For light leaks and glows, add an overlay effect layer with blend `screen` or `add`. For
26
33
  textures, use `multiply`.
27
34
  - Several effect filters render in order: each waits for the one below it.
@@ -31,6 +38,10 @@ user where to find what you changed.
31
38
  - **Effects render in the background.** Right after `apply_effect` or `update_effect`, the smart
32
39
  object shows the pixels without the new effect until the provider's result lands. This is a
33
40
  redraw, not an undo step. Render a preview after the effect has rendered.
41
+ - **Shaders ignore transparency.** Many provider shaders write opaque pixels everywhere. With
42
+ `preserveTransparency: false` (or a filter from an older document, where it is missing) the
43
+ effect's alpha replaces the layer's and fills its transparent area. `list_applied_effects`
44
+ shows the setting; turn it on with `update_effect`.
34
45
  - **Smart filters run on 8-bit pixels.** Effect layers render at the document's bit depth.
35
46
  - **Without a provider,** effect filters pass pixels through and effect layers keep their last
36
47
  pixels. Both keep their effect ids and values and save unchanged. The write tools refuse.
@@ -48,8 +48,9 @@ This skill is the method. `pixerate-image-editor` has the tool reference, and it
48
48
  3. **Make a retouch layer.** `add_pixel_layer` named "Retouch" above the photo; all healing goes
49
49
  on it with `sample: "current-below"`.
50
50
  **Check:** `list_layers` shows it active above the photo.
51
- 4. **Heal small to large.** `spot_heal` for spots (one dab, `brush.size` a little larger than the
52
- spot, `hardness` 0.2-0.5); a short stroke of dabs along a stray hair. `heal_brush` from a clean
51
+ 4. **Heal small to large.** `spot_heal` for spots (one dab, `hardness` 0.2-0.5, `brush.size`
52
+ 2.5-3× the spot's width: a soft brush heals fully only in its middle, so one just over the
53
+ spot leaves a dark ring); a short stroke of dabs along a stray hair. `heal_brush` from a clean
53
54
  source of the same texture for larger flaws; `clone_stamp` near edges (lips, eyes, hairline)
54
55
  where healing would pull colour across.
55
56
  **Check:** `measure_region` around each flaw: its `p1` is near the clean skin's; `capture_view`
@@ -82,7 +83,9 @@ This skill is the method. `pixerate-image-editor` has the tool reference, and it
82
83
  ## Recipes
83
84
 
84
85
  **Clean-up pass.** `add_pixel_layer` "Retouch" → one `spot_heal` per spot (`points: [{x, y}]`,
85
- `sample: "current-below"`, `brush: { size, hardness: 0.3 }`) → `measure_region` around each.
86
+ `sample: "current-below"`, `brush: { size: 3 × the spot, hardness: 0.3 }`) → `measure_region` on
87
+ a box about 3× the spot around each. The spot is gone when the box's `stats.luminance.p1` is
88
+ within about 10 levels of the skin's around it; if not, the edge is left: dab again one size up.
86
89
 
87
90
  **Stray hair.** `spot_heal` with `points` every 8-10 px along the hair and a brush 1.5-2× its
88
91
  width; check the whole length with one `measure_region` box over it.
@@ -97,8 +100,9 @@ width; check the whole length with one `measure_region` box over it.
97
100
  `current-below`.
98
101
  - **An empty layer with `sample: "current"`** has nothing to copy, so the stroke does nothing.
99
102
  - **Over-smoothing.** Blurring skin removes pores and looks fake; heal flaws instead.
100
- - **Big brushes.** A heal brush much larger than the flaw pulls in colour from around it; keep it
101
- just over the flaw.
103
+ - **Brush size.** Too small a soft brush leaves a faint ring of the flaw (its edge falls in the
104
+ brush's soft falloff); much larger than about 4× the flaw pulls in colour from around it. Aim
105
+ for 2.5-3× the flaw's width with a soft brush, or about 1.5× with `hardness` near 1.
102
106
  - **Healing across an edge** smears lips or lashes into skin; clone along edges instead.
103
107
  - **Removing features.** Moles, freckles and scars are part of a face; ask before removing them.
104
108
  - **Bright white eyes and teeth** look unnatural; small gamma moves, and measure.
@@ -148,8 +148,8 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
148
148
  opacity.
149
149
  - **Selective sharpening or blur:** select, then `set_smart_filter_mask` `from: "selection"` on
150
150
  a smart object's filters.
151
- - **Clip a texture or colour to a layer:** put it directly above and set `clipped: true` with
152
- `set_layer_properties`; no selection is needed.
151
+ - **Clip a texture or colour to a layer:** `add_effect_layer` / `add_adjustment_layer` with
152
+ `aboveId` and `clipped: true` (one step; `set_layer_properties` for an existing layer).
153
153
  - **Remove an object:** select it with a 2–4 px margin (`modify_selection` `expand`), then
154
154
  `content_aware_fill` `output: "new-layer"`; try another `seed` if the fill repeats texture,
155
155
  and mask out what is wrong. If it copies in something it shouldn't (a person, a sign), pass
@@ -253,4 +253,4 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
253
253
  - `add_adjustment_layer`, `apply_effect`, `add_smart_filter`: masked by an active selection
254
254
  - `paint_stroke`: paint on a mask with `channel: "mask"`
255
255
  - `undo_image`: take back a step
256
- - `set_layer_properties`: clipping
256
+ - `set_layer_properties`, `add_effect_layer`: clipping
@@ -140,6 +140,7 @@ the pitfalls, and uses the commands below.
140
140
  | `vector.importSvg` | Add the shapes of SVG markup `svg` on top of the document, or replace the document with `replace: true`. Reads paths, basic shapes, groups, transforms, linear and radial gradients, `clip-path` / `mask` references (as mask groups) `<text>` (as point text: content, font, anchor and fill) and `<use>` (as instances of symbols made from what they refer to); skips images and foreign filters. |
141
141
  | `vector.importLottie` | Add one `frame` of a Lottie animation (object or text) as editable groups, or replace the document (`replace: true`). Modifiers become live effects. Returns `{ ids, notes }`. |
142
142
  | `vector.delete` | Delete nodes (`ids`). |
143
+ | `vector.rename` | Rename node `id` to `name` (its name in the Layers panel). Name what you make by what it is; rename the user's layers only when asked. Returns `{ id, name }`. |
143
144
 
144
145
  ### Style
145
146