@pixerate/editor 0.203.0 → 0.205.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/dist/image-editor/controller.d.cts +30 -0
- package/dist/image-editor/controller.d.ts +30 -0
- package/dist/image-editor/index.cjs +298 -158
- package/dist/image-editor/index.js +152 -12
- package/dist/image-editor/selection/refine.d.cts +9 -0
- package/dist/image-editor/selection/refine.d.ts +9 -0
- package/dist/image-editor/selection/tool-options.d.cts +5 -0
- package/dist/image-editor/selection/tool-options.d.ts +5 -0
- package/dist/vector/controller.d.cts +10 -0
- package/dist/vector/controller.d.ts +10 -0
- package/dist/vector/index.cjs +249 -210
- package/dist/vector/index.js +55 -16
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +1 -1
- package/skills/pixerate-image-selection-masking/SKILL.md +8 -5
- package/skills/pixerate-vector/SKILL.md +1 -0
package/dist/vector/index.js
CHANGED
|
@@ -9470,24 +9470,42 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
9470
9470
|
* placed by position.
|
|
9471
9471
|
*/
|
|
9472
9472
|
reorderNode(id, index) {
|
|
9473
|
+
return this.moveNode(id, { index });
|
|
9474
|
+
}
|
|
9475
|
+
/**
|
|
9476
|
+
* Moves a node into group `parentId` (null: the top level; left out: where it is) at `index`
|
|
9477
|
+
* among its new siblings (bottom to top, 0 the bottom; left out: the top), as dragging it in a
|
|
9478
|
+
* layers panel does. It stays where it is on the canvas. Clipping groups and blends keep their
|
|
9479
|
+
* children: their mask and keys are placed by position.
|
|
9480
|
+
*/
|
|
9481
|
+
moveNode(id, options = {}) {
|
|
9473
9482
|
const node = this.getNode(id);
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
const
|
|
9480
|
-
if (
|
|
9481
|
-
return { ok: false, message: "
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
const
|
|
9486
|
-
|
|
9483
|
+
const at = node && locateVectorNode(this.doc.nodes, id);
|
|
9484
|
+
if (!node || !at) return { ok: false, message: `No node "${id}".` };
|
|
9485
|
+
const fixed = (g) => !!g && (isVectorMaskGroup(g) || isVectorBlendGroup(g));
|
|
9486
|
+
if (fixed(at.parent)) return { ok: false, message: "The order inside a clipping group or blend is fixed." };
|
|
9487
|
+
const parentId = options.parentId === void 0 ? at.parent?.id ?? null : options.parentId;
|
|
9488
|
+
const target = parentId === null ? null : this.getNode(parentId);
|
|
9489
|
+
if (parentId !== null) {
|
|
9490
|
+
if (target?.type !== "group") return { ok: false, message: `"${parentId}" is not a group.` };
|
|
9491
|
+
if (parentId === id || findVectorNode([node], parentId)) return { ok: false, message: "A layer cannot go inside itself." };
|
|
9492
|
+
if (fixed(target)) return { ok: false, message: "The order inside a clipping group or blend is fixed." };
|
|
9493
|
+
}
|
|
9494
|
+
const groupId = target?.id ?? null;
|
|
9495
|
+
const without = mapTree(this.doc.nodes, (n2) => n2.id === id ? null : n2);
|
|
9496
|
+
const inGroup = groupId === null ? null : findVectorNode(without, groupId);
|
|
9497
|
+
const siblings = inGroup?.type === "group" ? inGroup.children : without;
|
|
9498
|
+
const to = Math.max(0, Math.min(siblings.length, Math.round(options.index ?? siblings.length)));
|
|
9499
|
+
if (groupId === (at.parent?.id ?? null) && to === at.index) return { ok: true };
|
|
9500
|
+
const from = vectorParentMatrix(this.doc.nodes, id) ?? IDENTITY_MATRIX;
|
|
9501
|
+
const into = groupId === null ? IDENTITY_MATRIX : vectorWorldMatrix(this.doc.nodes, groupId) ?? IDENTITY_MATRIX;
|
|
9502
|
+
const m = multiplyMatrices(from, invertMatrix(into));
|
|
9487
9503
|
const next = [...siblings];
|
|
9488
|
-
next.splice(
|
|
9489
|
-
|
|
9490
|
-
|
|
9504
|
+
next.splice(to, 0, isIdentityMatrix(m) ? node : transformVectorNode(node, m));
|
|
9505
|
+
this.change(
|
|
9506
|
+
"Move Layer",
|
|
9507
|
+
() => this.setDoc(groupId === null ? next : mapTree(without, (n2) => n2.id === groupId && n2.type === "group" ? { ...n2, children: next } : n2))
|
|
9508
|
+
);
|
|
9491
9509
|
return { ok: true };
|
|
9492
9510
|
}
|
|
9493
9511
|
/**
|
|
@@ -17880,6 +17898,27 @@ function createVectorCommands(controller, options = {}) {
|
|
|
17880
17898
|
return { ok: true };
|
|
17881
17899
|
}
|
|
17882
17900
|
},
|
|
17901
|
+
{
|
|
17902
|
+
...base,
|
|
17903
|
+
id: `${prefix}moveLayer`,
|
|
17904
|
+
label: "Move Layer\u2026",
|
|
17905
|
+
keywords: ["reorder", "layer", "order", "into group", "out of group", "reparent", "nest", "z-index"],
|
|
17906
|
+
description: "Moves one node to a position among its siblings (0 the bottom; default the top), as dragging it in the layers panel does. With `parentId` it moves into that group, or with null to the top level; it stays where it is on the canvas.",
|
|
17907
|
+
params: {
|
|
17908
|
+
type: "object",
|
|
17909
|
+
properties: {
|
|
17910
|
+
id: { type: "string", description: "The node to move." },
|
|
17911
|
+
index: { type: "integer", minimum: 0, description: "Position among its new siblings, bottom to top (default: the top)." },
|
|
17912
|
+
parentId: { type: ["string", "null"], description: "The group to move into, or null for the top level (default: its current parent)." }
|
|
17913
|
+
},
|
|
17914
|
+
required: ["id"]
|
|
17915
|
+
},
|
|
17916
|
+
undoable: true,
|
|
17917
|
+
run: (_ctx, params) => {
|
|
17918
|
+
check2(controller.moveNode(params.id, { index: params.index, parentId: params.parentId }));
|
|
17919
|
+
return { ok: true };
|
|
17920
|
+
}
|
|
17921
|
+
},
|
|
17883
17922
|
{
|
|
17884
17923
|
...base,
|
|
17885
17924
|
id: `${prefix}group`,
|
package/package.json
CHANGED
|
@@ -269,7 +269,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
|
|
|
269
269
|
| `grow_selection` | Select › Grow: add connected pixels within `tolerance` (default 32) of a selected colour; follows colour, not distance. `sample`, `sampleMerged`. Fails when nothing is selected. Returns the summary. |
|
|
270
270
|
| `select_similar` | Select › Similar: add every pixel in the image within `tolerance` of a selected colour, connected or not. Fails when nothing is selected. Returns the summary. |
|
|
271
271
|
| `reselect` | Bring back the last selection `deselect` cleared (one undo step). Fails when there is none. Returns the summary. |
|
|
272
|
-
| `refine_selection` |
|
|
272
|
+
| `refine_selection` | Select and Mask: snap the selection edge to image edges within `radius` px (0..64, default 8), with `smartRadius`, `smooth` 0..100, `feather` px, `contrast` 0..100 and `shiftEdge` -100..100 %, then `output` to `selection` (default), `layer-mask`, `new-layer` or `new-layer-with-mask` (on `layerId`, default active; new layers hide the source), with `decontaminate` 0..100 for new layers. One step; returns `layerId` / `newLayerId`. Use on hair, fur, foliage or after a coarse AI mask. |
|
|
273
273
|
| `update_adjustment_layer` | Change a layer's `enabled` (false hides it without deleting), `blend`, `opacity` (0..1) or `name` in one undo step. Returns the layer. Its parameters change with `set_adjustments`. Toggle `enabled` to compare a layer's effect before and after. |
|
|
274
274
|
| `move_adjustment_layer` | Move a layer to index `to` (0 = bottom, applied first; past the top means top). Order matters: a curves layer above a hue/saturation layer works on its output. Fails when the layer is already there. Returns the ids bottom to top. |
|
|
275
275
|
| `remove_adjustment_layer` | Delete a layer and its mask. Prefer hiding it with `update_adjustment_layer` when the user may want it back. Returns the remaining ids. |
|
|
@@ -115,10 +115,12 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
|
|
|
115
115
|
|
|
116
116
|
## Recipes
|
|
117
117
|
|
|
118
|
-
- **Cut out a subject onto a new background:** select (table),
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
- **Cut out a subject onto a new background:** select (table), then `refine_selection` with
|
|
119
|
+
`output: "new-layer-with-mask"` (revisable) and, for hair or fur, `decontaminate` 50–100 so
|
|
120
|
+
the old background's colour leaves the soft edge. Add the new background with
|
|
121
|
+
`add_pixel_layer` and move it under the cutout (`move_layer`). `render_preview` and look for a
|
|
122
|
+
halo; if there is one, raise `decontaminate`, or load the mask as a selection, `contract`
|
|
123
|
+
1 px, and output again.
|
|
122
124
|
- **Replace the sky:** `select_sky` (or `magic_wand` / `select_color_range` `preset: "blues"`
|
|
123
125
|
if it finds none), `add` missed patches, `refine_selection` radius 8–16 along the horizon and trees, then
|
|
124
126
|
`add_layer_mask` on the new sky layer. Match it with a clipped curves layer (`clipped: true`).
|
|
@@ -176,7 +178,8 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
|
|
|
176
178
|
background, and drop `snapToEdges` where the edge is too faint.
|
|
177
179
|
- **Over-feathering hard objects:** a 10 px feather on a product looks like a glow. Keep hard
|
|
178
180
|
edges at 0–2 px and refine soft ones instead.
|
|
179
|
-
- **Halo:** the old background shows as a light or dark fringe. `
|
|
181
|
+
- **Halo:** the old background shows as a light or dark fringe. `decontaminate` on a
|
|
182
|
+
new-layer output for soft edges; for hard ones `contract` 1–2 px or
|
|
180
183
|
`shiftEdge` negative before masking.
|
|
181
184
|
- **Baking too early:** `apply_layer_mask`, `merge_down` and `layer_via_copy` with `cut: true`
|
|
182
185
|
are hard to revise. Keep masks until the user is happy.
|
|
@@ -246,6 +246,7 @@ arrays, to build or replace a stack in one call.
|
|
|
246
246
|
| `vector.align` | Align `ids` on `edge` (left, center, right, top, middle, bottom) to their combined bounds, or to the artboard with `to: "artboard"` (also the default for a single node). |
|
|
247
247
|
| `vector.distribute` | Give three or more nodes equal gaps in `direction` horizontal or vertical. |
|
|
248
248
|
| `vector.arrange` | Change stacking `order` within each node's parent: front, forward, backward, back. |
|
|
249
|
+
| `vector.moveLayer` | Move one node `id` to `index` among its siblings (0 the bottom; default the top); `parentId` moves it into a group, or `null` to the top level. It stays put on the canvas. |
|
|
249
250
|
| `vector.group` | Group nodes that share a parent, with an optional `name`. Returns `{ id }`. |
|
|
250
251
|
| `vector.ungroup` | Replace groups with their children (ungrouping a blend expands it). |
|
|
251
252
|
| `vector.select` | Select nodes by `ids` (`add: true` to extend; an empty list clears). Selection is the default target of most commands. |
|