@pixerate/editor 0.107.0 → 0.109.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/THIRD_PARTY_NOTICES.md +4 -0
- package/dist/animation/index.cjs +5 -5
- package/dist/animation/index.cjs.map +1 -1
- package/dist/animation/index.js +9 -9
- package/dist/animation-editor/index.cjs +59 -59
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +2 -1
- package/dist/animation-editor/index.d.ts +2 -1
- package/dist/animation-editor/index.js +29 -29
- package/dist/canvas/index.cjs +27 -27
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +11 -11
- package/dist/{chunk-2FGRTYJN.cjs → chunk-477UVMNR.cjs} +3 -3
- package/dist/{chunk-2FGRTYJN.cjs.map → chunk-477UVMNR.cjs.map} +1 -1
- package/dist/{chunk-T3QZ6S47.cjs → chunk-AZTZRLDI.cjs} +40 -2
- package/dist/chunk-AZTZRLDI.cjs.map +1 -0
- package/dist/{chunk-63EFQCT5.js → chunk-BLWCAQCW.js} +2879 -3362
- package/dist/chunk-BLWCAQCW.js.map +1 -0
- package/dist/{chunk-G4BIYE6R.js → chunk-CFMWALBM.js} +39 -1
- package/dist/chunk-CFMWALBM.js.map +1 -0
- package/dist/{chunk-FRD3FUXI.cjs → chunk-D37BX2ZA.cjs} +2081 -460
- package/dist/chunk-D37BX2ZA.cjs.map +1 -0
- package/dist/chunk-JLYX4V57.cjs +2001 -0
- package/dist/chunk-JLYX4V57.cjs.map +1 -0
- package/dist/chunk-KB2YBCVS.js +2001 -0
- package/dist/chunk-KB2YBCVS.js.map +1 -0
- package/dist/{chunk-SOROZ2BF.js → chunk-RE77QYUF.js} +1938 -317
- package/dist/chunk-RE77QYUF.js.map +1 -0
- package/dist/{chunk-KANRAHTL.cjs → chunk-W3GXSUSQ.cjs} +2830 -3313
- package/dist/chunk-W3GXSUSQ.cjs.map +1 -0
- package/dist/{chunk-JK6M6V7G.js → chunk-Z3YWVUWT.js} +4 -4
- package/dist/{export-a9bnF7Cl.d.ts → export-BLPLaE6Z.d.ts} +417 -16
- package/dist/{export-JGWQEPJn.d.cts → export-DSUc4fQD.d.cts} +417 -16
- package/dist/image-editor/index.cjs +1527 -1001
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +73 -9
- package/dist/image-editor/index.d.ts +73 -9
- package/dist/image-editor/index.js +814 -288
- package/dist/image-editor/index.js.map +1 -1
- package/dist/paint-editor/index.cjs +252 -64
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +101 -4
- package/dist/paint-editor/index.d.ts +101 -4
- package/dist/paint-editor/index.js +196 -8
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +4 -2
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +3 -129
- package/dist/raster/index.d.ts +3 -129
- package/dist/raster/index.js +3 -1
- package/dist/{compositor-D92URMlm.d.cts → render-C-fO_mes.d.cts} +135 -1
- package/dist/{compositor-Kt_M4ruo.d.ts → render-OLIMk_v0.d.ts} +135 -1
- package/dist/{svg-vme0PLNo.d.ts → svg-D_cfkhlB.d.cts} +6 -608
- package/dist/{svg-Bj1MQFh6.d.cts → svg-wIaKLrU0.d.ts} +6 -608
- package/dist/types-DtL_qLFz.d.ts +630 -0
- package/dist/types-DyQq-WPY.d.cts +630 -0
- package/dist/vector/index.cjs +1080 -1051
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +268 -7
- package/dist/vector/index.d.ts +268 -7
- package/dist/vector/index.js +495 -466
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.cjs +3 -3
- package/dist/video-editor/index.js +2 -2
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +50 -7
- package/skills/pixerate-vector/SKILL.md +35 -5
- package/dist/chunk-63EFQCT5.js.map +0 -1
- package/dist/chunk-DWGZUSES.cjs +0 -694
- package/dist/chunk-DWGZUSES.cjs.map +0 -1
- package/dist/chunk-FRD3FUXI.cjs.map +0 -1
- package/dist/chunk-G4BIYE6R.js.map +0 -1
- package/dist/chunk-KANRAHTL.cjs.map +0 -1
- package/dist/chunk-KKREERP2.js +0 -694
- package/dist/chunk-KKREERP2.js.map +0 -1
- package/dist/chunk-SOROZ2BF.js.map +0 -1
- package/dist/chunk-T3QZ6S47.cjs.map +0 -1
- /package/dist/{chunk-JK6M6V7G.js.map → chunk-Z3YWVUWT.js.map} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkD37BX2ZAcjs = require('../chunk-D37BX2ZA.cjs');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ var _chunkFRD3FUXIcjs = require('../chunk-FRD3FUXI.cjs');
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
var
|
|
20
|
+
var _chunkAZTZRLDIcjs = require('../chunk-AZTZRLDI.cjs');
|
|
21
21
|
require('../chunk-MUUXNRU4.cjs');
|
|
22
22
|
|
|
23
23
|
|
|
@@ -54,7 +54,16 @@ var _chunkHUFQD4CBcjs = require('../chunk-HUFQD4CB.cjs');
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
var _chunkSZ6KMZNMcjs = require('../chunk-SZ6KMZNM.cjs');
|
|
57
|
-
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
var _chunkEGFUVXKKcjs = require('../chunk-EGFUVXKK.cjs');
|
|
63
|
+
require('../chunk-W3GXSUSQ.cjs');
|
|
64
|
+
require('../chunk-XGD3FSNC.cjs');
|
|
65
|
+
require('../chunk-MR3Z4OQI.cjs');
|
|
66
|
+
require('../chunk-A6PHCAGX.cjs');
|
|
58
67
|
|
|
59
68
|
// src/paint-editor/noise.ts
|
|
60
69
|
function mix32(h) {
|
|
@@ -1268,7 +1277,7 @@ var PROFILE = {
|
|
|
1268
1277
|
}
|
|
1269
1278
|
};
|
|
1270
1279
|
function createPaintCompositor() {
|
|
1271
|
-
return new (0,
|
|
1280
|
+
return new (0, _chunkAZTZRLDIcjs.RasterCompositor)(PROFILE);
|
|
1272
1281
|
}
|
|
1273
1282
|
function downsampleRgba(data, width, height, tw, th) {
|
|
1274
1283
|
tw = Math.max(1, Math.round(tw));
|
|
@@ -1339,11 +1348,11 @@ function header(state, options) {
|
|
|
1339
1348
|
return out;
|
|
1340
1349
|
}
|
|
1341
1350
|
function serializePaintDocument(state, options = {}) {
|
|
1342
|
-
const { layers, assets } =
|
|
1351
|
+
const { layers, assets } = _chunkD37BX2ZAcjs.serializeLayers.call(void 0, state.layers);
|
|
1343
1352
|
return { ...header(state, options), layers, assets };
|
|
1344
1353
|
}
|
|
1345
1354
|
async function serializePaintDocumentExternal(state, store, options = {}) {
|
|
1346
|
-
const { layers, assets } = await
|
|
1355
|
+
const { layers, assets } = await _chunkD37BX2ZAcjs.serializeLayersExternal.call(void 0, state.layers, store);
|
|
1347
1356
|
return { ...header(state, options), layers, assets };
|
|
1348
1357
|
}
|
|
1349
1358
|
function paintLayersOnly(layers, problems) {
|
|
@@ -1380,16 +1389,16 @@ function deserializePaintDocument(raw) {
|
|
|
1380
1389
|
const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
|
|
1381
1390
|
const paper = normalizePaper(_nullishCoalesce(r.paper, () => ( {})));
|
|
1382
1391
|
const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
|
|
1383
|
-
const layers = paintLayersOnly(
|
|
1392
|
+
const layers = paintLayersOnly(_chunkD37BX2ZAcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
|
|
1384
1393
|
const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
|
|
1385
|
-
const activeLayerId = wanted &&
|
|
1394
|
+
const activeLayerId = wanted && _chunkAZTZRLDIcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.flattenLayers.call(void 0, layers), 'access', _25 => _25.filter, 'call', _26 => _26((l) => l.type === "pixel"), 'access', _27 => _27.pop, 'call', _28 => _28(), 'optionalAccess', _29 => _29.id]), () => ( null));
|
|
1386
1395
|
return { state: { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) }, extensions: documentExtensions(r), guides: r.guides, swatches: r.swatches, problems };
|
|
1387
1396
|
}
|
|
1388
1397
|
async function deserializePaintDocumentAsync(raw, store) {
|
|
1389
1398
|
if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
|
|
1390
1399
|
const r = raw;
|
|
1391
1400
|
const problems = [];
|
|
1392
|
-
const assets = await
|
|
1401
|
+
const assets = await _chunkD37BX2ZAcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
|
|
1393
1402
|
const loaded = deserializePaintDocument({ ...r, assets });
|
|
1394
1403
|
return { ...loaded, problems: [...problems, ...loaded.problems] };
|
|
1395
1404
|
}
|
|
@@ -2207,7 +2216,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2207
2216
|
}
|
|
2208
2217
|
// --- Layers --------------------------------------------------------------------
|
|
2209
2218
|
getLayer(id) {
|
|
2210
|
-
return _optionalChain([
|
|
2219
|
+
return _optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _35 => _35.layer]);
|
|
2211
2220
|
}
|
|
2212
2221
|
/** The active pixel layer (or `undefined`). */
|
|
2213
2222
|
getActiveLayer() {
|
|
@@ -2226,12 +2235,12 @@ var PaintEditorController = (_class9 = class {
|
|
|
2226
2235
|
walk(this.doc.layers, null, 0);
|
|
2227
2236
|
return out;
|
|
2228
2237
|
}
|
|
2229
|
-
describeLayer(l, parentId = _nullishCoalesce(_optionalChain([
|
|
2238
|
+
describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _36 => _36.parent, 'optionalAccess', _37 => _37.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _38 => _38.path, 'access', _39 => _39.length]), () => ( 0))) {
|
|
2230
2239
|
let bounds = null;
|
|
2231
2240
|
if (l.type === "pixel") {
|
|
2232
2241
|
const b = _chunkSZ6KMZNMcjs.contentBounds.call(void 0, l.surface);
|
|
2233
2242
|
bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;
|
|
2234
|
-
} else for (const c of
|
|
2243
|
+
} else for (const c of _chunkAZTZRLDIcjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
|
|
2235
2244
|
return {
|
|
2236
2245
|
id: l.id,
|
|
2237
2246
|
name: l.name,
|
|
@@ -2258,7 +2267,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2258
2267
|
if (!id) throw new PaintEditorError(`There is no active layer to ${what}; add one with add_layer.`);
|
|
2259
2268
|
const l = this.requireLayer(id);
|
|
2260
2269
|
if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; ${what} a pixel layer inside it.`);
|
|
2261
|
-
if (
|
|
2270
|
+
if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
|
|
2262
2271
|
if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) before you ${what} it.`);
|
|
2263
2272
|
return l;
|
|
2264
2273
|
}
|
|
@@ -2271,7 +2280,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2271
2280
|
/** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */
|
|
2272
2281
|
addLayer(options = {}) {
|
|
2273
2282
|
this.requireIdle("adding a layer");
|
|
2274
|
-
const count =
|
|
2283
|
+
const count = _chunkAZTZRLDIcjs.flattenLayers.call(void 0, this.doc.layers).length;
|
|
2275
2284
|
const type = _nullishCoalesce(options.type, () => ( "pixel"));
|
|
2276
2285
|
const name = _optionalChain([options, 'access', _40 => _40.name, 'optionalAccess', _41 => _41.trim, 'call', _42 => _42()]) || (type === "group" ? `Group ${count + 1}` : `Layer ${count + 1}`);
|
|
2277
2286
|
const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
|
|
@@ -2283,19 +2292,19 @@ var PaintEditorController = (_class9 = class {
|
|
|
2283
2292
|
if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
|
|
2284
2293
|
parentId = g.id;
|
|
2285
2294
|
} else if (above) {
|
|
2286
|
-
const loc =
|
|
2295
|
+
const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, above);
|
|
2287
2296
|
if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
|
|
2288
2297
|
parentId = _nullishCoalesce(_optionalChain([loc, 'access', _43 => _43.parent, 'optionalAccess', _44 => _44.id]), () => ( null));
|
|
2289
2298
|
index = loc.index + 1;
|
|
2290
2299
|
}
|
|
2291
|
-
const layers =
|
|
2300
|
+
const layers = _chunkAZTZRLDIcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
|
|
2292
2301
|
this.commit(type === "group" ? "Add group" : "Add layer", { ...this.doc, layers, activeLayerId: layer.id });
|
|
2293
2302
|
return this.describeLayer(layer);
|
|
2294
2303
|
}
|
|
2295
2304
|
updateLayer(id, update) {
|
|
2296
2305
|
this.requireIdle("changing a layer");
|
|
2297
2306
|
const l = this.requireLayer(id);
|
|
2298
|
-
if (
|
|
2307
|
+
if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
|
|
2299
2308
|
if (update.opacity !== void 0 && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);
|
|
2300
2309
|
if (update.blend !== void 0 && !_chunkSZ6KMZNMcjs.isBlendMode.call(void 0, update.blend) && !(l.type === "group" && update.blend === "pass-through")) {
|
|
2301
2310
|
throw new PaintEditorError(`Unknown blend mode "${update.blend}". Call get_canvas_info for the blend modes.`);
|
|
@@ -2311,57 +2320,57 @@ var PaintEditorController = (_class9 = class {
|
|
|
2311
2320
|
const locks = { ..._nullishCoalesce(l.locks, () => ( {})), ...update.locks };
|
|
2312
2321
|
next.locks = Object.values(locks).some(Boolean) ? locks : void 0;
|
|
2313
2322
|
}
|
|
2314
|
-
this.commit("Layer properties", { ...this.doc, layers:
|
|
2323
|
+
this.commit("Layer properties", { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
|
|
2315
2324
|
return this.describeLayer(next);
|
|
2316
2325
|
}
|
|
2317
2326
|
removeLayer(id) {
|
|
2318
2327
|
this.requireIdle("removing a layer");
|
|
2319
2328
|
const l = this.requireLayer(id);
|
|
2320
|
-
if (
|
|
2321
|
-
const layers =
|
|
2329
|
+
if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
|
|
2330
|
+
const layers = _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
|
|
2322
2331
|
let active = this.doc.activeLayerId;
|
|
2323
|
-
if (active && !
|
|
2332
|
+
if (active && !_chunkAZTZRLDIcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.flattenLayers.call(void 0, layers), 'access', _45 => _45.filter, 'call', _46 => _46((x) => x.type === "pixel"), 'access', _47 => _47.pop, 'call', _48 => _48(), 'optionalAccess', _49 => _49.id]), () => ( null));
|
|
2324
2333
|
this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active });
|
|
2325
2334
|
return { removed: id, activeLayerId: active };
|
|
2326
2335
|
}
|
|
2327
2336
|
duplicateLayer(id) {
|
|
2328
2337
|
this.requireIdle("duplicating a layer");
|
|
2329
|
-
const loc =
|
|
2338
|
+
const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id);
|
|
2330
2339
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
2331
2340
|
const copy = (l) => l.type === "group" ? { ...l, id: newPaintLayerId(), children: l.children.map(copy) } : { ...l, id: newPaintLayerId() };
|
|
2332
2341
|
const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
|
|
2333
|
-
const layers =
|
|
2342
|
+
const layers = _chunkAZTZRLDIcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _50 => _50.parent, 'optionalAccess', _51 => _51.id]), () => ( null)), loc.index + 1);
|
|
2334
2343
|
this.commit("Duplicate layer", { ...this.doc, layers, activeLayerId: dup.id });
|
|
2335
2344
|
return this.describeLayer(dup);
|
|
2336
2345
|
}
|
|
2337
2346
|
/** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */
|
|
2338
2347
|
moveLayer(id, index, parentId) {
|
|
2339
2348
|
this.requireIdle("moving a layer");
|
|
2340
|
-
const loc =
|
|
2349
|
+
const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id);
|
|
2341
2350
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
2342
2351
|
const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _52 => _52.parent, 'optionalAccess', _53 => _53.id]), () => ( null)) : parentId;
|
|
2343
2352
|
if (target) {
|
|
2344
2353
|
const g = this.requireLayer(target);
|
|
2345
2354
|
if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
|
|
2346
|
-
if (target === id || loc.layer.type === "group" &&
|
|
2355
|
+
if (target === id || loc.layer.type === "group" && _chunkAZTZRLDIcjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
|
|
2347
2356
|
}
|
|
2348
|
-
const without =
|
|
2349
|
-
const siblings = target ?
|
|
2357
|
+
const without = _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
|
|
2358
|
+
const siblings = target ? _chunkAZTZRLDIcjs.findLayer.call(void 0, without, target).layer.children : without;
|
|
2350
2359
|
if (!Number.isInteger(index) || index < 0 || index > siblings.length) throw new PaintEditorError(`index ${index} is out of range; use 0..${siblings.length} (0 is the bottom).`);
|
|
2351
|
-
const layers =
|
|
2360
|
+
const layers = _chunkAZTZRLDIcjs.insertLayer.call(void 0, without, loc.layer, target, index);
|
|
2352
2361
|
this.commit("Move layer", { ...this.doc, layers });
|
|
2353
2362
|
return this.describeLayer(loc.layer);
|
|
2354
2363
|
}
|
|
2355
2364
|
/** Merges a pixel layer into the pixel layer below it (keeping the lower one's settings). */
|
|
2356
2365
|
mergeDown(id) {
|
|
2357
2366
|
this.requireIdle("merging");
|
|
2358
|
-
const loc =
|
|
2367
|
+
const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id);
|
|
2359
2368
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
2360
2369
|
const siblings = loc.parent ? loc.parent.children : this.doc.layers;
|
|
2361
2370
|
const below = siblings[loc.index - 1];
|
|
2362
2371
|
const upper = loc.layer;
|
|
2363
2372
|
if (!isPixelLayer(upper) || !isPixelLayer(below)) throw new PaintEditorError("Merge down needs a pixel layer directly above another pixel layer in the same group.");
|
|
2364
|
-
if (
|
|
2373
|
+
if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
|
|
2365
2374
|
const rect = unionRect(this.describeLayer(below).bounds, this.describeLayer(upper).bounds);
|
|
2366
2375
|
let surface = _chunkSZ6KMZNMcjs.emptySurface.call(void 0, 4);
|
|
2367
2376
|
if (rect) {
|
|
@@ -2370,7 +2379,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2370
2379
|
surface = _chunkSZ6KMZNMcjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data: px }, 4, rect.x, rect.y);
|
|
2371
2380
|
}
|
|
2372
2381
|
const merged = { ...below, surface, offset: { x: 0, y: 0 } };
|
|
2373
|
-
const layers =
|
|
2382
|
+
const layers = _chunkAZTZRLDIcjs.mapLayer.call(void 0, _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
|
|
2374
2383
|
this.commit("Merge down", { ...this.doc, layers, activeLayerId: below.id });
|
|
2375
2384
|
return this.describeLayer(merged);
|
|
2376
2385
|
}
|
|
@@ -2379,7 +2388,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2379
2388
|
this.requireIdle("clearing");
|
|
2380
2389
|
const l = this.paintTarget(layerId, "clear");
|
|
2381
2390
|
const bounds = this.describeLayer(l).bounds;
|
|
2382
|
-
this.commit("Clear layer", { ...this.doc, layers:
|
|
2391
|
+
this.commit("Clear layer", { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunkSZ6KMZNMcjs.emptySurface.call(void 0, 4) })) });
|
|
2383
2392
|
return { layerId: l.id, bounds };
|
|
2384
2393
|
}
|
|
2385
2394
|
/**
|
|
@@ -2414,12 +2423,12 @@ var PaintEditorController = (_class9 = class {
|
|
|
2414
2423
|
background: rgbaOf(this.doc.paper.color),
|
|
2415
2424
|
opacity,
|
|
2416
2425
|
blend,
|
|
2417
|
-
lockTransparency:
|
|
2426
|
+
lockTransparency: _chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "transparency"),
|
|
2418
2427
|
selection: null,
|
|
2419
2428
|
offset: l.offset
|
|
2420
2429
|
};
|
|
2421
2430
|
const surface = this.applyCoverage(l, coverage, rect, apply);
|
|
2422
|
-
this.commit("Fill layer", { ...this.doc, layers:
|
|
2431
|
+
this.commit("Fill layer", { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })) });
|
|
2423
2432
|
return { layerId: l.id, bounds: rect };
|
|
2424
2433
|
}
|
|
2425
2434
|
applyCoverage(l, coverage, rect, apply) {
|
|
@@ -2602,11 +2611,11 @@ var PaintEditorController = (_class9 = class {
|
|
|
2602
2611
|
const layer = (() => {
|
|
2603
2612
|
const id = _nullishCoalesce(init.layerId, () => ( doc.activeLayerId));
|
|
2604
2613
|
if (!id) throw new PaintEditorError("There is no active layer to paint on; add one with add_layer.");
|
|
2605
|
-
const loc =
|
|
2614
|
+
const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, doc.layers, id);
|
|
2606
2615
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
2607
2616
|
const l = loc.layer;
|
|
2608
2617
|
if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; paint on a pixel layer inside it.`);
|
|
2609
|
-
if (
|
|
2618
|
+
if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
|
|
2610
2619
|
if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) to paint on it.`);
|
|
2611
2620
|
return l;
|
|
2612
2621
|
})();
|
|
@@ -2623,7 +2632,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2623
2632
|
layerId: layer.id,
|
|
2624
2633
|
surface: layer.surface,
|
|
2625
2634
|
offset: layer.offset,
|
|
2626
|
-
lockTransparency:
|
|
2635
|
+
lockTransparency: _chunkAZTZRLDIcjs.isLayerLocked.call(void 0, layer, "transparency"),
|
|
2627
2636
|
brush,
|
|
2628
2637
|
color: rgba,
|
|
2629
2638
|
background: rgbaOf(doc.paper.color),
|
|
@@ -2675,7 +2684,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2675
2684
|
const stroke = this.record(s);
|
|
2676
2685
|
s.result.strokeId = stroke.id;
|
|
2677
2686
|
const l = this.getLayer(s.layerId);
|
|
2678
|
-
this.commit(`${brush.name} stroke`, { ...this.doc, layers:
|
|
2687
|
+
this.commit(`${brush.name} stroke`, { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke] });
|
|
2679
2688
|
}
|
|
2680
2689
|
};
|
|
2681
2690
|
const session = this.sessionFor(this.doc, { snapToPerspective: true, ...init }, host);
|
|
@@ -2697,8 +2706,8 @@ var PaintEditorController = (_class9 = class {
|
|
|
2697
2706
|
if (cancelled || !surface) return;
|
|
2698
2707
|
const stroke = this.record(s);
|
|
2699
2708
|
s.result.strokeId = stroke.id;
|
|
2700
|
-
const l =
|
|
2701
|
-
out = { ...out, layers:
|
|
2709
|
+
const l = _chunkAZTZRLDIcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
|
|
2710
|
+
out = { ...out, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface })), strokes: [...out.strokes, stroke] };
|
|
2702
2711
|
}
|
|
2703
2712
|
};
|
|
2704
2713
|
const session = this.sessionFor(doc, init, host);
|
|
@@ -2716,6 +2725,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2716
2725
|
else this.emit([]);
|
|
2717
2726
|
return result;
|
|
2718
2727
|
}
|
|
2728
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
2719
2729
|
checkPoints(points) {
|
|
2720
2730
|
if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
|
|
2721
2731
|
const out = [];
|
|
@@ -2769,7 +2779,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2769
2779
|
brush = normalizePaintBrush({ tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
|
|
2770
2780
|
}
|
|
2771
2781
|
const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
|
|
2772
|
-
if (!
|
|
2782
|
+
if (!_chunkAZTZRLDIcjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
|
|
2773
2783
|
const run = this.runStroke(doc, { layerId, color: _nullishCoalesce(options.color, () => ( s.color)), brush, seed: s.seed, copies: _nullishCoalesce(v.copies, () => ( [])) }, v.points);
|
|
2774
2784
|
doc = run.doc;
|
|
2775
2785
|
bounds = unionRect(bounds, run.result.bounds);
|
|
@@ -2789,7 +2799,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2789
2799
|
const live = this.live;
|
|
2790
2800
|
if (!live) return this.doc.layers;
|
|
2791
2801
|
if (_optionalChain([this, 'access', _63 => _63.liveLayers, 'optionalAccess', _64 => _64.key]) === live.surface) return this.liveLayers.layers;
|
|
2792
|
-
const layers =
|
|
2802
|
+
const layers = _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
|
|
2793
2803
|
this.liveLayers = { key: live.surface, layers };
|
|
2794
2804
|
return layers;
|
|
2795
2805
|
}
|
|
@@ -2893,7 +2903,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2893
2903
|
/** The canvas as PNG bytes (paper included by default; `scale` below 1 shrinks it). */
|
|
2894
2904
|
exportPng(options = {}) {
|
|
2895
2905
|
const img = this.scaled(options);
|
|
2896
|
-
return
|
|
2906
|
+
return _chunkAZTZRLDIcjs.encodePng.call(void 0, img.width, img.height, img.data);
|
|
2897
2907
|
}
|
|
2898
2908
|
scaled(options) {
|
|
2899
2909
|
const full = this.compositePixels(options);
|
|
@@ -2947,7 +2957,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2947
2957
|
return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
|
|
2948
2958
|
});
|
|
2949
2959
|
const layers = toStandard(this.doc.layers);
|
|
2950
|
-
const result =
|
|
2960
|
+
const result = _chunkD37BX2ZAcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
|
|
2951
2961
|
for (const [mode, names] of changed) {
|
|
2952
2962
|
const label = _nullishCoalesce(_optionalChain([_chunkSZ6KMZNMcjs.BLEND_MODES, 'access', _72 => _72.find, 'call', _73 => _73((m) => m.id === mode), 'optionalAccess', _74 => _74.label]), () => ( mode));
|
|
2953
2963
|
const std = _nullishCoalesce(_optionalChain([_chunkSZ6KMZNMcjs.BLEND_MODES, 'access', _75 => _75.find, 'call', _76 => _76((m) => m.id === _chunkSZ6KMZNMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _77 => _77.label]), () => ( _chunkSZ6KMZNMcjs.standardBlendMode.call(void 0, mode)));
|
|
@@ -2960,7 +2970,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
2960
2970
|
/** `render_preview` as a base64 PNG. */
|
|
2961
2971
|
previewPngBase64(options = {}) {
|
|
2962
2972
|
const img = this.renderPreview(options);
|
|
2963
|
-
return { data:
|
|
2973
|
+
return { data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, _chunkAZTZRLDIcjs.encodePng.call(void 0, img.width, img.height, img.data)), width: img.width, height: img.height };
|
|
2964
2974
|
}
|
|
2965
2975
|
// --- Guides --------------------------------------------------------------------
|
|
2966
2976
|
setGuides(next) {
|
|
@@ -2998,17 +3008,17 @@ var PaintEditorController = (_class9 = class {
|
|
|
2998
3008
|
pixels = this.decodeImage(input.png.trim().startsWith("data:") ? input.png.trim() : `data:image/png;base64,${input.png.trim()}`, what);
|
|
2999
3009
|
} else throw new PaintEditorError(`${what}: pass png (a PNG as base64 or a data URL) or pixels.`);
|
|
3000
3010
|
if (pixels.width > MAX_IMAGE_SIDE || pixels.height > MAX_IMAGE_SIDE) throw new PaintEditorError(`${what} is ${pixels.width}\xD7${pixels.height}; the limit is ${MAX_IMAGE_SIDE} px per side.`);
|
|
3001
|
-
const src =
|
|
3011
|
+
const src = _chunkAZTZRLDIcjs.pngDataUrl.call(void 0, pixels.width, pixels.height, pixels.data);
|
|
3002
3012
|
this.imagePixels.set(src, pixels);
|
|
3003
3013
|
return { src, pixels };
|
|
3004
3014
|
}
|
|
3005
3015
|
decodeImage(src, what = "Image") {
|
|
3006
3016
|
const cached = this.imagePixels.get(src);
|
|
3007
3017
|
if (cached) return cached;
|
|
3008
|
-
const parsed =
|
|
3018
|
+
const parsed = _chunkAZTZRLDIcjs.parseDataUrl.call(void 0, src);
|
|
3009
3019
|
if (!parsed) throw new PaintEditorError(`${what} is not a data URL or base64 PNG.`);
|
|
3010
3020
|
try {
|
|
3011
|
-
const png =
|
|
3021
|
+
const png = _chunkAZTZRLDIcjs.decodePng.call(void 0, parsed.bytes);
|
|
3012
3022
|
const px = { width: png.width, height: png.height, data: png.data };
|
|
3013
3023
|
this.imagePixels.set(src, px);
|
|
3014
3024
|
return px;
|
|
@@ -3213,7 +3223,7 @@ var PaintEditorController = (_class9 = class {
|
|
|
3213
3223
|
}
|
|
3214
3224
|
/** A layer's tile surface (live while stroking), for thumbnails. */
|
|
3215
3225
|
layerSurface(id) {
|
|
3216
|
-
const l = _optionalChain([
|
|
3226
|
+
const l = _optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _86 => _86.layer]);
|
|
3217
3227
|
return isPixelLayer(l) ? l.surface : null;
|
|
3218
3228
|
}
|
|
3219
3229
|
}, _class9);
|
|
@@ -3250,6 +3260,169 @@ function resampleInto(src, rect, width, height) {
|
|
|
3250
3260
|
return { width, height, data: out };
|
|
3251
3261
|
}
|
|
3252
3262
|
|
|
3263
|
+
// src/paint-editor/presence.ts
|
|
3264
|
+
var PaintPresence = class extends _chunkEGFUVXKKcjs.PresenceStore {
|
|
3265
|
+
};
|
|
3266
|
+
var FRAME = 16;
|
|
3267
|
+
function strokeSchedule(points) {
|
|
3268
|
+
if (points.length < 2) return points.map(() => 1);
|
|
3269
|
+
const t0 = points[0].t;
|
|
3270
|
+
const t1 = points[points.length - 1].t;
|
|
3271
|
+
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) {
|
|
3272
|
+
return points.map((p) => Math.min(1, Math.max(0, (p.t - t0) / (t1 - t0))));
|
|
3273
|
+
}
|
|
3274
|
+
const acc = [0];
|
|
3275
|
+
for (let i = 1; i < points.length; i++) acc.push(acc[i - 1] + Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y));
|
|
3276
|
+
const total = acc[acc.length - 1];
|
|
3277
|
+
return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
|
|
3278
|
+
}
|
|
3279
|
+
function strokeDuration(points, max = 1800) {
|
|
3280
|
+
const t0 = _optionalChain([points, 'access', _87 => _87[0], 'optionalAccess', _88 => _88.t]);
|
|
3281
|
+
const t1 = _optionalChain([points, 'access', _89 => _89[points.length - 1], 'optionalAccess', _90 => _90.t]);
|
|
3282
|
+
let ms;
|
|
3283
|
+
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
|
|
3284
|
+
else {
|
|
3285
|
+
let length = 0;
|
|
3286
|
+
for (let i = 1; i < points.length; i++) length += Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y);
|
|
3287
|
+
ms = length / 1.5;
|
|
3288
|
+
}
|
|
3289
|
+
return Math.min(max, Math.max(250, ms));
|
|
3290
|
+
}
|
|
3291
|
+
function sweepPath(rect, rows = 4) {
|
|
3292
|
+
const inset = Math.min(rect.width, rect.height) * 0.08;
|
|
3293
|
+
const left = rect.x + inset;
|
|
3294
|
+
const right = rect.x + rect.width - inset;
|
|
3295
|
+
const out = [];
|
|
3296
|
+
for (let r = 0; r < rows; r++) {
|
|
3297
|
+
const y = rect.y + inset + (rect.height - 2 * inset) * (r + 0.5) / rows;
|
|
3298
|
+
out.push(r % 2 ? { x: right, y } : { x: left, y }, r % 2 ? { x: left, y } : { x: right, y });
|
|
3299
|
+
}
|
|
3300
|
+
return out;
|
|
3301
|
+
}
|
|
3302
|
+
var centre = (r) => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });
|
|
3303
|
+
var PaintDirector = class {
|
|
3304
|
+
constructor(controller, presence, options = {}) {
|
|
3305
|
+
this.controller = controller;
|
|
3306
|
+
this.presence = presence;
|
|
3307
|
+
this.options = options;
|
|
3308
|
+
this.clock = _nullishCoalesce(options.clock, () => ( _chunkEGFUVXKKcjs.realPresenceClock));
|
|
3309
|
+
this.queue = new (0, _chunkEGFUVXKKcjs.PerformanceQueue)(presence, { clock: this.clock, linger: options.linger });
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3312
|
+
|
|
3313
|
+
|
|
3314
|
+
|
|
3315
|
+
|
|
3316
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
3317
|
+
perform(actor, commands) {
|
|
3318
|
+
return this.queue.run(actor, async () => {
|
|
3319
|
+
const results = [];
|
|
3320
|
+
for (const command of commands) {
|
|
3321
|
+
try {
|
|
3322
|
+
results.push({ ok: true, command, result: await this.performOne(actor.id, command) });
|
|
3323
|
+
} catch (error) {
|
|
3324
|
+
results.push({ ok: false, command, message: error instanceof Error ? error.message : String(error) });
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
return results;
|
|
3328
|
+
});
|
|
3329
|
+
}
|
|
3330
|
+
ms(n) {
|
|
3331
|
+
return Math.round(n / Math.max(0.1, _nullishCoalesce(this.options.speed, () => ( 1))));
|
|
3332
|
+
}
|
|
3333
|
+
where(id) {
|
|
3334
|
+
const a = this.presence.get(id);
|
|
3335
|
+
return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _91 => _91.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _92 => _92.y]), () => ( 0)) };
|
|
3336
|
+
}
|
|
3337
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
3338
|
+
async glide(id, to, ms = 380) {
|
|
3339
|
+
const a = this.presence.get(id);
|
|
3340
|
+
if (!a || a.x === 0 && a.y === 0) {
|
|
3341
|
+
this.presence.set({ id, x: to.x, y: to.y });
|
|
3342
|
+
return;
|
|
3343
|
+
}
|
|
3344
|
+
await _chunkEGFUVXKKcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, this.where(id), to, this.ms(ms));
|
|
3345
|
+
}
|
|
3346
|
+
async say(id, text, ms) {
|
|
3347
|
+
if (!text) return;
|
|
3348
|
+
this.presence.set({ id, message: text });
|
|
3349
|
+
await this.clock.wait(this.ms(ms));
|
|
3350
|
+
}
|
|
3351
|
+
async performOne(id, command) {
|
|
3352
|
+
const c = this.controller;
|
|
3353
|
+
switch (command.kind) {
|
|
3354
|
+
case "say":
|
|
3355
|
+
await this.say(id, command.text, 900);
|
|
3356
|
+
return void 0;
|
|
3357
|
+
case "point":
|
|
3358
|
+
await this.say(id, command.note, 500);
|
|
3359
|
+
await this.glide(id, command.at);
|
|
3360
|
+
this.presence.set({ id, pressed: true });
|
|
3361
|
+
await this.clock.wait(this.ms(110));
|
|
3362
|
+
this.presence.set({ id, pressed: false });
|
|
3363
|
+
return void 0;
|
|
3364
|
+
case "stroke":
|
|
3365
|
+
await this.say(id, command.note, 500);
|
|
3366
|
+
return this.stroke(id, command.stroke);
|
|
3367
|
+
case "fill": {
|
|
3368
|
+
await this.say(id, command.note, 500);
|
|
3369
|
+
const { width, height } = c.getState().document.canvas;
|
|
3370
|
+
const path = sweepPath({ x: 0, y: 0, width, height });
|
|
3371
|
+
await this.glide(id, path[0]);
|
|
3372
|
+
this.presence.set({ id, pressed: true });
|
|
3373
|
+
try {
|
|
3374
|
+
for (let i = 1; i < path.length; i++) await _chunkEGFUVXKKcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, path[i - 1], path[i], this.ms(i % 2 ? 260 : 90));
|
|
3375
|
+
} finally {
|
|
3376
|
+
this.presence.set({ id, pressed: false });
|
|
3377
|
+
}
|
|
3378
|
+
return c.fillLayer(command.fill);
|
|
3379
|
+
}
|
|
3380
|
+
case "replay": {
|
|
3381
|
+
await this.say(id, command.note, 500);
|
|
3382
|
+
const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _93 => _93.replay, 'access', _94 => _94.strokeIds, 'optionalAccess', _95 => _95.includes, 'call', _96 => _96(s.id)]));
|
|
3383
|
+
const first = _optionalChain([source, 'access', _97 => _97[0], 'optionalAccess', _98 => _98.points, 'access', _99 => _99[0]]);
|
|
3384
|
+
if (first) await this.glide(id, first);
|
|
3385
|
+
const result = c.replayStrokes(command.replay);
|
|
3386
|
+
if (result.bounds) await this.glide(id, centre(result.bounds), 520);
|
|
3387
|
+
return result;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
3392
|
+
async stroke(id, init) {
|
|
3393
|
+
const c = this.controller;
|
|
3394
|
+
const points = c.checkPoints(init.points);
|
|
3395
|
+
const { points: _points, ...rest } = init;
|
|
3396
|
+
const session = c.beginStroke({ snapToPerspective: false, start: points[0], ...rest });
|
|
3397
|
+
try {
|
|
3398
|
+
await this.glide(id, points[0]);
|
|
3399
|
+
this.presence.set({ id, pressed: true });
|
|
3400
|
+
const at = strokeSchedule(points);
|
|
3401
|
+
const duration = this.ms(strokeDuration(points, this.options.maxStrokeMs));
|
|
3402
|
+
let next = 0;
|
|
3403
|
+
const frames = Math.max(1, Math.round(duration / FRAME));
|
|
3404
|
+
for (let f = 1; f <= frames; f++) {
|
|
3405
|
+
const t = f / frames;
|
|
3406
|
+
const from = next;
|
|
3407
|
+
while (next < points.length && at[next] <= t + 1e-9) next++;
|
|
3408
|
+
if (next > from) {
|
|
3409
|
+
session.push(points.slice(from, next));
|
|
3410
|
+
const p = points[next - 1];
|
|
3411
|
+
this.presence.set({ id, x: p.x, y: p.y });
|
|
3412
|
+
}
|
|
3413
|
+
if (f < frames) await this.clock.wait(duration / frames);
|
|
3414
|
+
}
|
|
3415
|
+
if (next < points.length) session.push(points.slice(next));
|
|
3416
|
+
this.presence.set({ id, pressed: false });
|
|
3417
|
+
return session.end();
|
|
3418
|
+
} catch (error) {
|
|
3419
|
+
if (c.activeStroke === session) session.cancel();
|
|
3420
|
+
this.presence.set({ id, pressed: false });
|
|
3421
|
+
throw error;
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
};
|
|
3425
|
+
|
|
3253
3426
|
// src/paint-editor/guide-tools.ts
|
|
3254
3427
|
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
3255
3428
|
var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
@@ -3570,7 +3743,7 @@ function createPaintGuideTools(c) {
|
|
|
3570
3743
|
const pad = c.mixingPad;
|
|
3571
3744
|
return {
|
|
3572
3745
|
content: [
|
|
3573
|
-
{ type: "image", data:
|
|
3746
|
+
{ type: "image", data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, _chunkAZTZRLDIcjs.encodePng.call(void 0, pad.width, pad.height, pad.pixels())), mimeType: "image/png" },
|
|
3574
3747
|
{ type: "text", text: `Mixing pad ${pad.width}\xD7${pad.height}` }
|
|
3575
3748
|
]
|
|
3576
3749
|
};
|
|
@@ -3685,6 +3858,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3685
3858
|
const c = controller;
|
|
3686
3859
|
const tools = [];
|
|
3687
3860
|
const add = (t) => tools.push(t);
|
|
3861
|
+
const act = async (command, direct) => {
|
|
3862
|
+
if (!options.director) return direct();
|
|
3863
|
+
const [r] = await options.director.perform(_nullishCoalesce(options.actor, () => ( { id: "agent", name: "Agent" })), [command]);
|
|
3864
|
+
if (!r || !r.ok) throw new Error(r && !r.ok ? r.message : "The director did not run the command.");
|
|
3865
|
+
return r.result;
|
|
3866
|
+
};
|
|
3688
3867
|
add({
|
|
3689
3868
|
name: "get_canvas_info",
|
|
3690
3869
|
title: "Get the canvas",
|
|
@@ -3949,7 +4128,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3949
4128
|
additionalProperties: false
|
|
3950
4129
|
},
|
|
3951
4130
|
annotations: { title: "Fill a layer", ...WRITE2 },
|
|
3952
|
-
handler: (a) => c.fillLayer(a)
|
|
4131
|
+
handler: (a) => act({ kind: "fill", fill: a }, () => c.fillLayer(a))
|
|
3953
4132
|
});
|
|
3954
4133
|
add({
|
|
3955
4134
|
name: "clear_layer",
|
|
@@ -3967,7 +4146,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3967
4146
|
annotations: { title: "List brushes", ...READ2 },
|
|
3968
4147
|
handler: () => {
|
|
3969
4148
|
const s = c.getState();
|
|
3970
|
-
return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access',
|
|
4149
|
+
return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _100 => _100.getBrush, 'call', _101 => _101(s.brush.id), 'optionalAccess', _102 => _102.builtin])), brushes: s.brushes.map(brushSummary) };
|
|
3971
4150
|
}
|
|
3972
4151
|
});
|
|
3973
4152
|
add({
|
|
@@ -4065,7 +4244,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4065
4244
|
const t = c.brushThumbnail(_nullishCoalesce(id, () => ( c.getState().brush.id)), { width, height, color });
|
|
4066
4245
|
return {
|
|
4067
4246
|
content: [
|
|
4068
|
-
{ type: "image", data:
|
|
4247
|
+
{ type: "image", data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, _chunkAZTZRLDIcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" },
|
|
4069
4248
|
{ type: "text", text: `Brush ${_nullishCoalesce(id, () => ( c.getState().brush.id))} ${t.width}\xD7${t.height}` }
|
|
4070
4249
|
]
|
|
4071
4250
|
};
|
|
@@ -4132,7 +4311,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4132
4311
|
add({
|
|
4133
4312
|
name: "paint_stroke",
|
|
4134
4313
|
title: "Paint a brush stroke",
|
|
4135
|
-
description: "Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.",
|
|
4314
|
+
description: "Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. With an agent cursor (a director), the stroke is painted live along the points at the pace of their times. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.",
|
|
4136
4315
|
inputSchema: {
|
|
4137
4316
|
type: "object",
|
|
4138
4317
|
properties: {
|
|
@@ -4148,8 +4327,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4148
4327
|
additionalProperties: false
|
|
4149
4328
|
},
|
|
4150
4329
|
annotations: { title: "Paint a brush stroke", ...WRITE2 },
|
|
4151
|
-
handler: (a) => {
|
|
4152
|
-
const
|
|
4330
|
+
handler: async (a) => {
|
|
4331
|
+
const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective };
|
|
4332
|
+
const r = await act({ kind: "stroke", stroke }, () => c.paintStroke(stroke));
|
|
4153
4333
|
return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
|
|
4154
4334
|
}
|
|
4155
4335
|
});
|
|
@@ -4186,7 +4366,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4186
4366
|
color: s.color,
|
|
4187
4367
|
points: ids ? s.points : s.points.length,
|
|
4188
4368
|
seed: s.seed,
|
|
4189
|
-
copies: _nullishCoalesce(_optionalChain([s, 'access',
|
|
4369
|
+
copies: _nullishCoalesce(_optionalChain([s, 'access', _103 => _103.copies, 'optionalAccess', _104 => _104.length]), () => ( 0)),
|
|
4190
4370
|
bounds: { x: Math.floor(Math.min(...xs) - pad), y: Math.floor(Math.min(...ys) - pad), width: Math.ceil(Math.max(...xs) - Math.min(...xs) + 2 * pad), height: Math.ceil(Math.max(...ys) - Math.min(...ys) + 2 * pad) }
|
|
4191
4371
|
};
|
|
4192
4372
|
})
|
|
@@ -4223,7 +4403,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4223
4403
|
additionalProperties: false
|
|
4224
4404
|
},
|
|
4225
4405
|
annotations: { title: "Replay strokes, varied", ...WRITE2 },
|
|
4226
|
-
handler: (a) =>
|
|
4406
|
+
handler: (a) => {
|
|
4407
|
+
const replay = a;
|
|
4408
|
+
return act({ kind: "replay", replay }, () => c.replayStrokes(replay));
|
|
4409
|
+
}
|
|
4227
4410
|
});
|
|
4228
4411
|
add({
|
|
4229
4412
|
name: "set_view",
|
|
@@ -4316,7 +4499,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4316
4499
|
annotations: { title: "Export the painting", ...READ2 },
|
|
4317
4500
|
handler: async ({ format, quality, scale, paper }) => {
|
|
4318
4501
|
const bytes = await c.exportImage({ format, quality, scale, paper });
|
|
4319
|
-
return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data:
|
|
4502
|
+
return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, bytes) };
|
|
4320
4503
|
}
|
|
4321
4504
|
});
|
|
4322
4505
|
add({
|
|
@@ -4327,7 +4510,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4327
4510
|
annotations: { title: "Export as PSD", ...READ2 },
|
|
4328
4511
|
handler: () => {
|
|
4329
4512
|
const r = c.exportPsd();
|
|
4330
|
-
return { data:
|
|
4513
|
+
return { data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };
|
|
4331
4514
|
}
|
|
4332
4515
|
});
|
|
4333
4516
|
add({
|
|
@@ -4457,12 +4640,12 @@ var PaintGesture = (_class10 = class {
|
|
|
4457
4640
|
if (!m || m.pointerId !== e.pointerId) return;
|
|
4458
4641
|
this.mode = null;
|
|
4459
4642
|
this.predicted = [];
|
|
4460
|
-
if (m.kind === "stroke") _optionalChain([this, 'access',
|
|
4643
|
+
if (m.kind === "stroke") _optionalChain([this, 'access', _105 => _105.controller, 'access', _106 => _106.activeStroke, 'optionalAccess', _107 => _107.end, 'call', _108 => _108()]);
|
|
4461
4644
|
}
|
|
4462
4645
|
cancel() {
|
|
4463
4646
|
this.penDown = false;
|
|
4464
4647
|
this.predicted = [];
|
|
4465
|
-
if (_optionalChain([this, 'access',
|
|
4648
|
+
if (_optionalChain([this, 'access', _109 => _109.mode, 'optionalAccess', _110 => _110.kind]) === "stroke") _optionalChain([this, 'access', _111 => _111.controller, 'access', _112 => _112.activeStroke, 'optionalAccess', _113 => _113.cancel, 'call', _114 => _114()]);
|
|
4466
4649
|
this.mode = null;
|
|
4467
4650
|
}
|
|
4468
4651
|
get active() {
|
|
@@ -4590,7 +4773,7 @@ var PAPER_SLIDERS = [
|
|
|
4590
4773
|
];
|
|
4591
4774
|
function readPath(obj, path) {
|
|
4592
4775
|
let v = obj;
|
|
4593
|
-
for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess',
|
|
4776
|
+
for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _115 => _115[k]]);
|
|
4594
4777
|
return typeof v === "number" ? v : 0;
|
|
4595
4778
|
}
|
|
4596
4779
|
function patchPath(obj, path, value) {
|
|
@@ -4777,5 +4960,10 @@ var BLEND_MENU_GROUPS = [
|
|
|
4777
4960
|
|
|
4778
4961
|
|
|
4779
4962
|
|
|
4780
|
-
|
|
4963
|
+
|
|
4964
|
+
|
|
4965
|
+
|
|
4966
|
+
|
|
4967
|
+
|
|
4968
|
+
exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkSZ6KMZNMcjs.BLEND_MODES; exports.BRUSH_ID = BRUSH_ID; exports.BRUSH_ROTATIONS = BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = BUILTIN_BRUSHES; exports.DEFAULT_BRUSH_ID = DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = DEFAULT_DYNAMICS; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DryStroke = DryStroke; exports.GRAIN_PATTERNS = GRAIN_PATTERNS; exports.GRAIN_TILE = GRAIN_TILE; exports.HARMONY_KINDS = HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.MAX_BRUSH_SIZE = _chunkHUFQD4CBcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MixingPad = MixingPad; exports.PAINTERLY_BLEND_MODES = _chunkSZ6KMZNMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = PAINT_BRUSH_ENGINES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintGesture = PaintGesture; exports.PaintPresence = PaintPresence; exports.PaintStrokeSession = PaintStrokeSession; exports.PaperGrain = PaperGrain; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.TileableNoise = TileableNoise; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushToJSON = brushToJSON; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony; exports.composeAffine = composeAffine; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintLayer = createPaintLayer; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.fitZoom = fitZoom; exports.grainCatch = grainCatch; exports.grainHeights = grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = hash2; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkSZ6KMZNMcjs.isBlendMode; exports.isPainterlyBlendMode = _chunkSZ6KMZNMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.mapPenPoint = mapPenPoint; exports.mix32 = mix32; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.newPaintLayerId = newPaintLayerId; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = normalizeDynamics; exports.normalizePaintBrush = normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.pointerToPenPoint = pointerToPenPoint; exports.rand01 = rand01; exports.randSigned = randSigned; exports.readPath = readPath; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.samplePressure = samplePressure; exports.screenToDocument = screenToDocument; exports.seedFromString = seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.standardBlendMode = _chunkSZ6KMZNMcjs.standardBlendMode; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.toStrokePoint = toStrokePoint; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = wheelToHue;
|
|
4781
4969
|
//# sourceMappingURL=index.cjs.map
|