@pixerate/editor 0.201.0 → 0.203.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/agent/index.cjs +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/{chunk-GLQQ2VIL.cjs → chunk-53GOGBTM.cjs} +23 -1
- package/dist/{chunk-3TNA7JKI.js → chunk-ZPJEH456.js} +22 -0
- package/dist/commands/builtins.d.cts +6 -0
- package/dist/commands/builtins.d.ts +6 -0
- package/dist/commands/index.cjs +4 -2
- package/dist/commands/index.js +4 -2
- package/dist/image-editor/controller.d.cts +24 -1
- package/dist/image-editor/controller.d.ts +24 -1
- package/dist/image-editor/index.cjs +226 -171
- package/dist/image-editor/index.js +78 -23
- package/dist/image-editor/selection/segmentation.d.cts +7 -0
- package/dist/image-editor/selection/segmentation.d.ts +7 -0
- package/dist/paint-editor/guide-tools.d.cts +2 -2
- package/dist/paint-editor/guide-tools.d.ts +2 -2
- package/dist/paint-editor/hosted.d.cts +34 -0
- package/dist/paint-editor/hosted.d.ts +34 -0
- package/dist/paint-editor/index.cjs +101 -10
- package/dist/paint-editor/index.d.cts +1 -0
- package/dist/paint-editor/index.d.ts +1 -0
- package/dist/paint-editor/index.js +96 -5
- package/dist/paint-editor/sticker-tools.d.cts +2 -2
- package/dist/paint-editor/sticker-tools.d.ts +2 -2
- package/dist/paint-editor/thick-tools.d.cts +2 -2
- package/dist/paint-editor/thick-tools.d.ts +2 -2
- package/dist/paint-editor/tools.d.cts +19 -2
- package/dist/paint-editor/tools.d.ts +19 -2
- package/dist/paint-editor/wet-tools.d.cts +2 -2
- package/dist/paint-editor/wet-tools.d.ts +2 -2
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +2 -2
- package/skills/pixerate-paint-editor/SKILL.md +9 -0
|
@@ -6213,6 +6213,49 @@ function withPaintPlayback(provider, options) {
|
|
|
6213
6213
|
};
|
|
6214
6214
|
}
|
|
6215
6215
|
|
|
6216
|
+
// src/paint-editor/hosted.ts
|
|
6217
|
+
function shiftAt(value, keys, dx, dy) {
|
|
6218
|
+
if (value === null || typeof value !== "object") return value;
|
|
6219
|
+
if (keys.length === 0) {
|
|
6220
|
+
if (Array.isArray(value)) return value;
|
|
6221
|
+
const o = { ...value };
|
|
6222
|
+
if (typeof o.x === "number") o.x += dx;
|
|
6223
|
+
if (typeof o.y === "number") o.y += dy;
|
|
6224
|
+
return o;
|
|
6225
|
+
}
|
|
6226
|
+
const [head, ...rest] = keys;
|
|
6227
|
+
const each = head.endsWith("[]");
|
|
6228
|
+
const key = each ? head.slice(0, -2) : head;
|
|
6229
|
+
const inner = key === "" ? value : value[key];
|
|
6230
|
+
if (inner === void 0) return value;
|
|
6231
|
+
const next = each ? Array.isArray(inner) ? inner.map((v) => shiftAt(v, rest, dx, dy)) : inner : shiftAt(inner, rest, dx, dy);
|
|
6232
|
+
if (key === "") return next;
|
|
6233
|
+
return Array.isArray(value) ? value : { ...value, [key]: next };
|
|
6234
|
+
}
|
|
6235
|
+
var shiftAll = (value, paths, dx, dy) => paths.reduce((v, p) => shiftAt(v, p === "" ? [] : p.split("."), dx, dy), value);
|
|
6236
|
+
var toDocument = (value, paths, origin) => shiftAll(value, paths, -origin.x, -origin.y);
|
|
6237
|
+
var fromDocument = (value, paths, origin) => shiftAll(value, paths, origin.x, origin.y);
|
|
6238
|
+
function hostedText(text) {
|
|
6239
|
+
return text.replace(/\ba document pixel\b/g, "a canvas point").replace(/\bdocument pixels\b/g, "canvas coordinates").replace(/\bDocument ([xy])\b/g, "Canvas $1").replace(/\bdocument ([xy])\b/g, "canvas $1");
|
|
6240
|
+
}
|
|
6241
|
+
function hostedSchema(schema) {
|
|
6242
|
+
if (Array.isArray(schema)) return schema.map(hostedSchema);
|
|
6243
|
+
if (schema === null || typeof schema !== "object") return schema;
|
|
6244
|
+
const out = {};
|
|
6245
|
+
for (const [k, v] of Object.entries(schema)) out[k] = k === "description" && typeof v === "string" ? hostedText(v) : hostedSchema(v);
|
|
6246
|
+
return out;
|
|
6247
|
+
}
|
|
6248
|
+
function lazyController(get) {
|
|
6249
|
+
return new Proxy({}, {
|
|
6250
|
+
get(_, key) {
|
|
6251
|
+
const target = get();
|
|
6252
|
+
const value = Reflect.get(target, key, target);
|
|
6253
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
6254
|
+
},
|
|
6255
|
+
has: (_, key) => Reflect.has(get(), key)
|
|
6256
|
+
});
|
|
6257
|
+
}
|
|
6258
|
+
|
|
6216
6259
|
// src/paint-editor/sticker-tools.ts
|
|
6217
6260
|
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
6218
6261
|
var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
@@ -6226,6 +6269,7 @@ function createPaintStickerTools(c) {
|
|
|
6226
6269
|
description: "Lists a layer\u2019s stickers bottom first: id, stamp, x, y (centre, document pixels), size (diameter px), rotation (degrees clockwise), color, opacity. Empty for a layer without stickers. Changes nothing.",
|
|
6227
6270
|
inputSchema: { type: "object", properties: { layerId: LAYER_ID }, additionalProperties: false },
|
|
6228
6271
|
annotations: { title: "List stickers", ...READ },
|
|
6272
|
+
coordinates: { out: ["stickers[]"] },
|
|
6229
6273
|
handler: ({ layerId }) => ({ layerId: _nullishCoalesce(layerId, () => ( c.document.activeLayerId)), stickers: c.listStickers(layerId) })
|
|
6230
6274
|
},
|
|
6231
6275
|
{
|
|
@@ -6249,6 +6293,7 @@ function createPaintStickerTools(c) {
|
|
|
6249
6293
|
additionalProperties: false
|
|
6250
6294
|
},
|
|
6251
6295
|
annotations: { title: "Change a sticker", ...WRITE },
|
|
6296
|
+
coordinates: { in: [""], out: [""] },
|
|
6252
6297
|
handler: ({ layerId, id, ...update }) => c.updateSticker(layerId, id, update)
|
|
6253
6298
|
},
|
|
6254
6299
|
{
|
|
@@ -6304,6 +6349,7 @@ var RECT = {
|
|
|
6304
6349
|
required: ["x", "y", "width", "height"],
|
|
6305
6350
|
additionalProperties: false
|
|
6306
6351
|
};
|
|
6352
|
+
var STENCIL_POSITIONS = ["from", "to", "center", "rect", "points[]"];
|
|
6307
6353
|
var PNG = { type: "string", minLength: 1, description: "The image as a PNG, base64 or a data:image/png URL." };
|
|
6308
6354
|
var tracingInfo = (t) => t ? { width: t.width, height: t.height, rect: t.rect, opacity: t.opacity, visible: t.visible, sampleColors: t.sampleColors } : null;
|
|
6309
6355
|
var refInfo = ({ src: _s, ...r }) => r;
|
|
@@ -6332,6 +6378,7 @@ function createPaintGuideTools(c) {
|
|
|
6332
6378
|
description: "Reads the painting guides: symmetry (mode, centre, rotation, segments, mirror, and how many copies each stroke paints), the perspective guide (vanishing points, snap), the tracing image (size, placement, opacity, visibility, colour sampling), the reference images and the stencils (id, kind, mode, geometry).",
|
|
6333
6379
|
inputSchema: EMPTY,
|
|
6334
6380
|
annotations: { title: "Get the painting guides", ...READ2 },
|
|
6381
|
+
coordinates: { out: ["symmetry.center", "perspective.points[]", "tracing.rect", ...STENCIL_POSITIONS.map((p) => `stencils[].${p}`)] },
|
|
6335
6382
|
handler: () => {
|
|
6336
6383
|
const g = guides();
|
|
6337
6384
|
return { symmetry: { ...g.symmetry, copies: symmetryCopies(g.symmetry).length }, perspective: g.perspective, tracing: tracingInfo(g.tracing), references: g.references.map(refInfo), stencils: g.stencils };
|
|
@@ -6353,6 +6400,7 @@ function createPaintGuideTools(c) {
|
|
|
6353
6400
|
additionalProperties: false
|
|
6354
6401
|
},
|
|
6355
6402
|
annotations: { title: "Set mirror or kaleidoscope painting", ...SET },
|
|
6403
|
+
coordinates: { in: ["center"], out: ["center"] },
|
|
6356
6404
|
handler: (a) => {
|
|
6357
6405
|
const s = c.setSymmetry(a);
|
|
6358
6406
|
return { ...s, copies: symmetryCopies(s).length };
|
|
@@ -6372,6 +6420,7 @@ function createPaintGuideTools(c) {
|
|
|
6372
6420
|
additionalProperties: false
|
|
6373
6421
|
},
|
|
6374
6422
|
annotations: { title: "Set the perspective guide", ...SET },
|
|
6423
|
+
coordinates: { in: ["points[]"], out: ["points[]"] },
|
|
6375
6424
|
handler: (a) => c.setPerspective(a)
|
|
6376
6425
|
},
|
|
6377
6426
|
{
|
|
@@ -6390,6 +6439,7 @@ function createPaintGuideTools(c) {
|
|
|
6390
6439
|
additionalProperties: false
|
|
6391
6440
|
},
|
|
6392
6441
|
annotations: { title: "Set a tracing image", ...WRITE2 },
|
|
6442
|
+
coordinates: { in: ["rect"], out: ["rect"] },
|
|
6393
6443
|
handler: (a) => tracingInfo(c.setTracingImage(a))
|
|
6394
6444
|
},
|
|
6395
6445
|
{
|
|
@@ -6407,6 +6457,7 @@ function createPaintGuideTools(c) {
|
|
|
6407
6457
|
additionalProperties: false
|
|
6408
6458
|
},
|
|
6409
6459
|
annotations: { title: "Change the tracing image", ...SET },
|
|
6460
|
+
coordinates: { in: ["rect"], out: ["rect"] },
|
|
6410
6461
|
handler: (a) => tracingInfo(c.updateTracing(a))
|
|
6411
6462
|
},
|
|
6412
6463
|
{
|
|
@@ -6700,6 +6751,7 @@ function createPaintGuideTools(c) {
|
|
|
6700
6751
|
description: "Lays a stencil on the canvas: a ruler (straight edge to draw along) or an arc (circle or part of one) that pointer and agent strokes starting near it follow exactly, or a line (straight masking edge) or a shape (rect, ellipse or polygon template) that paint lands only inside of (outside with invert). Editor state saved with the document, not an undo step; replays keep the mask they were painted through. Returns the stencil with its id.",
|
|
6701
6752
|
inputSchema: { type: "object", properties: { kind: { type: "string", enum: ["ruler", "arc", "line", "shape"], description: "ruler, arc, line or shape." }, ...STENCIL_GEOMETRY }, required: ["kind"], additionalProperties: false },
|
|
6702
6753
|
annotations: { title: "Lay a stencil", ...WRITE2 },
|
|
6754
|
+
coordinates: { in: STENCIL_POSITIONS, out: STENCIL_POSITIONS },
|
|
6703
6755
|
handler: (a) => c.addStencil(a)
|
|
6704
6756
|
},
|
|
6705
6757
|
{
|
|
@@ -6708,6 +6760,7 @@ function createPaintGuideTools(c) {
|
|
|
6708
6760
|
description: "Moves, reshapes, switches (guide or mask, invert) or hides (enabled false) a stencil by id from get_guides. Returns the stencil.",
|
|
6709
6761
|
inputSchema: { type: "object", properties: { id: { type: "string", description: "Stencil id from get_guides." }, ...STENCIL_GEOMETRY }, required: ["id"], additionalProperties: false },
|
|
6710
6762
|
annotations: { title: "Change a stencil", ...SET },
|
|
6763
|
+
coordinates: { in: STENCIL_POSITIONS, out: STENCIL_POSITIONS },
|
|
6711
6764
|
handler: ({ id, ...update }) => c.updateStencil(id, update)
|
|
6712
6765
|
},
|
|
6713
6766
|
{
|
|
@@ -6760,6 +6813,7 @@ function createPaintWetTools(c) {
|
|
|
6760
6813
|
description: "Reads the wet media: whether any paint is still wet, the simulation clock (steps), whether time is paused, its speed (steps per second), the canvas tilt, the kernel running it (typescript, wasm, wasm-threads with the thread count, and a message when it runs slower than it could, e.g. without cross-origin isolation), and each wet layer: wet cells, where the water is (wetBounds), live tiles, its settings and flow map. Also engine: Engine B, the WebGPU accelerator (mode auto/off, state, reason, adapter, minTiles, activeTiles). Call it after wet strokes to see what is still wet.",
|
|
6761
6814
|
inputSchema: EMPTY2,
|
|
6762
6815
|
annotations: { title: "Get the wet paint", ...READ3 },
|
|
6816
|
+
coordinates: { out: ["layers[].wetBounds", "layers[].flow.center"] },
|
|
6763
6817
|
handler: () => c.wetState()
|
|
6764
6818
|
},
|
|
6765
6819
|
{
|
|
@@ -6786,6 +6840,7 @@ function createPaintWetTools(c) {
|
|
|
6786
6840
|
description: "Dries wet paint at once: everything settles where it is and the water goes, as a hair dryer at full blast would (the same deterministic bake that saving uses). On one layer or every wet layer, optionally only inside rect. Dried washes stay put: later washes glaze over them instead of mixing in. One undo step. Returns dried (each layer id with the rectangle that dried) and stillWet.",
|
|
6787
6841
|
inputSchema: { type: "object", properties: { layerId: { type: "string", description: "Only this layer (default every wet layer)." }, rect: RECT2 }, additionalProperties: false },
|
|
6788
6842
|
annotations: { title: "Dry the wet paint", ...WRITE3 },
|
|
6843
|
+
coordinates: { in: ["rect"], out: ["dried[].bounds"] },
|
|
6789
6844
|
handler: async ({ layerId, rect }) => {
|
|
6790
6845
|
await c.wetIdle();
|
|
6791
6846
|
return c.dryPaint({ layerId, rect });
|
|
@@ -6801,6 +6856,7 @@ function createPaintWetTools(c) {
|
|
|
6801
6856
|
additionalProperties: false
|
|
6802
6857
|
},
|
|
6803
6858
|
annotations: { title: "Pre-wet the paper", ...WRITE3 },
|
|
6859
|
+
coordinates: { in: ["rect"], out: ["rect"] },
|
|
6804
6860
|
handler: async ({ layerId, rect, amount }) => {
|
|
6805
6861
|
await c.wetIdle();
|
|
6806
6862
|
return c.wetPaper({ layerId, rect, amount });
|
|
@@ -6843,6 +6899,7 @@ function createPaintWetTools(c) {
|
|
|
6843
6899
|
additionalProperties: false
|
|
6844
6900
|
},
|
|
6845
6901
|
annotations: { title: "Set a flow map", ...SET2 },
|
|
6902
|
+
coordinates: { in: ["center"], out: ["flow.center"] },
|
|
6846
6903
|
handler: async ({ layerId, ...flow }) => {
|
|
6847
6904
|
await c.wetIdle();
|
|
6848
6905
|
return { layerId: _nullishCoalesce(layerId, () => ( c.document.activeLayerId)), flow: c.setFlowMap(layerId, flow), stillWet: stillWet() };
|
|
@@ -6943,6 +7000,7 @@ function createPaintThickTools(c) {
|
|
|
6943
7000
|
description: "Reads a layer\u2019s thick paint: where the relief is (bounds, layer pixels), its highest point (0..255) and the lighting. relief is null when the layer is flat. Changes nothing.",
|
|
6944
7001
|
inputSchema: { type: "object", properties: { layerId: LAYER_ID3 }, additionalProperties: false },
|
|
6945
7002
|
annotations: { title: "Read a layer\u2019s relief", ...READ4 },
|
|
7003
|
+
coordinates: { out: ["relief.bounds"] },
|
|
6946
7004
|
handler: ({ layerId }) => ({ relief: c.reliefOf(layerId), lighting: c.getLighting() })
|
|
6947
7005
|
},
|
|
6948
7006
|
{
|
|
@@ -7039,7 +7097,7 @@ var TIP = {
|
|
|
7039
7097
|
type: "object",
|
|
7040
7098
|
description: "The tip (the shared brush engine). Missing fields keep their current values.",
|
|
7041
7099
|
properties: {
|
|
7042
|
-
size: { type: "number", minimum: 1, maximum: _chunkEBDCRTZIcjs.MAX_BRUSH_SIZE, description: "Diameter in
|
|
7100
|
+
size: { type: "number", minimum: 1, maximum: _chunkEBDCRTZIcjs.MAX_BRUSH_SIZE, description: "Diameter in pixels." },
|
|
7043
7101
|
hardness: { type: "number", minimum: 0, maximum: 1, description: "Edge hardness, 0 (soft) .. 1 (hard)." },
|
|
7044
7102
|
spacing: { type: "number", minimum: 0.01, maximum: 10, description: "Dab spacing as a fraction of the diameter (0.05 is smooth, 1 is dotted)." },
|
|
7045
7103
|
angle: { type: "number", minimum: -360, maximum: 360, description: "Tip angle in degrees, counter-clockwise; with rotation stroke or barrel it is added to the stroke direction or pen rotation." },
|
|
@@ -7289,7 +7347,7 @@ function brushSummary(b) {
|
|
|
7289
7347
|
};
|
|
7290
7348
|
}
|
|
7291
7349
|
function createPaintEditorToolProvider(controller, options = {}) {
|
|
7292
|
-
const c = controller;
|
|
7350
|
+
const c = typeof controller === "function" ? lazyController(controller) : controller;
|
|
7293
7351
|
const tools = [];
|
|
7294
7352
|
const add = (t) => tools.push(t);
|
|
7295
7353
|
const act = async (command, direct) => {
|
|
@@ -7301,9 +7359,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7301
7359
|
add({
|
|
7302
7360
|
name: "get_canvas_info",
|
|
7303
7361
|
title: "Get the canvas",
|
|
7304
|
-
description: "Reads the canvas: size in pixels and dpi, its origin (where (0, 0) is relative to the canvas it was extended from), the paper (preset, colour, grain depth), the active layer, the active brush id, the paint colour, the view (zoom, rotation, mirror), the hand, how many strokes are recorded, the undo / redo labels, and the blend modes. Call it first.",
|
|
7362
|
+
description: "Reads the canvas: size in pixels and dpi, its origin (where (0, 0) is relative to the canvas it was extended from), bounds (the rectangle the painting covers, in the coordinates every other tool takes), the paper (preset, colour, grain depth), the active layer, the active brush id, the paint colour, the view (zoom, rotation, mirror), the hand, how many strokes are recorded, the undo / redo labels, and the blend modes. Call it first.",
|
|
7305
7363
|
inputSchema: EMPTY3,
|
|
7306
7364
|
annotations: { title: "Get the canvas", ...READ6 },
|
|
7365
|
+
coordinates: { out: ["bounds"] },
|
|
7307
7366
|
handler: () => {
|
|
7308
7367
|
const s = c.getState();
|
|
7309
7368
|
const d = s.document;
|
|
@@ -7312,6 +7371,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7312
7371
|
height: d.canvas.height,
|
|
7313
7372
|
dpi: d.canvas.dpi,
|
|
7314
7373
|
origin: { ..._nullishCoalesce(d.origin, () => ( { x: 0, y: 0 })) },
|
|
7374
|
+
bounds: { x: 0, y: 0, width: d.canvas.width, height: d.canvas.height },
|
|
7315
7375
|
paper: { preset: d.paper.preset, name: d.paper.name, color: d.paper.color, depth: d.paper.depth },
|
|
7316
7376
|
activeLayerId: d.activeLayerId,
|
|
7317
7377
|
layerCount: c.listLayers().length,
|
|
@@ -7440,6 +7500,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7440
7500
|
description: "Lists the layers top first: id, name, type (pixel or group), visibility, opacity, blend, clipping, locks, whether it is active, the painted bounds in document pixels (null when empty), parent and depth.",
|
|
7441
7501
|
inputSchema: EMPTY3,
|
|
7442
7502
|
annotations: { title: "List layers", ...READ6 },
|
|
7503
|
+
coordinates: { out: ["layers[].bounds"] },
|
|
7443
7504
|
handler: () => ({ layers: c.listLayers(), activeLayerId: c.document.activeLayerId })
|
|
7444
7505
|
});
|
|
7445
7506
|
add({
|
|
@@ -7457,6 +7518,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7457
7518
|
additionalProperties: false
|
|
7458
7519
|
},
|
|
7459
7520
|
annotations: { title: "Add a layer", ...WRITE5 },
|
|
7521
|
+
coordinates: { out: ["bounds"] },
|
|
7460
7522
|
handler: (a) => c.addLayer({ name: a.name, type: a.type, aboveId: a.aboveId, parentId: a.parentId })
|
|
7461
7523
|
});
|
|
7462
7524
|
add({
|
|
@@ -7492,6 +7554,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7492
7554
|
additionalProperties: false
|
|
7493
7555
|
},
|
|
7494
7556
|
annotations: { title: "Change a layer", ...SET4 },
|
|
7557
|
+
coordinates: { out: ["bounds"] },
|
|
7495
7558
|
handler: ({ layerId, ...u }) => c.updateLayer(layerId, u)
|
|
7496
7559
|
});
|
|
7497
7560
|
add({
|
|
@@ -7516,6 +7579,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7516
7579
|
description: "Makes a layer active: strokes, fills and clears without a layerId go to it. Editor state, not an undo step. Returns the layer.",
|
|
7517
7580
|
inputSchema: { type: "object", properties: { layerId: { type: "string", description: "Layer id from list_layers." } }, required: ["layerId"], additionalProperties: false },
|
|
7518
7581
|
annotations: { title: "Choose the active layer", ...SET4 },
|
|
7582
|
+
coordinates: { out: ["bounds"] },
|
|
7519
7583
|
handler: ({ layerId }) => {
|
|
7520
7584
|
c.setActiveLayer(layerId);
|
|
7521
7585
|
return c.describeLayer(c.getLayer(layerId));
|
|
@@ -7535,6 +7599,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7535
7599
|
description: "Copies a layer (a group with its children) directly above it; the copy becomes active. One undo step. Returns the copy.",
|
|
7536
7600
|
inputSchema: { type: "object", properties: { layerId: { type: "string", description: "Layer id from list_layers." } }, required: ["layerId"], additionalProperties: false },
|
|
7537
7601
|
annotations: { title: "Duplicate a layer", ...WRITE5 },
|
|
7602
|
+
coordinates: { out: ["bounds"] },
|
|
7538
7603
|
handler: ({ layerId }) => c.duplicateLayer(layerId)
|
|
7539
7604
|
});
|
|
7540
7605
|
add({
|
|
@@ -7552,6 +7617,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7552
7617
|
additionalProperties: false
|
|
7553
7618
|
},
|
|
7554
7619
|
annotations: { title: "Reorder a layer", ...WRITE5 },
|
|
7620
|
+
coordinates: { out: ["bounds"] },
|
|
7555
7621
|
handler: ({ layerId, index, parentId }) => c.moveLayer(layerId, index, parentId)
|
|
7556
7622
|
});
|
|
7557
7623
|
add({
|
|
@@ -7560,6 +7626,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7560
7626
|
description: "Merges a pixel layer into the pixel layer directly below it, which keeps its name, opacity and blend. One undo step. Returns the merged layer.",
|
|
7561
7627
|
inputSchema: { type: "object", properties: { layerId: { type: "string", description: "The upper layer, from list_layers." } }, required: ["layerId"], additionalProperties: false },
|
|
7562
7628
|
annotations: { title: "Merge a layer down", ...DESTRUCTIVE3 },
|
|
7629
|
+
coordinates: { out: ["bounds"] },
|
|
7563
7630
|
handler: ({ layerId }) => c.mergeDown(layerId)
|
|
7564
7631
|
});
|
|
7565
7632
|
add({
|
|
@@ -7579,6 +7646,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7579
7646
|
additionalProperties: false
|
|
7580
7647
|
},
|
|
7581
7648
|
annotations: { title: "Fill a layer", ...WRITE5 },
|
|
7649
|
+
coordinates: { out: ["bounds"] },
|
|
7582
7650
|
handler: (a) => act({ kind: "fill", fill: a }, () => c.fillLayer(a))
|
|
7583
7651
|
});
|
|
7584
7652
|
add({
|
|
@@ -7587,6 +7655,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7587
7655
|
description: "Removes every pixel of a pixel layer. One undo step. Returns the layer id and the bounds that were cleared (null if it was empty).",
|
|
7588
7656
|
inputSchema: { type: "object", properties: { layerId: LAYER_ID4 }, additionalProperties: false },
|
|
7589
7657
|
annotations: { title: "Clear a layer", ...DESTRUCTIVE3 },
|
|
7658
|
+
coordinates: { out: ["bounds"] },
|
|
7590
7659
|
handler: ({ layerId }) => c.clearLayer(layerId)
|
|
7591
7660
|
});
|
|
7592
7661
|
add({
|
|
@@ -7746,6 +7815,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7746
7815
|
additionalProperties: false
|
|
7747
7816
|
},
|
|
7748
7817
|
annotations: { title: "Pick a colour", ...READ6 },
|
|
7818
|
+
coordinates: { in: [""] },
|
|
7749
7819
|
handler: ({ x, y, layerId }) => c.pickColor(x, y, { layerId })
|
|
7750
7820
|
});
|
|
7751
7821
|
add({
|
|
@@ -7792,6 +7862,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7792
7862
|
additionalProperties: false
|
|
7793
7863
|
},
|
|
7794
7864
|
annotations: { title: "Paint a brush stroke", ...WRITE5 },
|
|
7865
|
+
coordinates: { in: ["points[]"], out: ["bounds"] },
|
|
7795
7866
|
handler: async (a) => {
|
|
7796
7867
|
await c.wetIdle();
|
|
7797
7868
|
const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, paint: a.paint, seed: a.seed, snapToPerspective: a.snapToPerspective };
|
|
@@ -7812,6 +7883,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7812
7883
|
additionalProperties: false
|
|
7813
7884
|
},
|
|
7814
7885
|
annotations: { title: "List recorded strokes", ...READ6 },
|
|
7886
|
+
coordinates: { out: ["strokes[].bounds", "strokes[].points[]"] },
|
|
7815
7887
|
handler: ({ ids, last }) => {
|
|
7816
7888
|
const all = c.getStrokes();
|
|
7817
7889
|
const picked = ids ? all.filter((s) => ids.includes(s.id)) : all.slice(-(_nullishCoalesce(last, () => ( 100))));
|
|
@@ -7869,6 +7941,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7869
7941
|
additionalProperties: false
|
|
7870
7942
|
},
|
|
7871
7943
|
annotations: { title: "Replay strokes, varied", ...WRITE5 },
|
|
7944
|
+
coordinates: { in: ["origin"], out: ["bounds"] },
|
|
7872
7945
|
handler: (a) => {
|
|
7873
7946
|
const replay = a;
|
|
7874
7947
|
return act({ kind: "replay", replay }, () => c.replayStrokes(replay));
|
|
@@ -7985,15 +8058,33 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7985
8058
|
tools.push(...createPaintReplayTools(c));
|
|
7986
8059
|
tools.push(...createPaintStickerTools(c));
|
|
7987
8060
|
tools.push(..._chunkV7GWZIZKcjs.createPigmentTools.call(void 0, ));
|
|
8061
|
+
const exclude = new Set(_nullishCoalesce(options.exclude, () => ( [])));
|
|
8062
|
+
const description = "Natural-media painting: paper and grain, dry and wet brushes, the brush library, strokes as data, pigment mixing, stencils, guides, layers and export.";
|
|
7988
8063
|
return withPaintPlayback({
|
|
7989
8064
|
id: _nullishCoalesce(options.id, () => ( "paint-editor")),
|
|
7990
8065
|
namespace: options.namespace,
|
|
7991
8066
|
title: "Paint editor",
|
|
7992
|
-
description:
|
|
8067
|
+
description: options.origin ? `${description} It is a layer of a larger canvas: every position is in canvas coordinates.` : description,
|
|
7993
8068
|
skill: "pixerate-paint-editor",
|
|
7994
|
-
tools
|
|
8069
|
+
tools: tools.filter((t) => !exclude.has(t.name)).map((t) => hostTool(t, options))
|
|
7995
8070
|
}, { director: !!options.director, surface: options.playbackSurface });
|
|
7996
8071
|
}
|
|
8072
|
+
function hostTool({ coordinates, ...tool }, { origin, onChange }) {
|
|
8073
|
+
if (!origin && !onChange) return tool;
|
|
8074
|
+
const write = !_optionalChain([tool, 'access', _320 => _320.annotations, 'optionalAccess', _321 => _321.readOnlyHint]);
|
|
8075
|
+
const done = (result) => {
|
|
8076
|
+
if (write) _optionalChain([onChange, 'optionalCall', _322 => _322({ tool: tool.name })]);
|
|
8077
|
+
return origin && _optionalChain([coordinates, 'optionalAccess', _323 => _323.out]) ? fromDocument(result, coordinates.out, origin) : result;
|
|
8078
|
+
};
|
|
8079
|
+
return {
|
|
8080
|
+
...tool,
|
|
8081
|
+
...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
|
|
8082
|
+
handler: (args, context) => {
|
|
8083
|
+
const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _324 => _324.in]) ? toDocument(args, coordinates.in, origin) : args, context);
|
|
8084
|
+
return r instanceof Promise ? r.then(done) : done(r);
|
|
8085
|
+
}
|
|
8086
|
+
};
|
|
8087
|
+
}
|
|
7997
8088
|
|
|
7998
8089
|
// src/paint-editor/ui.ts
|
|
7999
8090
|
var PAINT_TOOLS = [
|
|
@@ -8097,12 +8188,12 @@ var PaintGesture = (_class11 = class {
|
|
|
8097
8188
|
if (!m || m.pointerId !== e.pointerId) return;
|
|
8098
8189
|
this.mode = null;
|
|
8099
8190
|
this.predicted = [];
|
|
8100
|
-
if (m.kind === "stroke") _optionalChain([this, 'access',
|
|
8191
|
+
if (m.kind === "stroke") _optionalChain([this, 'access', _325 => _325.controller, 'access', _326 => _326.activeStroke, 'optionalAccess', _327 => _327.end, 'call', _328 => _328()]);
|
|
8101
8192
|
}
|
|
8102
8193
|
cancel() {
|
|
8103
8194
|
this.penDown = false;
|
|
8104
8195
|
this.predicted = [];
|
|
8105
|
-
if (_optionalChain([this, 'access',
|
|
8196
|
+
if (_optionalChain([this, 'access', _329 => _329.mode, 'optionalAccess', _330 => _330.kind]) === "stroke") _optionalChain([this, 'access', _331 => _331.controller, 'access', _332 => _332.activeStroke, 'optionalAccess', _333 => _333.cancel, 'call', _334 => _334()]);
|
|
8106
8197
|
this.mode = null;
|
|
8107
8198
|
}
|
|
8108
8199
|
get active() {
|
|
@@ -8236,7 +8327,7 @@ var PAPER_SLIDERS = [
|
|
|
8236
8327
|
];
|
|
8237
8328
|
function readPath(obj, path) {
|
|
8238
8329
|
let v = obj;
|
|
8239
|
-
for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess',
|
|
8330
|
+
for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _335 => _335[k]]);
|
|
8240
8331
|
return typeof v === "number" ? v : 0;
|
|
8241
8332
|
}
|
|
8242
8333
|
function patchPath(obj, path, value) {
|
|
@@ -8358,7 +8449,7 @@ function brushEngineControls(brush) {
|
|
|
8358
8449
|
impastoTool: true
|
|
8359
8450
|
};
|
|
8360
8451
|
case "wet": {
|
|
8361
|
-
const tool = _nullishCoalesce(_optionalChain([brush, 'access',
|
|
8452
|
+
const tool = _nullishCoalesce(_optionalChain([brush, 'access', _336 => _336.wet, 'optionalAccess', _337 => _337.tool]), () => ( "paint"));
|
|
8362
8453
|
const sliders = tool === "paint" ? [
|
|
8363
8454
|
{ path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
|
|
8364
8455
|
{ path: "wet.pigment", label: "Pigment", min: 0, max: 1, step: 0.01 },
|
|
@@ -8491,7 +8582,7 @@ function startWetClock(controller, frame, cancel) {
|
|
|
8491
8582
|
id = raf(loop);
|
|
8492
8583
|
return () => {
|
|
8493
8584
|
stopped = true;
|
|
8494
|
-
_optionalChain([caf, 'optionalCall',
|
|
8585
|
+
_optionalChain([caf, 'optionalCall', _338 => _338(id)]);
|
|
8495
8586
|
};
|
|
8496
8587
|
}
|
|
8497
8588
|
function drawWaterOverlay(controller, ctx) {
|
|
@@ -26,6 +26,7 @@ export * from './mixing-pad.cjs';
|
|
|
26
26
|
export * from './controller.cjs';
|
|
27
27
|
export * from './presence.cjs';
|
|
28
28
|
export * from './tools.cjs';
|
|
29
|
+
export type { PaintAgentTool, PaintOrigin, PaintToolCoordinates } from './hosted.cjs';
|
|
29
30
|
export * from './ui.cjs';
|
|
30
31
|
export { BLEND_MODES, PAINTERLY_BLEND_MODES, isBlendMode, isPainterlyBlendMode, standardBlendMode, type BlendMode, type BlendModeInfo } from '../raster/blend.cjs';
|
|
31
32
|
export * from './wet.cjs';
|
|
@@ -26,6 +26,7 @@ export * from './mixing-pad.js';
|
|
|
26
26
|
export * from './controller.js';
|
|
27
27
|
export * from './presence.js';
|
|
28
28
|
export * from './tools.js';
|
|
29
|
+
export type { PaintAgentTool, PaintOrigin, PaintToolCoordinates } from './hosted.js';
|
|
29
30
|
export * from './ui.js';
|
|
30
31
|
export { BLEND_MODES, PAINTERLY_BLEND_MODES, isBlendMode, isPainterlyBlendMode, standardBlendMode, type BlendMode, type BlendModeInfo } from '../raster/blend.js';
|
|
31
32
|
export * from './wet.js';
|