@pixerate/editor 0.239.0 → 0.241.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/animation-editor/index.cjs +58 -58
- package/dist/animation-editor/index.js +3 -3
- package/dist/{brushstrokeRender-WB67GMUP.js → brushstrokeRender-MOYGEXOC.js} +2 -2
- package/dist/{brushstrokeRender-MPOM7BFW.cjs → brushstrokeRender-UKADOV5D.cjs} +5 -5
- package/dist/canvas/index.cjs +8 -8
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-NKTNLJUJ.cjs → chunk-5BR7LC24.cjs} +99 -11
- package/dist/{chunk-ZXNO3ZOX.cjs → chunk-7F4G74UQ.cjs} +35 -35
- package/dist/{chunk-AD7GA3TL.cjs → chunk-AFLMXITL.cjs} +23 -23
- package/dist/{chunk-PP6BXVRL.cjs → chunk-HGGJ36HR.cjs} +1 -1
- package/dist/{chunk-BBUE3UJL.cjs → chunk-HW72ABGR.cjs} +86 -86
- package/dist/{chunk-7YGBSFC6.js → chunk-ILM6GYAX.js} +1 -1
- package/dist/{chunk-THXFU3JB.cjs → chunk-KCMV2534.cjs} +2 -2
- package/dist/{chunk-3E36VDMJ.js → chunk-NE6OOKWJ.js} +1 -1
- package/dist/{chunk-RV5DKZHU.js → chunk-QP2B3MID.js} +1 -1
- package/dist/{chunk-UUBO6RB5.js → chunk-UDBDYZET.js} +1 -1
- package/dist/{chunk-PJYG6FCF.js → chunk-XBZK47LV.js} +98 -10
- package/dist/{chunk-XK4SST43.js → chunk-ZDPLZDTT.js} +1 -1
- package/dist/image-editor/index.cjs +775 -775
- package/dist/image-editor/index.js +4 -4
- package/dist/paint-editor/controller.d.cts +158 -1
- package/dist/paint-editor/controller.d.ts +158 -1
- package/dist/paint-editor/document.d.cts +7 -2
- package/dist/paint-editor/document.d.ts +7 -2
- package/dist/paint-editor/effect-paint.d.cts +60 -3
- package/dist/paint-editor/effect-paint.d.ts +60 -3
- package/dist/paint-editor/index.cjs +1246 -430
- package/dist/paint-editor/index.d.cts +1 -0
- package/dist/paint-editor/index.d.ts +1 -0
- package/dist/paint-editor/index.js +888 -72
- package/dist/paint-editor/live-strokes.d.cts +24 -0
- package/dist/paint-editor/live-strokes.d.ts +24 -0
- package/dist/paint-editor/stickers.d.cts +6 -0
- package/dist/paint-editor/stickers.d.ts +6 -0
- package/dist/paint-editor/thick.d.cts +4 -0
- package/dist/paint-editor/thick.d.ts +4 -0
- package/dist/paint-editor/ui.d.cts +24 -4
- package/dist/paint-editor/ui.d.ts +24 -4
- package/dist/paint-editor/wet.d.cts +8 -0
- package/dist/paint-editor/wet.d.ts +8 -0
- package/dist/vector/index.cjs +962 -962
- package/dist/vector/index.js +4 -4
- package/package.json +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +38 -27
- package/skills/pixerate-paint-editor/references/effect-paint.md +25 -0
|
@@ -7,7 +7,7 @@ var _chunkZQIWBJGHcjs = require('../chunk-ZQIWBJGH.cjs');
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunkHW72ABGRcjs = require('../chunk-HW72ABGR.cjs');
|
|
11
11
|
require('../chunk-A2IS7EHE.cjs');
|
|
12
12
|
require('../chunk-SS53NNZO.cjs');
|
|
13
13
|
|
|
@@ -55,7 +55,7 @@ var _chunkJLWLX52Lcjs = require('../chunk-JLWLX52L.cjs');
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
|
|
58
|
-
require('../chunk-
|
|
58
|
+
require('../chunk-KCMV2534.cjs');
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
|
|
@@ -126,7 +126,12 @@ require('../chunk-THXFU3JB.cjs');
|
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
var _chunk5BR7LC24cjs = require('../chunk-5BR7LC24.cjs');
|
|
130
135
|
require('../chunk-CVFAAZXE.cjs');
|
|
131
136
|
require('../chunk-GF2RBSDM.cjs');
|
|
132
137
|
require('../chunk-NM3G4VQT.cjs');
|
|
@@ -285,7 +290,7 @@ function normalizeCanvas(raw) {
|
|
|
285
290
|
function createPaintDocument(options = {}) {
|
|
286
291
|
const canvas = normalizeCanvas({ width: _nullishCoalesce(options.width, () => ( 2048)), height: _nullishCoalesce(options.height, () => ( 1536)), dpi: options.dpi });
|
|
287
292
|
const layer = createPaintLayer("Layer 1");
|
|
288
|
-
return { canvas, paper:
|
|
293
|
+
return { canvas, paper: _chunk5BR7LC24cjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
|
|
289
294
|
}
|
|
290
295
|
|
|
291
296
|
// src/paint-editor/dab-stroke.ts
|
|
@@ -339,13 +344,13 @@ var PaintDabStroke = (_class = class {
|
|
|
339
344
|
constructor(brush, options) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);
|
|
340
345
|
this.brush = brush;
|
|
341
346
|
this.options = options;
|
|
342
|
-
this.smoother = new (0,
|
|
343
|
-
this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [
|
|
347
|
+
this.smoother = new (0, _chunk5BR7LC24cjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
|
|
348
|
+
this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunk5BR7LC24cjs.IDENTITY_COPY];
|
|
344
349
|
const exchanging = brush.engine === "mixer" || brush.engine === "dab";
|
|
345
350
|
const rates = brush.engine === "mixer" ? _chunkPQ3H2AANcjs.mixerRates.call(void 0, brush.mixer) : _chunkPQ3H2AANcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, 1, brush.behavior.mixing);
|
|
346
351
|
this.mixing = brush.engine === "mixer" ? brush.mixer.mixing : brush.behavior.mixing;
|
|
347
352
|
this.states = this.copies.map((c, i) => ({
|
|
348
|
-
walker: new (0,
|
|
353
|
+
walker: new (0, _chunk5BR7LC24cjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
|
|
349
354
|
exchange: exchanging ? new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, options.load) : null,
|
|
350
355
|
smudge: brush.engine === "smudge" ? new (0, _chunkPQ3H2AANcjs.SmudgeTip)(brush.smudge, brush.tip.size * (1 + brush.dynamics.tiltSize * 1.5)) : null
|
|
351
356
|
}));
|
|
@@ -458,7 +463,7 @@ var PaintDabStroke = (_class = class {
|
|
|
458
463
|
let flow = 1;
|
|
459
464
|
if (this.options.effect) {
|
|
460
465
|
const rgb = [0, 0, 0];
|
|
461
|
-
flow =
|
|
466
|
+
flow = _chunk5BR7LC24cjs.sampleEffectAt.call(void 0, this.options.effect, d.x, d.y, rgb, d);
|
|
462
467
|
ex.setReservoirColor(rgb[0], rgb[1], rgb[2]);
|
|
463
468
|
} else if (this.sampler && !this.gradient) {
|
|
464
469
|
const g = this.sampler.dab(d, this.sample);
|
|
@@ -686,15 +691,15 @@ function expand(t, channels) {
|
|
|
686
691
|
return out;
|
|
687
692
|
}
|
|
688
693
|
var ThickStrokeDriver = (_class3 = class {
|
|
689
|
-
constructor(init) {;_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);
|
|
694
|
+
constructor(init) {;_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);_class3.prototype.__init21.call(this);
|
|
690
695
|
this.init = init;
|
|
691
696
|
const b = init.brush;
|
|
692
|
-
this.smoother = new (0,
|
|
693
|
-
const copies = init.copies.length ? init.copies : [
|
|
697
|
+
this.smoother = new (0, _chunk5BR7LC24cjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
|
|
698
|
+
const copies = init.copies.length ? init.copies : [_chunk5BR7LC24cjs.IDENTITY_COPY];
|
|
694
699
|
this.copies = copies;
|
|
695
700
|
const rates = _chunkPQ3H2AANcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
|
|
696
701
|
this.states = copies.map((c, i) => ({
|
|
697
|
-
walker: new (0,
|
|
702
|
+
walker: new (0, _chunk5BR7LC24cjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
|
|
698
703
|
exchange: new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, init.load),
|
|
699
704
|
smudge: b.impasto.tool === "knife" ? new (0, _chunkPQ3H2AANcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
|
|
700
705
|
carried: null,
|
|
@@ -711,13 +716,14 @@ var ThickStrokeDriver = (_class3 = class {
|
|
|
711
716
|
__init13() {this.height = /* @__PURE__ */ new Map()}
|
|
712
717
|
__init14() {this.material = /* @__PURE__ */ new Map()}
|
|
713
718
|
__init15() {this.paint = [0, 0, 0]}
|
|
714
|
-
__init16() {this.
|
|
715
|
-
__init17() {this.
|
|
716
|
-
__init18() {this.
|
|
717
|
-
__init19() {this.
|
|
719
|
+
__init16() {this.centre = [0, 0, 0]}
|
|
720
|
+
__init17() {this.tip = new Float32Array(0)}
|
|
721
|
+
__init18() {this.lastRaw = null}
|
|
722
|
+
__init19() {this.lastFed = null}
|
|
723
|
+
__init20() {this.version = 0}
|
|
718
724
|
|
|
719
725
|
|
|
720
|
-
|
|
726
|
+
__init21() {this.sample = { rgb: [0, 0, 0], alpha: 1 }}
|
|
721
727
|
/** What copy 0 carries after the dabs so far. */
|
|
722
728
|
get load() {
|
|
723
729
|
return this.states[0].exchange.load;
|
|
@@ -837,7 +843,11 @@ var ThickStrokeDriver = (_class3 = class {
|
|
|
837
843
|
}
|
|
838
844
|
const ex = st.exchange;
|
|
839
845
|
let flow = 1;
|
|
840
|
-
|
|
846
|
+
const effect = this.init.effect;
|
|
847
|
+
if (effect) {
|
|
848
|
+
_chunk5BR7LC24cjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
|
|
849
|
+
ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
|
|
850
|
+
} else if (this.sampler) {
|
|
841
851
|
const g = this.sampler.dab(d, this.sample);
|
|
842
852
|
ex.setReservoirColor(g.rgb[0], g.rgb[1], g.rgb[2]);
|
|
843
853
|
flow = g.alpha;
|
|
@@ -849,7 +859,12 @@ var ThickStrokeDriver = (_class3 = class {
|
|
|
849
859
|
if (dep > 0) {
|
|
850
860
|
const cov = new Float32Array(n);
|
|
851
861
|
for (let p = 0; p < n; p++) cov[p] = tip[p] > 0 ? Math.min(1, tip[p] * (im.tool === "roller" || im.tool === "gloop" || im.tool === "tube" ? 1.6 : 1.1)) : 0;
|
|
852
|
-
|
|
862
|
+
let field = null;
|
|
863
|
+
if (effect) {
|
|
864
|
+
field = new Float32Array(n * 3);
|
|
865
|
+
_chunk5BR7LC24cjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
|
|
866
|
+
}
|
|
867
|
+
this.medium.deposit(rect, cov, dep, this.paint, ex.paintPigment, field);
|
|
853
868
|
}
|
|
854
869
|
const seed = this.init.seed;
|
|
855
870
|
for (let yy = 0, p = 0; yy < rect.height; yy++) {
|
|
@@ -986,17 +1001,16 @@ function union(a, b) {
|
|
|
986
1001
|
return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
|
|
987
1002
|
}
|
|
988
1003
|
var PaintStrokeSession = (_class4 = class {
|
|
989
|
-
constructor(host, init) {;_class4.prototype.
|
|
1004
|
+
constructor(host, init) {;_class4.prototype.__init22.call(this);_class4.prototype.__init23.call(this);_class4.prototype.__init24.call(this);_class4.prototype.__init25.call(this);_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);_class4.prototype.__init28.call(this);_class4.prototype.__init29.call(this);_class4.prototype.__init30.call(this);_class4.prototype.__init31.call(this);_class4.prototype.__init32.call(this);_class4.prototype.__init33.call(this);_class4.prototype.__init34.call(this);_class4.prototype.__init35.call(this);
|
|
990
1005
|
this.host = host;
|
|
991
1006
|
this.init = init;
|
|
992
1007
|
this.layerId = init.layerId;
|
|
993
1008
|
this.base = init.surface;
|
|
994
1009
|
this.live = new Map(this.base.tiles);
|
|
995
|
-
this.copies = init.copies.length ? init.copies : [
|
|
1010
|
+
this.copies = init.copies.length ? init.copies : [_chunk5BR7LC24cjs.IDENTITY_COPY];
|
|
996
1011
|
const brush = init.brush;
|
|
997
1012
|
if (init.wet) this.wetDriver = init.wet.driver;
|
|
998
1013
|
const effect = _nullishCoalesce(_optionalChain([init, 'access', _15 => _15.effect, 'optionalAccess', _16 => _16.pixels]), () => ( null));
|
|
999
|
-
if (effect && (init.wet || init.thick || init.sticker)) throw new Error(`The ${brush.name} brush (${brush.engine} engine) cannot paint with effect paint.`);
|
|
1000
1014
|
this.apply = {
|
|
1001
1015
|
mode: brush.engine === "eraser" ? "erase" : "paint",
|
|
1002
1016
|
color: init.color,
|
|
@@ -1009,11 +1023,11 @@ var PaintStrokeSession = (_class4 = class {
|
|
|
1009
1023
|
};
|
|
1010
1024
|
if (this.wetDriver) {
|
|
1011
1025
|
} else if (init.sticker) {
|
|
1012
|
-
this.stickerSpray = new (0,
|
|
1026
|
+
this.stickerSpray = new (0, _chunk5BR7LC24cjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
|
|
1013
1027
|
} else if (init.thick) {
|
|
1014
1028
|
const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
|
|
1015
|
-
this.thickDriver = new ThickStrokeDriver({ brush, target: this.tileTarget(), channels: init.thick.channels, color: rgb(init.color), load: init.mixerLoad, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)) });
|
|
1016
|
-
} else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" ||
|
|
1029
|
+
this.thickDriver = new ThickStrokeDriver({ brush, target: this.tileTarget(), channels: init.thick.channels, color: rgb(init.color), load: init.mixerLoad, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
|
|
1030
|
+
} else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunk5BR7LC24cjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
|
|
1017
1031
|
const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
|
|
1018
1032
|
this.wet = new PaintDabStroke(brush, {
|
|
1019
1033
|
target: this.tileTarget(),
|
|
@@ -1029,33 +1043,33 @@ var PaintStrokeSession = (_class4 = class {
|
|
|
1029
1043
|
});
|
|
1030
1044
|
} else {
|
|
1031
1045
|
const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect };
|
|
1032
|
-
this.dry = brush.engine === "particle" ? new (0,
|
|
1046
|
+
this.dry = brush.engine === "particle" ? new (0, _chunk5BR7LC24cjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunk5BR7LC24cjs.BristleStroke)(brush, opts) : new (0, _chunk5BR7LC24cjs.DryStroke)(brush, opts);
|
|
1033
1047
|
}
|
|
1034
1048
|
}
|
|
1035
1049
|
|
|
1036
1050
|
|
|
1037
1051
|
|
|
1038
1052
|
/** The raw input so far (what a replay feeds back in). */
|
|
1039
|
-
|
|
1053
|
+
__init22() {this.points = []}
|
|
1040
1054
|
|
|
1041
1055
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1056
|
+
__init23() {this.touched = /* @__PURE__ */ new Set()}
|
|
1057
|
+
__init24() {this.fresh = /* @__PURE__ */ new Set()}
|
|
1058
|
+
__init25() {this.dry = null}
|
|
1059
|
+
__init26() {this.wet = null}
|
|
1060
|
+
__init27() {this.wetDriver = null}
|
|
1061
|
+
__init28() {this.thickDriver = null}
|
|
1062
|
+
__init29() {this.stickerSpray = null}
|
|
1049
1063
|
/** A wet stroke that ended while the simulation was mid-batch: it commits when the driver catches up. */
|
|
1050
|
-
|
|
1064
|
+
__init30() {this.wetEndPending = false}
|
|
1051
1065
|
|
|
1052
1066
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1067
|
+
__init31() {this.bounds = null}
|
|
1068
|
+
__init32() {this.lastRaw = null}
|
|
1069
|
+
__init33() {this.closed = false}
|
|
1070
|
+
__init34() {this.result = null}
|
|
1057
1071
|
/** The mask stencils this stroke was painted with when they are not the editor's (replays). */
|
|
1058
|
-
|
|
1072
|
+
__init35() {this.maskStencils = null}
|
|
1059
1073
|
tileTarget() {
|
|
1060
1074
|
return {
|
|
1061
1075
|
offset: this.init.offset,
|
|
@@ -1200,7 +1214,7 @@ function brushLoadForStroke(brush, current, color) {
|
|
|
1200
1214
|
if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
|
|
1201
1215
|
if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
|
|
1202
1216
|
if (brush.engine === "wet") return brush.wet.tool === "paint" ? { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null } : _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD;
|
|
1203
|
-
if (
|
|
1217
|
+
if (_chunk5BR7LC24cjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
|
|
1204
1218
|
return _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD;
|
|
1205
1219
|
}
|
|
1206
1220
|
|
|
@@ -1468,7 +1482,7 @@ function normalizeBrushStroke(raw) {
|
|
|
1468
1482
|
const out = {
|
|
1469
1483
|
id: r.id,
|
|
1470
1484
|
layerId: r.layerId,
|
|
1471
|
-
brush:
|
|
1485
|
+
brush: _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
|
|
1472
1486
|
color: typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : "#000000",
|
|
1473
1487
|
points,
|
|
1474
1488
|
seed: finite2(r.seed) ? r.seed | 0 : 0
|
|
@@ -1487,7 +1501,7 @@ function normalizeBrushStroke(raw) {
|
|
|
1487
1501
|
}
|
|
1488
1502
|
if (st.length) out.stencils = st;
|
|
1489
1503
|
}
|
|
1490
|
-
const effect =
|
|
1504
|
+
const effect = _chunk5BR7LC24cjs.readPaintEffectPaint.call(void 0, r.paint);
|
|
1491
1505
|
const paint = effect ? null : _chunkPQ3H2AANcjs.readPaintSource.call(void 0, r.paint);
|
|
1492
1506
|
if (effect) out.paint = effect;
|
|
1493
1507
|
else if (paint && paint.type === "gradient") out.paint = paint;
|
|
@@ -1519,17 +1533,19 @@ function variationAffine(v, origin) {
|
|
|
1519
1533
|
return composeAffine(back, composeAffine(linear, toOrigin));
|
|
1520
1534
|
}
|
|
1521
1535
|
function varyStroke(stroke, m, v) {
|
|
1522
|
-
const
|
|
1536
|
+
const det = Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2]));
|
|
1537
|
+
const s = Math.abs(det - 1) < 1e-9 ? 1 : det;
|
|
1523
1538
|
const ps = _nullishCoalesce(v.pressureScale, () => ( 1));
|
|
1524
1539
|
const points = stroke.points.map((p) => {
|
|
1525
1540
|
const q = mapPenPoint(m, p);
|
|
1526
1541
|
if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
|
|
1527
1542
|
return q;
|
|
1528
1543
|
});
|
|
1529
|
-
const brush = s !== 1 ?
|
|
1544
|
+
const brush = s !== 1 ? _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
|
|
1530
1545
|
const out = { ...stroke, brush, points };
|
|
1531
1546
|
if (_optionalChain([stroke, 'access', _59 => _59.paint, 'optionalAccess', _60 => _60.type]) === "gradient" && s !== 1) out.paint = _chunkPQ3H2AANcjs.scalePaintGradient.call(void 0, stroke.paint, s);
|
|
1532
|
-
if (_optionalChain([stroke, 'access', _61 => _61.
|
|
1547
|
+
if (_optionalChain([stroke, 'access', _61 => _61.paint, 'optionalAccess', _62 => _62.type]) === "effect" && stroke.paint.map && s !== 1) out.paint = { ...stroke.paint, map: { ...stroke.paint.map, length: Math.min(4096, Math.max(16, Math.round(stroke.paint.map.length * s))) } };
|
|
1548
|
+
if (_optionalChain([stroke, 'access', _63 => _63.copies, 'optionalAccess', _64 => _64.length])) {
|
|
1533
1549
|
const inv = invertAffine(m);
|
|
1534
1550
|
out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));
|
|
1535
1551
|
}
|
|
@@ -1548,7 +1564,7 @@ var paperNodes = /* @__PURE__ */ new WeakMap();
|
|
|
1548
1564
|
function paperNode(paper, light) {
|
|
1549
1565
|
let n = paperNodes.get(paper);
|
|
1550
1566
|
const metal = (_nullishCoalesce(paper.metallic, () => ( 0))) > 0;
|
|
1551
|
-
if (!n || metal && (_optionalChain([n, 'access',
|
|
1567
|
+
if (!n || metal && (_optionalChain([n, 'access', _65 => _65.light, 'optionalAccess', _66 => _66.azimuth]) !== _optionalChain([light, 'optionalAccess', _67 => _67.azimuth]) || _optionalChain([n, 'access', _68 => _68.light, 'optionalAccess', _69 => _69.elevation]) !== _optionalChain([light, 'optionalAccess', _70 => _70.elevation]))) {
|
|
1552
1568
|
n = { type: "paper", id: PAPER_NODE_ID, name: "Paper", visible: true, opacity: 1, blend: "normal", paper, ...metal && light ? { light: { azimuth: light.azimuth, elevation: light.elevation } } : {} };
|
|
1553
1569
|
paperNodes.set(paper, n);
|
|
1554
1570
|
}
|
|
@@ -1570,7 +1586,7 @@ function paperTile(paper, r, light) {
|
|
|
1570
1586
|
const key = `${paperKey(paper, light)}|${r.x},${r.y},${r.width},${r.height}`;
|
|
1571
1587
|
let t = tileCache.get(key);
|
|
1572
1588
|
if (!t) {
|
|
1573
|
-
t =
|
|
1589
|
+
t = _chunk5BR7LC24cjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
|
|
1574
1590
|
if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value);
|
|
1575
1591
|
tileCache.set(key, t);
|
|
1576
1592
|
}
|
|
@@ -1669,17 +1685,17 @@ function header(state, options) {
|
|
|
1669
1685
|
if (options.swatches !== void 0) out.swatches = JSON.parse(JSON.stringify(options.swatches));
|
|
1670
1686
|
if (options.mixingPad !== void 0) out.mixingPad = JSON.parse(JSON.stringify(options.mixingPad));
|
|
1671
1687
|
if (options.wet !== void 0) out.wet = JSON.parse(JSON.stringify(options.wet));
|
|
1672
|
-
if (_optionalChain([state, 'access',
|
|
1673
|
-
if (_optionalChain([state, 'access',
|
|
1688
|
+
if (_optionalChain([state, 'access', _71 => _71.wetEvents, 'optionalAccess', _72 => _72.length])) out.wetEvents = JSON.parse(JSON.stringify(state.wetEvents));
|
|
1689
|
+
if (_optionalChain([state, 'access', _73 => _73.paintEvents, 'optionalAccess', _74 => _74.length])) out.paintEvents = JSON.parse(JSON.stringify(state.paintEvents));
|
|
1674
1690
|
if (state.origin && (state.origin.x || state.origin.y)) out.origin = { ...state.origin };
|
|
1675
1691
|
return out;
|
|
1676
1692
|
}
|
|
1677
1693
|
function serializePaintDocument(state, options = {}) {
|
|
1678
|
-
const { layers, assets } =
|
|
1694
|
+
const { layers, assets } = _chunkHW72ABGRcjs.serializeLayers.call(void 0, state.layers);
|
|
1679
1695
|
return { ...header(state, options), layers, assets };
|
|
1680
1696
|
}
|
|
1681
1697
|
async function serializePaintDocumentExternal(state, store, options = {}) {
|
|
1682
|
-
const { layers, assets } = await
|
|
1698
|
+
const { layers, assets } = await _chunkHW72ABGRcjs.serializeLayersExternal.call(void 0, state.layers, store);
|
|
1683
1699
|
return { ...header(state, options), layers, assets };
|
|
1684
1700
|
}
|
|
1685
1701
|
function paintLayersOnly(layers, problems) {
|
|
@@ -1687,7 +1703,7 @@ function paintLayersOnly(layers, problems) {
|
|
|
1687
1703
|
for (const l of layers) {
|
|
1688
1704
|
if (l.type === "pixel") {
|
|
1689
1705
|
const { filters, source, ...rest } = l;
|
|
1690
|
-
if (_optionalChain([filters, 'optionalAccess',
|
|
1706
|
+
if (_optionalChain([filters, 'optionalAccess', _75 => _75.length])) problems.push(`Layer "${l.name}": its filters are an image editor feature and were dropped.`);
|
|
1691
1707
|
if (source) problems.push(`Layer "${l.name}" refers to an image editor source image; it loads empty.`);
|
|
1692
1708
|
out.push(rest);
|
|
1693
1709
|
} else if (l.type === "group") out.push({ ...l, children: paintLayersOnly(l.children, problems) });
|
|
@@ -1714,11 +1730,11 @@ function deserializePaintDocument(raw) {
|
|
|
1714
1730
|
}
|
|
1715
1731
|
const problems = [];
|
|
1716
1732
|
const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
|
|
1717
|
-
const paper =
|
|
1733
|
+
const paper = _chunk5BR7LC24cjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
|
|
1718
1734
|
const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
|
|
1719
|
-
const layers = paintLayersOnly(
|
|
1735
|
+
const layers = paintLayersOnly(_chunkHW72ABGRcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
|
|
1720
1736
|
const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
|
|
1721
|
-
const activeLayerId = wanted && _chunkHB4ICNNAcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access',
|
|
1737
|
+
const activeLayerId = wanted && _chunkHB4ICNNAcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _76 => _76.filter, 'call', _77 => _77((l) => l.type === "pixel"), 'access', _78 => _78.pop, 'call', _79 => _79(), 'optionalAccess', _80 => _80.id]), () => ( null));
|
|
1722
1738
|
const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
|
|
1723
1739
|
const state = { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) };
|
|
1724
1740
|
if (wetEvents.length) state.wetEvents = wetEvents;
|
|
@@ -1732,7 +1748,7 @@ async function deserializePaintDocumentAsync(raw, store) {
|
|
|
1732
1748
|
if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
|
|
1733
1749
|
const r = raw;
|
|
1734
1750
|
const problems = [];
|
|
1735
|
-
const assets = await
|
|
1751
|
+
const assets = await _chunkHW72ABGRcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
|
|
1736
1752
|
const loaded = deserializePaintDocument({ ...r, assets });
|
|
1737
1753
|
return { ...loaded, problems: [...problems, ...loaded.problems] };
|
|
1738
1754
|
}
|
|
@@ -1815,7 +1831,7 @@ function pointerToPenPoint(e, x, y, view) {
|
|
|
1815
1831
|
const p = { x, y, pressure: samplePressure(e) };
|
|
1816
1832
|
if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;
|
|
1817
1833
|
if (e.pointerType !== "pen") return p;
|
|
1818
|
-
const o =
|
|
1834
|
+
const o = _chunk5BR7LC24cjs.penOrientation.call(void 0, {
|
|
1819
1835
|
x,
|
|
1820
1836
|
y,
|
|
1821
1837
|
altitude: typeof e.altitudeAngle === "number" ? e.altitudeAngle : void 0,
|
|
@@ -1863,7 +1879,7 @@ async function decodeImageBlob(blob) {
|
|
|
1863
1879
|
if (!ctx) throw new Error("No 2D context to decode with.");
|
|
1864
1880
|
ctx.drawImage(bitmap, 0, 0);
|
|
1865
1881
|
const data = new Uint8ClampedArray(ctx.getImageData(0, 0, bitmap.width, bitmap.height).data);
|
|
1866
|
-
_optionalChain([bitmap, 'access',
|
|
1882
|
+
_optionalChain([bitmap, 'access', _81 => _81.close, 'optionalCall', _82 => _82()]);
|
|
1867
1883
|
return { width: bitmap.width, height: bitmap.height, data };
|
|
1868
1884
|
}
|
|
1869
1885
|
function downloadBytes(bytes, fileName, mimeType) {
|
|
@@ -1894,16 +1910,16 @@ function wetPaperInput(paper) {
|
|
|
1894
1910
|
absorption: paper.absorption,
|
|
1895
1911
|
permeability: paper.permeability,
|
|
1896
1912
|
roughness: flat ? 0 : paper.roughness,
|
|
1897
|
-
color:
|
|
1913
|
+
color: _chunk5BR7LC24cjs.hexToRgb8.call(void 0, paper.color),
|
|
1898
1914
|
heightAt: flat ? () => 0.5 : (x, y) => grain.at(x, y)
|
|
1899
1915
|
};
|
|
1900
1916
|
}
|
|
1901
1917
|
var WetStrokeDriver = (_class5 = class {
|
|
1902
|
-
constructor(init) {;_class5.prototype.
|
|
1918
|
+
constructor(init) {;_class5.prototype.__init36.call(this);_class5.prototype.__init37.call(this);_class5.prototype.__init38.call(this);_class5.prototype.__init39.call(this);_class5.prototype.__init40.call(this);_class5.prototype.__init41.call(this);_class5.prototype.__init42.call(this);_class5.prototype.__init43.call(this);_class5.prototype.__init44.call(this);_class5.prototype.__init45.call(this);_class5.prototype.__init46.call(this);_class5.prototype.__init47.call(this);_class5.prototype.__init48.call(this);
|
|
1903
1919
|
this.init = init;
|
|
1904
1920
|
const brush = init.brush;
|
|
1905
|
-
this.smoother = new (0,
|
|
1906
|
-
const copies = init.copies.length ? init.copies : [
|
|
1921
|
+
this.smoother = new (0, _chunk5BR7LC24cjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
|
|
1922
|
+
const copies = init.copies.length ? init.copies : [_chunk5BR7LC24cjs.IDENTITY_COPY];
|
|
1907
1923
|
const wet = brush.wet;
|
|
1908
1924
|
const spacing = Math.max(0.02, brush.tip.spacing);
|
|
1909
1925
|
const perDab = Math.min(1, spacing * 1.2);
|
|
@@ -1915,7 +1931,7 @@ var WetStrokeDriver = (_class5 = class {
|
|
|
1915
1931
|
});
|
|
1916
1932
|
const rates = _chunkPQ3H2AANcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
|
|
1917
1933
|
this.states = copies.map((c, i) => ({
|
|
1918
|
-
walker: new (0,
|
|
1934
|
+
walker: new (0, _chunk5BR7LC24cjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
|
|
1919
1935
|
exchange: wet.tool === "paint" ? new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, init.load) : null,
|
|
1920
1936
|
last: null
|
|
1921
1937
|
}));
|
|
@@ -1925,28 +1941,29 @@ var WetStrokeDriver = (_class5 = class {
|
|
|
1925
1941
|
this.sampler = g ? new (0, _chunkPQ3H2AANcjs.PaintGradientSampler)(g.map.by === "across-tip" ? { ...g, map: { by: "distance", length: 300, repeat: "mirror" } } : g, init.seed) : null;
|
|
1926
1942
|
}
|
|
1927
1943
|
|
|
1928
|
-
|
|
1929
|
-
|
|
1944
|
+
__init36() {this.dabCount = 0}
|
|
1945
|
+
__init37() {this.bounds = null}
|
|
1930
1946
|
/** The world's clock at which each raw point was applied (recorded with the stroke). */
|
|
1931
|
-
|
|
1947
|
+
__init38() {this.steps = []}
|
|
1932
1948
|
|
|
1933
1949
|
|
|
1934
1950
|
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1951
|
+
__init39() {this.queue = []}
|
|
1952
|
+
__init40() {this.finishing = false}
|
|
1953
|
+
__init41() {this.finished = false}
|
|
1954
|
+
__init42() {this.lastRaw = null}
|
|
1955
|
+
__init43() {this.lastFed = null}
|
|
1956
|
+
__init44() {this.tip = new Float32Array(0)}
|
|
1957
|
+
__init45() {this.cov = new Float32Array(0)}
|
|
1958
|
+
__init46() {this.paint = [0, 0, 0]}
|
|
1959
|
+
__init47() {this.centre = [0, 0, 0]}
|
|
1943
1960
|
|
|
1944
1961
|
|
|
1945
|
-
|
|
1962
|
+
__init48() {this.sample = { rgb: [0, 0, 0], alpha: 1 }}
|
|
1946
1963
|
|
|
1947
1964
|
/** What copy 0's brush carries after the dabs so far. */
|
|
1948
1965
|
get load() {
|
|
1949
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
1966
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _83 => _83.states, 'access', _84 => _84[0], 'access', _85 => _85.exchange, 'optionalAccess', _86 => _86.load]), () => ( null));
|
|
1950
1967
|
}
|
|
1951
1968
|
/** Whether every point (and the end) has been applied. */
|
|
1952
1969
|
get done() {
|
|
@@ -2040,14 +2057,23 @@ var WetStrokeDriver = (_class5 = class {
|
|
|
2040
2057
|
case "paint": {
|
|
2041
2058
|
const ex = st.exchange;
|
|
2042
2059
|
let flow = 1;
|
|
2043
|
-
|
|
2060
|
+
const effect = this.init.effect;
|
|
2061
|
+
if (effect) {
|
|
2062
|
+
_chunk5BR7LC24cjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
|
|
2063
|
+
ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
|
|
2064
|
+
} else if (this.sampler) {
|
|
2044
2065
|
const g = this.sampler.dab(d, this.sample);
|
|
2045
2066
|
ex.setReservoirColor(g.rgb[0], g.rgb[1], g.rgb[2]);
|
|
2046
2067
|
flow = g.alpha;
|
|
2047
2068
|
}
|
|
2048
2069
|
ex.pickUp(this.medium.sample(rect, tip));
|
|
2049
2070
|
const total = ex.paint(this.paint);
|
|
2050
|
-
if (total > 0 && flow > 0
|
|
2071
|
+
if (total > 0 && flow > 0 && effect) {
|
|
2072
|
+
const ec = cov.slice();
|
|
2073
|
+
const field = new Float32Array(ec.length * 3);
|
|
2074
|
+
_chunk5BR7LC24cjs.effectDabField.call(void 0, effect, rect, ec, this.centre, this.paint, field, COVERAGE_STEPS, d);
|
|
2075
|
+
this.medium.deposit(rect, ec, Math.min(1, total) * k, this.paint, null, field);
|
|
2076
|
+
} else if (total > 0 && flow > 0) this.medium.deposit(rect, cov, Math.min(1, total) * k * flow, this.paint, null);
|
|
2051
2077
|
else world.paint(laneId, rect, cov, this.medium.options.water * k, null);
|
|
2052
2078
|
ex.drain();
|
|
2053
2079
|
if (wet.rewet > 0) world.rewet(laneId, rect, cov, wet.rewet * k * 0.15, this.init.paperColor);
|
|
@@ -2089,7 +2115,7 @@ var WET_GPU_MODES = ["auto", "off"];
|
|
|
2089
2115
|
var GPU_LEAD = 16;
|
|
2090
2116
|
var DISPLAY_TILES_PER_TICK = 24;
|
|
2091
2117
|
var PaintWetLayers = (_class6 = class {
|
|
2092
|
-
constructor(host, options = {}) {;_class6.prototype.
|
|
2118
|
+
constructor(host, options = {}) {;_class6.prototype.__init49.call(this);_class6.prototype.__init50.call(this);_class6.prototype.__init51.call(this);_class6.prototype.__init52.call(this);_class6.prototype.__init53.call(this);_class6.prototype.__init54.call(this);_class6.prototype.__init55.call(this);_class6.prototype.__init56.call(this);_class6.prototype.__init57.call(this);_class6.prototype.__init58.call(this);_class6.prototype.__init59.call(this);_class6.prototype.__init60.call(this);_class6.prototype.__init61.call(this);_class6.prototype.__init62.call(this);_class6.prototype.__init63.call(this);_class6.prototype.__init64.call(this);
|
|
2093
2119
|
this.host = host;
|
|
2094
2120
|
this.options = options;
|
|
2095
2121
|
this.speed = Math.max(1, Math.min(2e3, _nullishCoalesce(options.speed, () => ( 120))));
|
|
@@ -2099,27 +2125,27 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2099
2125
|
}
|
|
2100
2126
|
|
|
2101
2127
|
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2128
|
+
__init49() {this.world = null}
|
|
2129
|
+
__init50() {this.tilt = { ..._chunkXFYLA3ZOcjs.FLAT }}
|
|
2130
|
+
__init51() {this.settings = /* @__PURE__ */ new Map()}
|
|
2131
|
+
__init52() {this.paused = false}
|
|
2106
2132
|
/** Wet strokes dry as soon as they end (one undo step with the stroke). */
|
|
2107
|
-
|
|
2133
|
+
__init53() {this.instantDry = false}
|
|
2108
2134
|
|
|
2109
|
-
|
|
2135
|
+
__init54() {this.overlay = false}
|
|
2110
2136
|
|
|
2111
2137
|
/** The live wet stroke, if any. */
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2138
|
+
__init55() {this.driver = null}
|
|
2139
|
+
__init56() {this.lastTick = null}
|
|
2140
|
+
__init57() {this.ticking = null}
|
|
2141
|
+
__init58() {this.stepsOwed = 0}
|
|
2142
|
+
__init59() {this.displaying = null}
|
|
2143
|
+
__init60() {this.leadAt = 0}
|
|
2118
2144
|
|
|
2119
2145
|
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2146
|
+
__init61() {this.gpu = null}
|
|
2147
|
+
__init62() {this.gpuSupport = null}
|
|
2148
|
+
__init63() {this.gpuStarting = null}
|
|
2123
2149
|
// --- Engine B ------------------------------------------------------------------
|
|
2124
2150
|
/** Starts the GPU engine for the world (once; it may turn out unavailable). */
|
|
2125
2151
|
startGpu() {
|
|
@@ -2155,8 +2181,8 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2155
2181
|
if (mode === this.gpuMode) return this.engineInfo();
|
|
2156
2182
|
this.gpuMode = mode;
|
|
2157
2183
|
if (mode === "off") {
|
|
2158
|
-
_optionalChain([this, 'access',
|
|
2159
|
-
_optionalChain([this, 'access',
|
|
2184
|
+
_optionalChain([this, 'access', _87 => _87.world, 'optionalAccess', _88 => _88.attachGpu, 'call', _89 => _89(null)]);
|
|
2185
|
+
_optionalChain([this, 'access', _90 => _90.gpu, 'optionalAccess', _91 => _91.destroy, 'call', _92 => _92()]);
|
|
2160
2186
|
this.gpu = null;
|
|
2161
2187
|
this.gpuSupport = null;
|
|
2162
2188
|
} else if (this.world) this.startGpu();
|
|
@@ -2164,13 +2190,13 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2164
2190
|
}
|
|
2165
2191
|
engineInfo() {
|
|
2166
2192
|
const w = this.world;
|
|
2167
|
-
const base = { mode: this.gpuMode, adapter: _nullishCoalesce(_optionalChain([this, 'access',
|
|
2193
|
+
const base = { mode: this.gpuMode, adapter: _nullishCoalesce(_optionalChain([this, 'access', _93 => _93.gpuSupport, 'optionalAccess', _94 => _94.adapter]), () => ( null)), maxTiles: _nullishCoalesce(_optionalChain([this, 'access', _95 => _95.gpuSupport, 'optionalAccess', _96 => _96.maxSlots]), () => ( 0)), minTiles: this.gpuMinTiles, activeTiles: _nullishCoalesce(_optionalChain([w, 'optionalAccess', _97 => _97.activeTiles, 'call', _98 => _98()]), () => ( 0)), cpu: this.backend() };
|
|
2168
2194
|
if (this.gpuMode === "off") return { ...base, state: "off", reason: "Forced to the CPU." };
|
|
2169
2195
|
if (this.gpuStarting) return { ...base, state: "starting", reason: null };
|
|
2170
|
-
if (_optionalChain([w, 'optionalAccess',
|
|
2196
|
+
if (_optionalChain([w, 'optionalAccess', _99 => _99.gpuError])) return { ...base, state: "failed", reason: w.gpuError };
|
|
2171
2197
|
if (this.gpuSupport && !this.gpuSupport.supported) return { ...base, state: "unavailable", reason: this.gpuSupport.reason };
|
|
2172
2198
|
if (!this.gpu) return { ...base, state: "not-started", reason: "Starts with the first wet stroke." };
|
|
2173
|
-
if (_optionalChain([w, 'optionalAccess',
|
|
2199
|
+
if (_optionalChain([w, 'optionalAccess', _100 => _100.gpuActive])) return { ...base, state: "active", reason: null };
|
|
2174
2200
|
return { ...base, state: "standby", reason: `The GPU takes over at ${this.gpuMinTiles} wet tiles (256 px).` };
|
|
2175
2201
|
}
|
|
2176
2202
|
/** The world (made on first use, at the canvas size). */
|
|
@@ -2209,13 +2235,13 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2209
2235
|
if (!this.canExtend(left, top)) throw new Error("Wet paint only moves by whole 256 px tiles, between strokes.");
|
|
2210
2236
|
for (const [id, s] of this.settings) if (s.flow.center) this.settings.set(id, { ...s, flow: { ...s.flow, center: { x: s.flow.center.x + left, y: s.flow.center.y + top } } });
|
|
2211
2237
|
const old = this.world;
|
|
2212
|
-
const snap = _optionalChain([old, 'optionalAccess',
|
|
2238
|
+
const snap = _optionalChain([old, 'optionalAccess', _101 => _101.laneIds, 'call', _102 => _102(), 'access', _103 => _103.length]) ? old.snapshot() : null;
|
|
2213
2239
|
this.dropWorld();
|
|
2214
2240
|
this.lastTick = null;
|
|
2215
2241
|
this.stepsOwed = 0;
|
|
2216
2242
|
if (!old || !snap) return;
|
|
2217
2243
|
const moved = _chunkXFYLA3ZOcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left, top, (l) => {
|
|
2218
|
-
const flow = _optionalChain([this, 'access',
|
|
2244
|
+
const flow = _optionalChain([this, 'access', _104 => _104.settings, 'access', _105 => _105.get, 'call', _106 => _106(l.id), 'optionalAccess', _107 => _107.flow]);
|
|
2219
2245
|
return {
|
|
2220
2246
|
base: _chunk474IQG74cjs.translateSurface.call(void 0, l.base, left, top),
|
|
2221
2247
|
flow: l.flow && flow && flow.kind !== "none" ? _chunkXFYLA3ZOcjs.flowField.call(void 0, flow, width, height) : l.flow
|
|
@@ -2233,11 +2259,11 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2233
2259
|
}
|
|
2234
2260
|
/** Layers holding a wet layer (wet or drying). */
|
|
2235
2261
|
wetLayerIds() {
|
|
2236
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
2262
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _108 => _108.world, 'optionalAccess', _109 => _109.laneIds, 'call', _110 => _110()]), () => ( []));
|
|
2237
2263
|
}
|
|
2238
2264
|
/** Whether a batch is running (edits wait). */
|
|
2239
2265
|
get busy() {
|
|
2240
|
-
return Boolean(_optionalChain([this, 'access',
|
|
2266
|
+
return Boolean(_optionalChain([this, 'access', _111 => _111.world, 'optionalAccess', _112 => _112.busy]));
|
|
2241
2267
|
}
|
|
2242
2268
|
/** Resolves when no batch is running. */
|
|
2243
2269
|
async idle() {
|
|
@@ -2266,13 +2292,13 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2266
2292
|
setParams(layerId, update) {
|
|
2267
2293
|
const s = this.settingsOf(layerId);
|
|
2268
2294
|
s.params = _chunkXFYLA3ZOcjs.normalizeWetParams.call(void 0, update, s.params);
|
|
2269
|
-
if (_optionalChain([this, 'access',
|
|
2295
|
+
if (_optionalChain([this, 'access', _113 => _113.world, 'optionalAccess', _114 => _114.hasLane, 'call', _115 => _115(layerId)])) this.world.setParams(layerId, s.params);
|
|
2270
2296
|
return { ...s.params };
|
|
2271
2297
|
}
|
|
2272
2298
|
setFlow(layerId, update) {
|
|
2273
2299
|
const s = this.settingsOf(layerId);
|
|
2274
2300
|
s.flow = _chunkXFYLA3ZOcjs.normalizeFlow.call(void 0, update, s.flow);
|
|
2275
|
-
if (_optionalChain([this, 'access',
|
|
2301
|
+
if (_optionalChain([this, 'access', _116 => _116.world, 'optionalAccess', _117 => _117.hasLane, 'call', _118 => _118(layerId)])) {
|
|
2276
2302
|
const { width, height } = this.host.canvas();
|
|
2277
2303
|
this.world.setFlow(layerId, _chunkXFYLA3ZOcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
|
|
2278
2304
|
}
|
|
@@ -2280,29 +2306,29 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2280
2306
|
}
|
|
2281
2307
|
setTilt(update) {
|
|
2282
2308
|
this.tilt = _chunkXFYLA3ZOcjs.normalizeTilt.call(void 0, update, this.tilt);
|
|
2283
|
-
_optionalChain([this, 'access',
|
|
2309
|
+
_optionalChain([this, 'access', _119 => _119.world, 'optionalAccess', _120 => _120.setTilt, 'call', _121 => _121(this.tilt)]);
|
|
2284
2310
|
return { ...this.tilt };
|
|
2285
2311
|
}
|
|
2286
2312
|
/** The paper changed. */
|
|
2287
2313
|
paperChanged() {
|
|
2288
|
-
_optionalChain([this, 'access',
|
|
2314
|
+
_optionalChain([this, 'access', _122 => _122.world, 'optionalAccess', _123 => _123.setPaper, 'call', _124 => _124(wetPaperInput(this.host.paper()))]);
|
|
2289
2315
|
}
|
|
2290
2316
|
/** A layer as tools describe it. */
|
|
2291
2317
|
info(layerId) {
|
|
2292
2318
|
const s = this.settingsOf(layerId);
|
|
2293
|
-
const st = _optionalChain([this, 'access',
|
|
2319
|
+
const st = _optionalChain([this, 'access', _125 => _125.world, 'optionalAccess', _126 => _126.hasLane, 'call', _127 => _127(layerId)]) ? this.world.stats(layerId) : null;
|
|
2294
2320
|
return {
|
|
2295
2321
|
layerId,
|
|
2296
2322
|
wet: Boolean(st && st.wetCells > 0),
|
|
2297
|
-
wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess',
|
|
2298
|
-
wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess',
|
|
2299
|
-
activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess',
|
|
2323
|
+
wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _128 => _128.wetCells]), () => ( 0)),
|
|
2324
|
+
wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _129 => _129.wetBounds]), () => ( null)),
|
|
2325
|
+
activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _130 => _130.activeTiles]), () => ( 0)),
|
|
2300
2326
|
params: { ...s.params },
|
|
2301
2327
|
flow: { ...s.flow }
|
|
2302
2328
|
};
|
|
2303
2329
|
}
|
|
2304
2330
|
backend() {
|
|
2305
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
2331
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _131 => _131.world, 'optionalAccess', _132 => _132.backend, 'call', _133 => _133()]), () => ( null));
|
|
2306
2332
|
}
|
|
2307
2333
|
/** Shows the current wet pixels (at most `maxTiles` reshaded per layer). */
|
|
2308
2334
|
syncDisplays(maxTiles = Infinity) {
|
|
@@ -2338,7 +2364,7 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2338
2364
|
const w = this.world;
|
|
2339
2365
|
if (!w) return;
|
|
2340
2366
|
for (const id of w.laneIds()) {
|
|
2341
|
-
if (w.isActive(id) || _optionalChain([this, 'access',
|
|
2367
|
+
if (w.isActive(id) || _optionalChain([this, 'access', _134 => _134.driver, 'optionalAccess', _135 => _135.init, 'access', _136 => _136.laneId]) === id) continue;
|
|
2342
2368
|
const base = w.getBase(id);
|
|
2343
2369
|
w.removeLane(id);
|
|
2344
2370
|
this.host.updateSurfaces(/* @__PURE__ */ new Map([[id, base]]), []);
|
|
@@ -2418,10 +2444,10 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2418
2444
|
if (!d || !this.world) return;
|
|
2419
2445
|
const rects = d.flush();
|
|
2420
2446
|
if (rects.length) this.syncDisplays(DISPLAY_TILES_PER_TICK);
|
|
2421
|
-
if (d.done) _optionalChain([this, 'access',
|
|
2447
|
+
if (d.done) _optionalChain([this, 'access', _137 => _137.onDriverDone, 'optionalCall', _138 => _138(d)]);
|
|
2422
2448
|
}
|
|
2423
2449
|
/** Called when a live stroke that ended mid-batch has finished applying. */
|
|
2424
|
-
|
|
2450
|
+
__init64() {this.onDriverDone = null}
|
|
2425
2451
|
/** Steps `steps` times now (agents, tests). Returns the steps run. */
|
|
2426
2452
|
async advance(steps) {
|
|
2427
2453
|
await this.idle();
|
|
@@ -2462,7 +2488,7 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2462
2488
|
/** The layer's pixels with all its wet paint dried (deterministic), without changing anything. */
|
|
2463
2489
|
bakedSurface(layerId) {
|
|
2464
2490
|
const w = this.world;
|
|
2465
|
-
if (!_optionalChain([w, 'optionalAccess',
|
|
2491
|
+
if (!_optionalChain([w, 'optionalAccess', _139 => _139.hasLane, 'call', _140 => _140(layerId)])) return null;
|
|
2466
2492
|
return w.bakedSurface(layerId);
|
|
2467
2493
|
}
|
|
2468
2494
|
/** A snapshot of the world for undo (`null` when there is none). */
|
|
@@ -2483,13 +2509,13 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2483
2509
|
this.syncDisplays();
|
|
2484
2510
|
}
|
|
2485
2511
|
dropWorld() {
|
|
2486
|
-
_optionalChain([this, 'access',
|
|
2512
|
+
_optionalChain([this, 'access', _141 => _141.world, 'optionalAccess', _142 => _142.destroy, 'call', _143 => _143()]);
|
|
2487
2513
|
this.world = null;
|
|
2488
2514
|
this.driver = null;
|
|
2489
2515
|
}
|
|
2490
2516
|
/** Forgets everything wet (a new canvas, a resize, opening a document). */
|
|
2491
2517
|
reset() {
|
|
2492
|
-
_optionalChain([this, 'access',
|
|
2518
|
+
_optionalChain([this, 'access', _144 => _144.world, 'optionalAccess', _145 => _145.destroy, 'call', _146 => _146()]);
|
|
2493
2519
|
this.world = null;
|
|
2494
2520
|
this.driver = null;
|
|
2495
2521
|
this.settings.clear();
|
|
@@ -2519,14 +2545,14 @@ var PaintWetLayers = (_class6 = class {
|
|
|
2519
2545
|
return out;
|
|
2520
2546
|
}
|
|
2521
2547
|
destroy() {
|
|
2522
|
-
_optionalChain([this, 'access',
|
|
2548
|
+
_optionalChain([this, 'access', _147 => _147.world, 'optionalAccess', _148 => _148.destroy, 'call', _149 => _149()]);
|
|
2523
2549
|
this.world = null;
|
|
2524
|
-
_optionalChain([this, 'access',
|
|
2550
|
+
_optionalChain([this, 'access', _150 => _150.gpu, 'optionalAccess', _151 => _151.destroy, 'call', _152 => _152()]);
|
|
2525
2551
|
this.gpu = null;
|
|
2526
2552
|
}
|
|
2527
2553
|
}, _class6);
|
|
2528
2554
|
function wetPigmentOf(hex, body) {
|
|
2529
|
-
const [r, g, b] =
|
|
2555
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, hex);
|
|
2530
2556
|
return Array.from(_chunkXFYLA3ZOcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
|
|
2531
2557
|
}
|
|
2532
2558
|
|
|
@@ -2534,13 +2560,13 @@ function wetPigmentOf(hex, body) {
|
|
|
2534
2560
|
var thumbWorld = null;
|
|
2535
2561
|
function paintWetTestStroke(brush, paper, color, width, height) {
|
|
2536
2562
|
if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
|
|
2537
|
-
_optionalChain([thumbWorld, 'optionalAccess',
|
|
2563
|
+
_optionalChain([thumbWorld, 'optionalAccess', _153 => _153.destroy, 'call', _154 => _154()]);
|
|
2538
2564
|
thumbWorld = new (0, _chunkXFYLA3ZOcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
|
|
2539
2565
|
} else thumbWorld.setPaper(wetPaperInput(paper));
|
|
2540
2566
|
const w = thumbWorld;
|
|
2541
2567
|
if (w.hasLane("thumb")) w.removeLane("thumb");
|
|
2542
2568
|
w.ensureLane("thumb");
|
|
2543
|
-
const [r, g, b] =
|
|
2569
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, color);
|
|
2544
2570
|
if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
|
|
2545
2571
|
const half = Math.ceil(height / 2);
|
|
2546
2572
|
w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkXFYLA3ZOcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
|
|
@@ -2554,9 +2580,9 @@ function paintWetTestStroke(brush, paper, color, width, height) {
|
|
|
2554
2580
|
load: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
|
|
2555
2581
|
grain: paperGrain(paper),
|
|
2556
2582
|
paperDepth: paper.depth,
|
|
2557
|
-
paperColor:
|
|
2583
|
+
paperColor: _chunk5BR7LC24cjs.hexToRgb8.call(void 0, paper.color),
|
|
2558
2584
|
seed: 7,
|
|
2559
|
-
copies: [
|
|
2585
|
+
copies: [_chunk5BR7LC24cjs.IDENTITY_COPY]
|
|
2560
2586
|
});
|
|
2561
2587
|
driver.push(thumbnailStroke(width, height));
|
|
2562
2588
|
driver.finish();
|
|
@@ -2576,7 +2602,7 @@ function thumbnailStroke(width, height) {
|
|
|
2576
2602
|
return pts;
|
|
2577
2603
|
}
|
|
2578
2604
|
function paintTestStroke(surface, brush, paper, color, width, height) {
|
|
2579
|
-
const [r, g, b] =
|
|
2605
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, color);
|
|
2580
2606
|
let result = surface;
|
|
2581
2607
|
let thick = null;
|
|
2582
2608
|
const session = new PaintStrokeSession(
|
|
@@ -2595,13 +2621,13 @@ function paintTestStroke(surface, brush, paper, color, width, height) {
|
|
|
2595
2621
|
lockTransparency: false,
|
|
2596
2622
|
brush,
|
|
2597
2623
|
color: [r, g, b, 255],
|
|
2598
|
-
background: [...
|
|
2624
|
+
background: [..._chunk5BR7LC24cjs.hexToRgb8.call(void 0, paper.color), 255],
|
|
2599
2625
|
grain: paperGrain(paper),
|
|
2600
2626
|
paperDepth: paper.depth,
|
|
2601
2627
|
seed: 7,
|
|
2602
2628
|
colorHex: color,
|
|
2603
2629
|
affineCopies: [],
|
|
2604
|
-
copies: [
|
|
2630
|
+
copies: [_chunk5BR7LC24cjs.IDENTITY_COPY],
|
|
2605
2631
|
mixerLoad: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
|
|
2606
2632
|
thick: brush.engine === "impasto" ? { channels: emptyThickChannels() } : void 0,
|
|
2607
2633
|
sticker: brush.engine === "sticker" ? { nextId: 1 } : void 0
|
|
@@ -2615,8 +2641,8 @@ function renderBrushThumbnail(brush, options) {
|
|
|
2615
2641
|
const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
|
|
2616
2642
|
const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
|
|
2617
2643
|
const maxSize = height * 0.42;
|
|
2618
|
-
const b = brush.tip.size > maxSize ?
|
|
2619
|
-
const rgba = [...
|
|
2644
|
+
const b = brush.tip.size > maxSize ? _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
|
|
2645
|
+
const rgba = [..._chunk5BR7LC24cjs.hexToRgb8.call(void 0, options.color), 255];
|
|
2620
2646
|
let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
|
|
2621
2647
|
if (b.engine === "eraser") {
|
|
2622
2648
|
surface = _chunk474IQG74cjs.fillRect.call(void 0, surface, { x: 0, y: 0, width, height }, rgba);
|
|
@@ -2758,12 +2784,12 @@ function perspectiveDirections(g, p) {
|
|
|
2758
2784
|
}
|
|
2759
2785
|
var SNAP_DECIDE_DISTANCE = 6;
|
|
2760
2786
|
var PerspectiveSnapper = (_class7 = class {
|
|
2761
|
-
constructor(guide) {;_class7.prototype.
|
|
2787
|
+
constructor(guide) {;_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);
|
|
2762
2788
|
this.guide = guide;
|
|
2763
2789
|
}
|
|
2764
2790
|
|
|
2765
|
-
|
|
2766
|
-
|
|
2791
|
+
__init65() {this.start = null}
|
|
2792
|
+
__init66() {this.dir = null}
|
|
2767
2793
|
/** The line the stroke follows, once chosen. */
|
|
2768
2794
|
get line() {
|
|
2769
2795
|
return this.start && this.dir ? { from: this.start, direction: this.dir } : null;
|
|
@@ -2869,11 +2895,11 @@ function readSwatch(raw) {
|
|
|
2869
2895
|
if (!raw || typeof raw !== "object") return null;
|
|
2870
2896
|
const r = raw;
|
|
2871
2897
|
const g = _chunkPQ3H2AANcjs.readPaintSource.call(void 0, r.paint);
|
|
2872
|
-
const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess',
|
|
2898
|
+
const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _155 => _155.type]) === "gradient" ? _chunkPQ3H2AANcjs.paintSourceColor.call(void 0, g) : null;
|
|
2873
2899
|
if (!color) return null;
|
|
2874
2900
|
const out = { color };
|
|
2875
2901
|
if (typeof r.name === "string" && r.name.trim()) out.name = r.name.trim().slice(0, 80);
|
|
2876
|
-
if (_optionalChain([g, 'optionalAccess',
|
|
2902
|
+
if (_optionalChain([g, 'optionalAccess', _156 => _156.type]) === "gradient") out.paint = g;
|
|
2877
2903
|
return out;
|
|
2878
2904
|
}
|
|
2879
2905
|
var DEFAULT_SWATCHES = [
|
|
@@ -2892,7 +2918,7 @@ var DEFAULT_SWATCHES = [
|
|
|
2892
2918
|
// src/paint-editor/mixing-pad.ts
|
|
2893
2919
|
var MIXING_PAD_WIDTH = 360;
|
|
2894
2920
|
var MIXING_PAD_HEIGHT = 220;
|
|
2895
|
-
var PAD_PAINT =
|
|
2921
|
+
var PAD_PAINT = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, {
|
|
2896
2922
|
id: "pad-paint",
|
|
2897
2923
|
name: "Pad paint",
|
|
2898
2924
|
category: "mixer",
|
|
@@ -2900,7 +2926,7 @@ var PAD_PAINT = _chunkNKTNLJUJcjs.normalizePaintBrush.call(void 0, {
|
|
|
2900
2926
|
tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
|
|
2901
2927
|
mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
|
|
2902
2928
|
});
|
|
2903
|
-
var PAD_KNIFE =
|
|
2929
|
+
var PAD_KNIFE = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, {
|
|
2904
2930
|
id: "pad-knife",
|
|
2905
2931
|
name: "Palette knife",
|
|
2906
2932
|
category: "smudge",
|
|
@@ -2910,19 +2936,19 @@ var PAD_KNIFE = _chunkNKTNLJUJcjs.normalizePaintBrush.call(void 0, {
|
|
|
2910
2936
|
// A knife drags streaks of paint and folds them into each other, mixing them as pigment.
|
|
2911
2937
|
smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
|
|
2912
2938
|
});
|
|
2913
|
-
var PAD_BLOB =
|
|
2939
|
+
var PAD_BLOB = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, {
|
|
2914
2940
|
id: "pad-blob",
|
|
2915
2941
|
name: "Pad blob",
|
|
2916
2942
|
category: "custom",
|
|
2917
2943
|
engine: "dab",
|
|
2918
2944
|
tip: { size: 20, hardness: 1, spacing: 0.1, opacity: 1, flow: 1, pressureSize: false, pressureOpacity: false }
|
|
2919
2945
|
});
|
|
2920
|
-
var MixingPad = (_class8 = class {constructor() { _class8.prototype.
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2946
|
+
var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init67.call(this);_class8.prototype.__init68.call(this);_class8.prototype.__init69.call(this);_class8.prototype.__init70.call(this); }
|
|
2947
|
+
__init67() {this.width = MIXING_PAD_WIDTH}
|
|
2948
|
+
__init68() {this.height = MIXING_PAD_HEIGHT}
|
|
2949
|
+
__init69() {this.surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4)}
|
|
2924
2950
|
/** Increments on every change (for redrawing). */
|
|
2925
|
-
|
|
2951
|
+
__init70() {this.version = 0}
|
|
2926
2952
|
/** Paints (`paint`, with `color`) or smears (`knife`) through `points` in pad pixels. */
|
|
2927
2953
|
stroke(points, options) {
|
|
2928
2954
|
if (!points.length) throw new Error("points is empty; give at least one {x, y} in pad pixels.");
|
|
@@ -2932,12 +2958,12 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
|
|
|
2932
2958
|
}
|
|
2933
2959
|
}
|
|
2934
2960
|
let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
|
|
2935
|
-
if (options.size !== void 0) brush =
|
|
2961
|
+
if (options.size !== void 0) brush = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
|
|
2936
2962
|
return this.run(brush, points, options.color);
|
|
2937
2963
|
}
|
|
2938
2964
|
/** Paints `points` with `brush` in `color` on the pad. */
|
|
2939
2965
|
run(brush, points, color) {
|
|
2940
|
-
const [r, g, b] =
|
|
2966
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, color);
|
|
2941
2967
|
let result = null;
|
|
2942
2968
|
const session = new PaintStrokeSession(
|
|
2943
2969
|
{ update: () => {
|
|
@@ -2955,7 +2981,7 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
|
|
|
2955
2981
|
seed: 1,
|
|
2956
2982
|
colorHex: color,
|
|
2957
2983
|
affineCopies: [],
|
|
2958
|
-
copies: [
|
|
2984
|
+
copies: [_chunk5BR7LC24cjs.IDENTITY_COPY],
|
|
2959
2985
|
mixerLoad: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
|
|
2960
2986
|
}
|
|
2961
2987
|
);
|
|
@@ -3031,10 +3057,10 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
|
|
|
3031
3057
|
const off = used.length === 1 ? 0 : 0.45 * R;
|
|
3032
3058
|
const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
|
|
3033
3059
|
const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
|
|
3034
|
-
const blob =
|
|
3060
|
+
const blob = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
|
|
3035
3061
|
this.run(blob, [{ x, y }], p.color.toLowerCase());
|
|
3036
3062
|
});
|
|
3037
|
-
const knife =
|
|
3063
|
+
const knife = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
|
|
3038
3064
|
for (let k = 0; k < passes; k++) {
|
|
3039
3065
|
const stir = [];
|
|
3040
3066
|
const turns = 1.6;
|
|
@@ -3046,10 +3072,10 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
|
|
|
3046
3072
|
this.run(knife, stir, "#000000");
|
|
3047
3073
|
}
|
|
3048
3074
|
const mixed = _chunkOLNIPTB3cjs.mixPigments.call(void 0,
|
|
3049
|
-
paints.map((p) =>
|
|
3075
|
+
paints.map((p) => _chunk5BR7LC24cjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
|
|
3050
3076
|
paints.map((p) => p.parts)
|
|
3051
3077
|
);
|
|
3052
|
-
const core =
|
|
3078
|
+
const core = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
|
|
3053
3079
|
const hex = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
|
|
3054
3080
|
this.run(core, [{ x: cx, y: cy }], hex);
|
|
3055
3081
|
return { color: this.pick(cx, cy, 2), bounds };
|
|
@@ -3060,7 +3086,7 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
|
|
|
3060
3086
|
}
|
|
3061
3087
|
/** Replaces the pad with a PNG (data URL or base64) of the pad's size, as `toPng` writes. */
|
|
3062
3088
|
fromPng(png) {
|
|
3063
|
-
const bytes = png.startsWith("data:") ? _optionalChain([_chunkOLNIPTB3cjs.parseDataUrl.call(void 0, png), 'optionalAccess',
|
|
3089
|
+
const bytes = png.startsWith("data:") ? _optionalChain([_chunkOLNIPTB3cjs.parseDataUrl.call(void 0, png), 'optionalAccess', _157 => _157.bytes]) : _chunkOLNIPTB3cjs.base64ToBytes.call(void 0, png);
|
|
3064
3090
|
if (!bytes || !_chunkOLNIPTB3cjs.isPng.call(void 0, bytes)) throw new Error("The pad image is not a PNG data URL or base64 PNG.");
|
|
3065
3091
|
const img = _chunkOLNIPTB3cjs.decodePng.call(void 0, bytes);
|
|
3066
3092
|
if (img.width !== this.width || img.height !== this.height) throw new Error(`The pad image is ${img.width}\xD7${img.height}; a mixing pad is ${this.width}\xD7${this.height}.`);
|
|
@@ -3085,6 +3111,43 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
|
|
|
3085
3111
|
}
|
|
3086
3112
|
}, _class8);
|
|
3087
3113
|
|
|
3114
|
+
// src/paint-editor/live-strokes.ts
|
|
3115
|
+
var LIVE_STROKE_ENGINES = ["dab", "particle", "bristle", "mixer"];
|
|
3116
|
+
function liveStrokeRefusal(brush) {
|
|
3117
|
+
switch (brush.engine) {
|
|
3118
|
+
case "wet":
|
|
3119
|
+
return `The ${brush.name} brush paints wet media, which a stroke layer can't redraw (the paint depends on the simulation's history); paint it on a pixel layer (add_layer).`;
|
|
3120
|
+
case "impasto":
|
|
3121
|
+
return `The ${brush.name} brush paints thick paint with relief, which a stroke layer doesn't keep; paint it on a pixel layer (add_layer).`;
|
|
3122
|
+
case "sticker":
|
|
3123
|
+
return `The ${brush.name} brush sprays stickers, which are their own objects; spray them on an empty pixel layer (add_layer).`;
|
|
3124
|
+
case "eraser":
|
|
3125
|
+
return `Erasers don't paint on a stroke layer; delete strokes instead (remove_strokes), or rasterize the layer first (rasterize_stroke_layer).`;
|
|
3126
|
+
case "blender":
|
|
3127
|
+
case "smudge":
|
|
3128
|
+
return `The ${brush.name} brush moves the paint under it, so it can't be redrawn on its own; rasterize the layer first (rasterize_stroke_layer) or blend on a pixel layer.`;
|
|
3129
|
+
}
|
|
3130
|
+
if (brush.behavior.pickup > 0) return `The ${brush.name} brush picks up the paint under it (pickup ${brush.behavior.pickup}), so it can't be redrawn on its own; set behavior.pickup to 0 (set_brush) or paint on a pixel layer.`;
|
|
3131
|
+
return null;
|
|
3132
|
+
}
|
|
3133
|
+
function liveStrokeBounds(stroke) {
|
|
3134
|
+
let x0 = Infinity;
|
|
3135
|
+
let y0 = Infinity;
|
|
3136
|
+
let x1 = -Infinity;
|
|
3137
|
+
let y1 = -Infinity;
|
|
3138
|
+
for (const m of [null, ..._nullishCoalesce(stroke.copies, () => ( []))]) {
|
|
3139
|
+
for (const p of stroke.points) {
|
|
3140
|
+
const q = m ? applyAffine(m, p.x, p.y) : p;
|
|
3141
|
+
if (q.x < x0) x0 = q.x;
|
|
3142
|
+
if (q.y < y0) y0 = q.y;
|
|
3143
|
+
if (q.x > x1) x1 = q.x;
|
|
3144
|
+
if (q.y > y1) y1 = q.y;
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
const pad = stroke.brush.tip.size * (stroke.brush.engine === "particle" ? 2 : 1) + 2;
|
|
3148
|
+
return { x: Math.floor(x0 - pad), y: Math.floor(y0 - pad), width: Math.ceil(x1 - x0 + 2 * pad), height: Math.ceil(y1 - y0 + 2 * pad) };
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3088
3151
|
// src/paint-editor/replay.ts
|
|
3089
3152
|
function replayItems(doc) {
|
|
3090
3153
|
const items = [];
|
|
@@ -3107,7 +3170,7 @@ async function replayPainting(source, target, options = {}) {
|
|
|
3107
3170
|
const maxStrokes = _nullishCoalesce(options.strokes, () => ( source.strokes.length));
|
|
3108
3171
|
const chunk = Math.max(1, _nullishCoalesce(options.wetChunk, () => ( 0))) || Infinity;
|
|
3109
3172
|
let strokes = 0;
|
|
3110
|
-
await target.prepareEffectPaints(source.strokes.slice(0, maxStrokes).flatMap((st) => _optionalChain([st, 'access',
|
|
3173
|
+
await target.prepareEffectPaints(source.strokes.slice(0, maxStrokes).flatMap((st) => _optionalChain([st, 'access', _158 => _158.paint, 'optionalAccess', _159 => _159.type]) === "effect" ? [st.paint] : []));
|
|
3111
3174
|
const advanceTo = async (clock) => {
|
|
3112
3175
|
const now = target.getState().wet.clock;
|
|
3113
3176
|
let left = clock - now;
|
|
@@ -3115,7 +3178,7 @@ async function replayPainting(source, target, options = {}) {
|
|
|
3115
3178
|
const n = Math.min(left, chunk);
|
|
3116
3179
|
await target.advanceWet({ steps: n });
|
|
3117
3180
|
left -= n;
|
|
3118
|
-
if (Number.isFinite(chunk)) await _optionalChain([options, 'access',
|
|
3181
|
+
if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _160 => _160.onWetSteps, 'optionalCall', _161 => _161(target.getState().wet.clock)]);
|
|
3119
3182
|
}
|
|
3120
3183
|
};
|
|
3121
3184
|
const sr = (r) => ({ x: r.x * s, y: r.y * s, width: r.width * s, height: r.height * s });
|
|
@@ -3126,8 +3189,16 @@ async function replayPainting(source, target, options = {}) {
|
|
|
3126
3189
|
if (!target.getLayer(e.layerId)) continue;
|
|
3127
3190
|
if (e.kind === "fill") target.fillLayer({ layerId: e.layerId, ...e.data });
|
|
3128
3191
|
else if (e.kind === "clear") target.clearLayer(e.layerId);
|
|
3129
|
-
else if (e.kind === "
|
|
3130
|
-
const
|
|
3192
|
+
else if (e.kind === "live-strokes") {
|
|
3193
|
+
const d = e.data;
|
|
3194
|
+
if (_optionalChain([d, 'optionalAccess', _162 => _162.rasterized])) target.replaceLiveStrokes(e.layerId, null);
|
|
3195
|
+
else {
|
|
3196
|
+
const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _163 => _163.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
|
|
3197
|
+
await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _164 => _164.paint, 'optionalAccess', _165 => _165.type]) === "effect" ? [st2.paint] : []));
|
|
3198
|
+
target.replaceLiveStrokes(e.layerId, list);
|
|
3199
|
+
}
|
|
3200
|
+
} else if (e.kind === "stickers") {
|
|
3201
|
+
const list = (_nullishCoalesce(_optionalChain([e, 'access', _166 => _166.data, 'optionalAccess', _167 => _167.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
|
|
3131
3202
|
target.replaceStickers(e.layerId, list);
|
|
3132
3203
|
} else target.flattenRelief(e.layerId);
|
|
3133
3204
|
continue;
|
|
@@ -3140,8 +3211,8 @@ async function replayPainting(source, target, options = {}) {
|
|
|
3140
3211
|
switch (e.kind) {
|
|
3141
3212
|
case "dry": {
|
|
3142
3213
|
const rect = e.data;
|
|
3143
|
-
const ids = _optionalChain([e, 'access',
|
|
3144
|
-
if (_optionalChain([ids, 'optionalAccess',
|
|
3214
|
+
const ids = _optionalChain([e, 'access', _168 => _168.layerId, 'optionalAccess', _169 => _169.split, 'call', _170 => _170(","), 'access', _171 => _171.filter, 'call', _172 => _172(Boolean)]);
|
|
3215
|
+
if (_optionalChain([ids, 'optionalAccess', _173 => _173.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
|
|
3145
3216
|
else target.dryPaint({ rect: rect ? sr(rect) : void 0 });
|
|
3146
3217
|
break;
|
|
3147
3218
|
}
|
|
@@ -3172,7 +3243,7 @@ async function replayPainting(source, target, options = {}) {
|
|
|
3172
3243
|
strokes++;
|
|
3173
3244
|
if (!target.getLayer(st.layerId)) continue;
|
|
3174
3245
|
const init = { layerId: st.layerId, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...st.paint ? { paint: st.paint } : {}, snapToPerspective: false, stencils: false, maskStencils: (_nullishCoalesce(st.stencils, () => ( []))).map((x) => s === 1 ? x : scaleStencil(x, s)) };
|
|
3175
|
-
if (st.brush.engine === "wet" && _optionalChain([st, 'access',
|
|
3246
|
+
if (st.brush.engine === "wet" && _optionalChain([st, 'access', _174 => _174.steps, 'optionalAccess', _175 => _175.length]) === st.points.length) {
|
|
3176
3247
|
await target.wetIdle();
|
|
3177
3248
|
await advanceTo(st.steps[0]);
|
|
3178
3249
|
const session = target.beginStroke({ ...init, start: st.points[0] });
|
|
@@ -3192,7 +3263,7 @@ async function replayPainting(source, target, options = {}) {
|
|
|
3192
3263
|
await target.wetIdle();
|
|
3193
3264
|
target.paintStroke({ ...init, points: st.points });
|
|
3194
3265
|
}
|
|
3195
|
-
await _optionalChain([options, 'access',
|
|
3266
|
+
await _optionalChain([options, 'access', _176 => _176.onStroke, 'optionalCall', _177 => _177(strokes)]);
|
|
3196
3267
|
}
|
|
3197
3268
|
void IDENTITY_AFFINE;
|
|
3198
3269
|
}
|
|
@@ -3237,7 +3308,7 @@ async function buildTimeLapse(source, target, options = {}) {
|
|
|
3237
3308
|
wetChunk: wetEvery > 0 ? wetEvery : 0,
|
|
3238
3309
|
onStroke: (i) => {
|
|
3239
3310
|
if (i % perFrame === 0 || i === total) shoot(i);
|
|
3240
|
-
_optionalChain([options, 'access',
|
|
3311
|
+
_optionalChain([options, 'access', _178 => _178.onProgress, 'optionalCall', _179 => _179(total ? i / total : 1)]);
|
|
3241
3312
|
},
|
|
3242
3313
|
onWetSteps: wetEvery > 0 ? () => shoot(-1) : void 0
|
|
3243
3314
|
});
|
|
@@ -3324,10 +3395,10 @@ function mixPixels(before, after, amount) {
|
|
|
3324
3395
|
}
|
|
3325
3396
|
return out;
|
|
3326
3397
|
}
|
|
3327
|
-
var PaintEffectsRenderer = (_class9 = class {constructor() { _class9.prototype.
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3398
|
+
var PaintEffectsRenderer = (_class9 = class {constructor() { _class9.prototype.__init71.call(this);_class9.prototype.__init72.call(this);_class9.prototype.__init73.call(this); }
|
|
3399
|
+
__init71() {this.pool = new (0, _chunkPY4GWSE2cjs.EffectRendererPool)({ maxRenderers: 3 })}
|
|
3400
|
+
__init72() {this.descriptions = /* @__PURE__ */ new Map()}
|
|
3401
|
+
__init73() {this.provider = null}
|
|
3331
3402
|
/** Forgets cached descriptions and renderers when the provider changes. */
|
|
3332
3403
|
follow(provider) {
|
|
3333
3404
|
if (provider === this.provider) return;
|
|
@@ -3412,7 +3483,7 @@ function parseColor(value, what = "color") {
|
|
|
3412
3483
|
return value.trim().toLowerCase();
|
|
3413
3484
|
}
|
|
3414
3485
|
function rgbaOf(hex) {
|
|
3415
|
-
const [r, g, b] =
|
|
3486
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, hex);
|
|
3416
3487
|
return [r, g, b, 255];
|
|
3417
3488
|
}
|
|
3418
3489
|
function rgbToHex(r, g, b) {
|
|
@@ -3425,75 +3496,87 @@ function unionRect(a, b) {
|
|
|
3425
3496
|
const y = Math.min(a.y, b.y);
|
|
3426
3497
|
return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
|
|
3427
3498
|
}
|
|
3428
|
-
var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess',
|
|
3499
|
+
var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _180 => _180.type]) === "pixel";
|
|
3429
3500
|
var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
3430
3501
|
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3502
|
+
__init74() {this.extensions = {}}
|
|
3503
|
+
__init75() {this.undoStack = []}
|
|
3504
|
+
__init76() {this.redoStack = []}
|
|
3434
3505
|
|
|
3435
3506
|
|
|
3436
3507
|
|
|
3437
3508
|
/** The library list in the state (the same array until the user brushes change, so thumbnails are not redrawn). */
|
|
3438
|
-
|
|
3509
|
+
__init77() {this.library = null}
|
|
3439
3510
|
|
|
3440
|
-
|
|
3511
|
+
__init78() {this.secondaryColor = "#ffffff"}
|
|
3441
3512
|
/** Gradient paint chosen with `setPaint` (`null`: the paint colour). */
|
|
3442
|
-
|
|
3513
|
+
__init79() {this.gradient = null}
|
|
3443
3514
|
/** Effect paint chosen with `setEffectPaint` (rendered), and one still rendering. */
|
|
3444
|
-
|
|
3445
|
-
|
|
3515
|
+
__init80() {this.effectPaint = null}
|
|
3516
|
+
__init81() {this.effectPaintPending = null}
|
|
3446
3517
|
/** Changes whenever the paint is chosen, so an effect paint that finishes rendering late does not take over. */
|
|
3447
|
-
|
|
3518
|
+
__init82() {this.paintEpoch = 0}
|
|
3448
3519
|
/** Rendered effect paints by `effectPaintKey` (most recently used last). */
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3520
|
+
__init83() {this.effectPaintPixels = /* @__PURE__ */ new Map()}
|
|
3521
|
+
__init84() {this.mixerLoad = _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD}
|
|
3522
|
+
__init85() {this.view = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } }}
|
|
3452
3523
|
|
|
3453
|
-
|
|
3524
|
+
__init86() {this.selectedStroke = null}
|
|
3525
|
+
__init87() {this.selectedSticker = null}
|
|
3454
3526
|
/** A sticker drag in progress (`previewSticker`): the document before it, so the drop undoes in one step, and the one it showed last. */
|
|
3455
|
-
|
|
3527
|
+
__init88() {this.stickerPreview = null}
|
|
3456
3528
|
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3529
|
+
__init89() {this.listeners = /* @__PURE__ */ new Set()}
|
|
3530
|
+
__init90() {this.version = 0}
|
|
3531
|
+
__init91() {this.cached = null}
|
|
3532
|
+
__init92() {this.session = null}
|
|
3533
|
+
__init93() {this.live = null}
|
|
3534
|
+
__init94() {this.liveLayers = null}
|
|
3535
|
+
__init95() {this.dirty = "all"}
|
|
3536
|
+
__init96() {this.seedCounter = 1}
|
|
3537
|
+
__init97() {this.strokeCounter = 1}
|
|
3538
|
+
/** Live effect paint: playing and the frame rate cap (editor state), and the time the view shows. */
|
|
3539
|
+
__init98() {this.effectPlaybackState = { playing: true, fps: 30 }}
|
|
3540
|
+
__init99() {this.effectTime = 0}
|
|
3541
|
+
/** While a frame is drawn: the time live effect strokes are drawn at (else their own time). */
|
|
3542
|
+
__init100() {this.liveEffectAt = null}
|
|
3543
|
+
/** The view's stroke layers at `effectTime`, each with the document surface it was drawn from (stale once that changes). */
|
|
3544
|
+
__init101() {this.animatedLayers = /* @__PURE__ */ new Map()}
|
|
3545
|
+
/** `renderAnimationFrame` / `withEffectTime`: layer surfaces at another time, for one render. */
|
|
3546
|
+
__init102() {this.frameOverride = null}
|
|
3547
|
+
/** The area each stroke painted (document pixels; `null`: nothing), learnt as it is painted or drawn, so a stroke layer edit redraws only where it changes (see `drawLiveStrokes`). */
|
|
3548
|
+
__init103() {this.paintedBounds = /* @__PURE__ */ new WeakMap()}
|
|
3466
3549
|
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3550
|
+
__init104() {this.swatches = DEFAULT_SWATCHES.map((s) => ({ ...s }))}
|
|
3551
|
+
__init105() {this.pad = new MixingPad()}
|
|
3552
|
+
__init106() {this.savedPads = []}
|
|
3553
|
+
__init107() {this.nextPadId = 1}
|
|
3554
|
+
__init108() {this.tracingVersion = 1}
|
|
3555
|
+
__init109() {this.tracingCache = null}
|
|
3556
|
+
__init110() {this.imagePixels = /* @__PURE__ */ new Map()}
|
|
3557
|
+
__init111() {this.nextReferenceId = 1}
|
|
3558
|
+
__init112() {this.viewCompositor = createPaintCompositor()}
|
|
3559
|
+
__init113() {this.exportCompositor = createPaintCompositor()}
|
|
3477
3560
|
/** Wet media: the simulation, its settings and time. */
|
|
3478
3561
|
|
|
3479
3562
|
|
|
3480
3563
|
/** Where the light comes from for thick paint (saved with the document, not undo steps). */
|
|
3481
|
-
|
|
3482
|
-
|
|
3564
|
+
__init114() {this.lighting = { ...DEFAULT_LIGHTING }}
|
|
3565
|
+
__init115() {this.litCaches = /* @__PURE__ */ new Map()}
|
|
3483
3566
|
/** The live impasto stroke's channels. */
|
|
3484
|
-
|
|
3567
|
+
__init116() {this.liveThick = null}
|
|
3485
3568
|
/** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
|
|
3486
|
-
|
|
3569
|
+
__init117() {this.wetOp = null}
|
|
3487
3570
|
/** The effects provider slot (see `setEffectsProvider`). */
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
constructor(options = {}) {;_class10.prototype.
|
|
3571
|
+
__init118() {this.effects = new (0, _chunkJAOSL334cjs.EffectsSlot)()}
|
|
3572
|
+
__init119() {this.effectsRenderer = new PaintEffectsRenderer()}
|
|
3573
|
+
__init120() {this.paperEffectNodeCache = null}
|
|
3574
|
+
constructor(options = {}) {;_class10.prototype.__init74.call(this);_class10.prototype.__init75.call(this);_class10.prototype.__init76.call(this);_class10.prototype.__init77.call(this);_class10.prototype.__init78.call(this);_class10.prototype.__init79.call(this);_class10.prototype.__init80.call(this);_class10.prototype.__init81.call(this);_class10.prototype.__init82.call(this);_class10.prototype.__init83.call(this);_class10.prototype.__init84.call(this);_class10.prototype.__init85.call(this);_class10.prototype.__init86.call(this);_class10.prototype.__init87.call(this);_class10.prototype.__init88.call(this);_class10.prototype.__init89.call(this);_class10.prototype.__init90.call(this);_class10.prototype.__init91.call(this);_class10.prototype.__init92.call(this);_class10.prototype.__init93.call(this);_class10.prototype.__init94.call(this);_class10.prototype.__init95.call(this);_class10.prototype.__init96.call(this);_class10.prototype.__init97.call(this);_class10.prototype.__init98.call(this);_class10.prototype.__init99.call(this);_class10.prototype.__init100.call(this);_class10.prototype.__init101.call(this);_class10.prototype.__init102.call(this);_class10.prototype.__init103.call(this);_class10.prototype.__init104.call(this);_class10.prototype.__init105.call(this);_class10.prototype.__init106.call(this);_class10.prototype.__init107.call(this);_class10.prototype.__init108.call(this);_class10.prototype.__init109.call(this);_class10.prototype.__init110.call(this);_class10.prototype.__init111.call(this);_class10.prototype.__init112.call(this);_class10.prototype.__init113.call(this);_class10.prototype.__init114.call(this);_class10.prototype.__init115.call(this);_class10.prototype.__init116.call(this);_class10.prototype.__init117.call(this);_class10.prototype.__init118.call(this);_class10.prototype.__init119.call(this);_class10.prototype.__init120.call(this);_class10.prototype.__init121.call(this);_class10.prototype.__init122.call(this);_class10.prototype.__init123.call(this);_class10.prototype.__init124.call(this);
|
|
3492
3575
|
this.historyLimit = Math.max(1, _nullishCoalesce(options.historyLimit, () => ( 200)));
|
|
3493
3576
|
this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
|
|
3494
|
-
this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) =>
|
|
3495
|
-
const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => (
|
|
3496
|
-
this.brush =
|
|
3577
|
+
this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
|
|
3578
|
+
const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunk5BR7LC24cjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunk5BR7LC24cjs.DEFAULT_BRUSH_ID)));
|
|
3579
|
+
this.brush = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, start);
|
|
3497
3580
|
this.color = options.color ? parseColor(options.color) : "#1f2937";
|
|
3498
3581
|
this.hand = options.hand === "left" ? "left" : "right";
|
|
3499
3582
|
this.encodeImage = options.encodeImage;
|
|
@@ -3504,7 +3587,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3504
3587
|
canvas: () => this.doc.canvas,
|
|
3505
3588
|
paper: () => this.doc.paper,
|
|
3506
3589
|
layerSurface: (id) => {
|
|
3507
|
-
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess',
|
|
3590
|
+
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _181 => _181.layer]);
|
|
3508
3591
|
return isPixelLayer(l) ? l.surface : null;
|
|
3509
3592
|
},
|
|
3510
3593
|
updateSurfaces: (surfaces, rects) => {
|
|
@@ -3518,7 +3601,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3518
3601
|
},
|
|
3519
3602
|
options.wet
|
|
3520
3603
|
);
|
|
3521
|
-
this.wet.onDriverDone = () => _optionalChain([this, 'access',
|
|
3604
|
+
this.wet.onDriverDone = () => _optionalChain([this, 'access', _182 => _182.session, 'optionalAccess', _183 => _183.completeWetEnd, 'call', _184 => _184()]);
|
|
3522
3605
|
}
|
|
3523
3606
|
// --- State and events ----------------------------------------------------------
|
|
3524
3607
|
subscribe(listener) {
|
|
@@ -3540,7 +3623,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3540
3623
|
this.cached = {
|
|
3541
3624
|
document: this.doc,
|
|
3542
3625
|
brush: this.brush,
|
|
3543
|
-
brushes: this.library ??= [...
|
|
3626
|
+
brushes: this.library ??= [..._chunk5BR7LC24cjs.BUILTIN_BRUSHES, ...this.userBrushes],
|
|
3544
3627
|
color: this.color,
|
|
3545
3628
|
secondaryColor: this.secondaryColor,
|
|
3546
3629
|
paint: _nullishCoalesce(this.gradient, () => ( { type: "color", color: this.color })),
|
|
@@ -3549,11 +3632,13 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3549
3632
|
mixerLoad: this.mixerLoad,
|
|
3550
3633
|
view: this.view,
|
|
3551
3634
|
hand: this.hand,
|
|
3635
|
+
effectPlayback: { ...this.effectPlaybackState, time: this.effectTime },
|
|
3636
|
+
selectedStroke: this.selectedStroke,
|
|
3552
3637
|
selectedSticker: this.selectedSticker,
|
|
3553
3638
|
canUndo: this.undoStack.length > 0 && !this.session,
|
|
3554
3639
|
canRedo: this.redoStack.length > 0 && !this.session,
|
|
3555
|
-
undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess',
|
|
3556
|
-
redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess',
|
|
3640
|
+
undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _185 => _185.label]), () => ( null)),
|
|
3641
|
+
redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _186 => _186.label]), () => ( null)),
|
|
3557
3642
|
guides: this.guides,
|
|
3558
3643
|
swatches: this.swatches,
|
|
3559
3644
|
mixingPadVersion: this.pad.version,
|
|
@@ -3566,10 +3651,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3566
3651
|
overlay: this.wet.overlay,
|
|
3567
3652
|
instantDry: this.wet.instantDry,
|
|
3568
3653
|
speed: this.wet.speed,
|
|
3569
|
-
clock: _nullishCoalesce(_optionalChain([this, 'access',
|
|
3654
|
+
clock: _nullishCoalesce(_optionalChain([this, 'access', _187 => _187.wet, 'access', _188 => _188.world, 'optionalAccess', _189 => _189.clock]), () => ( 0)),
|
|
3570
3655
|
tilt: { ...this.wet.tilt },
|
|
3571
3656
|
gpu: this.wet.gpuMode,
|
|
3572
|
-
gpuActive: Boolean(_optionalChain([this, 'access',
|
|
3657
|
+
gpuActive: Boolean(_optionalChain([this, 'access', _190 => _190.wet, 'access', _191 => _191.world, 'optionalAccess', _192 => _192.gpuActive]))
|
|
3573
3658
|
},
|
|
3574
3659
|
version: this.version
|
|
3575
3660
|
};
|
|
@@ -3588,7 +3673,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3588
3673
|
return d;
|
|
3589
3674
|
}
|
|
3590
3675
|
// --- History -------------------------------------------------------------------
|
|
3591
|
-
|
|
3676
|
+
__init121() {this.docRevision = 0}
|
|
3592
3677
|
/**
|
|
3593
3678
|
* Bumped on every change to the painting (a committed or amended step, undo, redo, opening a
|
|
3594
3679
|
* document), not on wet-paint frames or view changes. `createPaintEditorDocument` uses it.
|
|
@@ -3671,9 +3756,9 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3671
3756
|
return wetIds;
|
|
3672
3757
|
}
|
|
3673
3758
|
/** Records a wet event (for replays) in the document being built. */
|
|
3674
|
-
|
|
3759
|
+
__init122() {this.pendingWetEvents = []}
|
|
3675
3760
|
logWet(e) {
|
|
3676
|
-
this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access',
|
|
3761
|
+
this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _193 => _193.wet, 'access', _194 => _194.world, 'optionalAccess', _195 => _195.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
|
|
3677
3762
|
}
|
|
3678
3763
|
/** The document with a paint event appended (for replays). */
|
|
3679
3764
|
withPaintEvent(doc, e) {
|
|
@@ -3734,7 +3819,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3734
3819
|
// --- Canvas and paper ----------------------------------------------------------
|
|
3735
3820
|
resolvePaper(paper) {
|
|
3736
3821
|
if (typeof paper === "string") {
|
|
3737
|
-
const p =
|
|
3822
|
+
const p = _chunk5BR7LC24cjs.paperPreset.call(void 0, paper);
|
|
3738
3823
|
if (!p) throw new PaintEditorError(`Unknown paper "${paper}". Call list_papers for the ids.`);
|
|
3739
3824
|
return p;
|
|
3740
3825
|
}
|
|
@@ -3817,7 +3902,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3817
3902
|
}
|
|
3818
3903
|
let next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
|
|
3819
3904
|
for (const id of keptWet) {
|
|
3820
|
-
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess',
|
|
3905
|
+
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _196 => _196.layer]);
|
|
3821
3906
|
if (isPixelLayer(l)) next = { ...next, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, l.offset.x, l.offset.y), offset: { x: 0, y: 0 } })) };
|
|
3822
3907
|
}
|
|
3823
3908
|
if (this.wet.world) {
|
|
@@ -3845,23 +3930,23 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3845
3930
|
this.requireIdle("changing the paper");
|
|
3846
3931
|
let base = this.doc.paper;
|
|
3847
3932
|
if (update.preset !== void 0 && update.preset !== this.doc.paper.preset) {
|
|
3848
|
-
const p =
|
|
3933
|
+
const p = _chunk5BR7LC24cjs.paperPreset.call(void 0, update.preset);
|
|
3849
3934
|
if (!p) throw new PaintEditorError(`Unknown paper "${update.preset}". Call list_papers for the ids.`);
|
|
3850
3935
|
base = p;
|
|
3851
3936
|
}
|
|
3852
3937
|
const { preset: _p, ...rest } = update;
|
|
3853
3938
|
if (rest.color !== void 0) parseColor(rest.color, "paper color");
|
|
3854
|
-
const paper =
|
|
3939
|
+
const paper = _chunk5BR7LC24cjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
|
|
3855
3940
|
const changedKeys = Object.keys(rest).filter((k) => k !== "name");
|
|
3856
3941
|
if (changedKeys.length && update.preset === void 0) paper.preset = base.preset;
|
|
3857
3942
|
if (this.wet.world) this.beginWetOp();
|
|
3858
3943
|
this.commit("Paper", { ...this.doc, paper });
|
|
3859
3944
|
this.wet.paperChanged();
|
|
3860
|
-
return
|
|
3945
|
+
return _chunk5BR7LC24cjs.clonePaper.call(void 0, paper);
|
|
3861
3946
|
}
|
|
3862
3947
|
// --- Layers --------------------------------------------------------------------
|
|
3863
3948
|
getLayer(id) {
|
|
3864
|
-
return _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess',
|
|
3949
|
+
return _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _197 => _197.layer]);
|
|
3865
3950
|
}
|
|
3866
3951
|
/** The active pixel layer (or `undefined`). */
|
|
3867
3952
|
getActiveLayer() {
|
|
@@ -3880,7 +3965,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3880
3965
|
walk(this.doc.layers, null, 0);
|
|
3881
3966
|
return out;
|
|
3882
3967
|
}
|
|
3883
|
-
describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess',
|
|
3968
|
+
describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _198 => _198.parent, 'optionalAccess', _199 => _199.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _200 => _200.path, 'access', _201 => _201.length]), () => ( 0))) {
|
|
3884
3969
|
let bounds = null;
|
|
3885
3970
|
if (l.type === "pixel") {
|
|
3886
3971
|
const b = _chunk474IQG74cjs.contentBounds.call(void 0, l.surface);
|
|
@@ -3897,6 +3982,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3897
3982
|
locks: { ..._nullishCoalesce(l.locks, () => ( {})) },
|
|
3898
3983
|
active: l.id === this.doc.activeLayerId,
|
|
3899
3984
|
bounds,
|
|
3985
|
+
..._optionalChain([this, 'access', _202 => _202.doc, 'access', _203 => _203.liveStrokes, 'optionalAccess', _204 => _204[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
|
|
3900
3986
|
parentId,
|
|
3901
3987
|
depth
|
|
3902
3988
|
};
|
|
@@ -3923,11 +4009,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3923
4009
|
this.emit();
|
|
3924
4010
|
}
|
|
3925
4011
|
/** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */
|
|
4012
|
+
/** Adds a layer above the active one: `pixel` (default), `group`, or `strokes`, a live stroke layer whose strokes stay editable. */
|
|
3926
4013
|
addLayer(options = {}) {
|
|
3927
4014
|
this.requireIdle("adding a layer");
|
|
3928
4015
|
const count = _chunkHB4ICNNAcjs.flattenLayers.call(void 0, this.doc.layers).length;
|
|
3929
4016
|
const type = _nullishCoalesce(options.type, () => ( "pixel"));
|
|
3930
|
-
const name = _optionalChain([options, 'access',
|
|
4017
|
+
const name = _optionalChain([options, 'access', _205 => _205.name, 'optionalAccess', _206 => _206.trim, 'call', _207 => _207()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
|
|
3931
4018
|
const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
|
|
3932
4019
|
let parentId = null;
|
|
3933
4020
|
let index;
|
|
@@ -3939,11 +4026,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3939
4026
|
} else if (above) {
|
|
3940
4027
|
const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, above);
|
|
3941
4028
|
if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
|
|
3942
|
-
parentId = _nullishCoalesce(_optionalChain([loc, 'access',
|
|
4029
|
+
parentId = _nullishCoalesce(_optionalChain([loc, 'access', _208 => _208.parent, 'optionalAccess', _209 => _209.id]), () => ( null));
|
|
3943
4030
|
index = loc.index + 1;
|
|
3944
4031
|
}
|
|
3945
4032
|
const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
|
|
3946
|
-
|
|
4033
|
+
const live = type === "strokes" ? { liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [layer.id]: [] } } : {};
|
|
4034
|
+
this.commit(type === "group" ? "Add group" : type === "strokes" ? "Add stroke layer" : "Add layer", { ...this.doc, layers, activeLayerId: layer.id, ...live });
|
|
3947
4035
|
return this.describeLayer(layer);
|
|
3948
4036
|
}
|
|
3949
4037
|
updateLayer(id, update) {
|
|
@@ -3979,8 +4067,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3979
4067
|
}
|
|
3980
4068
|
const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
|
|
3981
4069
|
let active = this.doc.activeLayerId;
|
|
3982
|
-
if (active && !_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access',
|
|
3983
|
-
this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
|
|
4070
|
+
if (active && !_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _210 => _210.filter, 'call', _211 => _211((x) => x.type === "pixel"), 'access', _212 => _212.pop, 'call', _213 => _213(), 'optionalAccess', _214 => _214.id]), () => ( null));
|
|
4071
|
+
this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
|
|
3984
4072
|
return { removed: id, activeLayerId: active };
|
|
3985
4073
|
}
|
|
3986
4074
|
duplicateLayer(id) {
|
|
@@ -3993,15 +4081,17 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
3993
4081
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
3994
4082
|
const thick = { ..._nullishCoalesce(this.doc.thick, () => ( {})) };
|
|
3995
4083
|
const stickers = { ..._nullishCoalesce(this.doc.stickers, () => ( {})) };
|
|
4084
|
+
const liveStrokes = { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})) };
|
|
3996
4085
|
const copy = (l) => {
|
|
3997
4086
|
const id2 = newPaintLayerId();
|
|
3998
4087
|
if (thick[l.id]) thick[id2] = thick[l.id];
|
|
3999
4088
|
if (stickers[l.id]) stickers[id2] = stickers[l.id].map((x) => ({ ...x }));
|
|
4089
|
+
if (liveStrokes[l.id]) liveStrokes[id2] = liveStrokes[l.id].map((x) => ({ ...x, id: `s${this.strokeCounter++}`, layerId: id2 }));
|
|
4000
4090
|
return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
|
|
4001
4091
|
};
|
|
4002
4092
|
const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
|
|
4003
|
-
const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access',
|
|
4004
|
-
this.commit("Duplicate layer", this.withWetEvents({ ...this.doc, layers, activeLayerId: dup.id, ...this.doc.thick ? { thick } : {}, ...this.doc.stickers ? { stickers } : {} }));
|
|
4093
|
+
const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _215 => _215.parent, 'optionalAccess', _216 => _216.id]), () => ( null)), loc.index + 1);
|
|
4094
|
+
this.commit("Duplicate layer", this.withWetEvents({ ...this.doc, layers, activeLayerId: dup.id, ...this.doc.thick ? { thick } : {}, ...this.doc.stickers ? { stickers } : {}, ...this.doc.liveStrokes ? { liveStrokes } : {} }));
|
|
4005
4095
|
return this.describeLayer(dup);
|
|
4006
4096
|
}
|
|
4007
4097
|
/** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */
|
|
@@ -4009,7 +4099,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4009
4099
|
this.requireIdle("moving a layer");
|
|
4010
4100
|
const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
|
|
4011
4101
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
4012
|
-
const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access',
|
|
4102
|
+
const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _217 => _217.parent, 'optionalAccess', _218 => _218.id]), () => ( null)) : parentId;
|
|
4013
4103
|
if (target) {
|
|
4014
4104
|
const g = this.requireLayer(target);
|
|
4015
4105
|
if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
|
|
@@ -4028,7 +4118,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4028
4118
|
const pre = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
|
|
4029
4119
|
if (pre) {
|
|
4030
4120
|
const sib = pre.parent ? pre.parent.children : this.doc.layers;
|
|
4031
|
-
this.dryLayersFirst([id, _optionalChain([sib, 'access',
|
|
4121
|
+
this.dryLayersFirst([id, _optionalChain([sib, 'access', _219 => _219[pre.index - 1], 'optionalAccess', _220 => _220.id])].filter((x) => Boolean(x)));
|
|
4032
4122
|
}
|
|
4033
4123
|
const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
|
|
4034
4124
|
if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
|
|
@@ -4047,7 +4137,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4047
4137
|
}
|
|
4048
4138
|
const merged = { ...below, surface, offset: { x: 0, y: 0 } };
|
|
4049
4139
|
const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
|
|
4050
|
-
this.commit("Merge down", this.withWetEvents({ ...this.doc, layers, activeLayerId: below.id, ...this.thickWithout([upper.id]), ...this.stickersWithout([upper.id, below.id]) }));
|
|
4140
|
+
this.commit("Merge down", this.withWetEvents({ ...this.doc, layers, activeLayerId: below.id, ...this.thickWithout([upper.id]), ...this.stickersWithout([upper.id, below.id]), ...this.liveStrokesWithout([upper.id, below.id]) }));
|
|
4051
4141
|
return this.describeLayer(merged);
|
|
4052
4142
|
}
|
|
4053
4143
|
/** Removes every pixel of a layer. */
|
|
@@ -4059,7 +4149,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4059
4149
|
this.wet.world.removeLane(l.id);
|
|
4060
4150
|
}
|
|
4061
4151
|
const bounds = this.describeLayer(l).bounds;
|
|
4062
|
-
this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]) }, { kind: "clear", layerId: l.id }));
|
|
4152
|
+
this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _221 => _221.doc, 'access', _222 => _222.liveStrokes, 'optionalAccess', _223 => _223[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {} }, { kind: "clear", layerId: l.id }));
|
|
4063
4153
|
return { layerId: l.id, bounds };
|
|
4064
4154
|
}
|
|
4065
4155
|
/**
|
|
@@ -4069,7 +4159,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4069
4159
|
fillLayer(options = {}) {
|
|
4070
4160
|
this.requireIdle("filling");
|
|
4071
4161
|
const fillTarget = this.paintTarget(options.layerId, "fill");
|
|
4072
|
-
if (_optionalChain([this, 'access',
|
|
4162
|
+
if (_optionalChain([this, 'access', _224 => _224.doc, 'access', _225 => _225.stickers, 'optionalAccess', _226 => _226[fillTarget.id], 'optionalAccess', _227 => _227.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
|
|
4163
|
+
if (_optionalChain([this, 'access', _228 => _228.doc, 'access', _229 => _229.liveStrokes, 'optionalAccess', _230 => _230[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
|
|
4073
4164
|
this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
|
|
4074
4165
|
const l = this.paintTarget(options.layerId, "fill");
|
|
4075
4166
|
const color = options.color === void 0 ? this.color : parseColor(options.color);
|
|
@@ -4110,7 +4201,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4110
4201
|
const tiles = new Map(base.tiles);
|
|
4111
4202
|
for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {
|
|
4112
4203
|
const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
|
|
4113
|
-
const src = _nullishCoalesce(_optionalChain([base, 'access',
|
|
4204
|
+
const src = _nullishCoalesce(_optionalChain([base, 'access', _231 => _231.tiles, 'access', _232 => _232.get, 'call', _233 => _233(key), 'optionalAccess', _234 => _234.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
|
|
4114
4205
|
const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkPQ3H2AANcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
|
|
4115
4206
|
if (tile) tiles.set(key, tile);
|
|
4116
4207
|
else tiles.delete(key);
|
|
@@ -4143,7 +4234,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4143
4234
|
}
|
|
4144
4235
|
/** The effect a layer is drawn from, or `undefined` for other layers. */
|
|
4145
4236
|
getEffectLayer(layerId) {
|
|
4146
|
-
return _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access',
|
|
4237
|
+
return _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _235 => _235.doc, 'access', _236 => _236.effectLayers, 'optionalAccess', _237 => _237[layerId]]) : void 0;
|
|
4147
4238
|
}
|
|
4148
4239
|
/** The effect paper (without its pixels), or `null`. */
|
|
4149
4240
|
getPaperEffect() {
|
|
@@ -4180,7 +4271,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4180
4271
|
/** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
|
|
4181
4272
|
effectTarget(layerId, what) {
|
|
4182
4273
|
const l = this.paintTarget(layerId, what);
|
|
4183
|
-
if (_optionalChain([this, 'access',
|
|
4274
|
+
if (_optionalChain([this, 'access', _238 => _238.doc, 'access', _239 => _239.stickers, 'optionalAccess', _240 => _240[l.id], 'optionalAccess', _241 => _241.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
|
|
4275
|
+
if (_optionalChain([this, 'access', _242 => _242.doc, 'access', _243 => _243.liveStrokes, 'optionalAccess', _244 => _244[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
|
|
4184
4276
|
if (this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" holds wet paint; effects go on dried paint, so dry it first (dry_paint) and try again.`);
|
|
4185
4277
|
return l;
|
|
4186
4278
|
}
|
|
@@ -4219,8 +4311,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4219
4311
|
const was = this.doc.paperEffect;
|
|
4220
4312
|
const paperEffect = {
|
|
4221
4313
|
...this.sourceOf(d, values, options.time),
|
|
4222
|
-
opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess',
|
|
4223
|
-
blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess',
|
|
4314
|
+
opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _245 => _245.opacity]))), () => ( 1)),
|
|
4315
|
+
blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _246 => _246.blend]))), () => ( "multiply")),
|
|
4224
4316
|
image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
|
|
4225
4317
|
version: nextPaperEffectVersion()
|
|
4226
4318
|
};
|
|
@@ -4273,8 +4365,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4273
4365
|
const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
|
|
4274
4366
|
const loc = above ? _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, above) : null;
|
|
4275
4367
|
if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
|
|
4276
|
-
const layer = { ...createPaintLayer(_optionalChain([options, 'access',
|
|
4277
|
-
const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess',
|
|
4368
|
+
const layer = { ...createPaintLayer(_optionalChain([options, 'access', _247 => _247.name, 'optionalAccess', _248 => _248.trim, 'call', _249 => _249()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
|
|
4369
|
+
const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _250 => _250.parent, 'optionalAccess', _251 => _251.id]), () => ( null)), loc ? loc.index + 1 : void 0);
|
|
4278
4370
|
const source = this.sourceOf(d, values, options.time);
|
|
4279
4371
|
this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
|
|
4280
4372
|
return { layer: this.describeLayer(layer), source };
|
|
@@ -4344,16 +4436,25 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4344
4436
|
* size, and brushes then take each pixel's colour (and alpha) from it, fixed to the canvas, as if
|
|
4345
4437
|
* painting a hidden picture into view. `setColor` and `setPaint` go back to colour. Editor state,
|
|
4346
4438
|
* not an undo step. Strokes that would paint with it throw while it renders. Returns the paint.
|
|
4439
|
+
* With `map: { by: 'stroke' }` the effect lies along each stroke instead of the canvas; with
|
|
4440
|
+
* `live`, strokes on a stroke layer keep playing it (see `setEffectPlayback`).
|
|
4347
4441
|
*/
|
|
4348
4442
|
async setEffectPaint(source) {
|
|
4349
4443
|
if (!source || typeof source.effect !== "string" || !source.effect) throw new PaintEditorError("effect is missing; pass an effect id from search_effects (use generator, overlay or title).");
|
|
4350
4444
|
this.checkTime(source.time);
|
|
4445
|
+
let map;
|
|
4446
|
+
try {
|
|
4447
|
+
map = _chunk5BR7LC24cjs.readEffectStrokeMap.call(void 0, source.map);
|
|
4448
|
+
} catch (e) {
|
|
4449
|
+
throw new PaintEditorError(e.message);
|
|
4450
|
+
}
|
|
4451
|
+
if (source.live !== void 0 && typeof source.live !== "boolean") throw new PaintEditorError("live must be true or false.");
|
|
4351
4452
|
const epoch = ++this.paintEpoch;
|
|
4352
4453
|
const changed = (name) => new PaintEditorError(`The paint changed while "${name}" rendered (set_color, set_paint or another set_effect_paint); call set_effect_paint again to paint with it.`);
|
|
4353
4454
|
const d = await this.describeEffect(source.effect, "paint");
|
|
4354
4455
|
const values = this.effectValues(d, { ...d.defaults }, source.values);
|
|
4355
4456
|
if (epoch !== this.paintEpoch) throw changed(d.name);
|
|
4356
|
-
const paint = { type: "effect", effect: d.id, provider: this.effects.require().id, values, time: _nullishCoalesce(source.time, () => ( 0)) };
|
|
4457
|
+
const paint = { type: "effect", effect: d.id, provider: this.effects.require().id, values, time: _nullishCoalesce(source.time, () => ( 0)), ...map ? { map } : {}, ...source.live ? { live: true } : {} };
|
|
4357
4458
|
this.effectPaintPending = paint;
|
|
4358
4459
|
this.emit([]);
|
|
4359
4460
|
try {
|
|
@@ -4374,9 +4475,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4374
4475
|
}
|
|
4375
4476
|
/** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
|
|
4376
4477
|
effectPaintImage(p) {
|
|
4377
|
-
const key =
|
|
4478
|
+
const key = _chunk5BR7LC24cjs.effectPaintKey.call(void 0, p);
|
|
4378
4479
|
const img = this.effectPaintPixels.get(key);
|
|
4379
|
-
|
|
4480
|
+
const size = _chunk5BR7LC24cjs.effectPaintSize.call(void 0, p, this.doc.canvas);
|
|
4481
|
+
if (!img || img.width !== size.width || img.height !== size.height) return null;
|
|
4380
4482
|
this.effectPaintPixels.delete(key);
|
|
4381
4483
|
this.effectPaintPixels.set(key, img);
|
|
4382
4484
|
return img;
|
|
@@ -4389,15 +4491,15 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4389
4491
|
const what = `the effect "${p.effect}"${p.provider ? ` from provider "${p.provider}"` : ""}`;
|
|
4390
4492
|
if (!provider) throw new PaintEditorError(`Effect paint needs ${what}, but no effects provider is registered; register it (setEffectsProvider) and try again.`);
|
|
4391
4493
|
if (p.provider && provider.id !== p.provider) throw new PaintEditorError(`Effect paint needs ${what}, but the registered provider is "${provider.id}"; register "${p.provider}" (setEffectsProvider) and try again.`);
|
|
4392
|
-
const { width, height } = this.doc.canvas;
|
|
4494
|
+
const { width, height } = _chunk5BR7LC24cjs.effectPaintSize.call(void 0, p, this.doc.canvas);
|
|
4393
4495
|
let pixels;
|
|
4394
4496
|
try {
|
|
4395
4497
|
pixels = await this.effectsRenderer.render(provider, p.effect, { width, height }, { time: p.time, values: p.values });
|
|
4396
4498
|
} catch (e) {
|
|
4397
4499
|
throw new PaintEditorError(`Effect paint could not render ${what}: ${e instanceof Error ? e.message : String(e)}`);
|
|
4398
4500
|
}
|
|
4399
|
-
const img = { width, height, data: new Uint8ClampedArray(pixels.data) };
|
|
4400
|
-
this.effectPaintPixels.set(
|
|
4501
|
+
const img = { width, height, data: new Uint8ClampedArray(pixels.data), ...p.map ? { map: p.map } : {} };
|
|
4502
|
+
this.effectPaintPixels.set(_chunk5BR7LC24cjs.effectPaintKey.call(void 0, p), img);
|
|
4401
4503
|
while (this.effectPaintPixels.size > _PaintEditorController.EFFECT_PAINT_CACHE) this.effectPaintPixels.delete(this.effectPaintPixels.keys().next().value);
|
|
4402
4504
|
return img;
|
|
4403
4505
|
}
|
|
@@ -4408,7 +4510,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4408
4510
|
async prepareEffectPaints(paints) {
|
|
4409
4511
|
const seen = /* @__PURE__ */ new Set();
|
|
4410
4512
|
for (const p of paints) {
|
|
4411
|
-
const key =
|
|
4513
|
+
const key = _chunk5BR7LC24cjs.effectPaintKey.call(void 0, p);
|
|
4412
4514
|
if (seen.has(key)) continue;
|
|
4413
4515
|
seen.add(key);
|
|
4414
4516
|
await this.renderEffectPaint(p);
|
|
@@ -4417,7 +4519,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4417
4519
|
/** Renders the effect paints of recorded strokes (default all of them) before a replay. */
|
|
4418
4520
|
async prepareStrokeEffects(strokeIds) {
|
|
4419
4521
|
const ids = strokeIds ? new Set(strokeIds) : null;
|
|
4420
|
-
const paints = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access',
|
|
4522
|
+
const paints = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _252 => _252.paint, 'optionalAccess', _253 => _253.type]) === "effect").map((s) => s.paint);
|
|
4421
4523
|
await this.prepareEffectPaints(paints);
|
|
4422
4524
|
}
|
|
4423
4525
|
/** A small preview of the effect paint (a PNG data URL `size` px wide), or `null` without a rendered one. */
|
|
@@ -4446,22 +4548,17 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4446
4548
|
* its pixels are not rendered.
|
|
4447
4549
|
*/
|
|
4448
4550
|
strokeEffect(init, brush) {
|
|
4449
|
-
if (!
|
|
4551
|
+
if (!_chunk5BR7LC24cjs.brushTakesPaint.call(void 0, brush)) return null;
|
|
4450
4552
|
let source = null;
|
|
4451
4553
|
if (init.paint !== void 0) {
|
|
4452
|
-
if (!
|
|
4453
|
-
source =
|
|
4554
|
+
if (!_chunk5BR7LC24cjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
|
|
4555
|
+
source = _chunk5BR7LC24cjs.readPaintEffectPaint.call(void 0, init.paint);
|
|
4454
4556
|
if (!source) throw new PaintEditorError("The stroke's effect paint needs an effect id and values (getEffectPaint returns one).");
|
|
4455
4557
|
} else if (init.color === void 0 && !brush.paint) {
|
|
4456
4558
|
if (this.effectPaintPending) throw new PaintEditorError(`The effect paint "${this.effectPaintPending.effect}" is still rendering; wait for set_effect_paint to finish, then paint.`);
|
|
4457
4559
|
source = this.effectPaint;
|
|
4458
4560
|
}
|
|
4459
4561
|
if (!source) return null;
|
|
4460
|
-
if (brush.engine === "wet" || brush.engine === "impasto" || brush.engine === "sticker") {
|
|
4461
|
-
throw new PaintEditorError(
|
|
4462
|
-
`The ${brush.name} brush (${brush.engine} engine) cannot paint with effect paint: it carries one colour as ${brush.engine === "sticker" ? "stickers" : brush.engine === "wet" ? "wet pigment" : "thick paint"}. Paint with a dry brush (a dab, particle, bristle or mixer brush), or paint the shape first and fill it with fill_layer_with_effect {lockTransparency: true}.`
|
|
4463
|
-
);
|
|
4464
|
-
}
|
|
4465
4562
|
const pixels = this.effectPaintImage(source);
|
|
4466
4563
|
if (!pixels) throw new PaintEditorError(`The effect paint "${source.effect}"${source.provider ? ` from provider "${source.provider}"` : ""} is not rendered at this canvas size; call set_effect_paint (or prepareEffectPaints) first.`);
|
|
4467
4564
|
return { source, pixels };
|
|
@@ -4485,14 +4582,14 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4485
4582
|
const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
|
|
4486
4583
|
const inputs = { source: { width: rect.width, height: rect.height, data: before } };
|
|
4487
4584
|
const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
|
|
4488
|
-
const relief = _optionalChain([this, 'access',
|
|
4585
|
+
const relief = _optionalChain([this, 'access', _254 => _254.doc, 'access', _255 => _255.thick, 'optionalAccess', _256 => _256[l.id]]);
|
|
4489
4586
|
if (heightInput && relief) {
|
|
4490
4587
|
const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
|
|
4491
4588
|
const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
|
|
4492
4589
|
for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
|
|
4493
4590
|
inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
|
|
4494
4591
|
}
|
|
4495
|
-
const sourceInput = _nullishCoalesce(_optionalChain([d, 'access',
|
|
4592
|
+
const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _257 => _257.inputs, 'access', _258 => _258.find, 'call', _259 => _259((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _260 => _260.name])), 'optionalAccess', _261 => _261.name]), () => ( "source"));
|
|
4496
4593
|
if (sourceInput !== "source") {
|
|
4497
4594
|
inputs[sourceInput] = inputs.source;
|
|
4498
4595
|
delete inputs.source;
|
|
@@ -4505,12 +4602,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4505
4602
|
}
|
|
4506
4603
|
// --- Brushes -------------------------------------------------------------------
|
|
4507
4604
|
findBrush(id) {
|
|
4508
|
-
return _nullishCoalesce(
|
|
4605
|
+
return _nullishCoalesce(_chunk5BR7LC24cjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
|
|
4509
4606
|
}
|
|
4510
4607
|
/** A library brush by id (`undefined` when unknown). */
|
|
4511
4608
|
getBrush(id) {
|
|
4512
4609
|
const b = this.findBrush(id);
|
|
4513
|
-
return b ?
|
|
4610
|
+
return b ? _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, b, b) : void 0;
|
|
4514
4611
|
}
|
|
4515
4612
|
requireBrush(id) {
|
|
4516
4613
|
const b = this.findBrush(id);
|
|
@@ -4525,7 +4622,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4525
4622
|
const { id, ...changes } = update;
|
|
4526
4623
|
const base = id !== void 0 ? this.requireBrush(id) : this.brush;
|
|
4527
4624
|
if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
|
|
4528
|
-
const next =
|
|
4625
|
+
const next = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
|
|
4529
4626
|
if (base.builtin && !Object.keys(changes).length) next.builtin = true;
|
|
4530
4627
|
else delete next.builtin;
|
|
4531
4628
|
this.brush = next;
|
|
@@ -4534,10 +4631,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4534
4631
|
}
|
|
4535
4632
|
/** Saves the active brush (or `brush`) into the user library under `id` / `name`. */
|
|
4536
4633
|
saveBrush(options) {
|
|
4537
|
-
if (!
|
|
4538
|
-
if (
|
|
4539
|
-
const source = options.brush ?
|
|
4540
|
-
const saved =
|
|
4634
|
+
if (!_chunk5BR7LC24cjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
|
|
4635
|
+
if (_chunk5BR7LC24cjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
|
|
4636
|
+
const source = options.brush ? _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
|
|
4637
|
+
const saved = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
|
|
4541
4638
|
delete saved.builtin;
|
|
4542
4639
|
const i = this.userBrushes.findIndex((b) => b.id === options.id);
|
|
4543
4640
|
if (i >= 0) this.userBrushes[i] = saved;
|
|
@@ -4547,7 +4644,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4547
4644
|
return saved;
|
|
4548
4645
|
}
|
|
4549
4646
|
removeBrush(id) {
|
|
4550
|
-
if (
|
|
4647
|
+
if (_chunk5BR7LC24cjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
|
|
4551
4648
|
const i = this.userBrushes.findIndex((b) => b.id === id);
|
|
4552
4649
|
if (i < 0) throw new PaintEditorError(`Unknown brush "${id}". Call list_brushes for the ids.`);
|
|
4553
4650
|
this.userBrushes.splice(i, 1);
|
|
@@ -4556,12 +4653,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4556
4653
|
}
|
|
4557
4654
|
/** The user's saved brushes. */
|
|
4558
4655
|
getUserBrushes() {
|
|
4559
|
-
return this.userBrushes.map((b) =>
|
|
4656
|
+
return this.userBrushes.map((b) => _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, b, b));
|
|
4560
4657
|
}
|
|
4561
4658
|
/** A brush library file of the given brushes (default: the user's brushes). */
|
|
4562
4659
|
exportBrushes(ids) {
|
|
4563
4660
|
const list = ids ? ids.map((id) => this.requireBrush(id)) : this.userBrushes;
|
|
4564
|
-
return { format: "pixerate-brushes", version: 1, brushes: list.map(
|
|
4661
|
+
return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunk5BR7LC24cjs.brushToJSON) };
|
|
4565
4662
|
}
|
|
4566
4663
|
/**
|
|
4567
4664
|
* Adds the brushes of a library file to the user library. A brush whose id is taken is skipped
|
|
@@ -4571,14 +4668,14 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4571
4668
|
const problems = [];
|
|
4572
4669
|
let list;
|
|
4573
4670
|
try {
|
|
4574
|
-
list =
|
|
4671
|
+
list = _chunk5BR7LC24cjs.parseBrushLibrary.call(void 0, file, problems);
|
|
4575
4672
|
} catch (e) {
|
|
4576
4673
|
throw new PaintEditorError(e.message);
|
|
4577
4674
|
}
|
|
4578
4675
|
const added = [];
|
|
4579
4676
|
const skipped = [];
|
|
4580
4677
|
for (const b of list) {
|
|
4581
|
-
if (
|
|
4678
|
+
if (_chunk5BR7LC24cjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
|
|
4582
4679
|
skipped.push(b.id);
|
|
4583
4680
|
problems.push(`"${b.id}" is a built-in brush id; rename it to import it.`);
|
|
4584
4681
|
continue;
|
|
@@ -4643,10 +4740,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4643
4740
|
* brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
|
|
4644
4741
|
*/
|
|
4645
4742
|
strokeGradient(init, brush, color) {
|
|
4646
|
-
if (!
|
|
4743
|
+
if (!_chunk5BR7LC24cjs.brushTakesPaint.call(void 0, brush)) return null;
|
|
4647
4744
|
let g = null;
|
|
4648
4745
|
if (init.paint !== void 0) {
|
|
4649
|
-
if (
|
|
4746
|
+
if (_chunk5BR7LC24cjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
|
|
4650
4747
|
const p = this.readStrokePaint(init.paint);
|
|
4651
4748
|
g = p.type === "gradient" ? p : null;
|
|
4652
4749
|
} else g = _nullishCoalesce(brush.paint, () => ( (init.color === void 0 ? this.gradient : null)));
|
|
@@ -4690,7 +4787,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4690
4787
|
// --- Mixer Brush ---------------------------------------------------------------
|
|
4691
4788
|
/** Fills the Mixer Brush reservoir with a colour (default the editor colour). */
|
|
4692
4789
|
loadMixerBrush(color) {
|
|
4693
|
-
const [r, g, b] =
|
|
4790
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
|
|
4694
4791
|
this.mixerLoad = _chunkPQ3H2AANcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
|
|
4695
4792
|
this.emit([]);
|
|
4696
4793
|
return this.mixerLoad;
|
|
@@ -4720,7 +4817,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4720
4817
|
// --- Strokes -------------------------------------------------------------------
|
|
4721
4818
|
strokeBrush(init) {
|
|
4722
4819
|
let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
|
|
4723
|
-
if (init.brush) brush =
|
|
4820
|
+
if (init.brush) brush = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
|
|
4724
4821
|
return brush;
|
|
4725
4822
|
}
|
|
4726
4823
|
/**
|
|
@@ -4736,7 +4833,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4736
4833
|
return symmetryCopies(this.guides.symmetry);
|
|
4737
4834
|
}
|
|
4738
4835
|
sessionFor(doc, init, host) {
|
|
4739
|
-
if (init.paint !== void 0 && !
|
|
4836
|
+
if (init.paint !== void 0 && !_chunk5BR7LC24cjs.isPaintEffectPaint.call(void 0, init.paint)) {
|
|
4740
4837
|
const p = this.readStrokePaint(init.paint);
|
|
4741
4838
|
if (p.type === "color") init = { ...init, color: p.color, paint: void 0 };
|
|
4742
4839
|
else init = { ...init, paint: p };
|
|
@@ -4754,14 +4851,25 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4754
4851
|
})();
|
|
4755
4852
|
const brush = this.strokeBrush(init);
|
|
4756
4853
|
const effect = this.strokeEffect(init, brush);
|
|
4757
|
-
|
|
4854
|
+
if (_optionalChain([doc, 'access', _262 => _262.liveStrokes, 'optionalAccess', _263 => _263[layer.id]])) {
|
|
4855
|
+
const why = liveStrokeRefusal(brush);
|
|
4856
|
+
if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
|
|
4857
|
+
}
|
|
4858
|
+
if (_optionalChain([doc, 'access', _264 => _264.liveStrokes, 'optionalAccess', _265 => _265[layer.id]]) && _optionalChain([effect, 'optionalAccess', _266 => _266.source, 'access', _267 => _267.live])) {
|
|
4859
|
+
const key = _chunk5BR7LC24cjs.effectPaintKey.call(void 0, effect.source);
|
|
4860
|
+
const { sources } = this.liveEffects(doc);
|
|
4861
|
+
if (!sources.some((p) => _chunk5BR7LC24cjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
|
|
4862
|
+
throw new PaintEditorError(`The painting already plays ${MAX_LIVE_EFFECT_SOURCES} live effects, the most it can; paint with one of them, or set_effect_paint with live false to bake this one.`);
|
|
4863
|
+
}
|
|
4864
|
+
}
|
|
4865
|
+
const stickerLayer = Boolean(_optionalChain([doc, 'access', _268 => _268.stickers, 'optionalAccess', _269 => _269[layer.id], 'optionalAccess', _270 => _270.length]));
|
|
4758
4866
|
if (brush.engine === "sticker") {
|
|
4759
4867
|
if (!stickerLayer && _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; spray stickers onto an empty layer (add_layer) so they stay editable.`);
|
|
4760
4868
|
} else if (stickerLayer) {
|
|
4761
4869
|
throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
|
|
4762
4870
|
}
|
|
4763
4871
|
let wet;
|
|
4764
|
-
if (
|
|
4872
|
+
if (_chunk5BR7LC24cjs.isWetBrush.call(void 0, brush)) {
|
|
4765
4873
|
this.requireWetIdle("painting");
|
|
4766
4874
|
if (layer.offset.x || layer.offset.y) {
|
|
4767
4875
|
const moved = { ...layer, surface: _chunk474IQG74cjs.translateSurface.call(void 0, layer.surface, layer.offset.x, layer.offset.y), offset: { x: 0, y: 0 } };
|
|
@@ -4776,7 +4884,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4776
4884
|
const world = this.wet.ensureLane(layer.id, brush.wet.medium);
|
|
4777
4885
|
const id = layer.id;
|
|
4778
4886
|
const wetColor = init.color === void 0 ? this.color : parseColor(init.color);
|
|
4779
|
-
const [r, g, b] =
|
|
4887
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, wetColor);
|
|
4780
4888
|
const wetGradient = this.strokeGradient(init, brush, wetColor);
|
|
4781
4889
|
const load = _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [r / 255, g / 255, b / 255])));
|
|
4782
4890
|
const seedW = _nullishCoalesce(init.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
|
|
@@ -4789,11 +4897,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4789
4897
|
load,
|
|
4790
4898
|
grain: paperGrain(doc.paper),
|
|
4791
4899
|
paperDepth: doc.paper.depth,
|
|
4792
|
-
paperColor:
|
|
4900
|
+
paperColor: _chunk5BR7LC24cjs.hexToRgb8.call(void 0, doc.paper.color),
|
|
4793
4901
|
seed: seedW,
|
|
4794
4902
|
copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
|
|
4795
4903
|
mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
|
|
4796
|
-
paint: wetGradient
|
|
4904
|
+
paint: effect ? null : wetGradient,
|
|
4905
|
+
effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _271 => _271.pixels]), () => ( null))
|
|
4797
4906
|
});
|
|
4798
4907
|
init = { ...init, seed: seedW, load };
|
|
4799
4908
|
wet = { driver, surface: () => world.display(id).surface };
|
|
@@ -4804,7 +4913,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4804
4913
|
}
|
|
4805
4914
|
let color = init.color === void 0 ? this.color : parseColor(init.color);
|
|
4806
4915
|
const tracing = this.guides.tracing;
|
|
4807
|
-
if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess',
|
|
4916
|
+
if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _272 => _272.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
|
|
4808
4917
|
const perspective = this.guides.perspective;
|
|
4809
4918
|
const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
|
|
4810
4919
|
const useStencils = init.stencils !== false;
|
|
@@ -4837,7 +4946,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4837
4946
|
mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
|
|
4838
4947
|
secondary: rgbaOf(this.secondaryColor),
|
|
4839
4948
|
wet,
|
|
4840
|
-
thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access',
|
|
4949
|
+
thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _273 => _273.thick, 'optionalAccess', _274 => _274[layer.id]]), () => ( emptyThickChannels())) } : void 0,
|
|
4841
4950
|
sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc) } : void 0,
|
|
4842
4951
|
paint: effect ? null : this.strokeGradient(init, brush, color),
|
|
4843
4952
|
effect
|
|
@@ -4851,7 +4960,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4851
4960
|
const stroke = {
|
|
4852
4961
|
id: `s${this.strokeCounter++}`,
|
|
4853
4962
|
layerId: session.layerId,
|
|
4854
|
-
brush:
|
|
4963
|
+
brush: _chunk5BR7LC24cjs.brushToJSON.call(void 0, init.brush),
|
|
4855
4964
|
color: init.colorHex,
|
|
4856
4965
|
points: session.points.map((p) => ({ ...p })),
|
|
4857
4966
|
seed: init.seed
|
|
@@ -4876,12 +4985,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4876
4985
|
const before = this.doc;
|
|
4877
4986
|
const host = {
|
|
4878
4987
|
update: (layerId, surface, rects) => {
|
|
4879
|
-
if (_optionalChain([this, 'access',
|
|
4988
|
+
if (_optionalChain([this, 'access', _275 => _275.session, 'optionalAccess', _276 => _276.init, 'access', _277 => _277.wet])) {
|
|
4880
4989
|
this.wet.syncDisplays();
|
|
4881
4990
|
return;
|
|
4882
4991
|
}
|
|
4883
4992
|
this.live = { layerId, surface };
|
|
4884
|
-
const ch = _optionalChain([this, 'access',
|
|
4993
|
+
const ch = _optionalChain([this, 'access', _278 => _278.session, 'optionalAccess', _279 => _279.thickChannels, 'call', _280 => _280()]);
|
|
4885
4994
|
this.liveThick = ch ? { layerId, channels: ch } : null;
|
|
4886
4995
|
this.emit(rects);
|
|
4887
4996
|
},
|
|
@@ -4893,7 +5002,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4893
5002
|
const wetStroke = Boolean(s.init.wet);
|
|
4894
5003
|
if (wetStroke) this.wet.driver = null;
|
|
4895
5004
|
const brush = s.init.brush;
|
|
4896
|
-
if (!cancelled && _optionalChain([s, 'access',
|
|
5005
|
+
if (!cancelled && _optionalChain([s, 'access', _281 => _281.result, 'optionalAccess', _282 => _282.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
|
|
4897
5006
|
if (cancelled || !surface) {
|
|
4898
5007
|
if (this.wetOp) {
|
|
4899
5008
|
const snap = this.wetOp.before;
|
|
@@ -4908,6 +5017,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4908
5017
|
}
|
|
4909
5018
|
const stroke = this.record(s);
|
|
4910
5019
|
s.result.strokeId = stroke.id;
|
|
5020
|
+
this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _283 => _283.result, 'optionalAccess', _284 => _284.bounds]), () => ( null)));
|
|
4911
5021
|
if (wetStroke && this.wet.instantDry) {
|
|
4912
5022
|
this.wet.dry(s.layerId);
|
|
4913
5023
|
this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
|
|
@@ -4918,8 +5028,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4918
5028
|
const ch = s.thickChannels();
|
|
4919
5029
|
const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
|
|
4920
5030
|
const sprayed = s.stickers();
|
|
4921
|
-
const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access',
|
|
4922
|
-
this.commit(`${brush.name} stroke`, this.withWetEvents({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {} }), wetStroke ? before : this.doc);
|
|
5031
|
+
const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _285 => _285.doc, 'access', _286 => _286.stickers, 'optionalAccess', _287 => _287[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
|
|
5032
|
+
this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {} }, stroke)), wetStroke ? before : this.doc);
|
|
4923
5033
|
}
|
|
4924
5034
|
};
|
|
4925
5035
|
let session;
|
|
@@ -4947,17 +5057,18 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
4947
5057
|
if (cancelled || !surface) return;
|
|
4948
5058
|
const stroke = this.record(s);
|
|
4949
5059
|
s.result.strokeId = stroke.id;
|
|
5060
|
+
this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _288 => _288.result, 'optionalAccess', _289 => _289.bounds]), () => ( null)));
|
|
4950
5061
|
const l = _chunkHB4ICNNAcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
|
|
4951
5062
|
const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
|
|
4952
5063
|
const ch = s.thickChannels();
|
|
4953
5064
|
const sprayed = s.stickers();
|
|
4954
|
-
out = {
|
|
5065
|
+
out = withLiveStroke({
|
|
4955
5066
|
...out,
|
|
4956
5067
|
layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
|
|
4957
5068
|
strokes: [...out.strokes, stroke],
|
|
4958
5069
|
...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
|
|
4959
|
-
...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access',
|
|
4960
|
-
};
|
|
5070
|
+
...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _290 => _290.stickers, 'optionalAccess', _291 => _291[l.id]]), () => ( [])), ...sprayed] } } : {}
|
|
5071
|
+
}, stroke);
|
|
4961
5072
|
}
|
|
4962
5073
|
};
|
|
4963
5074
|
const session = this.sessionFor(doc, init, host);
|
|
@@ -5014,7 +5125,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5014
5125
|
*/
|
|
5015
5126
|
replayStrokes(options) {
|
|
5016
5127
|
this.requireIdle("replaying");
|
|
5017
|
-
if (!_optionalChain([options, 'access',
|
|
5128
|
+
if (!_optionalChain([options, 'access', _292 => _292.strokeIds, 'optionalAccess', _293 => _293.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
|
|
5018
5129
|
const strokes = options.strokeIds.map((id) => {
|
|
5019
5130
|
const s = this.doc.strokes.find((x) => x.id === id);
|
|
5020
5131
|
if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
|
|
@@ -5028,7 +5139,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5028
5139
|
if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
|
|
5029
5140
|
if (options.color === void 0) {
|
|
5030
5141
|
for (const s of strokes) {
|
|
5031
|
-
if (_optionalChain([s, 'access',
|
|
5142
|
+
if (_optionalChain([s, 'access', _294 => _294.paint, 'optionalAccess', _295 => _295.type]) === "effect" && !this.effectPaintImage(s.paint)) {
|
|
5032
5143
|
throw new PaintEditorError(`Stroke "${s.id}" paints with the effect "${s.paint.effect}"${s.paint.provider ? ` from provider "${s.paint.provider}"` : ""}, which is not rendered in this editor; render it first (prepareStrokeEffects; the replay_strokes tool does this) or recolour the replay with color.`);
|
|
5033
5144
|
}
|
|
5034
5145
|
}
|
|
@@ -5051,13 +5162,13 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5051
5162
|
let brush = v.brush;
|
|
5052
5163
|
if (options.brushId !== void 0) {
|
|
5053
5164
|
const b = this.requireBrush(options.brushId);
|
|
5054
|
-
brush =
|
|
5165
|
+
brush = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
|
|
5055
5166
|
}
|
|
5056
5167
|
const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
|
|
5057
5168
|
if (!_chunkHB4ICNNAcjs.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.`);
|
|
5058
5169
|
let load = s.load;
|
|
5059
5170
|
if (load && options.color !== void 0 && load.reservoir) {
|
|
5060
|
-
const [r, g, b] =
|
|
5171
|
+
const [r, g, b] = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, options.color);
|
|
5061
5172
|
load = { ...load, reservoir: [r / 255, g / 255, b / 255] };
|
|
5062
5173
|
}
|
|
5063
5174
|
const paint = v.paint && options.color === void 0 ? { paint: v.paint } : {};
|
|
@@ -5097,7 +5208,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5097
5208
|
const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
|
|
5098
5209
|
if (!id) return null;
|
|
5099
5210
|
this.requireLayer(id);
|
|
5100
|
-
const ch = _optionalChain([this, 'access',
|
|
5211
|
+
const ch = _optionalChain([this, 'access', _296 => _296.doc, 'access', _297 => _297.thick, 'optionalAccess', _298 => _298[id]]);
|
|
5101
5212
|
if (!ch) return null;
|
|
5102
5213
|
const r = reliefInfo(ch);
|
|
5103
5214
|
return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
|
|
@@ -5205,7 +5316,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5205
5316
|
wetState() {
|
|
5206
5317
|
const st = this.getState().wet;
|
|
5207
5318
|
const backend = this.wet.backend();
|
|
5208
|
-
return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess',
|
|
5319
|
+
return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _299 => _299.message]), () => ( _chunkXFYLA3ZOcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
|
|
5209
5320
|
}
|
|
5210
5321
|
/**
|
|
5211
5322
|
* Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
|
|
@@ -5290,7 +5401,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5290
5401
|
}
|
|
5291
5402
|
/** Records a settings change as a wet event (not an undo step). */
|
|
5292
5403
|
recordWetSetting(e) {
|
|
5293
|
-
this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access',
|
|
5404
|
+
this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _300 => _300.wet, 'access', _301 => _301.world, 'optionalAccess', _302 => _302.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
|
|
5294
5405
|
}
|
|
5295
5406
|
/** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
|
|
5296
5407
|
setWetParams(layerId, update) {
|
|
@@ -5355,9 +5466,11 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5355
5466
|
}
|
|
5356
5467
|
/** The layers with the live stroke's surface in place. */
|
|
5357
5468
|
currentLayers() {
|
|
5469
|
+
const override = this.frameOverride;
|
|
5470
|
+
if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkHB4ICNNAcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
|
|
5358
5471
|
const live = this.live;
|
|
5359
|
-
if (!live) return this.
|
|
5360
|
-
if (_optionalChain([this, 'access',
|
|
5472
|
+
if (!live) return this.animatedView();
|
|
5473
|
+
if (_optionalChain([this, 'access', _303 => _303.liveLayers, 'optionalAccess', _304 => _304.key]) === live.surface) return this.liveLayers.layers;
|
|
5361
5474
|
const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
|
|
5362
5475
|
this.liveLayers = { key: live.surface, layers };
|
|
5363
5476
|
return layers;
|
|
@@ -5380,7 +5493,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5380
5493
|
tracingNode(t) {
|
|
5381
5494
|
const { width, height } = this.doc.canvas;
|
|
5382
5495
|
const key = this.tracingVersion * 100003 + width * 7 + height;
|
|
5383
|
-
if (_optionalChain([this, 'access',
|
|
5496
|
+
if (_optionalChain([this, 'access', _305 => _305.tracingCache, 'optionalAccess', _306 => _306.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
|
|
5384
5497
|
const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
|
|
5385
5498
|
const image = resampleInto(src, t.rect, width, height);
|
|
5386
5499
|
const node = { type: "image", id: TRACING_NODE_ID, name: "Tracing", visible: true, opacity: t.opacity, blend: "normal", image, version: key + Math.round(t.opacity * 1e3) / 1e4 };
|
|
@@ -5407,8 +5520,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5407
5520
|
let out = layers;
|
|
5408
5521
|
const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
|
|
5409
5522
|
for (const id of ids) {
|
|
5410
|
-
const ch = _optionalChain([live, 'optionalAccess',
|
|
5411
|
-
const l = ch && _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess',
|
|
5523
|
+
const ch = _optionalChain([live, 'optionalAccess', _307 => _307.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _308 => _308[id]]);
|
|
5524
|
+
const l = ch && _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _309 => _309.layer]);
|
|
5412
5525
|
if (!ch || !isPixelLayer(l)) continue;
|
|
5413
5526
|
let cache = this.litCaches.get(id);
|
|
5414
5527
|
if (!cache) this.litCaches.set(id, cache = new LitCache());
|
|
@@ -5421,7 +5534,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5421
5534
|
let layers = this.litLayers((_nullishCoalesce(options.wet, () => ( "display"))) === "dried" ? this.driedLayers() : this.currentLayers());
|
|
5422
5535
|
if (options.layerIds) {
|
|
5423
5536
|
const picked = [];
|
|
5424
|
-
for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess',
|
|
5537
|
+
for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _310 => _310.layer]), () => ( this.requireLayer(id))));
|
|
5425
5538
|
layers = picked.map((l) => ({ ...l, visible: true }));
|
|
5426
5539
|
}
|
|
5427
5540
|
const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
|
|
@@ -5437,7 +5550,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5437
5550
|
*/
|
|
5438
5551
|
compositeTiles(rect, onTile, options = {}) {
|
|
5439
5552
|
const dirty = options.dirty === "all" ? void 0 : options.dirty;
|
|
5440
|
-
this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access',
|
|
5553
|
+
this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _311 => _311.live, 'optionalAccess', _312 => _312.layerId]), () => ( this.doc.activeLayerId)) });
|
|
5441
5554
|
}
|
|
5442
5555
|
/** The canvas as canvas-sized RGBA (paper included by default). */
|
|
5443
5556
|
compositePixels(options = {}) {
|
|
@@ -5501,7 +5614,11 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5501
5614
|
for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.stickers, () => ( {})))) if (list.length && _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) stickers[id] = list.map((x) => ({ ...x }));
|
|
5502
5615
|
if (Object.keys(stickers).length) ext.stickers = stickers;
|
|
5503
5616
|
else delete ext.stickers;
|
|
5504
|
-
const
|
|
5617
|
+
const liveStrokes = {};
|
|
5618
|
+
for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) if (_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) liveStrokes[id] = list.map((x) => JSON.parse(JSON.stringify(x)));
|
|
5619
|
+
if (Object.keys(liveStrokes).length) ext.liveStrokes = liveStrokes;
|
|
5620
|
+
else delete ext.liveStrokes;
|
|
5621
|
+
const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _313 => _313.layer])));
|
|
5505
5622
|
if (effectLayers) ext.effectLayers = effectLayers;
|
|
5506
5623
|
else delete ext.effectLayers;
|
|
5507
5624
|
if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
|
|
@@ -5518,16 +5635,26 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5518
5635
|
const stickers = {};
|
|
5519
5636
|
for (const [id, list] of Object.entries(ext.stickers)) {
|
|
5520
5637
|
if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
|
|
5521
|
-
const ok = list.filter((x) => x && typeof x.id === "string" &&
|
|
5638
|
+
const ok = list.filter((x) => x && typeof x.id === "string" && _chunk5BR7LC24cjs.STAMP_KINDS.includes(x.stamp) && Number.isFinite(x.x) && Number.isFinite(x.y) && x.size > 0);
|
|
5522
5639
|
if (ok.length !== list.length) problems.push(`Some stickers of layer "${id}" could not be read; they were dropped.`);
|
|
5523
5640
|
stickers[id] = ok.map((x) => ({ ...x }));
|
|
5524
5641
|
}
|
|
5525
5642
|
if (Object.keys(stickers).length) state = { ...state, stickers };
|
|
5526
5643
|
}
|
|
5644
|
+
if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
|
|
5645
|
+
const liveStrokes = {};
|
|
5646
|
+
for (const [id, list] of Object.entries(ext.liveStrokes)) {
|
|
5647
|
+
if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _314 => _314.layer])) || !Array.isArray(list)) continue;
|
|
5648
|
+
const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
|
|
5649
|
+
if (ok.length !== list.length) problems.push(`Some strokes of stroke layer "${id}" could not be read; they were dropped (the layer's pixels are kept until a stroke is edited).`);
|
|
5650
|
+
liveStrokes[id] = ok;
|
|
5651
|
+
}
|
|
5652
|
+
if (Object.keys(liveStrokes).length) state = { ...state, liveStrokes };
|
|
5653
|
+
}
|
|
5527
5654
|
if (ext.effectLayers && typeof ext.effectLayers === "object") {
|
|
5528
5655
|
const effectLayers = {};
|
|
5529
5656
|
for (const [id, v] of Object.entries(ext.effectLayers)) {
|
|
5530
|
-
if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess',
|
|
5657
|
+
if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _315 => _315.layer]))) continue;
|
|
5531
5658
|
const source = readPaintEffectSource(v);
|
|
5532
5659
|
if (source) effectLayers[id] = source;
|
|
5533
5660
|
else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
|
|
@@ -5568,16 +5695,23 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5568
5695
|
this.readGuides(loaded.guides, loaded.state, loaded.problems);
|
|
5569
5696
|
if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
|
|
5570
5697
|
for (const s of loaded.state.strokes) {
|
|
5571
|
-
const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access',
|
|
5698
|
+
const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _316 => _316.exec, 'call', _317 => _317(s.id), 'optionalAccess', _318 => _318[1]]), () => ( 0)));
|
|
5572
5699
|
if (n >= this.strokeCounter) this.strokeCounter = n + 1;
|
|
5573
5700
|
}
|
|
5574
5701
|
this.undoStack = [];
|
|
5575
5702
|
this.redoStack = [];
|
|
5576
5703
|
this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
|
|
5704
|
+
for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
|
|
5705
|
+
for (const s of list) {
|
|
5706
|
+
const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _319 => _319.exec, 'call', _320 => _320(s.id), 'optionalAccess', _321 => _321[1]]), () => ( 0)));
|
|
5707
|
+
if (n >= this.strokeCounter) this.strokeCounter = n + 1;
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5577
5710
|
this.docRevision++;
|
|
5578
5711
|
delete this.extensions.layerChannels;
|
|
5579
5712
|
delete this.extensions.lighting;
|
|
5580
5713
|
delete this.extensions.stickers;
|
|
5714
|
+
delete this.extensions.liveStrokes;
|
|
5581
5715
|
delete this.extensions.effectLayers;
|
|
5582
5716
|
delete this.extensions.paperEffect;
|
|
5583
5717
|
this.viewCompositor.clear();
|
|
@@ -5660,10 +5794,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5660
5794
|
return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
|
|
5661
5795
|
});
|
|
5662
5796
|
const layers = toStandard(dried);
|
|
5663
|
-
const result =
|
|
5797
|
+
const result = _chunkHW72ABGRcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
|
|
5664
5798
|
for (const [mode, names] of changed) {
|
|
5665
|
-
const label = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access',
|
|
5666
|
-
const std = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access',
|
|
5799
|
+
const label = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _322 => _322.find, 'call', _323 => _323((m) => m.id === mode), 'optionalAccess', _324 => _324.label]), () => ( mode));
|
|
5800
|
+
const std = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _325 => _325.find, 'call', _326 => _326((m) => m.id === _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _327 => _327.label]), () => ( _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)));
|
|
5667
5801
|
const list = names.map((n) => `"${n}"`).join(", ");
|
|
5668
5802
|
const one = names.length === 1;
|
|
5669
5803
|
result.warnings.push(`${label} blending has no PSD equivalent; ${list} ${one ? "was" : "were"} written as ${std}, the nearest Photoshop mode, so ${one ? "it looks" : "they look"} different in Photoshop (the merged image is exact).`);
|
|
@@ -5779,7 +5913,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5779
5913
|
const { src, pixels } = this.importImage(options, "The reference image");
|
|
5780
5914
|
const ref2 = {
|
|
5781
5915
|
id: `ref${this.nextReferenceId++}`,
|
|
5782
|
-
name: _optionalChain([options, 'access',
|
|
5916
|
+
name: _optionalChain([options, 'access', _328 => _328.name, 'optionalAccess', _329 => _329.trim, 'call', _330 => _330()]) || `Reference ${this.guides.references.length + 1}`,
|
|
5783
5917
|
src,
|
|
5784
5918
|
width: pixels.width,
|
|
5785
5919
|
height: pixels.height,
|
|
@@ -5858,7 +5992,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5858
5992
|
try {
|
|
5859
5993
|
const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
|
|
5860
5994
|
guides.references.push({ id: ref2.id, name: String(_nullishCoalesce(ref2.name, () => ( ref2.id))), src: ref2.src, width: px.width, height: px.height, x: Number(ref2.x) || 0, y: Number(ref2.y) || 0, displayWidth: Number(ref2.displayWidth) || 240, visible: ref2.visible !== false });
|
|
5861
|
-
const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access',
|
|
5995
|
+
const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _331 => _331.exec, 'call', _332 => _332(ref2.id), 'optionalAccess', _333 => _333[1]]), () => ( 0)));
|
|
5862
5996
|
if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
|
|
5863
5997
|
} catch (e) {
|
|
5864
5998
|
problems.push(e.message);
|
|
@@ -5869,7 +6003,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5869
6003
|
guides.stencils = [];
|
|
5870
6004
|
r.stencils.forEach((raw2, i) => {
|
|
5871
6005
|
try {
|
|
5872
|
-
const id = typeof _optionalChain([raw2, 'optionalAccess',
|
|
6006
|
+
const id = typeof _optionalChain([raw2, 'optionalAccess', _334 => _334.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
|
|
5873
6007
|
guides.stencils.push(normalizeStencil(raw2, id));
|
|
5874
6008
|
const n = Number(id.slice(7));
|
|
5875
6009
|
if (n >= this.nextStencilId) this.nextStencilId = n + 1;
|
|
@@ -5892,12 +6026,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5892
6026
|
/** The next free sticker number (ids `st<n>` are unique across the document). */
|
|
5893
6027
|
nextStickerNumber(doc = this.doc) {
|
|
5894
6028
|
let n = 0;
|
|
5895
|
-
for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access',
|
|
6029
|
+
for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _335 => _335.exec, 'call', _336 => _336(st.id), 'optionalAccess', _337 => _337[1]]), () => ( 0))));
|
|
5896
6030
|
return n + 1;
|
|
5897
6031
|
}
|
|
5898
6032
|
stickerLayer(layerId) {
|
|
5899
6033
|
const l = this.wetLayer(layerId, "edit the stickers of");
|
|
5900
|
-
const stickers = _optionalChain([this, 'access',
|
|
6034
|
+
const stickers = _optionalChain([this, 'access', _338 => _338.doc, 'access', _339 => _339.stickers, 'optionalAccess', _340 => _340[l.id]]);
|
|
5901
6035
|
if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (list_brushes category sticker).`);
|
|
5902
6036
|
return { layer: l, stickers };
|
|
5903
6037
|
}
|
|
@@ -5906,7 +6040,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5906
6040
|
const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
|
|
5907
6041
|
if (!id) return [];
|
|
5908
6042
|
this.requireLayer(id);
|
|
5909
|
-
return (_nullishCoalesce(_optionalChain([this, 'access',
|
|
6043
|
+
return (_nullishCoalesce(_optionalChain([this, 'access', _341 => _341.doc, 'access', _342 => _342.stickers, 'optionalAccess', _343 => _343[id]]), () => ( []))).map((s) => ({ ...s }));
|
|
5910
6044
|
}
|
|
5911
6045
|
/**
|
|
5912
6046
|
* Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
|
|
@@ -5922,15 +6056,15 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5922
6056
|
}
|
|
5923
6057
|
redrawStickers(layer, stickers, dirty) {
|
|
5924
6058
|
const partial = dirty && !layer.offset.x && !layer.offset.y;
|
|
5925
|
-
return partial ?
|
|
6059
|
+
return partial ? _chunk5BR7LC24cjs.stickerSurface.call(void 0, stickers, layer.surface, dirty) : _chunk5BR7LC24cjs.stickerSurface.call(void 0, stickers);
|
|
5926
6060
|
}
|
|
5927
6061
|
/** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
|
|
5928
6062
|
previewBase() {
|
|
5929
|
-
return _optionalChain([this, 'access',
|
|
6063
|
+
return _optionalChain([this, 'access', _344 => _344.stickerPreview, 'optionalAccess', _345 => _345.shown]) === this.doc ? this.stickerPreview.base : null;
|
|
5930
6064
|
}
|
|
5931
6065
|
readStickerUpdate(update) {
|
|
5932
6066
|
try {
|
|
5933
|
-
return
|
|
6067
|
+
return _chunk5BR7LC24cjs.normalizeStickerUpdate.call(void 0, update);
|
|
5934
6068
|
} catch (e) {
|
|
5935
6069
|
throw new PaintEditorError(e.message);
|
|
5936
6070
|
}
|
|
@@ -5941,7 +6075,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5941
6075
|
const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
|
|
5942
6076
|
if (!id) return null;
|
|
5943
6077
|
this.requireLayer(id);
|
|
5944
|
-
const hit =
|
|
6078
|
+
const hit = _chunk5BR7LC24cjs.stickerAt.call(void 0, _nullishCoalesce(_optionalChain([this, 'access', _346 => _346.doc, 'access', _347 => _347.stickers, 'optionalAccess', _348 => _348[id]]), () => ( [])), x, y);
|
|
5945
6079
|
return hit ? { ...hit } : null;
|
|
5946
6080
|
}
|
|
5947
6081
|
/** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
|
|
@@ -5962,7 +6096,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5962
6096
|
if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
|
|
5963
6097
|
const next = { ...stickers[i], ...this.readStickerUpdate(update) };
|
|
5964
6098
|
const list = stickers.map((s, j) => j === i ? next : s);
|
|
5965
|
-
const dirty = [
|
|
6099
|
+
const dirty = [_chunk5BR7LC24cjs.stickerRect.call(void 0, stickers[i]), _chunk5BR7LC24cjs.stickerRect.call(void 0, next)];
|
|
5966
6100
|
const base = _nullishCoalesce(this.previewBase(), () => ( this.doc));
|
|
5967
6101
|
const surface = this.redrawStickers(layer, list, dirty);
|
|
5968
6102
|
this.doc = { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: list } };
|
|
@@ -5985,7 +6119,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5985
6119
|
if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
|
|
5986
6120
|
const u = this.readStickerUpdate(update);
|
|
5987
6121
|
const next = { ...stickers[i], ...u };
|
|
5988
|
-
this.commitStickers("Edit sticker", layer, stickers.map((s, j) => j === i ? next : s), [
|
|
6122
|
+
this.commitStickers("Edit sticker", layer, stickers.map((s, j) => j === i ? next : s), [_chunk5BR7LC24cjs.stickerRect.call(void 0, stickers[i]), _chunk5BR7LC24cjs.stickerRect.call(void 0, next)]);
|
|
5989
6123
|
return { ...next };
|
|
5990
6124
|
}
|
|
5991
6125
|
/**
|
|
@@ -5997,8 +6131,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5997
6131
|
const layer = this.wetLayer(layerId, "add stickers to");
|
|
5998
6132
|
if (!input.length) throw new PaintEditorError("Pass at least one sticker (stamp, x, y).");
|
|
5999
6133
|
if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
|
|
6000
|
-
const existing = _optionalChain([this, 'access',
|
|
6001
|
-
if (!_optionalChain([existing, 'optionalAccess',
|
|
6134
|
+
const existing = _optionalChain([this, 'access', _349 => _349.doc, 'access', _350 => _350.stickers, 'optionalAccess', _351 => _351[layer.id]]);
|
|
6135
|
+
if (!_optionalChain([existing, 'optionalAccess', _352 => _352.length])) {
|
|
6002
6136
|
if (this.wet.wetLayerIds().includes(layer.id) || _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; add stickers to an empty layer (add_layer) or a sticker layer so they stay editable.`);
|
|
6003
6137
|
}
|
|
6004
6138
|
let n = this.nextStickerNumber();
|
|
@@ -6014,7 +6148,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6014
6148
|
const id = n++;
|
|
6015
6149
|
return { id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u };
|
|
6016
6150
|
});
|
|
6017
|
-
this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess',
|
|
6151
|
+
this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _353 => _353.length]) ? added.map(_chunk5BR7LC24cjs.stickerRect) : void 0);
|
|
6018
6152
|
return added.map((s) => ({ ...s }));
|
|
6019
6153
|
}
|
|
6020
6154
|
/** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
|
|
@@ -6024,7 +6158,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6024
6158
|
const picked = stickers.filter((s) => ids.includes(s.id));
|
|
6025
6159
|
const rest = stickers.filter((s) => !ids.includes(s.id));
|
|
6026
6160
|
const next = to === "front" ? [...rest, ...picked] : [...picked, ...rest];
|
|
6027
|
-
this.commitStickers("Arrange stickers", layer, next, picked.map(
|
|
6161
|
+
this.commitStickers("Arrange stickers", layer, next, picked.map(_chunk5BR7LC24cjs.stickerRect));
|
|
6028
6162
|
return next.map((s) => s.id);
|
|
6029
6163
|
}
|
|
6030
6164
|
/** Deletes stickers (`ids`, or all of them on the layer) (one undo step). Returns the ids removed. */
|
|
@@ -6034,7 +6168,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6034
6168
|
for (const id of ids) if (!stickers.some((s) => s.id === id)) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
|
|
6035
6169
|
}
|
|
6036
6170
|
const removed = ids ? [...ids] : stickers.map((s) => s.id);
|
|
6037
|
-
this.commitStickers("Remove stickers", layer, stickers.filter((s) => !removed.includes(s.id)), ids ? stickers.filter((s) => removed.includes(s.id)).map(
|
|
6171
|
+
this.commitStickers("Remove stickers", layer, stickers.filter((s) => !removed.includes(s.id)), ids ? stickers.filter((s) => removed.includes(s.id)).map(_chunk5BR7LC24cjs.stickerRect) : void 0);
|
|
6038
6172
|
return removed;
|
|
6039
6173
|
}
|
|
6040
6174
|
/** Sets a layer's stickers (replays). */
|
|
@@ -6042,14 +6176,428 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6042
6176
|
const l = this.wetLayer(layerId, "set the stickers of");
|
|
6043
6177
|
this.commitStickers("Stickers", l, stickers.map((s) => ({ ...s })));
|
|
6044
6178
|
}
|
|
6179
|
+
// --- Live stroke layers ---------------------------------------------------------
|
|
6180
|
+
/** The document's `liveStrokes` without these layers (as a spread: `{}` when unchanged). */
|
|
6181
|
+
liveStrokesWithout(ids) {
|
|
6182
|
+
const t = this.doc.liveStrokes;
|
|
6183
|
+
if (!t || !ids.some((id) => t[id])) return {};
|
|
6184
|
+
const out = { ...t };
|
|
6185
|
+
for (const id of ids) delete out[id];
|
|
6186
|
+
return { liveStrokes: out };
|
|
6187
|
+
}
|
|
6188
|
+
liveStrokeLayer(layerId, what) {
|
|
6189
|
+
const l = this.wetLayer(layerId, what);
|
|
6190
|
+
const strokes = _optionalChain([this, 'access', _354 => _354.doc, 'access', _355 => _355.liveStrokes, 'optionalAccess', _356 => _356[l.id]]);
|
|
6191
|
+
if (!strokes) throw new PaintEditorError(`Layer "${l.name}" is not a stroke layer; add one with add_layer {type: "strokes"} (or convert_to_stroke_layer on an empty layer), then paint on it.`);
|
|
6192
|
+
return { layer: l, strokes };
|
|
6193
|
+
}
|
|
6194
|
+
/** Whether a layer is a live stroke layer. */
|
|
6195
|
+
isLiveStrokeLayer(layerId) {
|
|
6196
|
+
return Boolean(_optionalChain([this, 'access', _357 => _357.doc, 'access', _358 => _358.liveStrokes, 'optionalAccess', _359 => _359[layerId]]));
|
|
6197
|
+
}
|
|
6198
|
+
/** Makes an empty pixel layer a live stroke layer (one undo step). */
|
|
6199
|
+
convertToLiveStrokes(layerId) {
|
|
6200
|
+
this.requireIdle("converting a layer");
|
|
6201
|
+
const l = this.paintTarget(layerId, "convert");
|
|
6202
|
+
if (_optionalChain([this, 'access', _360 => _360.doc, 'access', _361 => _361.liveStrokes, 'optionalAccess', _362 => _362[l.id]])) return this.describeLayer(l);
|
|
6203
|
+
if (_optionalChain([this, 'access', _363 => _363.doc, 'access', _364 => _364.stickers, 'optionalAccess', _365 => _365[l.id], 'optionalAccess', _366 => _366.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
|
|
6204
|
+
if (_chunk474IQG74cjs.contentBounds.call(void 0, l.surface) || this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" already has paint, which isn't kept as strokes; convert an empty layer or add a stroke layer (add_layer {type: "strokes"}).`);
|
|
6205
|
+
this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
|
|
6206
|
+
return this.describeLayer(this.getLayer(l.id));
|
|
6207
|
+
}
|
|
6208
|
+
/** A stroke layer's strokes, bottom first. */
|
|
6209
|
+
listLiveStrokes(layerId) {
|
|
6210
|
+
return this.liveStrokeLayer(layerId, "list the strokes of").strokes.map((x) => ({ ...x }));
|
|
6211
|
+
}
|
|
6212
|
+
/** The stroke layer holding a live stroke, and where. */
|
|
6213
|
+
findLiveStroke(id) {
|
|
6214
|
+
for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
|
|
6215
|
+
const index = strokes.findIndex((x) => x.id === id);
|
|
6216
|
+
const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _367 => _367.layer]);
|
|
6217
|
+
if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
|
|
6218
|
+
}
|
|
6219
|
+
const baked = this.doc.strokes.some((x) => x.id === id);
|
|
6220
|
+
throw new PaintEditorError(
|
|
6221
|
+
baked ? `Stroke "${id}" was painted on a pixel layer, so its pixels are baked; only strokes on a stroke layer can be edited (list_strokes {live: true}). Replay it onto a stroke layer (replay_strokes layerId) to edit the copy.` : `Unknown stroke "${id}". Call list_strokes {live: true} for the ids of editable strokes.`
|
|
6222
|
+
);
|
|
6223
|
+
}
|
|
6224
|
+
/**
|
|
6225
|
+
* Changes a live stroke's brush (a preset by `brushId`, keeping the stroke's size, and/or brush
|
|
6226
|
+
* settings), colour, paint or seed, and redraws its layer (one undo step). A new colour replaces
|
|
6227
|
+
* gradient or effect paint. Returns the stroke and the area that changed.
|
|
6228
|
+
*/
|
|
6229
|
+
updateStroke(id, update) {
|
|
6230
|
+
this.requireIdle("editing a stroke");
|
|
6231
|
+
const { layer, strokes, index } = this.findLiveStroke(id);
|
|
6232
|
+
const was = strokes[index];
|
|
6233
|
+
let brush = was.brush;
|
|
6234
|
+
if (update.brushId !== void 0) {
|
|
6235
|
+
const b = this.requireBrush(update.brushId);
|
|
6236
|
+
brush = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
|
|
6237
|
+
}
|
|
6238
|
+
if (update.brush !== void 0) {
|
|
6239
|
+
if (!update.brush || typeof update.brush !== "object") throw new PaintEditorError("brush must be an object of brush settings (as set_brush takes).");
|
|
6240
|
+
brush = _chunk5BR7LC24cjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
|
|
6241
|
+
}
|
|
6242
|
+
const why = liveStrokeRefusal(brush);
|
|
6243
|
+
if (why) throw new PaintEditorError(why);
|
|
6244
|
+
const next = { ...was, brush: _chunk5BR7LC24cjs.brushToJSON.call(void 0, brush) };
|
|
6245
|
+
if (update.seed !== void 0) {
|
|
6246
|
+
if (!Number.isInteger(update.seed) || update.seed < 0) throw new PaintEditorError(`seed ${update.seed} must be a whole number of 0 or more.`);
|
|
6247
|
+
next.seed = update.seed;
|
|
6248
|
+
}
|
|
6249
|
+
if (update.color !== void 0) {
|
|
6250
|
+
next.color = parseColor(update.color);
|
|
6251
|
+
delete next.paint;
|
|
6252
|
+
}
|
|
6253
|
+
if (update.paint !== void 0) {
|
|
6254
|
+
if (update.paint === null) delete next.paint;
|
|
6255
|
+
else if (_chunk5BR7LC24cjs.isPaintEffectPaint.call(void 0, update.paint)) {
|
|
6256
|
+
if (!this.effectPaintImage(update.paint)) throw new PaintEditorError(`The effect "${update.paint.effect}" is not rendered yet; render it first (prepareEffectPaints; the update_stroke tool does this).`);
|
|
6257
|
+
next.paint = JSON.parse(JSON.stringify(update.paint));
|
|
6258
|
+
} else {
|
|
6259
|
+
const p = this.readStrokePaint(update.paint);
|
|
6260
|
+
if (p.type === "color") {
|
|
6261
|
+
next.color = p.color;
|
|
6262
|
+
delete next.paint;
|
|
6263
|
+
} else next.paint = JSON.parse(JSON.stringify(p));
|
|
6264
|
+
}
|
|
6265
|
+
}
|
|
6266
|
+
const rgb = _chunk5BR7LC24cjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
|
|
6267
|
+
const load = brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, rgb);
|
|
6268
|
+
if (load.reservoir || load.pickup) next.load = load;
|
|
6269
|
+
else delete next.load;
|
|
6270
|
+
const list = strokes.map((x, i) => i === index ? next : x);
|
|
6271
|
+
this.commitLiveStrokes("Edit stroke", layer, list, this.strokeAreas([was]));
|
|
6272
|
+
return { stroke: { ...next }, bounds: _nullishCoalesce(unionRect(this.strokeArea(was), this.strokeArea(next)), () => ( { x: 0, y: 0, width: 0, height: 0 })) };
|
|
6273
|
+
}
|
|
6274
|
+
/**
|
|
6275
|
+
* Replaces a live stroke's points, or moves, scales, rotates or flips them (`transform`, about
|
|
6276
|
+
* the stroke's centre unless an origin is given; the brush size scales too), and redraws its
|
|
6277
|
+
* layer (one undo step). Returns the stroke and the area that changed.
|
|
6278
|
+
*/
|
|
6279
|
+
editStrokePoints(id, edit) {
|
|
6280
|
+
this.requireIdle("editing a stroke");
|
|
6281
|
+
if (edit.points === void 0 === (edit.transform === void 0)) throw new PaintEditorError("Pass either points (the new pen samples) or transform (dx, dy, scale, rotate, flipX), not both.");
|
|
6282
|
+
const { layer, strokes, index } = this.findLiveStroke(id);
|
|
6283
|
+
const was = strokes[index];
|
|
6284
|
+
let next;
|
|
6285
|
+
if (edit.points !== void 0) {
|
|
6286
|
+
const points = this.checkPoints(edit.points);
|
|
6287
|
+
next = { ...was, points: points.map((p) => ({ ...p })) };
|
|
6288
|
+
} else {
|
|
6289
|
+
const t = edit.transform;
|
|
6290
|
+
if (t.scale !== void 0 && !(t.scale > 0 && t.scale <= 20)) throw new PaintEditorError(`scale ${t.scale} is out of range; use above 0 up to 20.`);
|
|
6291
|
+
for (const k of ["dx", "dy", "rotate"]) if (t[k] !== void 0 && !Number.isFinite(t[k])) throw new PaintEditorError(`${k} must be a number.`);
|
|
6292
|
+
const b = strokeBounds(was.points);
|
|
6293
|
+
const m = variationAffine(t, _nullishCoalesce(t.origin, () => ( { x: b.x + b.width / 2, y: b.y + b.height / 2 })));
|
|
6294
|
+
next = varyStroke(was, m, {});
|
|
6295
|
+
if (was.stencils) next.stencils = was.stencils;
|
|
6296
|
+
}
|
|
6297
|
+
const list = strokes.map((x, i) => i === index ? next : x);
|
|
6298
|
+
this.commitLiveStrokes("Edit stroke points", layer, list, this.strokeAreas([was]));
|
|
6299
|
+
return { stroke: { ...next }, bounds: _nullishCoalesce(unionRect(this.strokeArea(was), this.strokeArea(next)), () => ( { x: 0, y: 0, width: 0, height: 0 })) };
|
|
6300
|
+
}
|
|
6301
|
+
/** Deletes live strokes (one undo step). Returns the ids removed and the area that changed. */
|
|
6302
|
+
removeStrokes(ids) {
|
|
6303
|
+
this.requireIdle("removing strokes");
|
|
6304
|
+
if (!ids.length) throw new PaintEditorError("Pass at least one stroke id (list_strokes {live: true}).");
|
|
6305
|
+
const found = ids.map((id) => this.findLiveStroke(id));
|
|
6306
|
+
let doc = this.doc;
|
|
6307
|
+
let bounds = null;
|
|
6308
|
+
const layers = /* @__PURE__ */ new Map();
|
|
6309
|
+
for (const f of found) layers.set(f.layer.id, f.layer);
|
|
6310
|
+
for (const [layerId, layer] of layers) {
|
|
6311
|
+
const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _368 => _368.liveStrokes, 'optionalAccess', _369 => _369[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
|
|
6312
|
+
for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
|
|
6313
|
+
doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _370 => _370.liveStrokes, 'optionalAccess', _371 => _371[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
|
|
6314
|
+
}
|
|
6315
|
+
this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
|
|
6316
|
+
return { removed: [...ids], bounds };
|
|
6317
|
+
}
|
|
6318
|
+
/** Moves a live stroke to `index` in its layer (0 = bottom) and redraws (one undo step). Returns the new order. */
|
|
6319
|
+
reorderStroke(id, index) {
|
|
6320
|
+
this.requireIdle("reordering strokes");
|
|
6321
|
+
const { layer, strokes, index: from } = this.findLiveStroke(id);
|
|
6322
|
+
if (!Number.isInteger(index) || index < 0 || index >= strokes.length) throw new PaintEditorError(`index ${index} is out of range; the layer has ${strokes.length} strokes, so use 0..${strokes.length - 1} (0 = bottom).`);
|
|
6323
|
+
const list = [...strokes];
|
|
6324
|
+
const [moved] = list.splice(from, 1);
|
|
6325
|
+
list.splice(index, 0, moved);
|
|
6326
|
+
if (from !== index) this.commitLiveStrokes("Reorder stroke", layer, list, this.strokeAreas([moved]));
|
|
6327
|
+
return list.map((x) => x.id);
|
|
6328
|
+
}
|
|
6329
|
+
/** Turns a stroke layer into a plain pixel layer with the same pixels (one undo step). */
|
|
6330
|
+
rasterizeLiveStrokes(layerId) {
|
|
6331
|
+
this.requireIdle("rasterizing");
|
|
6332
|
+
const { layer } = this.liveStrokeLayer(layerId, "rasterize");
|
|
6333
|
+
this.commit("Rasterize stroke layer", this.withPaintEvent({ ...this.doc, ...this.liveStrokesWithout([layer.id]) }, { kind: "live-strokes", layerId: layer.id, data: { rasterized: true } }));
|
|
6334
|
+
return this.describeLayer(this.getLayer(layer.id));
|
|
6335
|
+
}
|
|
6336
|
+
/** Sets a layer's live strokes and redraws it (replays). `null` makes it a plain pixel layer. */
|
|
6337
|
+
replaceLiveStrokes(layerId, strokes) {
|
|
6338
|
+
const l = this.wetLayer(layerId, "set the strokes of");
|
|
6339
|
+
if (strokes === null) {
|
|
6340
|
+
this.commit("Rasterize stroke layer", { ...this.doc, ...this.liveStrokesWithout([l.id]) });
|
|
6341
|
+
return;
|
|
6342
|
+
}
|
|
6343
|
+
this.commitLiveStrokes("Strokes", l, strokes.map((x) => ({ ...x, layerId: l.id })));
|
|
6344
|
+
}
|
|
6345
|
+
/**
|
|
6346
|
+
* The top-most stroke of a stroke layer (default the active layer) that painted the pixel at
|
|
6347
|
+
* (x, y) document pixels, or `null`. Strokes whose area holds the point are drawn alone, top
|
|
6348
|
+
* first, until one covers it.
|
|
6349
|
+
*/
|
|
6350
|
+
liveStrokeAt(layerId, x, y) {
|
|
6351
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) throw new PaintEditorError("x and y must be numbers of document pixels.");
|
|
6352
|
+
const { layer, strokes } = this.liveStrokeLayer(layerId, "pick a stroke on");
|
|
6353
|
+
const plain = { ...layer, visible: true, locks: void 0, offset: { x: 0, y: 0 } };
|
|
6354
|
+
const doc = { ...this.doc, liveStrokes: void 0, stickers: void 0 };
|
|
6355
|
+
const px = Math.floor(x);
|
|
6356
|
+
const py = Math.floor(y);
|
|
6357
|
+
for (let i = strokes.length - 1; i >= 0; i--) {
|
|
6358
|
+
const area = this.strokeArea(strokes[i]);
|
|
6359
|
+
if (!area || px < area.x || py < area.y || px >= area.x + area.width || py >= area.y + area.height) continue;
|
|
6360
|
+
const drawn = this.drawLiveStroke(doc, plain, _chunk474IQG74cjs.emptySurface.call(void 0, 4), strokes[i]).surface;
|
|
6361
|
+
if (_chunk474IQG74cjs.readPixel.call(void 0, drawn, px, py)[3] > 24) return { ...strokes[i] };
|
|
6362
|
+
}
|
|
6363
|
+
return null;
|
|
6364
|
+
}
|
|
6365
|
+
/** Picks a stroke for the stroke panel and canvas (`null` for none). Editor state, not an undo step. */
|
|
6366
|
+
selectStroke(id) {
|
|
6367
|
+
if (id === this.selectedStroke) return;
|
|
6368
|
+
this.selectedStroke = id;
|
|
6369
|
+
this.emit([]);
|
|
6370
|
+
}
|
|
6371
|
+
/** Where a live stroke painted (document pixels), or `null`. */
|
|
6372
|
+
liveStrokeArea(id) {
|
|
6373
|
+
return this.strokeArea(this.findLiveStroke(id).strokes.find((s) => s.id === id));
|
|
6374
|
+
}
|
|
6375
|
+
/** Commits a layer's new stroke list with its redrawn pixels, recorded for replays (one undo step). */
|
|
6376
|
+
commitLiveStrokes(label, layer, list, dirty) {
|
|
6377
|
+
this.commit(label, this.withLiveStrokes(this.doc, layer, list, dirty));
|
|
6378
|
+
}
|
|
6379
|
+
withLiveStrokes(doc, layer, list, dirty) {
|
|
6380
|
+
if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
|
|
6381
|
+
const current = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _372 => _372.layer]);
|
|
6382
|
+
const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
|
|
6383
|
+
const next = { ...doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
|
|
6384
|
+
return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
|
|
6385
|
+
}
|
|
6386
|
+
/** Where a stroke painted (document pixels): as learnt when it was painted or drawn, else an estimate from its points and brush. */
|
|
6387
|
+
strokeArea(s) {
|
|
6388
|
+
return this.paintedBounds.has(s) ? this.paintedBounds.get(s) : liveStrokeBounds(s);
|
|
6389
|
+
}
|
|
6390
|
+
/** The areas strokes painted, or `null` when one is not known (a full redraw then). */
|
|
6391
|
+
strokeAreas(strokes) {
|
|
6392
|
+
const out = [];
|
|
6393
|
+
for (const s of strokes) {
|
|
6394
|
+
if (!this.paintedBounds.has(s)) return null;
|
|
6395
|
+
const b = this.paintedBounds.get(s);
|
|
6396
|
+
if (b) out.push(b);
|
|
6397
|
+
}
|
|
6398
|
+
return out;
|
|
6399
|
+
}
|
|
6400
|
+
/** Draws one stroke onto `surface` of a plain copy of the layer; returns the result and the area it painted. */
|
|
6401
|
+
drawLiveStroke(doc, plain, surface, st) {
|
|
6402
|
+
let out = surface;
|
|
6403
|
+
const host = {
|
|
6404
|
+
update: () => {
|
|
6405
|
+
},
|
|
6406
|
+
commit: (_s, drawn, cancelled) => {
|
|
6407
|
+
if (!cancelled && drawn) out = drawn;
|
|
6408
|
+
}
|
|
6409
|
+
};
|
|
6410
|
+
const paint = st.paint && this.liveEffectAt !== null && isLiveEffect(st) ? framePaint(st.paint, this.liveEffectAt) : st.paint;
|
|
6411
|
+
const init = { layerId: plain.id, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...paint ? { paint } : {}, snapToPerspective: false, stencils: false, maskStencils: _nullishCoalesce(st.stencils, () => ( [])) };
|
|
6412
|
+
const session = this.sessionFor({ ...doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, doc.layers, plain.id, () => ({ ...plain, surface })) }, init, host);
|
|
6413
|
+
session.push(st.points);
|
|
6414
|
+
const result = session.end();
|
|
6415
|
+
const had = this.paintedBounds.get(st);
|
|
6416
|
+
this.paintedBounds.set(st, had && result.bounds ? unionRect(had, result.bounds) : _nullishCoalesce(_nullishCoalesce(result.bounds, () => ( had)), () => ( null)));
|
|
6417
|
+
return { surface: out, bounds: result.bounds };
|
|
6418
|
+
}
|
|
6419
|
+
/**
|
|
6420
|
+
* A stroke layer's pixels drawn from its strokes, bottom first. With `dirty` (the areas the old
|
|
6421
|
+
* strokes that changed had painted), only the tiles there and under any stroke whose area isn't
|
|
6422
|
+
* known yet are drawn again, from the strokes that reach them (a pixel depends only on the
|
|
6423
|
+
* strokes over it); the other tiles are kept. Without it, or with `null`, every stroke is drawn.
|
|
6424
|
+
*/
|
|
6425
|
+
drawLiveStrokes(layer, list, dirty) {
|
|
6426
|
+
const plain = { ...layer, visible: true, locks: void 0, offset: { x: 0, y: 0 } };
|
|
6427
|
+
const doc = { ...this.doc, liveStrokes: void 0, stickers: void 0 };
|
|
6428
|
+
const unknown = list.filter((s) => !this.paintedBounds.has(s));
|
|
6429
|
+
const partial = dirty && !layer.offset.x && !layer.offset.y && unknown.length <= 4;
|
|
6430
|
+
if (!partial) {
|
|
6431
|
+
let surface2 = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
|
|
6432
|
+
for (const st of list) surface2 = this.drawLiveStroke(doc, plain, surface2, st).surface;
|
|
6433
|
+
return surface2;
|
|
6434
|
+
}
|
|
6435
|
+
const areas = [...dirty];
|
|
6436
|
+
for (const st of unknown) {
|
|
6437
|
+
const b = this.drawLiveStroke(doc, plain, _chunk474IQG74cjs.emptySurface.call(void 0, 4), st).bounds;
|
|
6438
|
+
if (b) areas.push(b);
|
|
6439
|
+
}
|
|
6440
|
+
const { width, height } = this.doc.canvas;
|
|
6441
|
+
const rects = areas.map((r) => clipRect(r, width, height)).filter((r) => r !== null);
|
|
6442
|
+
if (!rects.length) return layer.surface;
|
|
6443
|
+
const overlaps = (a, b) => a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height;
|
|
6444
|
+
let drawn = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
|
|
6445
|
+
for (const st of list) {
|
|
6446
|
+
const b = this.paintedBounds.get(st);
|
|
6447
|
+
if (b && rects.some((r) => overlaps(r, b))) drawn = this.drawLiveStroke(doc, plain, drawn, st).surface;
|
|
6448
|
+
}
|
|
6449
|
+
let surface = layer.surface;
|
|
6450
|
+
for (const r of rects) surface = _chunk474IQG74cjs.writeRegion.call(void 0, surface, r, _chunk474IQG74cjs.readRegion.call(void 0, drawn, r));
|
|
6451
|
+
return surface;
|
|
6452
|
+
}
|
|
6453
|
+
// --- Live effect paint ------------------------------------------------------------
|
|
6454
|
+
/** The view's layers: stroke layers playing live effects at `effectTime`, the rest as they are. */
|
|
6455
|
+
animatedView() {
|
|
6456
|
+
if (!this.animatedLayers.size) return this.doc.layers;
|
|
6457
|
+
let layers = this.doc.layers;
|
|
6458
|
+
for (const [id, a] of this.animatedLayers) {
|
|
6459
|
+
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _373 => _373.layer]);
|
|
6460
|
+
if (isPixelLayer(l) && l.surface === a.base) layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
|
|
6461
|
+
}
|
|
6462
|
+
return layers;
|
|
6463
|
+
}
|
|
6464
|
+
/** Stroke layers with live effect strokes, and the distinct live sources (frame 0). */
|
|
6465
|
+
liveEffects(doc = this.doc) {
|
|
6466
|
+
const layers = [];
|
|
6467
|
+
const sources = /* @__PURE__ */ new Map();
|
|
6468
|
+
for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
|
|
6469
|
+
const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _374 => _374.layer]);
|
|
6470
|
+
const live = strokes.filter(isLiveEffect);
|
|
6471
|
+
if (!isPixelLayer(layer) || !live.length) continue;
|
|
6472
|
+
layers.push({ layer, strokes });
|
|
6473
|
+
for (const st of live) sources.set(_chunk5BR7LC24cjs.effectPaintKey.call(void 0, st.paint), st.paint);
|
|
6474
|
+
}
|
|
6475
|
+
return { layers, sources: [...sources.values()] };
|
|
6476
|
+
}
|
|
6477
|
+
/** What plays: the live effect strokes and their layers, or `null` when nothing does. */
|
|
6478
|
+
getAnimation() {
|
|
6479
|
+
const { layers, sources } = this.liveEffects();
|
|
6480
|
+
if (!layers.length) return null;
|
|
6481
|
+
return { layerIds: layers.map((x) => x.layer.id), strokes: layers.reduce((n, x) => n + x.strokes.filter(isLiveEffect).length, 0), sources: sources.length };
|
|
6482
|
+
}
|
|
6483
|
+
/** Plays or pauses live effect paint, and caps its frame rate (1..60). Editor state, not an undo step. */
|
|
6484
|
+
setEffectPlayback(update) {
|
|
6485
|
+
if (update.playing !== void 0 && typeof update.playing !== "boolean") throw new PaintEditorError("playing must be true or false.");
|
|
6486
|
+
if (update.fps !== void 0 && !(Number.isInteger(update.fps) && update.fps >= 1 && update.fps <= 60)) throw new PaintEditorError(`fps ${update.fps} is out of range; use a whole number 1..60.`);
|
|
6487
|
+
this.effectPlaybackState = { ...this.effectPlaybackState, ...update };
|
|
6488
|
+
this.emit([]);
|
|
6489
|
+
return { ...this.effectPlaybackState, time: this.effectTime };
|
|
6490
|
+
}
|
|
6491
|
+
/** The surfaces of every stroke layer with live effects at `time` ms, drawn in full (frames rendered first). */
|
|
6492
|
+
async liveSurfacesAt(time) {
|
|
6493
|
+
const { layers, sources } = this.liveEffects();
|
|
6494
|
+
await this.prepareEffectPaints(sources.map((p) => framePaint(p, time)));
|
|
6495
|
+
const out = /* @__PURE__ */ new Map();
|
|
6496
|
+
this.liveEffectAt = time;
|
|
6497
|
+
try {
|
|
6498
|
+
for (const { layer, strokes } of layers) out.set(layer.id, this.drawLiveStrokes({ ...layer, offset: { x: 0, y: 0 } }, strokes));
|
|
6499
|
+
} finally {
|
|
6500
|
+
this.liveEffectAt = null;
|
|
6501
|
+
}
|
|
6502
|
+
return out;
|
|
6503
|
+
}
|
|
6504
|
+
/**
|
|
6505
|
+
* Shows the live effects at `time` ms (each live stroke's effect at its own time plus `time`):
|
|
6506
|
+
* renders their frames, then redraws only where live effect strokes paint. Nothing in the
|
|
6507
|
+
* document changes. Resolves `false` when the document changed while frames rendered (the next
|
|
6508
|
+
* frame catches up).
|
|
6509
|
+
*/
|
|
6510
|
+
async showEffectTime(time) {
|
|
6511
|
+
this.checkTime(time);
|
|
6512
|
+
const { layers, sources } = this.liveEffects();
|
|
6513
|
+
const revision = this.docRevision;
|
|
6514
|
+
await this.prepareEffectPaints(sources.map((p) => framePaint(p, time)));
|
|
6515
|
+
if (revision !== this.docRevision || this.session) return false;
|
|
6516
|
+
const next = /* @__PURE__ */ new Map();
|
|
6517
|
+
const dirty = [];
|
|
6518
|
+
this.liveEffectAt = time;
|
|
6519
|
+
try {
|
|
6520
|
+
for (const { layer, strokes } of layers) {
|
|
6521
|
+
const shown = this.animatedLayers.get(layer.id);
|
|
6522
|
+
const from = shown && shown.base === layer.surface ? shown.surface : layer.surface;
|
|
6523
|
+
const areas = strokes.filter(isLiveEffect).flatMap((st) => [liveStrokeBounds(st), ...this.paintedBounds.get(st) ? [this.paintedBounds.get(st)] : []]);
|
|
6524
|
+
const surface = this.drawLiveStrokes({ ...layer, surface: from, offset: { x: 0, y: 0 } }, strokes, layer.offset.x || layer.offset.y ? null : areas);
|
|
6525
|
+
next.set(layer.id, { base: layer.surface, surface });
|
|
6526
|
+
dirty.push(...areas);
|
|
6527
|
+
}
|
|
6528
|
+
} finally {
|
|
6529
|
+
this.liveEffectAt = null;
|
|
6530
|
+
}
|
|
6531
|
+
this.animatedLayers = next;
|
|
6532
|
+
this.effectTime = time;
|
|
6533
|
+
this.emit(dirty);
|
|
6534
|
+
return true;
|
|
6535
|
+
}
|
|
6536
|
+
/**
|
|
6537
|
+
* Plays live effect paint in the view until `stop`: a frame per tick of `clock` (default
|
|
6538
|
+
* animation frames) at most `fps` a second, one render in flight. Idle while paused, while a
|
|
6539
|
+
* stroke is painted, or when nothing is live. The bindings start it while the editor is shown.
|
|
6540
|
+
*/
|
|
6541
|
+
playEffects(clock = defaultEffectClock) {
|
|
6542
|
+
let stopped = false;
|
|
6543
|
+
let cancel = () => {
|
|
6544
|
+
};
|
|
6545
|
+
let last = -Infinity;
|
|
6546
|
+
let started = clock.now() - this.effectTime;
|
|
6547
|
+
const tick = () => {
|
|
6548
|
+
if (stopped) return;
|
|
6549
|
+
const now = clock.now();
|
|
6550
|
+
const { playing, fps } = this.effectPlaybackState;
|
|
6551
|
+
if (!playing) started = now - this.effectTime;
|
|
6552
|
+
if (!playing || this.session || now - last < 1e3 / fps - 1 || !this.liveEffects().layers.length) {
|
|
6553
|
+
cancel = clock.frame(tick);
|
|
6554
|
+
return;
|
|
6555
|
+
}
|
|
6556
|
+
last = now;
|
|
6557
|
+
this.showEffectTime(Math.max(0, now - started)).then(
|
|
6558
|
+
() => {
|
|
6559
|
+
if (!stopped) cancel = clock.frame(tick);
|
|
6560
|
+
},
|
|
6561
|
+
() => {
|
|
6562
|
+
if (!stopped) cancel = clock.frame(tick);
|
|
6563
|
+
}
|
|
6564
|
+
);
|
|
6565
|
+
};
|
|
6566
|
+
cancel = clock.frame(tick);
|
|
6567
|
+
return {
|
|
6568
|
+
stop() {
|
|
6569
|
+
stopped = true;
|
|
6570
|
+
cancel();
|
|
6571
|
+
}
|
|
6572
|
+
};
|
|
6573
|
+
}
|
|
6574
|
+
/**
|
|
6575
|
+
* Runs `fn` with the painting as it is `time` ms into its live effects (see `getAnimation`): for
|
|
6576
|
+
* exports at a moment. Nothing in the document changes.
|
|
6577
|
+
*/
|
|
6578
|
+
async withEffectTime(time, fn) {
|
|
6579
|
+
this.checkTime(time);
|
|
6580
|
+
const surfaces = await this.liveSurfacesAt(time);
|
|
6581
|
+
const was = this.frameOverride;
|
|
6582
|
+
this.frameOverride = surfaces;
|
|
6583
|
+
try {
|
|
6584
|
+
return await fn();
|
|
6585
|
+
} finally {
|
|
6586
|
+
this.frameOverride = was;
|
|
6587
|
+
}
|
|
6588
|
+
}
|
|
6589
|
+
/** The painting composited `time` ms into its live effects, like `compositePixels`. Nothing in the document changes. */
|
|
6590
|
+
async renderAnimationFrame(time, options = {}) {
|
|
6591
|
+
return this.withEffectTime(time, () => this.compositePixels(options));
|
|
6592
|
+
}
|
|
6045
6593
|
// --- Stencils --------------------------------------------------------------------
|
|
6046
|
-
|
|
6047
|
-
|
|
6594
|
+
__init123() {this.stencilCache = null}
|
|
6595
|
+
__init124() {this.nextStencilId = 1}
|
|
6048
6596
|
/** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
|
|
6049
6597
|
stencilSelection(stencils = this.guides.stencils) {
|
|
6050
6598
|
const { width, height } = this.doc.canvas;
|
|
6051
6599
|
const size = `${width}x${height}`;
|
|
6052
|
-
if (_optionalChain([this, 'access',
|
|
6600
|
+
if (_optionalChain([this, 'access', _375 => _375.stencilCache, 'optionalAccess', _376 => _376.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
|
|
6053
6601
|
const mask = stencilMask(stencils, width, height);
|
|
6054
6602
|
this.stencilCache = { key: stencils, size, mask };
|
|
6055
6603
|
return mask;
|
|
@@ -6111,7 +6659,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6111
6659
|
makeSwatch(color, name) {
|
|
6112
6660
|
const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
|
|
6113
6661
|
const out = { color: _chunkPQ3H2AANcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
|
|
6114
|
-
if (_optionalChain([name, 'optionalAccess',
|
|
6662
|
+
if (_optionalChain([name, 'optionalAccess', _377 => _377.trim, 'call', _378 => _378()])) out.name = name.trim();
|
|
6115
6663
|
if (p.type === "gradient") out.paint = p;
|
|
6116
6664
|
return out;
|
|
6117
6665
|
}
|
|
@@ -6163,7 +6711,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6163
6711
|
* mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
|
|
6164
6712
|
*/
|
|
6165
6713
|
mixOnPad(paints, options = {}) {
|
|
6166
|
-
const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess',
|
|
6714
|
+
const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _379 => _379.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _380 => _380.parts]) }));
|
|
6167
6715
|
let r;
|
|
6168
6716
|
try {
|
|
6169
6717
|
r = this.pad.mix(parsed, options);
|
|
@@ -6252,13 +6800,42 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
6252
6800
|
}
|
|
6253
6801
|
/** A layer's tile surface (live while stroking), for thumbnails. */
|
|
6254
6802
|
layerSurface(id) {
|
|
6255
|
-
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess',
|
|
6803
|
+
const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _381 => _381.layer]);
|
|
6256
6804
|
return isPixelLayer(l) ? l.surface : null;
|
|
6257
6805
|
}
|
|
6258
6806
|
}, _class10.__initStatic(), _class10);
|
|
6259
6807
|
var MAX_IMAGE_SIDE = 8192;
|
|
6260
6808
|
var movePoint = (p, dx, dy) => ({ x: p.x + dx, y: p.y + dy });
|
|
6261
6809
|
var moveRect = (r, dx, dy) => ({ ...r, x: r.x + dx, y: r.y + dy });
|
|
6810
|
+
function isLiveEffect(s) {
|
|
6811
|
+
return _optionalChain([s, 'access', _382 => _382.paint, 'optionalAccess', _383 => _383.type]) === "effect" && s.paint.live === true;
|
|
6812
|
+
}
|
|
6813
|
+
function framePaint(p, t) {
|
|
6814
|
+
return { ...p, time: p.time + t };
|
|
6815
|
+
}
|
|
6816
|
+
var MAX_LIVE_EFFECT_SOURCES = 8;
|
|
6817
|
+
var defaultEffectClock = {
|
|
6818
|
+
now: () => typeof performance !== "undefined" ? performance.now() : Date.now(),
|
|
6819
|
+
frame: (cb) => {
|
|
6820
|
+
if (typeof requestAnimationFrame === "undefined") {
|
|
6821
|
+
const t = setTimeout(cb, 16);
|
|
6822
|
+
return () => clearTimeout(t);
|
|
6823
|
+
}
|
|
6824
|
+
const id = requestAnimationFrame(cb);
|
|
6825
|
+
return () => cancelAnimationFrame(id);
|
|
6826
|
+
}
|
|
6827
|
+
};
|
|
6828
|
+
function clipRect(r, width, height) {
|
|
6829
|
+
const x0 = Math.max(0, Math.floor(r.x));
|
|
6830
|
+
const y0 = Math.max(0, Math.floor(r.y));
|
|
6831
|
+
const x1 = Math.min(width, Math.ceil(r.x + r.width));
|
|
6832
|
+
const y1 = Math.min(height, Math.ceil(r.y + r.height));
|
|
6833
|
+
return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
|
|
6834
|
+
}
|
|
6835
|
+
function withLiveStroke(doc, stroke) {
|
|
6836
|
+
const list = _optionalChain([doc, 'access', _384 => _384.liveStrokes, 'optionalAccess', _385 => _385[stroke.layerId]]);
|
|
6837
|
+
return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
|
|
6838
|
+
}
|
|
6262
6839
|
function shiftDocument(doc, dx, dy) {
|
|
6263
6840
|
if (!dx && !dy) return doc;
|
|
6264
6841
|
let layers = doc.layers;
|
|
@@ -6275,11 +6852,18 @@ function shiftDocument(doc, dx, dy) {
|
|
|
6275
6852
|
return s.stencils ? { ...moved, stencils: s.stencils.map((x) => translateStencil(x, dx, dy)) } : moved;
|
|
6276
6853
|
})
|
|
6277
6854
|
};
|
|
6855
|
+
const moveStroke = (s) => {
|
|
6856
|
+
const moved = varyStroke(s, m, {});
|
|
6857
|
+
return s.stencils ? { ...moved, stencils: s.stencils.map((x) => translateStencil(x, dx, dy)) } : moved;
|
|
6858
|
+
};
|
|
6278
6859
|
if (doc.stickers) out.stickers = Object.fromEntries(Object.entries(doc.stickers).map(([id, list]) => [id, moveStickers(list)]));
|
|
6860
|
+
if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
|
|
6279
6861
|
if (doc.paintEvents) {
|
|
6280
6862
|
out.paintEvents = doc.paintEvents.map((e) => {
|
|
6281
|
-
const list = e.kind === "stickers" ? _optionalChain([e, 'access',
|
|
6282
|
-
|
|
6863
|
+
const list = e.kind === "stickers" ? _optionalChain([e, 'access', _386 => _386.data, 'optionalAccess', _387 => _387.stickers]) : void 0;
|
|
6864
|
+
if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
|
|
6865
|
+
const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _388 => _388.data, 'optionalAccess', _389 => _389.strokes]) : void 0;
|
|
6866
|
+
return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
|
|
6283
6867
|
});
|
|
6284
6868
|
}
|
|
6285
6869
|
if (doc.wetEvents) {
|
|
@@ -6360,8 +6944,8 @@ function strokeSchedule(points) {
|
|
|
6360
6944
|
return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
|
|
6361
6945
|
}
|
|
6362
6946
|
function strokeDuration(points, max = 1800) {
|
|
6363
|
-
const t0 = _optionalChain([points, 'access',
|
|
6364
|
-
const t1 = _optionalChain([points, 'access',
|
|
6947
|
+
const t0 = _optionalChain([points, 'access', _390 => _390[0], 'optionalAccess', _391 => _391.t]);
|
|
6948
|
+
const t1 = _optionalChain([points, 'access', _392 => _392[points.length - 1], 'optionalAccess', _393 => _393.t]);
|
|
6365
6949
|
let ms;
|
|
6366
6950
|
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
|
|
6367
6951
|
else {
|
|
@@ -6415,7 +6999,7 @@ var PaintDirector = class {
|
|
|
6415
6999
|
}
|
|
6416
7000
|
where(id) {
|
|
6417
7001
|
const a = this.presence.get(id);
|
|
6418
|
-
return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess',
|
|
7002
|
+
return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _394 => _394.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _395 => _395.y]), () => ( 0)) };
|
|
6419
7003
|
}
|
|
6420
7004
|
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
6421
7005
|
async glide(id, to, ms = 380) {
|
|
@@ -6462,8 +7046,8 @@ var PaintDirector = class {
|
|
|
6462
7046
|
}
|
|
6463
7047
|
case "replay": {
|
|
6464
7048
|
await this.say(id, command.note, 500);
|
|
6465
|
-
const source = c.getStrokes().filter((s) => _optionalChain([command, 'access',
|
|
6466
|
-
const first = _optionalChain([source, 'access',
|
|
7049
|
+
const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _396 => _396.replay, 'access', _397 => _397.strokeIds, 'optionalAccess', _398 => _398.includes, 'call', _399 => _399(s.id)]));
|
|
7050
|
+
const first = _optionalChain([source, 'access', _400 => _400[0], 'optionalAccess', _401 => _401.points, 'access', _402 => _402[0]]);
|
|
6467
7051
|
if (first) await this.glide(id, first);
|
|
6468
7052
|
const result = c.replayStrokes(command.replay);
|
|
6469
7053
|
if (result.bounds) await this.glide(id, centre(result.bounds), 520);
|
|
@@ -6644,7 +7228,7 @@ function createPaintStickerTools(c) {
|
|
|
6644
7228
|
items: {
|
|
6645
7229
|
type: "object",
|
|
6646
7230
|
properties: {
|
|
6647
|
-
stamp: { type: "string", enum: [...
|
|
7231
|
+
stamp: { type: "string", enum: [..._chunk5BR7LC24cjs.STAMP_KINDS], description: "The stamp." },
|
|
6648
7232
|
x: { type: "number", description: "Centre x in document pixels." },
|
|
6649
7233
|
y: { type: "number", description: "Centre y in document pixels." },
|
|
6650
7234
|
size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels (default 48)." },
|
|
@@ -6674,7 +7258,7 @@ function createPaintStickerTools(c) {
|
|
|
6674
7258
|
properties: {
|
|
6675
7259
|
layerId: LAYER_ID,
|
|
6676
7260
|
id: { type: "string", description: "Sticker id from list_stickers." },
|
|
6677
|
-
stamp: { type: "string", enum: [...
|
|
7261
|
+
stamp: { type: "string", enum: [..._chunk5BR7LC24cjs.STAMP_KINDS], description: "Another stamp." },
|
|
6678
7262
|
x: { type: "number", description: "Centre x in document pixels." },
|
|
6679
7263
|
y: { type: "number", description: "Centre y in document pixels." },
|
|
6680
7264
|
size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels." },
|
|
@@ -7552,7 +8136,7 @@ var BEHAVIOR = {
|
|
|
7552
8136
|
type: "object",
|
|
7553
8137
|
description: "Multi-coloured brush (the older form of paint, the brush's own gradient: tip is across-tip, dab is distance in dabs or random). Read back from paint when it has a multi-colour equivalent. Missing fields keep their current values.",
|
|
7554
8138
|
properties: {
|
|
7555
|
-
mode: { type: "string", enum: [...
|
|
8139
|
+
mode: { type: "string", enum: [..._chunk5BR7LC24cjs.MULTI_COLOR_MODES], description: "off; tip: the colours lie side by side across the tip (stripes along the stroke, like a brush loaded with several paints); dab: the colour changes along the stroke." },
|
|
7556
8140
|
colors: { type: "array", maxItems: 8, items: { ...COLOR3 }, description: "2..8 colours #rrggbb; fewer than 2 uses the paint colour and the secondary colour." },
|
|
7557
8141
|
order: { type: "string", enum: ["sequence", "random"], description: "dab mode: sequence runs through the colours in order, blending between them; random picks one per run of dabs (seeded)." },
|
|
7558
8142
|
length: { type: "integer", minimum: 1, maximum: 500, description: "dab mode: dabs per colour (default 12)." },
|
|
@@ -7593,10 +8177,10 @@ var WET_BRUSH = {
|
|
|
7593
8177
|
properties: {
|
|
7594
8178
|
tool: {
|
|
7595
8179
|
type: "string",
|
|
7596
|
-
enum: [...
|
|
8180
|
+
enum: [..._chunk5BR7LC24cjs.WET_TOOLS],
|
|
7597
8181
|
description: "paint: water and pigment (picks up and mixes wet paint by behavior.pickup / mix); water: clear water (with rewet it lifts dried paint); dry: a hair dryer, takes water; blow: pushes the water along the stroke; blend: evens out wet pigment; smudge: drags wet paint; blot: a tissue, takes wet paint up (erase wet)."
|
|
7598
8182
|
},
|
|
7599
|
-
medium: { type: "string", enum: [...
|
|
8183
|
+
medium: { type: "string", enum: [..._chunk5BR7LC24cjs.WET_MEDIA], description: "The medium: watercolor, gouache or oil. A layer takes the medium's wet settings the first time it holds wet paint (oil: thick, barely flows, stays wet long and blends into the wet paint it meets)." },
|
|
7600
8184
|
load: { type: "number", minimum: 0, maximum: 1, description: "Paint loading: 1 never runs out; lower, the brush runs dry along a long stroke (each stroke reloads)." },
|
|
7601
8185
|
thinner: { type: "number", minimum: 0, maximum: 1, description: "Thinner (water or solvent): more transparent, runnier paint." },
|
|
7602
8186
|
water: { type: "number", minimum: 0, maximum: 1, description: "Wetness: water laid per stroke, 0.2 a damp brush .. 1 a dripping one." },
|
|
@@ -7613,7 +8197,7 @@ var IMPASTO_BRUSH = {
|
|
|
7613
8197
|
properties: {
|
|
7614
8198
|
tool: {
|
|
7615
8199
|
type: "string",
|
|
7616
|
-
enum: [...
|
|
8200
|
+
enum: [..._chunk5BR7LC24cjs.IMPASTO_TOOLS],
|
|
7617
8201
|
description: "brush: thick paint with bristle ridges along the stroke; tube: blobs squeezed from the tube; knife: a palette knife that scrapes the relief flat and smears the paint; roller: a flat stippled band; gloop: a thick, glossy, rounded bead."
|
|
7618
8202
|
},
|
|
7619
8203
|
thickness: { type: "number", minimum: 0, maximum: 1, description: "How far the paint stands up." },
|
|
@@ -7629,8 +8213,8 @@ var PARTICLE_BRUSH = {
|
|
|
7629
8213
|
type: "object",
|
|
7630
8214
|
description: "Particle engine settings (procedural brushes). Missing fields keep their current values.",
|
|
7631
8215
|
properties: {
|
|
7632
|
-
kind: { type: "string", enum: [...
|
|
7633
|
-
render: { type: "string", enum: [...
|
|
8216
|
+
kind: { type: "string", enum: [..._chunk5BR7LC24cjs.PARTICLE_KINDS], description: "string: strands of masses on springs dragged behind the pen (hair, fur, wet string); spring: particles on springs to the pen, overshooting and wobbling; orbit: particles circling the pen (curls); flow: particles thrown off the pen into a swirling flow until they fade." },
|
|
8217
|
+
render: { type: "string", enum: [..._chunk5BR7LC24cjs.PARTICLE_RENDERS], description: "dot: a mark at each step; line: each particle draws a continuous line; sequence: beads spaced along each path." },
|
|
7634
8218
|
count: { type: "integer", minimum: 1, maximum: 64, description: "Particles (flow: how many are thrown per tip of travel)." },
|
|
7635
8219
|
size: { type: "number", minimum: 0, maximum: 1, description: "Mark size as a fraction of the tip size." },
|
|
7636
8220
|
spread: { type: "number", minimum: 0, maximum: 1, description: "How far apart the particles start, as a fraction of the tip size." },
|
|
@@ -7660,7 +8244,7 @@ var STICKER_BRUSH = {
|
|
|
7660
8244
|
type: "object",
|
|
7661
8245
|
description: "Sticker engine settings: stamps sprayed along the stroke as editable stickers. Missing fields keep their current values.",
|
|
7662
8246
|
properties: {
|
|
7663
|
-
stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [...
|
|
8247
|
+
stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [..._chunk5BR7LC24cjs.STAMP_KINDS], description: "A stamp." }, description: "The stamps to spray (one picked at random per sticker)." },
|
|
7664
8248
|
density: { type: "number", minimum: 0, maximum: 1, description: "How closely stickers follow each other: about density \xD7 4 stickers per tip diameter of travel (0.25 \u2248 one per diameter, 1 \u2248 four). Default 0.4." },
|
|
7665
8249
|
sizeJitter: { type: "number", minimum: 0, maximum: 1, description: "Random size change." },
|
|
7666
8250
|
rotationJitter: { type: "number", minimum: 0, maximum: 1, description: "Random turn as a fraction of \xB1180\xB0." },
|
|
@@ -7671,16 +8255,16 @@ var STICKER_BRUSH = {
|
|
|
7671
8255
|
};
|
|
7672
8256
|
var BRUSH_FIELDS = {
|
|
7673
8257
|
name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." },
|
|
7674
|
-
category: { type: "string", enum: [...
|
|
8258
|
+
category: { type: "string", enum: [..._chunk5BR7LC24cjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
|
|
7675
8259
|
engine: {
|
|
7676
8260
|
type: "string",
|
|
7677
|
-
enum: [...
|
|
8261
|
+
enum: [..._chunk5BR7LC24cjs.PAINT_BRUSH_ENGINES],
|
|
7678
8262
|
description: "dab: paints dabs (with behavior.pickup or gradient paint it paints dab by dab, lifting and mixing paint); eraser: removes paint; mixer: the Mixer Brush (a reservoir plus picked-up paint); blender: mixes the colours under and near the tip; smudge: drags paint along the stroke; wet: watercolour, gouache, oil and the wet tools on a simulated wet layer (see wet); impasto: thick paint with relief (see impasto); particle: procedural particle brushes (see particle); bristle: a tuft of bristles that bend and splay (see bristle); sticker: sprays editable sticker stamps (see sticker)."
|
|
7679
8263
|
},
|
|
7680
8264
|
tip: TIP,
|
|
7681
8265
|
grain: { type: "number", minimum: 0, maximum: 1, description: "Paper grain response: 0 ignores the grain, 1 catches only its peaks at light pressure (pencil, pastel, charcoal). Multiplied by the paper depth." },
|
|
7682
8266
|
pressureSmoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Pressure smoothing, separate from the tip position smoothing." },
|
|
7683
|
-
rotation: { type: "string", enum: [...
|
|
8267
|
+
rotation: { type: "string", enum: [..._chunk5BR7LC24cjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
|
|
7684
8268
|
dynamics: DYNAMICS,
|
|
7685
8269
|
mixer: MIXER,
|
|
7686
8270
|
loadsColor: { type: "boolean", description: "Mixer engine: load the colour each stroke (false for a mixer that only moves paint)." },
|
|
@@ -7694,6 +8278,7 @@ var BRUSH_FIELDS = {
|
|
|
7694
8278
|
sticker: STICKER_BRUSH,
|
|
7695
8279
|
paint: BRUSH_PAINT
|
|
7696
8280
|
};
|
|
8281
|
+
var TIME = { type: "number", minimum: 0, description: "Draw live effect paint (strokes on stroke layers painted with live effect paint) this many ms into its animation (default: as painted, its own time)." };
|
|
7697
8282
|
var POINTS = {
|
|
7698
8283
|
type: "array",
|
|
7699
8284
|
minItems: 1,
|
|
@@ -7730,7 +8315,7 @@ function brushSummary(b) {
|
|
|
7730
8315
|
size: b.tip.size,
|
|
7731
8316
|
grain: b.grain,
|
|
7732
8317
|
rotation: b.rotation,
|
|
7733
|
-
wetCapable:
|
|
8318
|
+
wetCapable: _chunk5BR7LC24cjs.isWetCapable.call(void 0, b),
|
|
7734
8319
|
pickup: b.behavior.pickup,
|
|
7735
8320
|
dirty: b.behavior.dirty,
|
|
7736
8321
|
multicolor: b.behavior.multicolor.mode,
|
|
@@ -7838,8 +8423,8 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7838
8423
|
inputSchema: EMPTY3,
|
|
7839
8424
|
annotations: { title: "List papers", ...READ6 },
|
|
7840
8425
|
handler: () => ({
|
|
7841
|
-
papers:
|
|
7842
|
-
families: [...
|
|
8426
|
+
papers: _chunk5BR7LC24cjs.PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),
|
|
8427
|
+
families: [..._chunk5BR7LC24cjs.PAPER_FAMILIES],
|
|
7843
8428
|
patterns: [..._chunkPQ3H2AANcjs.GRAIN_PATTERNS]
|
|
7844
8429
|
})
|
|
7845
8430
|
});
|
|
@@ -7899,12 +8484,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
7899
8484
|
add({
|
|
7900
8485
|
name: "add_layer",
|
|
7901
8486
|
title: "Add a layer",
|
|
7902
|
-
description: "Adds an empty pixel layer
|
|
8487
|
+
description: "Adds an empty pixel layer, a group, or a stroke layer (type strokes: its strokes stay editable with update_stroke and edit_stroke_points) above the active layer, or above aboveId, or at the top of parentId; it becomes the active layer. One undo step. Returns the layer (liveStrokes: its stroke count, for a stroke layer).",
|
|
7903
8488
|
inputSchema: {
|
|
7904
8489
|
type: "object",
|
|
7905
8490
|
properties: {
|
|
7906
8491
|
name: { type: "string", minLength: 1, description: 'Layer name (default "Layer n").' },
|
|
7907
|
-
type: { type: "string", enum: ["pixel", "group"], description: "pixel (default) or
|
|
8492
|
+
type: { type: "string", enum: ["pixel", "group", "strokes"], description: "pixel (default), group, or strokes: a live stroke layer whose pixels are drawn from its strokes, so each stays editable. It takes dab, particle, bristle and Mixer Brush strokes that pick up no paint." },
|
|
7908
8493
|
aboveId: { type: "string", description: "Put it directly above this layer (default the active layer)." },
|
|
7909
8494
|
parentId: { type: "string", description: "Put it at the top of this group instead." }
|
|
7910
8495
|
},
|
|
@@ -8059,7 +8644,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8059
8644
|
annotations: { title: "List brushes", ...READ6 },
|
|
8060
8645
|
handler: () => {
|
|
8061
8646
|
const s = c.getState();
|
|
8062
|
-
return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access',
|
|
8647
|
+
return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _403 => _403.getBrush, 'call', _404 => _404(s.brush.id), 'optionalAccess', _405 => _405.builtin])), brushes: s.brushes.map(brushSummary) };
|
|
8063
8648
|
}
|
|
8064
8649
|
});
|
|
8065
8650
|
add({
|
|
@@ -8070,10 +8655,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8070
8655
|
annotations: { title: "Get a brush", ...READ6 },
|
|
8071
8656
|
handler: ({ id }) => {
|
|
8072
8657
|
const st = c.getState();
|
|
8073
|
-
if (id === void 0) return { ...
|
|
8658
|
+
if (id === void 0) return { ..._chunk5BR7LC24cjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
|
|
8074
8659
|
const b = c.getBrush(id);
|
|
8075
8660
|
if (!b) throw new Error(`Unknown brush "${id}". Call list_brushes for the ids.`);
|
|
8076
|
-
return { ...
|
|
8661
|
+
return { ..._chunk5BR7LC24cjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
|
|
8077
8662
|
}
|
|
8078
8663
|
});
|
|
8079
8664
|
add({
|
|
@@ -8082,7 +8667,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8082
8667
|
description: "Chooses the active brush (id) and / or changes its settings; strokes without a brush use it. Editor state, not an undo step. Changes stay on the active brush until save_brush stores them. Returns the active brush.",
|
|
8083
8668
|
inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brushes to start from." }, ...BRUSH_FIELDS }, additionalProperties: false },
|
|
8084
8669
|
annotations: { title: "Set the brush", ...SET4 },
|
|
8085
|
-
handler: (a) =>
|
|
8670
|
+
handler: (a) => _chunk5BR7LC24cjs.brushToJSON.call(void 0, c.setBrush(a))
|
|
8086
8671
|
});
|
|
8087
8672
|
add({
|
|
8088
8673
|
name: "save_brush",
|
|
@@ -8098,7 +8683,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8098
8683
|
additionalProperties: false
|
|
8099
8684
|
},
|
|
8100
8685
|
annotations: { title: "Save a brush", ...SET4 },
|
|
8101
|
-
handler: ({ id, name }) =>
|
|
8686
|
+
handler: ({ id, name }) => _chunk5BR7LC24cjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
|
|
8102
8687
|
});
|
|
8103
8688
|
add({
|
|
8104
8689
|
name: "remove_brush",
|
|
@@ -8266,44 +8851,156 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8266
8851
|
add({
|
|
8267
8852
|
name: "list_strokes",
|
|
8268
8853
|
title: "List recorded strokes",
|
|
8269
|
-
description: "Lists the recorded strokes, oldest first (every stroke is kept as data): id, layer, brush id and name, colour, point count, bounds and
|
|
8854
|
+
description: "Lists the recorded strokes, oldest first (every stroke is kept as data): id, layer, brush id and name, colour, point count, bounds, seed and whether it is live. With ids, also the points. Use the ids with replay_strokes. With live true, lists the strokes of stroke layers as they are now, bottom first: the ones update_stroke, edit_stroke_points, reorder_stroke and remove_strokes change.",
|
|
8270
8855
|
inputSchema: {
|
|
8271
8856
|
type: "object",
|
|
8272
8857
|
properties: {
|
|
8273
8858
|
ids: { type: "array", items: { type: "string", description: "Stroke id." }, description: "Only these strokes, with their points." },
|
|
8274
|
-
last: { type: "integer", minimum: 1, maximum: 1e3, description: "Only the most recent n strokes (default 100)." }
|
|
8859
|
+
last: { type: "integer", minimum: 1, maximum: 1e3, description: "Only the most recent n strokes (default 100)." },
|
|
8860
|
+
live: { type: "boolean", description: "Only the editable strokes of stroke layers, as they are now, bottom first (default false: the whole recorded history)." },
|
|
8861
|
+
layerId: { type: "string", description: "Only strokes of this layer." }
|
|
8275
8862
|
},
|
|
8276
8863
|
additionalProperties: false
|
|
8277
8864
|
},
|
|
8278
8865
|
annotations: { title: "List recorded strokes", ...READ6 },
|
|
8279
8866
|
coordinates: { out: ["strokes[].bounds", "strokes[].points[]"] },
|
|
8280
|
-
handler: ({ ids, last }) => {
|
|
8281
|
-
|
|
8867
|
+
handler: ({ ids, last, live, layerId }) => {
|
|
8868
|
+
if (layerId !== void 0 && !c.getLayer(layerId)) throw new Error(`Unknown layer "${layerId}". Call list_layers for the ids.`);
|
|
8869
|
+
const liveAll = Object.values(_nullishCoalesce(c.document.liveStrokes, () => ( {}))).flat();
|
|
8870
|
+
const liveIds = new Set(liveAll.map((s) => s.id));
|
|
8871
|
+
let all = live ? liveAll : c.getStrokes();
|
|
8872
|
+
if (layerId !== void 0) all = all.filter((s) => s.layerId === layerId);
|
|
8282
8873
|
const picked = ids ? all.filter((s) => ids.includes(s.id)) : all.slice(-(_nullishCoalesce(last, () => ( 100))));
|
|
8283
8874
|
if (ids) {
|
|
8284
8875
|
for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke "${id}". Call list_strokes without ids for the ids.`);
|
|
8285
8876
|
}
|
|
8286
|
-
return {
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8877
|
+
return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _406 => _406.document, 'access', _407 => _407.liveStrokes, 'optionalAccess', _408 => _408[s.layerId], 'optionalAccess', _409 => _409.includes, 'call', _410 => _410(s)]) === true)) };
|
|
8878
|
+
}
|
|
8879
|
+
});
|
|
8880
|
+
add({
|
|
8881
|
+
name: "stroke_at",
|
|
8882
|
+
title: "Find the stroke at a point",
|
|
8883
|
+
description: "Returns the top-most stroke of a stroke layer that painted the pixel at a point (document pixels), or stroke null when none did, so you can pick one stroke among overlapping ones before update_stroke, edit_stroke_points or remove_strokes. Changes nothing.",
|
|
8884
|
+
inputSchema: {
|
|
8885
|
+
type: "object",
|
|
8886
|
+
properties: {
|
|
8887
|
+
layerId: { type: "string", description: "Stroke layer id from list_layers (default the active layer)." },
|
|
8888
|
+
x: { type: "number", description: "Point x in document pixels." },
|
|
8889
|
+
y: { type: "number", description: "Point y in document pixels." }
|
|
8890
|
+
},
|
|
8891
|
+
required: ["x", "y"],
|
|
8892
|
+
additionalProperties: false
|
|
8893
|
+
},
|
|
8894
|
+
annotations: { title: "Find the stroke at a point", ...READ6 },
|
|
8895
|
+
coordinates: { in: [""], out: ["stroke.bounds"] },
|
|
8896
|
+
handler: ({ layerId, x, y }) => {
|
|
8897
|
+
const s = c.liveStrokeAt(layerId, x, y);
|
|
8898
|
+
return { stroke: s ? strokeSummary(s, false, true) : null };
|
|
8899
|
+
}
|
|
8900
|
+
});
|
|
8901
|
+
add({
|
|
8902
|
+
name: "update_stroke",
|
|
8903
|
+
title: "Change a stroke",
|
|
8904
|
+
description: "Changes a stroke on a stroke layer after it was painted: another brush preset (brushId, keeping the stroke size), brush settings (as set_brush takes), colour (replaces gradient paint), paint, or seed, then redraws the layer exactly. Ids come from list_strokes {live: true}. Refuses brushes a stroke layer cannot redraw (wet, impasto, sticker, eraser, smudge, blender, pick-up). One undo step. Returns the stroke and the area that changed.",
|
|
8905
|
+
inputSchema: {
|
|
8906
|
+
type: "object",
|
|
8907
|
+
properties: {
|
|
8908
|
+
id: { type: "string", description: "Stroke id from list_strokes {live: true}." },
|
|
8909
|
+
brushId: { type: "string", description: "Brush preset id from list_brushes; the stroke keeps its size." },
|
|
8910
|
+
brush: { type: "object", properties: BRUSH_FIELDS, additionalProperties: false, description: "Brush settings to change on top of brushId or the stroke\u2019s brush; missing fields keep their values." },
|
|
8911
|
+
color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", description: "New colour #rrggbb (replaces gradient paint)." },
|
|
8912
|
+
paint: { anyOf: [_chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA, { type: "null", description: "Back to the stroke\u2019s plain colour." }], description: "A colour or gradient paint for the stroke; null drops its gradient." },
|
|
8913
|
+
seed: { type: "integer", minimum: 0, description: "Another jitter seed: particles, scatter and texture fall differently." }
|
|
8914
|
+
},
|
|
8915
|
+
required: ["id"],
|
|
8916
|
+
additionalProperties: false
|
|
8917
|
+
},
|
|
8918
|
+
annotations: { title: "Change a stroke", ...WRITE5 },
|
|
8919
|
+
coordinates: { out: ["bounds", "stroke.bounds"] },
|
|
8920
|
+
handler: ({ id, ...update }) => {
|
|
8921
|
+
if (!Object.keys(update).length) throw new Error("Pass at least one change: brushId, brush, color, paint or seed.");
|
|
8922
|
+
const r = c.updateStroke(id, update);
|
|
8923
|
+
return { stroke: strokeSummary(r.stroke, false, true), bounds: r.bounds };
|
|
8924
|
+
}
|
|
8925
|
+
});
|
|
8926
|
+
add({
|
|
8927
|
+
name: "edit_stroke_points",
|
|
8928
|
+
title: "Move or reshape a stroke",
|
|
8929
|
+
description: "Replaces a stroke\u2019s points (points, document pixels), or moves, scales, rotates or flips it (transform, about its centre unless origin is given; the brush size scales with it), then redraws its stroke layer exactly. Pass one of points or transform. One undo step. Returns the stroke with its points and the area that changed.",
|
|
8930
|
+
inputSchema: {
|
|
8931
|
+
type: "object",
|
|
8932
|
+
properties: {
|
|
8933
|
+
id: { type: "string", description: "Stroke id from list_strokes {live: true}." },
|
|
8934
|
+
points: POINTS,
|
|
8935
|
+
transform: {
|
|
8936
|
+
type: "object",
|
|
8937
|
+
description: "A move, scale, rotation or flip of the whole stroke.",
|
|
8938
|
+
properties: {
|
|
8939
|
+
dx: { type: "number", description: "Move right by this many pixels (default 0)." },
|
|
8940
|
+
dy: { type: "number", description: "Move down by this many pixels (default 0)." },
|
|
8941
|
+
scale: { type: "number", exclusiveMinimum: 0, maximum: 20, description: "Scale about the origin; brush size scales too (default 1)." },
|
|
8942
|
+
rotate: { type: "number", minimum: -360, maximum: 360, description: "Rotate about the origin, degrees clockwise (default 0)." },
|
|
8943
|
+
flipX: { type: "boolean", description: "Mirror left to right about the origin (default false)." },
|
|
8944
|
+
origin: { type: "object", description: "Centre for scale, rotate and flip (default the centre of the stroke).", properties: { x: { type: "number", description: "Document x." }, y: { type: "number", description: "Document y." } }, required: ["x", "y"], additionalProperties: false }
|
|
8945
|
+
},
|
|
8946
|
+
additionalProperties: false
|
|
8947
|
+
}
|
|
8948
|
+
},
|
|
8949
|
+
required: ["id"],
|
|
8950
|
+
additionalProperties: false
|
|
8951
|
+
},
|
|
8952
|
+
annotations: { title: "Move or reshape a stroke", ...WRITE5 },
|
|
8953
|
+
coordinates: { in: ["points[]", "transform.origin"], out: ["bounds", "stroke.bounds", "stroke.points[]"] },
|
|
8954
|
+
handler: ({ id, points, transform }) => {
|
|
8955
|
+
const r = c.editStrokePoints(id, { points, transform });
|
|
8956
|
+
return { stroke: strokeSummary(r.stroke, true, true), bounds: r.bounds };
|
|
8305
8957
|
}
|
|
8306
8958
|
});
|
|
8959
|
+
add({
|
|
8960
|
+
name: "reorder_stroke",
|
|
8961
|
+
title: "Move a stroke up or down",
|
|
8962
|
+
description: "Moves a stroke to index in its stroke layer (0 = bottom, drawn first) and redraws the layer. One undo step. Returns the new order of ids, bottom first.",
|
|
8963
|
+
inputSchema: {
|
|
8964
|
+
type: "object",
|
|
8965
|
+
properties: { id: { type: "string", description: "Stroke id from list_strokes {live: true}." }, index: { type: "integer", minimum: 0, description: "New position, 0 = bottom." } },
|
|
8966
|
+
required: ["id", "index"],
|
|
8967
|
+
additionalProperties: false
|
|
8968
|
+
},
|
|
8969
|
+
annotations: { title: "Move a stroke up or down", ...WRITE5 },
|
|
8970
|
+
handler: ({ id, index }) => ({ order: c.reorderStroke(id, index) })
|
|
8971
|
+
});
|
|
8972
|
+
add({
|
|
8973
|
+
name: "remove_strokes",
|
|
8974
|
+
title: "Delete strokes",
|
|
8975
|
+
description: "Deletes strokes from their stroke layers (the eraser of a stroke layer) and redraws them. All checked first; one undo step. Returns the ids removed and the area that changed.",
|
|
8976
|
+
inputSchema: {
|
|
8977
|
+
type: "object",
|
|
8978
|
+
properties: { ids: { type: "array", minItems: 1, items: { type: "string", description: "Stroke id." }, description: "Stroke ids from list_strokes {live: true}." } },
|
|
8979
|
+
required: ["ids"],
|
|
8980
|
+
additionalProperties: false
|
|
8981
|
+
},
|
|
8982
|
+
annotations: { title: "Delete strokes", ...DESTRUCTIVE3 },
|
|
8983
|
+
coordinates: { out: ["bounds"] },
|
|
8984
|
+
handler: ({ ids }) => c.removeStrokes(ids)
|
|
8985
|
+
});
|
|
8986
|
+
add({
|
|
8987
|
+
name: "convert_to_stroke_layer",
|
|
8988
|
+
title: "Make a layer a stroke layer",
|
|
8989
|
+
description: 'Makes an empty pixel layer a stroke layer, so strokes painted on it stay editable. Refuses a layer with paint (add_layer {type: "strokes"} instead). One undo step. Returns the layer.',
|
|
8990
|
+
inputSchema: { type: "object", properties: { layerId: { type: "string", description: "Layer id from list_layers (default the active layer)." } }, additionalProperties: false },
|
|
8991
|
+
annotations: { title: "Make a layer a stroke layer", ...WRITE5 },
|
|
8992
|
+
coordinates: { out: ["bounds"] },
|
|
8993
|
+
handler: ({ layerId }) => c.convertToLiveStrokes(layerId)
|
|
8994
|
+
});
|
|
8995
|
+
add({
|
|
8996
|
+
name: "rasterize_stroke_layer",
|
|
8997
|
+
title: "Rasterize a stroke layer",
|
|
8998
|
+
description: "Turns a stroke layer into a plain pixel layer with the same pixels: its strokes stop being editable, and erasers, smudges and fills work on it. One undo step. Returns the layer.",
|
|
8999
|
+
inputSchema: { type: "object", properties: { layerId: { type: "string", description: "Stroke layer id from list_layers (default the active layer)." } }, additionalProperties: false },
|
|
9000
|
+
annotations: { title: "Rasterize a stroke layer", ...DESTRUCTIVE3 },
|
|
9001
|
+
coordinates: { out: ["bounds"] },
|
|
9002
|
+
handler: ({ layerId }) => c.rasterizeLiveStrokes(layerId)
|
|
9003
|
+
});
|
|
8307
9004
|
add({
|
|
8308
9005
|
name: "replay_strokes",
|
|
8309
9006
|
title: "Replay strokes, varied",
|
|
@@ -8418,20 +9115,22 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8418
9115
|
add({
|
|
8419
9116
|
name: "export_image",
|
|
8420
9117
|
title: "Export the painting",
|
|
8421
|
-
description: "Exports the painting as PNG, JPEG or WebP (base64). JPEG always includes the paper; JPEG and WebP need a browser canvas. Changes nothing. Returns the data, its MIME type and size.",
|
|
9118
|
+
description: "Exports the painting as PNG, JPEG or WebP (base64). JPEG always includes the paper; JPEG and WebP need a browser canvas. With time, live effect paint is drawn at that moment (get_effect_playback / set_effect_playback). Changes nothing. Returns the data, its MIME type and size.",
|
|
8422
9119
|
inputSchema: {
|
|
8423
9120
|
type: "object",
|
|
8424
9121
|
properties: {
|
|
8425
9122
|
format: { type: "string", enum: ["image/png", "image/jpeg", "image/webp"], description: "File type (default image/png)." },
|
|
8426
9123
|
quality: { type: "number", minimum: 0, maximum: 1, description: "JPEG / WebP quality 0..1 (default 0.92)." },
|
|
8427
9124
|
scale: { type: "number", exclusiveMinimum: 0, maximum: 1, description: "Shrink by this factor (default 1)." },
|
|
8428
|
-
paper: { type: "boolean", description: "Include the paper (default true)." }
|
|
9125
|
+
paper: { type: "boolean", description: "Include the paper (default true)." },
|
|
9126
|
+
time: TIME
|
|
8429
9127
|
},
|
|
8430
9128
|
additionalProperties: false
|
|
8431
9129
|
},
|
|
8432
9130
|
annotations: { title: "Export the painting", ...READ6 },
|
|
8433
|
-
handler: async ({ format, quality, scale, paper }) => {
|
|
8434
|
-
const
|
|
9131
|
+
handler: async ({ format, quality, scale, paper, time }) => {
|
|
9132
|
+
const run = () => c.exportImage({ format, quality, scale, paper });
|
|
9133
|
+
const bytes = time === void 0 ? await run() : await c.withEffectTime(time, run);
|
|
8435
9134
|
return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, bytes) };
|
|
8436
9135
|
}
|
|
8437
9136
|
});
|
|
@@ -8439,10 +9138,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8439
9138
|
name: "export_psd",
|
|
8440
9139
|
title: "Export as PSD",
|
|
8441
9140
|
description: 'Writes the painting as an 8-bit RGB PSD (PSB above 30000 px) through the shared PSD writer: every layer and group with its opacity, blend, mask and locks, the paper as a locked "Paper" pixel layer at the bottom, and the composite as the merged image. Changes nothing. Returns the file as base64, its size, whether it is a PSB, and warnings (pigment and painterly blend modes have no PSD equivalent: they are written as the nearest standard mode, see list_blend_modes).',
|
|
8442
|
-
inputSchema:
|
|
9141
|
+
inputSchema: { type: "object", properties: { time: TIME }, additionalProperties: false },
|
|
8443
9142
|
annotations: { title: "Export as PSD", ...READ6 },
|
|
8444
|
-
handler: () => {
|
|
8445
|
-
const r = c.exportPsd();
|
|
9143
|
+
handler: async ({ time }) => {
|
|
9144
|
+
const r = time === void 0 ? c.exportPsd() : await c.withEffectTime(time, () => c.exportPsd());
|
|
8446
9145
|
return { data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };
|
|
8447
9146
|
}
|
|
8448
9147
|
});
|
|
@@ -8465,44 +9164,62 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
8465
9164
|
}
|
|
8466
9165
|
function hostTool({ coordinates, ...tool }, { origin, onChange }) {
|
|
8467
9166
|
if (!origin && !onChange) return tool;
|
|
8468
|
-
const write = !_optionalChain([tool, 'access',
|
|
9167
|
+
const write = !_optionalChain([tool, 'access', _411 => _411.annotations, 'optionalAccess', _412 => _412.readOnlyHint]);
|
|
8469
9168
|
const done = (result) => {
|
|
8470
|
-
if (write) _optionalChain([onChange, 'optionalCall',
|
|
8471
|
-
return origin && _optionalChain([coordinates, 'optionalAccess',
|
|
9169
|
+
if (write) _optionalChain([onChange, 'optionalCall', _413 => _413({ tool: tool.name })]);
|
|
9170
|
+
return origin && _optionalChain([coordinates, 'optionalAccess', _414 => _414.out]) ? fromDocument(result, coordinates.out, origin) : result;
|
|
8472
9171
|
};
|
|
8473
9172
|
return {
|
|
8474
9173
|
...tool,
|
|
8475
9174
|
...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
|
|
8476
9175
|
handler: (args, context) => {
|
|
8477
|
-
const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess',
|
|
9176
|
+
const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _415 => _415.in]) ? toDocument(args, coordinates.in, origin) : args, context);
|
|
8478
9177
|
return r instanceof Promise ? r.then(done) : done(r);
|
|
8479
9178
|
}
|
|
8480
9179
|
};
|
|
8481
9180
|
}
|
|
9181
|
+
function strokeSummary(s, withPoints, live) {
|
|
9182
|
+
const xs = s.points.map((p) => p.x);
|
|
9183
|
+
const ys = s.points.map((p) => p.y);
|
|
9184
|
+
const pad = s.brush.tip.size / 2;
|
|
9185
|
+
return {
|
|
9186
|
+
id: s.id,
|
|
9187
|
+
layerId: s.layerId,
|
|
9188
|
+
brushId: s.brush.id,
|
|
9189
|
+
brushName: s.brush.name,
|
|
9190
|
+
color: s.color,
|
|
9191
|
+
points: withPoints ? s.points : s.points.length,
|
|
9192
|
+
seed: s.seed,
|
|
9193
|
+
copies: _nullishCoalesce(_optionalChain([s, 'access', _416 => _416.copies, 'optionalAccess', _417 => _417.length]), () => ( 0)),
|
|
9194
|
+
live,
|
|
9195
|
+
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) }
|
|
9196
|
+
};
|
|
9197
|
+
}
|
|
8482
9198
|
|
|
8483
9199
|
// src/paint-editor/ui.ts
|
|
8484
9200
|
var PAINT_TOOLS = [
|
|
8485
9201
|
{ id: "brush", label: "Brush", key: "b" },
|
|
8486
9202
|
{ id: "eyedropper", label: "Eyedropper", key: "i" },
|
|
8487
9203
|
{ id: "sticker", label: "Stickers", key: "s" },
|
|
9204
|
+
{ id: "stroke", label: "Select stroke", key: "v" },
|
|
8488
9205
|
{ id: "pan", label: "Pan", key: "h" },
|
|
8489
9206
|
{ id: "rotate", label: "Rotate view", key: "r" }
|
|
8490
9207
|
];
|
|
8491
9208
|
var PaintGesture = (_class11 = class {
|
|
8492
|
-
constructor(controller, box) {;_class11.prototype.
|
|
9209
|
+
constructor(controller, box) {;_class11.prototype.__init125.call(this);_class11.prototype.__init126.call(this);_class11.prototype.__init127.call(this);_class11.prototype.__init128.call(this);_class11.prototype.__init129.call(this);_class11.prototype.__init130.call(this);
|
|
8493
9210
|
this.controller = controller;
|
|
8494
9211
|
this.box = box;
|
|
8495
9212
|
}
|
|
8496
9213
|
|
|
8497
9214
|
|
|
8498
|
-
|
|
9215
|
+
__init125() {this.tool = "brush"}
|
|
8499
9216
|
/** The last refusal (a hidden or locked layer), for the editor to show. */
|
|
8500
|
-
|
|
9217
|
+
__init126() {this.error = null}
|
|
8501
9218
|
/** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
9219
|
+
__init127() {this.predicted = []}
|
|
9220
|
+
__init128() {this.mode = null}
|
|
9221
|
+
__init129() {this.penAt = null}
|
|
9222
|
+
__init130() {this.penDown = false}
|
|
8506
9223
|
doc(e) {
|
|
8507
9224
|
const b = this.box();
|
|
8508
9225
|
const s = this.controller.getState();
|
|
@@ -8533,6 +9250,7 @@ var PaintGesture = (_class11 = class {
|
|
|
8533
9250
|
this.mode = { kind: "rotate", pointerId: e.pointerId, angle: Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2), rotation: this.controller.getState().view.rotation };
|
|
8534
9251
|
return true;
|
|
8535
9252
|
}
|
|
9253
|
+
if (tool === "stroke") return this.strokeDown(e);
|
|
8536
9254
|
if (tool === "eyedropper" || e.altKey) {
|
|
8537
9255
|
this.pick(e);
|
|
8538
9256
|
return false;
|
|
@@ -8549,6 +9267,34 @@ var PaintGesture = (_class11 = class {
|
|
|
8549
9267
|
return false;
|
|
8550
9268
|
}
|
|
8551
9269
|
}
|
|
9270
|
+
/**
|
|
9271
|
+
* The Select stroke tool, on a stroke layer: pressing a stroke picks it and dragging moves it
|
|
9272
|
+
* (one undo step at the drop); pressing where no stroke painted clears the pick.
|
|
9273
|
+
*/
|
|
9274
|
+
strokeDown(e) {
|
|
9275
|
+
const p = this.doc(e);
|
|
9276
|
+
const s = this.controller.getState();
|
|
9277
|
+
const layerId = s.document.activeLayerId;
|
|
9278
|
+
if (!layerId || !_optionalChain([s, 'access', _418 => _418.document, 'access', _419 => _419.liveStrokes, 'optionalAccess', _420 => _420[layerId]])) {
|
|
9279
|
+
this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
|
|
9280
|
+
return false;
|
|
9281
|
+
}
|
|
9282
|
+
try {
|
|
9283
|
+
const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
|
|
9284
|
+
this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _421 => _421.id]), () => ( null)));
|
|
9285
|
+
if (!hit) return false;
|
|
9286
|
+
this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
|
|
9287
|
+
return true;
|
|
9288
|
+
} catch (err) {
|
|
9289
|
+
this.error = err instanceof Error ? err.message : String(err);
|
|
9290
|
+
return false;
|
|
9291
|
+
}
|
|
9292
|
+
}
|
|
9293
|
+
/** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
|
|
9294
|
+
get strokeDrag() {
|
|
9295
|
+
const m = this.mode;
|
|
9296
|
+
return _optionalChain([m, 'optionalAccess', _422 => _422.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
|
|
9297
|
+
}
|
|
8552
9298
|
/**
|
|
8553
9299
|
* The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
|
|
8554
9300
|
* drop); pressing anywhere else places the active brush's first stamp there, at its tip size and
|
|
@@ -8594,6 +9340,10 @@ var PaintGesture = (_class11 = class {
|
|
|
8594
9340
|
this.controller.setView({ rotation: r });
|
|
8595
9341
|
return;
|
|
8596
9342
|
}
|
|
9343
|
+
if (m.kind === "move-stroke") {
|
|
9344
|
+
m.to = this.doc(e);
|
|
9345
|
+
return;
|
|
9346
|
+
}
|
|
8597
9347
|
if (m.kind === "sticker") {
|
|
8598
9348
|
const p = this.doc(e);
|
|
8599
9349
|
m.at = { x: round2(p.x + m.dx), y: round2(p.y + m.dy) };
|
|
@@ -8617,7 +9367,18 @@ var PaintGesture = (_class11 = class {
|
|
|
8617
9367
|
if (!m || m.pointerId !== e.pointerId) return;
|
|
8618
9368
|
this.mode = null;
|
|
8619
9369
|
this.predicted = [];
|
|
8620
|
-
if (m.kind === "stroke") _optionalChain([this, 'access',
|
|
9370
|
+
if (m.kind === "stroke") _optionalChain([this, 'access', _423 => _423.controller, 'access', _424 => _424.activeStroke, 'optionalAccess', _425 => _425.end, 'call', _426 => _426()]);
|
|
9371
|
+
if (m.kind === "move-stroke") {
|
|
9372
|
+
const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
|
|
9373
|
+
const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
|
|
9374
|
+
if (dx || dy) {
|
|
9375
|
+
try {
|
|
9376
|
+
this.controller.editStrokePoints(m.id, { transform: { dx, dy } });
|
|
9377
|
+
} catch (err) {
|
|
9378
|
+
this.error = err instanceof Error ? err.message : String(err);
|
|
9379
|
+
}
|
|
9380
|
+
}
|
|
9381
|
+
}
|
|
8621
9382
|
if (m.kind === "sticker" && m.at) {
|
|
8622
9383
|
try {
|
|
8623
9384
|
this.controller.updateSticker(void 0, m.id, m.at);
|
|
@@ -8630,8 +9391,8 @@ var PaintGesture = (_class11 = class {
|
|
|
8630
9391
|
cancel() {
|
|
8631
9392
|
this.penDown = false;
|
|
8632
9393
|
this.predicted = [];
|
|
8633
|
-
if (_optionalChain([this, 'access',
|
|
8634
|
-
if (_optionalChain([this, 'access',
|
|
9394
|
+
if (_optionalChain([this, 'access', _427 => _427.mode, 'optionalAccess', _428 => _428.kind]) === "stroke") _optionalChain([this, 'access', _429 => _429.controller, 'access', _430 => _430.activeStroke, 'optionalAccess', _431 => _431.cancel, 'call', _432 => _432()]);
|
|
9395
|
+
if (_optionalChain([this, 'access', _433 => _433.mode, 'optionalAccess', _434 => _434.kind]) === "sticker") this.controller.cancelStickerPreview();
|
|
8635
9396
|
this.mode = null;
|
|
8636
9397
|
}
|
|
8637
9398
|
get active() {
|
|
@@ -8693,13 +9454,13 @@ function handlePaintShortcut(controller, gesture, e) {
|
|
|
8693
9454
|
return false;
|
|
8694
9455
|
}
|
|
8695
9456
|
var PaintCanvasPresenter = (_class12 = class {
|
|
8696
|
-
constructor(controller) {;_class12.prototype.
|
|
9457
|
+
constructor(controller) {;_class12.prototype.__init131.call(this);_class12.prototype.__init132.call(this);_class12.prototype.__init133.call(this);
|
|
8697
9458
|
this.controller = controller;
|
|
8698
9459
|
}
|
|
8699
9460
|
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
9461
|
+
__init131() {this.uploaded = /* @__PURE__ */ new Map()}
|
|
9462
|
+
__init132() {this.scratch = null}
|
|
9463
|
+
__init133() {this.size = ""}
|
|
8703
9464
|
/** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
|
|
8704
9465
|
render(ctx) {
|
|
8705
9466
|
const { width, height } = this.controller.document.canvas;
|
|
@@ -8726,12 +9487,25 @@ var PaintCanvasPresenter = (_class12 = class {
|
|
|
8726
9487
|
return drawn;
|
|
8727
9488
|
}
|
|
8728
9489
|
}, _class12);
|
|
8729
|
-
function guideOverlay(controller) {
|
|
9490
|
+
function guideOverlay(controller, drag) {
|
|
8730
9491
|
const s = controller.getState();
|
|
8731
9492
|
const size = s.document.canvas;
|
|
8732
9493
|
const out = [];
|
|
8733
9494
|
const layerId = s.document.activeLayerId;
|
|
8734
|
-
const
|
|
9495
|
+
const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _435 => _435.document, 'access', _436 => _436.liveStrokes, 'optionalAccess', _437 => _437[layerId], 'optionalAccess', _438 => _438.some, 'call', _439 => _439((x) => x.id === s.selectedStroke)]) : false;
|
|
9496
|
+
const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
|
|
9497
|
+
if (area) {
|
|
9498
|
+
const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
|
|
9499
|
+
const dy = drag && drag.id === s.selectedStroke ? drag.dy : 0;
|
|
9500
|
+
const box = [
|
|
9501
|
+
{ x: area.x + dx, y: area.y + dy },
|
|
9502
|
+
{ x: area.x + area.width + dx, y: area.y + dy },
|
|
9503
|
+
{ x: area.x + area.width + dx, y: area.y + area.height + dy },
|
|
9504
|
+
{ x: area.x + dx, y: area.y + area.height + dy }
|
|
9505
|
+
];
|
|
9506
|
+
for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
|
|
9507
|
+
}
|
|
9508
|
+
const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _440 => _440.document, 'access', _441 => _441.stickers, 'optionalAccess', _442 => _442[layerId], 'optionalAccess', _443 => _443.find, 'call', _444 => _444((x) => x.id === s.selectedSticker)]) : void 0;
|
|
8735
9509
|
if (picked) {
|
|
8736
9510
|
const r = picked.size / 2 + 2;
|
|
8737
9511
|
const a = picked.rotation * Math.PI / 180;
|
|
@@ -8775,7 +9549,7 @@ var PAPER_SLIDERS = [
|
|
|
8775
9549
|
];
|
|
8776
9550
|
function readPath(obj, path) {
|
|
8777
9551
|
let v = obj;
|
|
8778
|
-
for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess',
|
|
9552
|
+
for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _445 => _445[k]]);
|
|
8779
9553
|
return typeof v === "number" ? v : 0;
|
|
8780
9554
|
}
|
|
8781
9555
|
function patchPath(obj, path, value) {
|
|
@@ -8897,7 +9671,7 @@ function brushEngineControls(brush) {
|
|
|
8897
9671
|
impastoTool: true
|
|
8898
9672
|
};
|
|
8899
9673
|
case "wet": {
|
|
8900
|
-
const tool = _nullishCoalesce(_optionalChain([brush, 'access',
|
|
9674
|
+
const tool = _nullishCoalesce(_optionalChain([brush, 'access', _446 => _446.wet, 'optionalAccess', _447 => _447.tool]), () => ( "paint"));
|
|
8901
9675
|
const sliders = tool === "paint" ? [
|
|
8902
9676
|
{ path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
|
|
8903
9677
|
{ path: "wet.pigment", label: "Pigment", min: 0, max: 1, step: 0.01 },
|
|
@@ -9030,7 +9804,7 @@ function startWetClock(controller, frame, cancel) {
|
|
|
9030
9804
|
id = raf(loop);
|
|
9031
9805
|
return () => {
|
|
9032
9806
|
stopped = true;
|
|
9033
|
-
_optionalChain([caf, 'optionalCall',
|
|
9807
|
+
_optionalChain([caf, 'optionalCall', _448 => _448(id)]);
|
|
9034
9808
|
};
|
|
9035
9809
|
}
|
|
9036
9810
|
function drawWaterOverlay(controller, ctx) {
|
|
@@ -9060,6 +9834,11 @@ function toggleStamp(stamps, stamp) {
|
|
|
9060
9834
|
const next = stamps.includes(stamp) ? stamps.filter((s) => s !== stamp) : [...stamps, stamp];
|
|
9061
9835
|
return next.length ? next : [stamp];
|
|
9062
9836
|
}
|
|
9837
|
+
var STROKE_SLIDERS = [
|
|
9838
|
+
{ path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
|
|
9839
|
+
{ path: "tip.opacity", label: "Opacity", min: 0, max: 1, step: 0.01 },
|
|
9840
|
+
{ path: "tip.flow", label: "Flow", min: 0, max: 1, step: 0.01 }
|
|
9841
|
+
];
|
|
9063
9842
|
var STICKER_SLIDERS = [
|
|
9064
9843
|
{ path: "size", label: "Size", min: 2, max: 400, step: 1 },
|
|
9065
9844
|
{ path: "rotation", label: "Rotation", min: -180, max: 180, step: 1 },
|
|
@@ -9094,7 +9873,7 @@ function createPaintEffectsToolProvider(controller, options = {}) {
|
|
|
9094
9873
|
};
|
|
9095
9874
|
const paintInfo = () => {
|
|
9096
9875
|
const p = controller.getEffectPaint();
|
|
9097
|
-
return p ? [{ id: PAINT_TARGET, effect: p.effect, provider: p.provider, role: controller.getState().effectPaintRendering ? "effect paint (rendering)" : "effect paint", enabled: true, values: p.values, ...p.time ? { time: p.time } : {} }] : [];
|
|
9876
|
+
return p ? [{ id: PAINT_TARGET, effect: p.effect, provider: p.provider, role: controller.getState().effectPaintRendering ? "effect paint (rendering)" : "effect paint", enabled: true, values: p.values, ...p.time ? { time: p.time } : {}, ...p.map ? { map: p.map } : {}, ...p.live ? { live: true } : {} }] : [];
|
|
9098
9877
|
};
|
|
9099
9878
|
const layerInfo = (layerId) => {
|
|
9100
9879
|
const s = controller.getEffectLayer(layerId);
|
|
@@ -9163,7 +9942,7 @@ function createPaintEffectsToolProvider(controller, options = {}) {
|
|
|
9163
9942
|
if (target === PAINT_TARGET) {
|
|
9164
9943
|
if (changes.opacity !== void 0) throw new Error("opacity does not apply to the effect paint: change the brush opacity (set_brush tip.opacity).");
|
|
9165
9944
|
const p = controller.getEffectPaint();
|
|
9166
|
-
await controller.setEffectPaint({ effect: p.effect, values: { ...p.values, ..._nullishCoalesce(changes.values, () => ( {})) }, time: p.time });
|
|
9945
|
+
await controller.setEffectPaint({ effect: p.effect, values: { ...p.values, ..._nullishCoalesce(changes.values, () => ( {})) }, time: p.time, map: p.map, live: p.live });
|
|
9167
9946
|
const effects2 = paintInfo();
|
|
9168
9947
|
return { target, effect: effects2[0], effects: effects2 };
|
|
9169
9948
|
}
|
|
@@ -9222,13 +10001,25 @@ function createPaintEffectsToolProvider(controller, options = {}) {
|
|
|
9222
10001
|
{
|
|
9223
10002
|
name: "set_effect_paint",
|
|
9224
10003
|
title: "Paint with an effect",
|
|
9225
|
-
description: `Makes brushes paint with a provider generator, overlay or title effect (search_effects with use generator, overlay or title): it is rendered once at the canvas size, and each stroke then takes every pixel's colour from it, fixed to the canvas, as if painting a hidden picture into view (the effect's transparency paints nothing). Dab, particle and bristle brushes take the colour per pixel; mixer brushes and dab brushes that pick up paint take it per dab, at its centre.
|
|
10004
|
+
description: `Makes brushes paint with a provider generator, overlay or title effect (search_effects with use generator, overlay or title): it is rendered once at the canvas size, and each stroke then takes every pixel's colour from it, fixed to the canvas, as if painting a hidden picture into view (the effect's transparency paints nothing). Dab, particle and bristle brushes take the colour per pixel; mixer brushes and dab brushes that pick up paint take it per dab, at its centre. Watercolour, gouache, oil and impasto brushes take it per pixel too, shifted by paint they pick up (in wet paint the pattern then flows with the water; impasto keeps its relief), and sprayed stickers take the colour at their centre. Erasers, blenders and smudges ignore it. It replaces the paint colour or gradient until set_color or set_paint; a brush with its own gradient paints that instead. Strokes record it and replay exactly. Editor state, not an undo step. Returns the effect paint: { effect, provider, values (every control), time } (list_applied_effects target "paint" shows it; update_effect / remove_effect with target and effect "paint" change or clear it).`,
|
|
9226
10005
|
inputSchema: {
|
|
9227
10006
|
type: "object",
|
|
9228
10007
|
properties: {
|
|
9229
10008
|
effect: ctx.effectIdSchema(["generator", "overlay", "title"]),
|
|
9230
10009
|
values: ctx.valuesSchema("Control values over the effect's defaults"),
|
|
9231
|
-
time: { type: "number", minimum: 0, description: "Which moment of an animated effect to paint with, in ms (default 0)." }
|
|
10010
|
+
time: { type: "number", minimum: 0, description: "Which moment of an animated effect to paint with, in ms (default 0)." },
|
|
10011
|
+
map: {
|
|
10012
|
+
type: "object",
|
|
10013
|
+
description: "How the effect lies on the paint: by canvas (default: fixed to the canvas, painting reveals a hidden picture) or by stroke (along each stroke: the effect is rendered as a strip length px long, and each pixel takes the colour at its distance along the stroke and its place across the tip).",
|
|
10014
|
+
properties: {
|
|
10015
|
+
by: { type: "string", enum: ["canvas", "stroke"], description: "canvas (default) or stroke." },
|
|
10016
|
+
length: { type: "number", minimum: 16, maximum: 4096, description: "by stroke: px of stroke per repeat of the effect (default 300)." },
|
|
10017
|
+
repeat: { type: "string", enum: ["repeat", "mirror", "clamp"], description: "by stroke: past the strip end start again (default), run back, or hold the last colour." }
|
|
10018
|
+
},
|
|
10019
|
+
required: ["by"],
|
|
10020
|
+
additionalProperties: false
|
|
10021
|
+
},
|
|
10022
|
+
live: { type: "boolean", description: "Live effect paint (default false): strokes on a stroke layer (add_layer type strokes) keep playing the effect, so the paint moves (set_effect_playback); elsewhere strokes bake the frame at time." }
|
|
9232
10023
|
},
|
|
9233
10024
|
required: ["effect"],
|
|
9234
10025
|
additionalProperties: false
|
|
@@ -9236,9 +10027,24 @@ function createPaintEffectsToolProvider(controller, options = {}) {
|
|
|
9236
10027
|
annotations: { title: "Paint with an effect", ...ctx.annotations.writeIdempotent },
|
|
9237
10028
|
handler: async (args) => {
|
|
9238
10029
|
ctx.requireProvider();
|
|
9239
|
-
return { effectPaint: await controller.setEffectPaint({ effect: args.effect, values: values(args.values), time: args.time }) };
|
|
10030
|
+
return { effectPaint: await controller.setEffectPaint({ effect: args.effect, values: values(args.values), time: args.time, map: args.map, live: args.live }) };
|
|
9240
10031
|
}
|
|
9241
10032
|
},
|
|
10033
|
+
{
|
|
10034
|
+
name: "set_effect_playback",
|
|
10035
|
+
title: "Play or pause live effect paint",
|
|
10036
|
+
description: "Plays or pauses live effect paint (strokes painted on stroke layers with set_effect_paint live true) in the editor view, and caps its frame rate. Exports draw it at a chosen time with export_image / export_psd time. Editor state, not an undo step. Returns playing, fps, the time the view shows (ms) and what plays (animation: layer ids, live strokes, sources; null when nothing does).",
|
|
10037
|
+
inputSchema: {
|
|
10038
|
+
type: "object",
|
|
10039
|
+
properties: {
|
|
10040
|
+
playing: { type: "boolean", description: "Play (true, the default state) or pause at the current frame." },
|
|
10041
|
+
fps: { type: "integer", minimum: 1, maximum: 60, description: "Frame rate cap, frames a second (default 30); lower it on large canvases." }
|
|
10042
|
+
},
|
|
10043
|
+
additionalProperties: false
|
|
10044
|
+
},
|
|
10045
|
+
annotations: { title: "Play or pause live effect paint", ...ctx.annotations.writeIdempotent },
|
|
10046
|
+
handler: async (args) => ({ ...controller.setEffectPlayback({ playing: args.playing, fps: args.fps }), animation: controller.getAnimation() })
|
|
10047
|
+
},
|
|
9242
10048
|
{
|
|
9243
10049
|
name: "add_effect_layer",
|
|
9244
10050
|
title: "Add an effect layer",
|
|
@@ -9634,4 +10440,14 @@ function createPaintEditorDocument(controller, options = {}) {
|
|
|
9634
10440
|
|
|
9635
10441
|
|
|
9636
10442
|
|
|
9637
|
-
exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.BRUSH_ID = _chunkNKTNLJUJcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkNKTNLJUJcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkNKTNLJUJcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunkNKTNLJUJcjs.BristleStroke; exports.DEFAULT_BEHAVIOR = _chunkNKTNLJUJcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkNKTNLJUJcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkNKTNLJUJcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkNKTNLJUJcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkXFYLA3ZOcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkNKTNLJUJcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkNKTNLJUJcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkNKTNLJUJcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkNKTNLJUJcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunkNKTNLJUJcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkNKTNLJUJcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkXFYLA3ZOcjs.DEFAULT_WET_PARAMS; exports.DryStroke = _chunkNKTNLJUJcjs.DryStroke; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPQ3H2AANcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPQ3H2AANcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunk7PT4RJL5cjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkNKTNLJUJcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkNKTNLJUJcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkPQ3H2AANcjs.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.MULTI_COLOR_MODES = _chunkNKTNLJUJcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkNKTNLJUJcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkNKTNLJUJcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkPQ3H2AANcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkPQ3H2AANcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkNKTNLJUJcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkNKTNLJUJcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkNKTNLJUJcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkNKTNLJUJcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkPQ3H2AANcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkPQ3H2AANcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPQ3H2AANcjs.PaperGrain; exports.ParticleStroke = _chunkNKTNLJUJcjs.ParticleStroke; exports.PenDabWalker = _chunkNKTNLJUJcjs.PenDabWalker; exports.PenSmoother = _chunkNKTNLJUJcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkNKTNLJUJcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunkNKTNLJUJcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkPQ3H2AANcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkXFYLA3ZOcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkNKTNLJUJcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkXFYLA3ZOcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkNKTNLJUJcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkPQ3H2AANcjs.addPaintGradientStop; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkNKTNLJUJcjs.brushTakesPaint; exports.brushToJSON = _chunkNKTNLJUJcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkNKTNLJUJcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; 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.drawSticker = _chunkNKTNLJUJcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkNKTNLJUJcjs.effectPaintKey; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPQ3H2AANcjs.grainCatch; exports.grainHeights = _chunkPQ3H2AANcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkPQ3H2AANcjs.hash2; exports.hexToPaintRgb = _chunkPQ3H2AANcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkNKTNLJUJcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunk7PT4RJL5cjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isGradientPaint = _chunkPQ3H2AANcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkNKTNLJUJcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkNKTNLJUJcjs.isWetBrush; exports.isWetCapable = _chunkNKTNLJUJcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkPQ3H2AANcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkNKTNLJUJcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunkNKTNLJUJcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkNKTNLJUJcjs.normalizeBehavior; exports.normalizeBristle = _chunkNKTNLJUJcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkNKTNLJUJcjs.normalizeDynamics; exports.normalizeFlow = _chunkXFYLA3ZOcjs.normalizeFlow; exports.normalizeHexColor = _chunkPQ3H2AANcjs.normalizeHexColor; exports.normalizeImpasto = _chunkNKTNLJUJcjs.normalizeImpasto; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkNKTNLJUJcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkNKTNLJUJcjs.normalizePaintBrush; exports.normalizePaper = _chunkNKTNLJUJcjs.normalizePaper; exports.normalizeParticle = _chunkNKTNLJUJcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkNKTNLJUJcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunkNKTNLJUJcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkNKTNLJUJcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkXFYLA3ZOcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkPQ3H2AANcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkPQ3H2AANcjs.paintSourceColor; exports.paintSourceCss = _chunkPQ3H2AANcjs.paintSourceCss; exports.paintToMultiColor = _chunkNKTNLJUJcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkNKTNLJUJcjs.paperPreset; exports.parseBrushLibrary = _chunkNKTNLJUJcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkPQ3H2AANcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkNKTNLJUJcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkPQ3H2AANcjs.rand01; exports.randSigned = _chunkPQ3H2AANcjs.randSigned; exports.readPaintEffectPaint = _chunkNKTNLJUJcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkPQ3H2AANcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkPQ3H2AANcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkNKTNLJUJcjs.renderPaper; exports.renderStickers = _chunkNKTNLJUJcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkPQ3H2AANcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkPQ3H2AANcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleEffectAt = _chunkNKTNLJUJcjs.sampleEffectAt; exports.sampleEffectField = _chunkNKTNLJUJcjs.sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkPQ3H2AANcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkPQ3H2AANcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkPQ3H2AANcjs.solidPaint; exports.stampCoverage = _chunkNKTNLJUJcjs.stampCoverage; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = _chunkNKTNLJUJcjs.stickerAt; exports.stickerRect = _chunkNKTNLJUJcjs.stickerRect; exports.stickerSurface = _chunkNKTNLJUJcjs.stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkNKTNLJUJcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkNKTNLJUJcjs.toStrokePoint; exports.toggleStamp = toggleStamp; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkPQ3H2AANcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkNKTNLJUJcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkXFYLA3ZOcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunk7PT4RJL5cjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
|
|
10443
|
+
|
|
10444
|
+
|
|
10445
|
+
|
|
10446
|
+
|
|
10447
|
+
|
|
10448
|
+
|
|
10449
|
+
|
|
10450
|
+
|
|
10451
|
+
|
|
10452
|
+
|
|
10453
|
+
exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.BRUSH_ID = _chunk5BR7LC24cjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunk5BR7LC24cjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunk5BR7LC24cjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunk5BR7LC24cjs.BristleStroke; exports.DEFAULT_BEHAVIOR = _chunk5BR7LC24cjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunk5BR7LC24cjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunk5BR7LC24cjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunk5BR7LC24cjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkXFYLA3ZOcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunk5BR7LC24cjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunk5BR7LC24cjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunk5BR7LC24cjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunk5BR7LC24cjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunk5BR7LC24cjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunk5BR7LC24cjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkXFYLA3ZOcjs.DEFAULT_WET_PARAMS; exports.DryStroke = _chunk5BR7LC24cjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunk5BR7LC24cjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunk5BR7LC24cjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPQ3H2AANcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPQ3H2AANcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunk7PT4RJL5cjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunk5BR7LC24cjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunk5BR7LC24cjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkPQ3H2AANcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; 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.MULTI_COLOR_MODES = _chunk5BR7LC24cjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunk5BR7LC24cjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunk5BR7LC24cjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkPQ3H2AANcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkPQ3H2AANcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunk5BR7LC24cjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunk5BR7LC24cjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunk5BR7LC24cjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunk5BR7LC24cjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkPQ3H2AANcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkPQ3H2AANcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPQ3H2AANcjs.PaperGrain; exports.ParticleStroke = _chunk5BR7LC24cjs.ParticleStroke; exports.PenDabWalker = _chunk5BR7LC24cjs.PenDabWalker; exports.PenSmoother = _chunk5BR7LC24cjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunk5BR7LC24cjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunk5BR7LC24cjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkPQ3H2AANcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkXFYLA3ZOcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunk5BR7LC24cjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkXFYLA3ZOcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunk5BR7LC24cjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkPQ3H2AANcjs.addPaintGradientStop; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunk5BR7LC24cjs.brushTakesPaint; exports.brushToJSON = _chunk5BR7LC24cjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunk5BR7LC24cjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; 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.drawSticker = _chunk5BR7LC24cjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunk5BR7LC24cjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunk5BR7LC24cjs.effectPaintKey; exports.effectPaintSize = _chunk5BR7LC24cjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPQ3H2AANcjs.grainCatch; exports.grainHeights = _chunkPQ3H2AANcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkPQ3H2AANcjs.hash2; exports.hexToPaintRgb = _chunkPQ3H2AANcjs.hexToPaintRgb; exports.hexToRgb8 = _chunk5BR7LC24cjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunk7PT4RJL5cjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isGradientPaint = _chunkPQ3H2AANcjs.isGradientPaint; exports.isPaintEffectPaint = _chunk5BR7LC24cjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunk5BR7LC24cjs.isWetBrush; exports.isWetCapable = _chunk5BR7LC24cjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkPQ3H2AANcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunk5BR7LC24cjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunk5BR7LC24cjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunk5BR7LC24cjs.normalizeBehavior; exports.normalizeBristle = _chunk5BR7LC24cjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunk5BR7LC24cjs.normalizeDynamics; exports.normalizeFlow = _chunkXFYLA3ZOcjs.normalizeFlow; exports.normalizeHexColor = _chunkPQ3H2AANcjs.normalizeHexColor; exports.normalizeImpasto = _chunk5BR7LC24cjs.normalizeImpasto; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunk5BR7LC24cjs.normalizeMultiColor; exports.normalizePaintBrush = _chunk5BR7LC24cjs.normalizePaintBrush; exports.normalizePaper = _chunk5BR7LC24cjs.normalizePaper; exports.normalizeParticle = _chunk5BR7LC24cjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunk5BR7LC24cjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunk5BR7LC24cjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunk5BR7LC24cjs.normalizeWetBrush; exports.normalizeWetParams = _chunkXFYLA3ZOcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkPQ3H2AANcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkPQ3H2AANcjs.paintSourceColor; exports.paintSourceCss = _chunkPQ3H2AANcjs.paintSourceCss; exports.paintToMultiColor = _chunk5BR7LC24cjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunk5BR7LC24cjs.paperPreset; exports.parseBrushLibrary = _chunk5BR7LC24cjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkPQ3H2AANcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunk5BR7LC24cjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkPQ3H2AANcjs.rand01; exports.randSigned = _chunkPQ3H2AANcjs.randSigned; exports.readEffectStrokeMap = _chunk5BR7LC24cjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunk5BR7LC24cjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkPQ3H2AANcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkPQ3H2AANcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunk5BR7LC24cjs.renderPaper; exports.renderStickers = _chunk5BR7LC24cjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkPQ3H2AANcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkPQ3H2AANcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleEffectAt = _chunk5BR7LC24cjs.sampleEffectAt; exports.sampleEffectField = _chunk5BR7LC24cjs.sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkPQ3H2AANcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkPQ3H2AANcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkPQ3H2AANcjs.solidPaint; exports.stampCoverage = _chunk5BR7LC24cjs.stampCoverage; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = _chunk5BR7LC24cjs.stickerAt; exports.stickerRect = _chunk5BR7LC24cjs.stickerRect; exports.stickerSurface = _chunk5BR7LC24cjs.stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunk5BR7LC24cjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunk5BR7LC24cjs.toStrokePoint; exports.toggleStamp = toggleStamp; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkPQ3H2AANcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunk5BR7LC24cjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkXFYLA3ZOcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunk7PT4RJL5cjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
|