@pixerate/editor 0.259.0 → 0.261.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.cjs +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/animation-editor/index.cjs +61 -59
- package/dist/animation-editor/index.js +5 -3
- package/dist/brushes/index.cjs +52 -52
- package/dist/brushes/index.js +6 -6
- package/dist/{brushstrokeRender-JI4W6F2G.js → brushstrokeRender-25Q5BEY6.js} +17 -7
- package/dist/{brushstrokeRender-MQ6PSDM5.cjs → brushstrokeRender-N6UPZSQS.cjs} +31 -21
- package/dist/canvas/brushTypes.d.cts +5 -0
- package/dist/canvas/brushTypes.d.ts +5 -0
- package/dist/canvas/drawController.d.cts +15 -1
- package/dist/canvas/drawController.d.ts +15 -1
- package/dist/canvas/index.cjs +136 -102
- package/dist/canvas/index.js +35 -1
- package/dist/{chunk-3PPJRMIG.js → chunk-3O47TPGX.js} +197 -18
- package/dist/{chunk-5Q5MLXAD.cjs → chunk-3TQW5MPW.cjs} +23 -23
- package/dist/{chunk-JBBJE76O.cjs → chunk-3ZRNK3RO.cjs} +1138 -85
- package/dist/{chunk-YSGW7VV4.cjs → chunk-43NT242D.cjs} +1401 -228
- package/dist/{chunk-SMTUQWGY.js → chunk-5IW65VQ6.js} +1 -1
- package/dist/{chunk-YQ4PQTBB.js → chunk-6NZL24W4.js} +9 -1
- package/dist/{chunk-O3ZVZSNJ.cjs → chunk-7AUQ2UJ3.cjs} +137 -129
- package/dist/{chunk-4M4E3N6X.js → chunk-CQVTGBQI.js} +1 -1
- package/dist/{chunk-SSFMWJDK.js → chunk-D4TE5JNW.js} +1192 -19
- package/dist/{chunk-AORZ5M5C.js → chunk-EHALWBBD.js} +1 -1
- package/dist/{chunk-6WCQ35GI.cjs → chunk-NHA26O5X.cjs} +2 -2
- package/dist/{chunk-DPYAO5U6.cjs → chunk-PVJMTLPJ.cjs} +197 -18
- package/dist/{chunk-MQGQTKVW.cjs → chunk-PYTJBVW5.cjs} +29 -29
- package/dist/{chunk-IXQZHCOF.js → chunk-QAR2N7HZ.js} +1 -1
- package/dist/{chunk-5P4JEOIV.js → chunk-TMDDMJCR.js} +2 -2
- package/dist/{chunk-RSIKDWOP.cjs → chunk-TZOX7KWV.cjs} +15 -15
- package/dist/{chunk-IPUTIUGQ.cjs → chunk-UVZ7RQOE.cjs} +1 -1
- package/dist/{chunk-A7GJ6BXI.js → chunk-WJ4WQJCC.js} +1062 -9
- package/dist/{chunk-ICTPLVSR.js → chunk-X2EXYY4J.js} +1 -1
- package/dist/{chunk-WQCNC4DK.js → chunk-XC6DPRYI.js} +695 -4
- package/dist/{chunk-KBYB7OWB.cjs → chunk-YHDHFJUC.cjs} +776 -85
- package/dist/{chunk-P3PZ63M3.cjs → chunk-YLUIFXSL.cjs} +35 -35
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/image-editor/index.cjs +1385 -2484
- package/dist/image-editor/index.js +139 -1238
- package/dist/image-editor/selection-worker.cjs +3 -4
- package/dist/image-editor/selection-worker.js +1 -2
- package/dist/paint/index.cjs +3 -5
- package/dist/paint/index.js +40 -42
- package/dist/paint-editor/contract.d.cts +29 -0
- package/dist/paint-editor/contract.d.ts +29 -0
- package/dist/paint-editor/controller.d.cts +17 -0
- package/dist/paint-editor/controller.d.ts +17 -0
- package/dist/paint-editor/dab-stroke.d.cts +5 -0
- package/dist/paint-editor/dab-stroke.d.ts +5 -0
- package/dist/paint-editor/index.cjs +610 -327
- package/dist/paint-editor/index.d.cts +2 -0
- package/dist/paint-editor/index.d.ts +2 -0
- package/dist/paint-editor/index.js +337 -54
- package/dist/paint-editor/path-samples.d.cts +19 -0
- package/dist/paint-editor/path-samples.d.ts +19 -0
- package/dist/paint-editor/stamp-tip.d.cts +17 -0
- package/dist/paint-editor/stamp-tip.d.ts +17 -0
- package/dist/paint-editor/ui.d.cts +27 -1
- package/dist/paint-editor/ui.d.ts +27 -1
- package/dist/raster/index.cjs +2 -4
- package/dist/raster/index.js +6 -8
- package/dist/vector/brushstroke.d.cts +6 -0
- package/dist/vector/brushstroke.d.ts +6 -0
- package/dist/vector/controller.d.cts +11 -2
- package/dist/vector/controller.d.ts +11 -2
- package/dist/vector/index.cjs +990 -973
- package/dist/vector/index.js +28 -11
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +1 -1
- package/skills/pixerate-canvas/SKILL.md +3 -1
- package/skills/pixerate-paint-editor/SKILL.md +2 -0
- package/skills/pixerate-paint-sketch-to-finish/SKILL.md +5 -1
- package/skills/pixerate-vector/SKILL.md +2 -2
- package/dist/chunk-2VJAVXLI.js +0 -192
- package/dist/chunk-62Z5WLRA.js +0 -700
- package/dist/chunk-BOHDJJ2O.cjs +0 -192
- package/dist/chunk-NKGB64CW.cjs +0 -700
- package/dist/chunk-SS53NNZO.cjs +0 -1066
- package/dist/chunk-ZNA3IQZF.js +0 -1066
|
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
|
|
|
74
74
|
var round3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
75
75
|
var loading = null;
|
|
76
76
|
function loadCanvasBrushstrokeRenderer() {
|
|
77
|
-
loading ??= import("./brushstrokeRender-
|
|
77
|
+
loading ??= import("./brushstrokeRender-25Q5BEY6.js").catch((error) => {
|
|
78
78
|
loading = null;
|
|
79
79
|
throw error;
|
|
80
80
|
});
|
|
@@ -337,7 +337,7 @@ function createDrawCommands(target, options = {}) {
|
|
|
337
337
|
description: "Stroke points as [x, y] pairs in canvas (flow) units, in drawing order. Use a point every few units along curves."
|
|
338
338
|
},
|
|
339
339
|
tool: { type: "string", enum: ["pen", "highlighter"], description: "Pen (default: blue, width 3) or highlighter (yellow, width 24, opacity 0.35); sets the defaults below." },
|
|
340
|
-
color: { type: "string", description: "Stroke colour, any CSS colour (default
|
|
340
|
+
color: { type: "string", description: "Stroke colour, any CSS colour (default: the brush's default colour, such as the ballpoint's blue, else the tool's)." },
|
|
341
341
|
width: { type: "number", exclusiveMinimum: 0, maximum: 2500, description: "Stroke width in canvas units (default from the tool). For brushed strokes it is the brush diameter; leave it out to use the preset's own size (canvas.listBrushes gives it)." },
|
|
342
342
|
opacity: { type: "number", minimum: 0, maximum: 1, description: "Stroke opacity 0..1 (default from the tool)." },
|
|
343
343
|
brush: {
|
|
@@ -420,7 +420,7 @@ var gestureBoxes = (what) => ({
|
|
|
420
420
|
});
|
|
421
421
|
var GESTURE_STYLE_PARAMS = {
|
|
422
422
|
tool: { type: "string", enum: ["pen", "highlighter"], description: "Pen (default: blue, width 3) or highlighter (yellow, width 24, opacity 0.35); sets the defaults below." },
|
|
423
|
-
color: { type: "string", description: "Stroke colour, any CSS colour (default
|
|
423
|
+
color: { type: "string", description: "Stroke colour, any CSS colour (default: the brush's default colour, such as the ballpoint's blue, else the tool's)." },
|
|
424
424
|
width: { type: "number", exclusiveMinimum: 0, maximum: 2500, description: "Stroke width in canvas units (default from the tool; with a brush, the preset's own size)." },
|
|
425
425
|
opacity: { type: "number", minimum: 0, maximum: 1, description: "Stroke opacity 0..1 (default from the tool)." },
|
|
426
426
|
brush: {
|
|
@@ -26,6 +26,7 @@ var _chunkK6PXS6DOcjs = require('./chunk-K6PXS6DO.cjs');
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
|
|
29
30
|
var _chunk2VX55NFMcjs = require('./chunk-2VX55NFM.cjs');
|
|
30
31
|
|
|
31
32
|
|
|
@@ -762,8 +763,8 @@ function edtNearest(inside, w, h) {
|
|
|
762
763
|
dt1(f, w, o, nr, v, z);
|
|
763
764
|
for (let x = 0; x < w; x++) {
|
|
764
765
|
d[y * w + x] = Math.sqrt(o[x]);
|
|
765
|
-
const
|
|
766
|
-
near[y * w + x] = nc[
|
|
766
|
+
const px2 = nr[x];
|
|
767
|
+
near[y * w + x] = nc[px2 * h + y] * w + px2;
|
|
767
768
|
}
|
|
768
769
|
}
|
|
769
770
|
return { d, near };
|
|
@@ -3446,21 +3447,21 @@ function readWindow(src, srcRect, rect, depth = null) {
|
|
|
3446
3447
|
const win = { x: rect.x, y: rect.y, w: rect.width, h: rect.height, n, data };
|
|
3447
3448
|
const r = intersect(rect, srcRect);
|
|
3448
3449
|
if (!r) return win;
|
|
3449
|
-
const
|
|
3450
|
+
const px2 = depth ? readScaled(src, r, depth) : _chunk474IQG74cjs.readRegion.call(void 0, src, r);
|
|
3450
3451
|
for (let y = 0; y < r.height; y++) {
|
|
3451
3452
|
let s = y * r.width * src.channels;
|
|
3452
3453
|
let d = ((r.y - rect.y + y) * rect.width + (r.x - rect.x)) * n;
|
|
3453
3454
|
if (n === 4) {
|
|
3454
3455
|
for (let x = 0; x < r.width; x++, s += 4, d += 4) {
|
|
3455
|
-
const a =
|
|
3456
|
-
data[d] =
|
|
3457
|
-
data[d + 1] =
|
|
3458
|
-
data[d + 2] =
|
|
3456
|
+
const a = px2[s + 3] / 255;
|
|
3457
|
+
data[d] = px2[s] * a;
|
|
3458
|
+
data[d + 1] = px2[s + 1] * a;
|
|
3459
|
+
data[d + 2] = px2[s + 2] * a;
|
|
3459
3460
|
data[d + 3] = a;
|
|
3460
3461
|
}
|
|
3461
3462
|
} else {
|
|
3462
3463
|
for (let x = 0; x < r.width; x++, s++, d += 2) {
|
|
3463
|
-
data[d] =
|
|
3464
|
+
data[d] = px2[s];
|
|
3464
3465
|
data[d + 1] = 1;
|
|
3465
3466
|
}
|
|
3466
3467
|
}
|
|
@@ -3631,7 +3632,7 @@ function boxReduce(src, srcRect, kx, ky, depth = null) {
|
|
|
3631
3632
|
for (let ry = ry0; ry < ry1; ry += rowsPer) {
|
|
3632
3633
|
const rows = Math.min(rowsPer, ry1 - ry);
|
|
3633
3634
|
const strip = { x: rx0 * kx, y: ry * ky, width: rw * kx, height: rows * ky };
|
|
3634
|
-
const
|
|
3635
|
+
const px2 = depth ? readScaled(src, strip, depth) : _chunk474IQG74cjs.readRegion.call(void 0, src, strip);
|
|
3635
3636
|
const red = depth ? new Float32Array(rw * rows * ch) : new Uint8ClampedArray(rw * rows * ch);
|
|
3636
3637
|
for (let j = 0; j < rows; j++) {
|
|
3637
3638
|
for (let i = 0; i < rw; i++) {
|
|
@@ -3643,11 +3644,11 @@ function boxReduce(src, srcRect, kx, ky, depth = null) {
|
|
|
3643
3644
|
for (let y = 0; y < ky; y++) {
|
|
3644
3645
|
let s = ((j * ky + y) * strip.width + i * kx) * 4;
|
|
3645
3646
|
for (let x = 0; x < kx; x++, s += 4) {
|
|
3646
|
-
const al =
|
|
3647
|
+
const al = px2[s + 3];
|
|
3647
3648
|
a += al;
|
|
3648
|
-
r +=
|
|
3649
|
-
g +=
|
|
3650
|
-
b +=
|
|
3649
|
+
r += px2[s] * al;
|
|
3650
|
+
g += px2[s + 1] * al;
|
|
3651
|
+
b += px2[s + 2] * al;
|
|
3651
3652
|
}
|
|
3652
3653
|
}
|
|
3653
3654
|
const o = (j * rw + i) * 4;
|
|
@@ -3661,7 +3662,7 @@ function boxReduce(src, srcRect, kx, ky, depth = null) {
|
|
|
3661
3662
|
let v = 0;
|
|
3662
3663
|
for (let y = 0; y < ky; y++) {
|
|
3663
3664
|
const s = (j * ky + y) * strip.width + i * kx;
|
|
3664
|
-
for (let x = 0; x < kx; x++) v +=
|
|
3665
|
+
for (let x = 0; x < kx; x++) v += px2[s + x];
|
|
3665
3666
|
}
|
|
3666
3667
|
red[j * rw + i] = v / area;
|
|
3667
3668
|
}
|
|
@@ -4038,9 +4039,9 @@ function warpSurface(src, f, options = {}) {
|
|
|
4038
4039
|
for (let y = ay0; y < ry1; y += step) {
|
|
4039
4040
|
const py = y + 0.5;
|
|
4040
4041
|
for (let x = ax0; x < rx1; x += step) {
|
|
4041
|
-
const
|
|
4042
|
-
const l1 = ((
|
|
4043
|
-
const l2 = ((p1x - p0x) * (py - p0y) - (
|
|
4042
|
+
const px2 = x + 0.5;
|
|
4043
|
+
const l1 = ((px2 - p0x) * (p2y - p0y) - (p2x - p0x) * (py - p0y)) / det;
|
|
4044
|
+
const l2 = ((p1x - p0x) * (py - p0y) - (px2 - p0x) * (p1y - p0y)) / det;
|
|
4044
4045
|
const l0 = 1 - l1 - l2;
|
|
4045
4046
|
if (l0 < eps || l1 < eps || l2 < eps) continue;
|
|
4046
4047
|
const o = (y - t.y) * tw + (x - t.x);
|
|
@@ -4197,6 +4198,184 @@ function compositeSurfaceOver(base, top) {
|
|
|
4197
4198
|
return new (0, _chunk474IQG74cjs.TiledSurface)(ch, tiles, base.defaultValue);
|
|
4198
4199
|
}
|
|
4199
4200
|
|
|
4201
|
+
// src/raster/effects/ui.ts
|
|
4202
|
+
function layerEffectsPanel(layer) {
|
|
4203
|
+
const empty = { readOnly: true, enabled: true, scale: 1, rows: [] };
|
|
4204
|
+
if (!layer) return { ...empty, available: false, reason: "Select a layer to add a layer style." };
|
|
4205
|
+
if (layer.type === "adjustment") return { ...empty, available: false, reason: "Adjustment layers cannot have a layer style." };
|
|
4206
|
+
const fx = layer.effects;
|
|
4207
|
+
const readOnly = Boolean(_optionalChain([layer, 'access', _95 => _95.locks, 'optionalAccess', _96 => _96.all]));
|
|
4208
|
+
return {
|
|
4209
|
+
available: true,
|
|
4210
|
+
readOnly,
|
|
4211
|
+
reason: readOnly ? "The layer is locked; unlock it to change its layer style." : void 0,
|
|
4212
|
+
enabled: _nullishCoalesce(_optionalChain([fx, 'optionalAccess', _97 => _97.enabled]), () => ( true)),
|
|
4213
|
+
scale: _nullishCoalesce(_optionalChain([fx, 'optionalAccess', _98 => _98.scale]), () => ( 1)),
|
|
4214
|
+
rows: (_nullishCoalesce(_optionalChain([fx, 'optionalAccess', _99 => _99.items]), () => ( []))).map((e) => ({ id: e.id, kind: e.kind, label: layerEffectLabel(e.kind), enabled: e.enabled }))
|
|
4215
|
+
};
|
|
4216
|
+
}
|
|
4217
|
+
function layerEffectsBadge(layer) {
|
|
4218
|
+
if (!_optionalChain([layer, 'access', _100 => _100.effects, 'optionalAccess', _101 => _101.items, 'access', _102 => _102.length])) return null;
|
|
4219
|
+
return hasActiveEffects(layer.effects) ? "on" : "off";
|
|
4220
|
+
}
|
|
4221
|
+
var LAYER_EFFECT_MENU = LAYER_EFFECT_KINDS.map((kind) => ({ kind, label: layerEffectLabel(kind) }));
|
|
4222
|
+
var BLENDS = _chunk2VX55NFMcjs.BLEND_MODES.filter((m) => m.id !== "pigment").map((m) => ({ value: m.id, label: m.label }));
|
|
4223
|
+
var opt = (...pairs) => pairs.map(([value, label]) => ({ value, label }));
|
|
4224
|
+
function patternOptions(patterns) {
|
|
4225
|
+
return [...patterns.map((p) => ({ value: p.id, label: p.name || p.id })), ...builtinPatternIds().map((id) => ({ value: id, label: builtinPattern(id).name }))];
|
|
4226
|
+
}
|
|
4227
|
+
function getPath(o, path) {
|
|
4228
|
+
let v = o;
|
|
4229
|
+
for (const p of path.split(".")) {
|
|
4230
|
+
if (v === null || v === void 0) return void 0;
|
|
4231
|
+
if (Array.isArray(v)) v = p === "last" ? v[v.length - 1] : v[Number(p)];
|
|
4232
|
+
else v = v[p];
|
|
4233
|
+
}
|
|
4234
|
+
return v;
|
|
4235
|
+
}
|
|
4236
|
+
function setPath(o, parts, value) {
|
|
4237
|
+
if (!parts.length) return value;
|
|
4238
|
+
const [p, ...rest] = parts;
|
|
4239
|
+
if (Array.isArray(o)) {
|
|
4240
|
+
const i = p === "last" ? o.length - 1 : Number(p);
|
|
4241
|
+
const out = [...o];
|
|
4242
|
+
out[i] = setPath(o[i], rest, value);
|
|
4243
|
+
return out;
|
|
4244
|
+
}
|
|
4245
|
+
const r = _nullishCoalesce(o, () => ( {}));
|
|
4246
|
+
return { ...r, [p]: setPath(r[p], rest, value) };
|
|
4247
|
+
}
|
|
4248
|
+
function fillControls(f, allowPattern, patterns) {
|
|
4249
|
+
const types = allowPattern ? opt(["color", "Color"], ["gradient", "Gradient"], ["pattern", "Pattern"]) : opt(["color", "Color"], ["gradient", "Gradient"]);
|
|
4250
|
+
const out = [{ key: "fill.type", label: "Fill", type: "select", value: f.type, options: types }];
|
|
4251
|
+
if (f.type === "color") out.push({ key: "fill.color", label: "Color", type: "color", value: f.color });
|
|
4252
|
+
else if (f.type === "gradient") out.push(...gradientControls("fill.gradient", f.gradient));
|
|
4253
|
+
else {
|
|
4254
|
+
out.push(
|
|
4255
|
+
{ key: "fill.patternId", label: "Pattern", type: "select", value: f.patternId, options: patternOptions(patterns) },
|
|
4256
|
+
{ key: "fill.scale", label: "Scale", type: "range", min: 0.01, max: 10, step: 0.01, value: f.scale, percent: true, unit: "%" }
|
|
4257
|
+
);
|
|
4258
|
+
}
|
|
4259
|
+
return out;
|
|
4260
|
+
}
|
|
4261
|
+
function gradientControls(prefix, g) {
|
|
4262
|
+
return [
|
|
4263
|
+
{ key: `${prefix}.stops.0.color`, label: "Start colour", type: "color", value: _nullishCoalesce(_optionalChain([g, 'access', _103 => _103.stops, 'access', _104 => _104[0], 'optionalAccess', _105 => _105.color]), () => ( "#000000")) },
|
|
4264
|
+
{ key: `${prefix}.stops.last.color`, label: "End colour", type: "color", value: _nullishCoalesce(_optionalChain([g, 'access', _106 => _106.stops, 'access', _107 => _107[g.stops.length - 1], 'optionalAccess', _108 => _108.color]), () => ( "#ffffff")) },
|
|
4265
|
+
{ key: `${prefix}.style`, label: "Style", type: "select", value: g.style, options: opt(["linear", "Linear"], ["radial", "Radial"], ["angle", "Angle"], ["reflected", "Reflected"], ["diamond", "Diamond"]) },
|
|
4266
|
+
{ key: `${prefix}.angle`, label: "Angle", type: "range", min: -180, max: 180, step: 1, value: g.angle, unit: "\xB0" },
|
|
4267
|
+
{ key: `${prefix}.scale`, label: "Scale", type: "range", min: 0.1, max: 1.5, step: 0.01, value: g.scale, percent: true, unit: "%" },
|
|
4268
|
+
{ key: `${prefix}.reverse`, label: "Reverse", type: "checkbox", value: g.reverse },
|
|
4269
|
+
{ key: `${prefix}.align`, label: "Align with layer", type: "checkbox", value: g.align }
|
|
4270
|
+
];
|
|
4271
|
+
}
|
|
4272
|
+
var px = (key, label, value, max = 250) => ({ key, label, type: "range", min: 0, max, step: 1, value, unit: "px" });
|
|
4273
|
+
var pct = (key, label, value, min = 0, max = 1) => ({ key, label, type: "range", min, max, step: 0.01, value, percent: true, unit: "%" });
|
|
4274
|
+
var deg = (key, label, value, min = -180, max = 180) => ({ key, label, type: "range", min, max, step: 1, value, unit: "\xB0" });
|
|
4275
|
+
function layerEffectControls(e, patterns = []) {
|
|
4276
|
+
const blended = e.kind === "bevel-emboss" ? [] : [
|
|
4277
|
+
{ key: "blend", label: "Blend mode", type: "select", value: e.blend, options: BLENDS },
|
|
4278
|
+
pct("opacity", "Opacity", e.opacity)
|
|
4279
|
+
];
|
|
4280
|
+
switch (e.kind) {
|
|
4281
|
+
case "drop-shadow":
|
|
4282
|
+
case "inner-shadow":
|
|
4283
|
+
return [
|
|
4284
|
+
...blended,
|
|
4285
|
+
{ key: "color", label: "Color", type: "color", value: e.color },
|
|
4286
|
+
{ key: "useGlobalLight", label: "Use global light", type: "checkbox", value: e.useGlobalLight },
|
|
4287
|
+
deg("angle", "Angle", e.angle),
|
|
4288
|
+
px("distance", "Distance", e.distance, 500),
|
|
4289
|
+
e.kind === "drop-shadow" ? pct("spread", "Spread", e.spread) : pct("choke", "Choke", e.choke),
|
|
4290
|
+
px("size", "Size", e.size),
|
|
4291
|
+
pct("noise", "Noise", e.noise),
|
|
4292
|
+
...e.kind === "drop-shadow" ? [{ key: "knocksOut", label: "Layer knocks out shadow", type: "checkbox", value: e.knocksOut }] : []
|
|
4293
|
+
];
|
|
4294
|
+
case "outer-glow":
|
|
4295
|
+
case "inner-glow":
|
|
4296
|
+
return [
|
|
4297
|
+
...blended,
|
|
4298
|
+
...fillControls(e.fill, false, patterns),
|
|
4299
|
+
{ key: "technique", label: "Technique", type: "select", value: e.technique, options: opt(["softer", "Softer"], ["precise", "Precise"]) },
|
|
4300
|
+
...e.kind === "inner-glow" ? [{ key: "source", label: "Source", type: "select", value: e.source, options: opt(["edge", "Edge"], ["center", "Center"]) }] : [],
|
|
4301
|
+
e.kind === "outer-glow" ? pct("spread", "Spread", e.spread) : pct("choke", "Choke", e.choke),
|
|
4302
|
+
px("size", "Size", e.size),
|
|
4303
|
+
pct("range", "Range", e.range, 0.01, 1),
|
|
4304
|
+
pct("noise", "Noise", e.noise)
|
|
4305
|
+
];
|
|
4306
|
+
case "bevel-emboss":
|
|
4307
|
+
return [
|
|
4308
|
+
{ key: "style", label: "Style", type: "select", value: e.style, options: opt(["inner-bevel", "Inner Bevel"], ["outer-bevel", "Outer Bevel"], ["emboss", "Emboss"], ["pillow-emboss", "Pillow Emboss"], ["stroke-emboss", "Stroke Emboss"]) },
|
|
4309
|
+
{ key: "technique", label: "Technique", type: "select", value: e.technique, options: opt(["smooth", "Smooth"], ["chisel-hard", "Chisel Hard"], ["chisel-soft", "Chisel Soft"]) },
|
|
4310
|
+
pct("depth", "Depth", e.depth, 0, 10),
|
|
4311
|
+
{ key: "direction", label: "Direction", type: "select", value: e.direction, options: opt(["up", "Up"], ["down", "Down"]) },
|
|
4312
|
+
px("size", "Size", e.size),
|
|
4313
|
+
px("soften", "Soften", e.soften, 16),
|
|
4314
|
+
{ key: "useGlobalLight", label: "Use global light", type: "checkbox", value: e.useGlobalLight },
|
|
4315
|
+
deg("angle", "Angle", e.angle),
|
|
4316
|
+
deg("altitude", "Altitude", e.altitude, 0, 90),
|
|
4317
|
+
{ key: "highlightColor", label: "Highlight", type: "color", value: e.highlightColor },
|
|
4318
|
+
{ key: "highlightBlend", label: "Highlight mode", type: "select", value: e.highlightBlend, options: BLENDS },
|
|
4319
|
+
pct("highlightOpacity", "Highlight opacity", e.highlightOpacity),
|
|
4320
|
+
{ key: "shadowColor", label: "Shadow", type: "color", value: e.shadowColor },
|
|
4321
|
+
{ key: "shadowBlend", label: "Shadow mode", type: "select", value: e.shadowBlend, options: BLENDS },
|
|
4322
|
+
pct("shadowOpacity", "Shadow opacity", e.shadowOpacity)
|
|
4323
|
+
];
|
|
4324
|
+
case "satin":
|
|
4325
|
+
return [
|
|
4326
|
+
...blended,
|
|
4327
|
+
{ key: "color", label: "Color", type: "color", value: e.color },
|
|
4328
|
+
deg("angle", "Angle", e.angle),
|
|
4329
|
+
px("distance", "Distance", e.distance),
|
|
4330
|
+
px("size", "Size", e.size),
|
|
4331
|
+
{ key: "invert", label: "Invert", type: "checkbox", value: e.invert }
|
|
4332
|
+
];
|
|
4333
|
+
case "color-overlay":
|
|
4334
|
+
return [...blended, { key: "color", label: "Color", type: "color", value: e.color }];
|
|
4335
|
+
case "gradient-overlay":
|
|
4336
|
+
return [...blended, ...gradientControls("gradient", e.gradient)];
|
|
4337
|
+
case "pattern-overlay":
|
|
4338
|
+
return [
|
|
4339
|
+
...blended,
|
|
4340
|
+
{ key: "patternId", label: "Pattern", type: "select", value: e.patternId, options: patternOptions(patterns) },
|
|
4341
|
+
pct("scale", "Scale", e.scale, 0.01, 10),
|
|
4342
|
+
deg("angle", "Angle", _nullishCoalesce(e.angle, () => ( 0))),
|
|
4343
|
+
{ key: "link", label: "Link with layer", type: "checkbox", value: _nullishCoalesce(e.link, () => ( true)) }
|
|
4344
|
+
];
|
|
4345
|
+
case "stroke":
|
|
4346
|
+
return [
|
|
4347
|
+
...blended,
|
|
4348
|
+
px("size", "Size", e.size),
|
|
4349
|
+
{ key: "position", label: "Position", type: "select", value: e.position, options: opt(["outside", "Outside"], ["inside", "Inside"], ["center", "Center"]) },
|
|
4350
|
+
...fillControls(e.fill, true, patterns)
|
|
4351
|
+
];
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
function fillOfType(current, type, patterns) {
|
|
4355
|
+
if (type === "gradient") return { type: "gradient", gradient: defaultEffectGradient() };
|
|
4356
|
+
if (type === "pattern") return { type: "pattern", patternId: _nullishCoalesce(_optionalChain([patterns, 'access', _109 => _109[0], 'optionalAccess', _110 => _110.id]), () => ( "checker")), scale: 1 };
|
|
4357
|
+
return { type: "color", color: current.type === "color" ? current.color : "#000000" };
|
|
4358
|
+
}
|
|
4359
|
+
function effectControlChange(effect, key, value, patterns = []) {
|
|
4360
|
+
const [top, ...rest] = key.split(".");
|
|
4361
|
+
if (top === "fill" && rest[0] === "type") return { fill: fillOfType(effect.fill, String(value), patterns) };
|
|
4362
|
+
if (top === "patternId" && !rest.length) {
|
|
4363
|
+
const name = _optionalChain([patternOptions, 'call', _111 => _111(patterns), 'access', _112 => _112.find, 'call', _113 => _113((o) => o.value === value), 'optionalAccess', _114 => _114.label]);
|
|
4364
|
+
return name ? { patternId: value, name } : { patternId: value };
|
|
4365
|
+
}
|
|
4366
|
+
if (!rest.length) return { [top]: value };
|
|
4367
|
+
if (top === "fill" && rest[0] === "patternId") {
|
|
4368
|
+
const name = _optionalChain([patternOptions, 'call', _115 => _115(patterns), 'access', _116 => _116.find, 'call', _117 => _117((o) => o.value === value), 'optionalAccess', _118 => _118.label]);
|
|
4369
|
+
return { fill: { ...effect.fill, patternId: value, ...name ? { name } : {} } };
|
|
4370
|
+
}
|
|
4371
|
+
return { [top]: setPath(getPath(effect, top), rest, value) };
|
|
4372
|
+
}
|
|
4373
|
+
|
|
4374
|
+
|
|
4375
|
+
|
|
4376
|
+
|
|
4377
|
+
|
|
4378
|
+
|
|
4200
4379
|
|
|
4201
4380
|
|
|
4202
4381
|
|
|
@@ -4259,4 +4438,4 @@ function compositeSurfaceOver(base, top) {
|
|
|
4259
4438
|
|
|
4260
4439
|
|
|
4261
4440
|
|
|
4262
|
-
exports.DEFAULT_GLOBAL_LIGHT = DEFAULT_GLOBAL_LIGHT; exports.LAYER_EFFECT_KINDS = LAYER_EFFECT_KINDS; exports.layerEffectLabel = layerEffectLabel; exports.isLayerEffectKind = isLayerEffectKind; exports.defaultEffectGradient = defaultEffectGradient; exports.newEffectId = newEffectId; exports.defaultLayerEffect = defaultLayerEffect; exports.hasActiveEffects = hasActiveEffects; exports.MAX_EFFECT_REACH = MAX_EFFECT_REACH; exports.effectReach = effectReach; exports.effectsMargin = effectsMargin; exports.effectsScale = effectsScale; exports.scaleLayerEffect = scaleLayerEffect; exports.parseEffectColor = parseEffectColor; exports.effectColorHex = effectColorHex; exports.LayerEffectError = LayerEffectError; exports.validateEffectGradient = validateEffectGradient; exports.layerEffectFields = layerEffectFields; exports.validateLayerEffect = validateLayerEffect; exports.mergeLayerEffect = mergeLayerEffect; exports.validateLayerEffects = validateLayerEffects; exports.normalizeLayerEffects = normalizeLayerEffects; exports.effectsFingerprint = effectsFingerprint; exports.PatternTile = PatternTile; exports.PatternPlacement = PatternPlacement; exports.builtinPatternIds = builtinPatternIds; exports.builtinPattern = builtinPattern; exports.hashNoise = hashNoise; exports.CURVE_LUT_SIZE = CURVE_LUT_SIZE; exports.curveLut = curveLut; exports.STROKE_CHAMFER_MAX = STROKE_CHAMFER_MAX; exports.contourLut = contourLut; exports.activeEffectItems = activeEffectItems; exports.effectsAreLocal = effectsAreLocal; exports.buildEffectMaps = buildEffectMaps; exports.patchEffectMaps = patchEffectMaps; exports.gradientT = gradientT; exports.effectFillColors = effectFillColors; exports.compositeLayerEffects = compositeLayerEffects; exports.renderLayerEffects = renderLayerEffects; exports.applyEdgeAmbient = applyEdgeAmbient; exports.blendTile = blendTile; exports.RasterCompositor = RasterCompositor; exports.changedTiles = changedTiles; exports.DeepCompositor = DeepCompositor; exports.workingToSamples = workingToSamples; exports.flattenLayers = flattenLayers; exports.findLayer = findLayer; exports.mapLayer = mapLayer; exports.insertLayer = insertLayer; exports.isLayerLocked = isLayerLocked; exports.INTERPOLATIONS = INTERPOLATIONS; exports.isInterpolation = isInterpolation; exports.MAX_TRANSFORM_PIXELS = MAX_TRANSFORM_PIXELS; exports.TransformTooLargeError = TransformTooLargeError; exports.keysWeight = keysWeight; exports.reduceSurface = reduceSurface; exports.transformedBounds = transformedBounds; exports.transformSurface = transformSurface; exports.warpSurface = warpSurface; exports.compositeSurfaceOver = compositeSurfaceOver;
|
|
4441
|
+
exports.DEFAULT_GLOBAL_LIGHT = DEFAULT_GLOBAL_LIGHT; exports.LAYER_EFFECT_KINDS = LAYER_EFFECT_KINDS; exports.layerEffectLabel = layerEffectLabel; exports.isLayerEffectKind = isLayerEffectKind; exports.defaultEffectGradient = defaultEffectGradient; exports.newEffectId = newEffectId; exports.defaultLayerEffect = defaultLayerEffect; exports.hasActiveEffects = hasActiveEffects; exports.MAX_EFFECT_REACH = MAX_EFFECT_REACH; exports.effectReach = effectReach; exports.effectsMargin = effectsMargin; exports.effectsScale = effectsScale; exports.scaleLayerEffect = scaleLayerEffect; exports.parseEffectColor = parseEffectColor; exports.effectColorHex = effectColorHex; exports.LayerEffectError = LayerEffectError; exports.validateEffectGradient = validateEffectGradient; exports.layerEffectFields = layerEffectFields; exports.validateLayerEffect = validateLayerEffect; exports.mergeLayerEffect = mergeLayerEffect; exports.validateLayerEffects = validateLayerEffects; exports.normalizeLayerEffects = normalizeLayerEffects; exports.effectsFingerprint = effectsFingerprint; exports.PatternTile = PatternTile; exports.PatternPlacement = PatternPlacement; exports.builtinPatternIds = builtinPatternIds; exports.builtinPattern = builtinPattern; exports.hashNoise = hashNoise; exports.CURVE_LUT_SIZE = CURVE_LUT_SIZE; exports.curveLut = curveLut; exports.STROKE_CHAMFER_MAX = STROKE_CHAMFER_MAX; exports.contourLut = contourLut; exports.activeEffectItems = activeEffectItems; exports.effectsAreLocal = effectsAreLocal; exports.buildEffectMaps = buildEffectMaps; exports.patchEffectMaps = patchEffectMaps; exports.gradientT = gradientT; exports.effectFillColors = effectFillColors; exports.compositeLayerEffects = compositeLayerEffects; exports.renderLayerEffects = renderLayerEffects; exports.applyEdgeAmbient = applyEdgeAmbient; exports.blendTile = blendTile; exports.RasterCompositor = RasterCompositor; exports.changedTiles = changedTiles; exports.DeepCompositor = DeepCompositor; exports.workingToSamples = workingToSamples; exports.flattenLayers = flattenLayers; exports.findLayer = findLayer; exports.mapLayer = mapLayer; exports.insertLayer = insertLayer; exports.isLayerLocked = isLayerLocked; exports.INTERPOLATIONS = INTERPOLATIONS; exports.isInterpolation = isInterpolation; exports.MAX_TRANSFORM_PIXELS = MAX_TRANSFORM_PIXELS; exports.TransformTooLargeError = TransformTooLargeError; exports.keysWeight = keysWeight; exports.reduceSurface = reduceSurface; exports.transformedBounds = transformedBounds; exports.transformSurface = transformSurface; exports.warpSurface = warpSurface; exports.compositeSurfaceOver = compositeSurfaceOver; exports.layerEffectsPanel = layerEffectsPanel; exports.layerEffectsBadge = layerEffectsBadge; exports.LAYER_EFFECT_MENU = LAYER_EFFECT_MENU; exports.layerEffectControls = layerEffectControls; exports.effectControlChange = effectControlChange;
|
|
@@ -15,12 +15,12 @@ var _chunkAVTPZO4Zcjs = require('./chunk-AVTPZO4Z.cjs');
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var _chunkTZOX7KWVcjs = require('./chunk-TZOX7KWV.cjs');
|
|
19
19
|
|
|
20
20
|
// src/brushes/patch.ts
|
|
21
21
|
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22
22
|
var copy = (v) => JSON.parse(JSON.stringify(v));
|
|
23
|
-
var FACETS =
|
|
23
|
+
var FACETS = _chunkTZOX7KWVcjs.BRUSH_JSON_SCHEMA.properties;
|
|
24
24
|
var BRUSH_PATCH_PROPERTIES = (() => {
|
|
25
25
|
const { id: _id, name: _name, ...rest } = FACETS;
|
|
26
26
|
const { required: _r, ...tip } = rest.tip;
|
|
@@ -52,17 +52,17 @@ function changedBrushPaths(a, b, path = "") {
|
|
|
52
52
|
// src/brushes/tools.ts
|
|
53
53
|
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
54
54
|
var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
55
|
-
var FACETS2 =
|
|
55
|
+
var FACETS2 = _chunkTZOX7KWVcjs.BRUSH_JSON_SCHEMA.properties;
|
|
56
56
|
var ID = { type: "string", pattern: String(FACETS2.id.pattern), description: "Brush id from list_brush_presets (lowercase letters, digits and dashes)." };
|
|
57
57
|
var FACET_PROPS = BRUSH_PATCH_PROPERTIES;
|
|
58
|
-
var HOSTS = Object.keys(
|
|
58
|
+
var HOSTS = Object.keys(_chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES);
|
|
59
59
|
var copy2 = (v) => JSON.parse(JSON.stringify(v));
|
|
60
60
|
var merge = mergeBrushPatch;
|
|
61
61
|
var changedPaths = changedBrushPaths;
|
|
62
62
|
function summary(entry, profile, withCheck) {
|
|
63
63
|
const b = entry.brush;
|
|
64
|
-
const engine =
|
|
65
|
-
const check = withCheck ?
|
|
64
|
+
const engine = _chunkTZOX7KWVcjs.resolveEngine.call(void 0, b);
|
|
65
|
+
const check = withCheck ? _chunkTZOX7KWVcjs.checkBrush.call(void 0, b, profile) : null;
|
|
66
66
|
return {
|
|
67
67
|
id: b.id,
|
|
68
68
|
name: b.name,
|
|
@@ -71,7 +71,7 @@ function summary(entry, profile, withCheck) {
|
|
|
71
71
|
...b.medium ? { medium: b.medium } : {},
|
|
72
72
|
...b.variety ? { variety: b.variety } : {},
|
|
73
73
|
...b.tool ? { tool: b.tool } : {},
|
|
74
|
-
category:
|
|
74
|
+
category: _chunkTZOX7KWVcjs.resolveCategory.call(void 0, b, engine),
|
|
75
75
|
engine,
|
|
76
76
|
tip: b.tip.shape,
|
|
77
77
|
...b.tip.size !== void 0 ? { size: b.tip.size } : {},
|
|
@@ -85,21 +85,21 @@ function summary(entry, profile, withCheck) {
|
|
|
85
85
|
var refusal = (check, host) => `${host.name} can't use this brush: ${check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`).join(" ")} (check_brush lists every issue; nothing was saved.)`;
|
|
86
86
|
var warnings = (check) => check.issues.filter((i) => i.severity === "warning");
|
|
87
87
|
function createBrushLibraryTools(library, options = {}) {
|
|
88
|
-
const profile = _nullishCoalesce(options.profile, () => (
|
|
88
|
+
const profile = _nullishCoalesce(options.profile, () => ( _chunkTZOX7KWVcjs.PAINT_PROFILE));
|
|
89
89
|
const hostOf = (id) => {
|
|
90
90
|
if (id === void 0) return profile;
|
|
91
|
-
const p =
|
|
92
|
-
if (!p) throw new (0,
|
|
91
|
+
const p = _chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES[id];
|
|
92
|
+
if (!p) throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("invalid", `No host "${id}"; use one of: ${HOSTS.join(", ")}.`);
|
|
93
93
|
return p;
|
|
94
94
|
};
|
|
95
95
|
const entry = async (id) => {
|
|
96
96
|
const found = await library.get(id);
|
|
97
97
|
if (found) return found;
|
|
98
98
|
const ids = (await library.list()).map((e) => e.brush.id);
|
|
99
|
-
throw new (0,
|
|
99
|
+
throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("unknown_brush", `No brush "${id}". ${_chunkTZOX7KWVcjs.closest.call(void 0, id, ids)}list_brush_presets lists them.`);
|
|
100
100
|
};
|
|
101
101
|
const checkFor = async (brush, p) => {
|
|
102
|
-
const check2 =
|
|
102
|
+
const check2 = _chunkTZOX7KWVcjs.checkBrush.call(void 0, brush, p);
|
|
103
103
|
const provider = _optionalChain([options, 'access', _9 => _9.stickers, 'optionalCall', _10 => _10()]);
|
|
104
104
|
if (!provider || brush.tip.shape !== "stamp") return check2;
|
|
105
105
|
const issues = [...check2.issues];
|
|
@@ -117,12 +117,12 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
117
117
|
const problems = [];
|
|
118
118
|
let brush;
|
|
119
119
|
try {
|
|
120
|
-
brush =
|
|
120
|
+
brush = _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, raw, problems);
|
|
121
121
|
} catch (e) {
|
|
122
|
-
throw new (0,
|
|
122
|
+
throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("invalid", e.message);
|
|
123
123
|
}
|
|
124
124
|
const check2 = await checkFor(brush, profile);
|
|
125
|
-
if (!check2.ok) throw new (0,
|
|
125
|
+
if (!check2.ok) throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("invalid", refusal(check2, profile));
|
|
126
126
|
const saved = await library.save(brush, { overwrite });
|
|
127
127
|
return { ...saved, problems, check: check2 };
|
|
128
128
|
};
|
|
@@ -133,10 +133,10 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
133
133
|
inputSchema: {
|
|
134
134
|
type: "object",
|
|
135
135
|
properties: {
|
|
136
|
-
kind: { type: "string", enum: [...
|
|
137
|
-
medium: { type: "string", enum: [...
|
|
136
|
+
kind: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_KINDS], description: "mark (lays a material) or tool (works on paint already down)." },
|
|
137
|
+
medium: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_MEDIA], description: "Marks laying this medium." },
|
|
138
138
|
variety: { type: "string", maxLength: 40, description: "This variety (oil, watercolor, pencil, highlighter\u2026)." },
|
|
139
|
-
tool: { type: "string", enum: [...
|
|
139
|
+
tool: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_TOOLS], description: "Tools that do this." },
|
|
140
140
|
tag: { type: "string", maxLength: 40, description: "Brushes with this tag." },
|
|
141
141
|
text: { type: "string", maxLength: 200, description: "Words in the id, name, description, variety or tags (each word must match the start of one)." },
|
|
142
142
|
source: { type: "string", enum: ["all", "builtin", "user"], description: "all (default), builtin presets only, or user (saved) brushes only." },
|
|
@@ -163,8 +163,8 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
163
163
|
annotations: { title: "Describe a brush", ...READ },
|
|
164
164
|
handler: async ({ id }) => {
|
|
165
165
|
const e = await entry(id);
|
|
166
|
-
const engine =
|
|
167
|
-
return { brush: e.brush, builtin: e.builtin, engine, category:
|
|
166
|
+
const engine = _chunkTZOX7KWVcjs.resolveEngine.call(void 0, e.brush);
|
|
167
|
+
return { brush: e.brush, builtin: e.builtin, engine, category: _chunkTZOX7KWVcjs.resolveCategory.call(void 0, e.brush, engine), check: await checkFor(e.brush, profile) };
|
|
168
168
|
}
|
|
169
169
|
};
|
|
170
170
|
const check = {
|
|
@@ -182,20 +182,20 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
182
182
|
},
|
|
183
183
|
annotations: { title: "Check a brush for a host", ...READ },
|
|
184
184
|
handler: async ({ id, brush, host }) => {
|
|
185
|
-
if (id === void 0 === (brush === void 0)) throw new (0,
|
|
185
|
+
if (id === void 0 === (brush === void 0)) throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("invalid", "Give either id (a library brush) or brush (a spec), not both or neither.");
|
|
186
186
|
const p = hostOf(host);
|
|
187
187
|
let b;
|
|
188
188
|
const problems = [];
|
|
189
189
|
if (id !== void 0) b = (await entry(id)).brush;
|
|
190
190
|
else {
|
|
191
191
|
try {
|
|
192
|
-
b =
|
|
192
|
+
b = _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, brush, problems);
|
|
193
193
|
} catch (e) {
|
|
194
|
-
throw new (0,
|
|
194
|
+
throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("invalid", e.message);
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
const result = await checkFor(b, p);
|
|
198
|
-
return { host: p.id, ...result, ...problems.length ? { problems } : {}, ...!result.ok ? { degraded:
|
|
198
|
+
return { host: p.id, ...result, ...problems.length ? { problems } : {}, ...!result.ok ? { degraded: _chunkTZOX7KWVcjs.degrade.call(void 0, b, p) } : {} };
|
|
199
199
|
}
|
|
200
200
|
};
|
|
201
201
|
const exportTool = {
|
|
@@ -254,12 +254,12 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
254
254
|
},
|
|
255
255
|
annotations: { title: "Save a new brush", ...WRITE },
|
|
256
256
|
handler: async ({ basedOn, ...spec }) => {
|
|
257
|
-
if (library.isBuiltin(spec.id)) throw new (0,
|
|
258
|
-
if (await library.get(spec.id)) throw new (0,
|
|
257
|
+
if (library.isBuiltin(spec.id)) throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("builtin", `"${spec.id}" is a built-in brush id; pick another id (or basedOn "${spec.id}" with a new id).`);
|
|
258
|
+
if (await library.get(spec.id)) throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("exists", `A brush "${spec.id}" exists already; pick another id, or change it with update_brush.`);
|
|
259
259
|
const base = basedOn !== void 0 ? (await entry(basedOn)).brush : void 0;
|
|
260
260
|
const raw = base ? merge(base, spec) : spec;
|
|
261
261
|
const saved = await store(raw, false);
|
|
262
|
-
return { id: saved.brush.id, brush: saved.brush, engine:
|
|
262
|
+
return { id: saved.brush.id, brush: saved.brush, engine: _chunkTZOX7KWVcjs.resolveEngine.call(void 0, saved.brush), problems: saved.problems, warnings: warnings(saved.check) };
|
|
263
263
|
}
|
|
264
264
|
},
|
|
265
265
|
{
|
|
@@ -280,7 +280,7 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
280
280
|
annotations: { title: "Update a brush", ...WRITE, idempotentHint: true },
|
|
281
281
|
handler: async ({ id, unset, ...patch }) => {
|
|
282
282
|
const e = await entry(id);
|
|
283
|
-
if (e.builtin) throw new (0,
|
|
283
|
+
if (e.builtin) throw new (0, _chunkTZOX7KWVcjs.BrushLibraryError)("builtin", `"${id}" is a built-in brush and can't be changed; duplicate_brush makes a copy you can change.`);
|
|
284
284
|
const base = copy2(e.brush);
|
|
285
285
|
for (const k of _nullishCoalesce(unset, () => ( []))) delete base[k];
|
|
286
286
|
const saved = await store(merge(base, { ...patch, id }), true);
|
|
@@ -339,7 +339,7 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
339
339
|
return tools;
|
|
340
340
|
}
|
|
341
341
|
function createBrushLibraryToolProvider(library, options = {}) {
|
|
342
|
-
const profile = _nullishCoalesce(options.profile, () => (
|
|
342
|
+
const profile = _nullishCoalesce(options.profile, () => ( _chunkTZOX7KWVcjs.PAINT_PROFILE));
|
|
343
343
|
const tools = createBrushLibraryTools(library, options);
|
|
344
344
|
return {
|
|
345
345
|
id: _nullishCoalesce(options.id, () => ( "brushes")),
|
|
@@ -337,7 +337,7 @@ function createDrawCommands(target, options = {}) {
|
|
|
337
337
|
description: "Stroke points as [x, y] pairs in canvas (flow) units, in drawing order. Use a point every few units along curves."
|
|
338
338
|
},
|
|
339
339
|
tool: { type: "string", enum: ["pen", "highlighter"], description: "Pen (default: blue, width 3) or highlighter (yellow, width 24, opacity 0.35); sets the defaults below." },
|
|
340
|
-
color: { type: "string", description: "Stroke colour, any CSS colour (default
|
|
340
|
+
color: { type: "string", description: "Stroke colour, any CSS colour (default: the brush's default colour, such as the ballpoint's blue, else the tool's)." },
|
|
341
341
|
width: { type: "number", exclusiveMinimum: 0, maximum: 2500, description: "Stroke width in canvas units (default from the tool). For brushed strokes it is the brush diameter; leave it out to use the preset's own size (canvas.listBrushes gives it)." },
|
|
342
342
|
opacity: { type: "number", minimum: 0, maximum: 1, description: "Stroke opacity 0..1 (default from the tool)." },
|
|
343
343
|
brush: {
|
|
@@ -420,7 +420,7 @@ var gestureBoxes = (what) => ({
|
|
|
420
420
|
});
|
|
421
421
|
var GESTURE_STYLE_PARAMS = {
|
|
422
422
|
tool: { type: "string", enum: ["pen", "highlighter"], description: "Pen (default: blue, width 3) or highlighter (yellow, width 24, opacity 0.35); sets the defaults below." },
|
|
423
|
-
color: { type: "string", description: "Stroke colour, any CSS colour (default
|
|
423
|
+
color: { type: "string", description: "Stroke colour, any CSS colour (default: the brush's default colour, such as the ballpoint's blue, else the tool's)." },
|
|
424
424
|
width: { type: "number", exclusiveMinimum: 0, maximum: 2500, description: "Stroke width in canvas units (default from the tool; with a brush, the preset's own size)." },
|
|
425
425
|
opacity: { type: "number", minimum: 0, maximum: 1, description: "Stroke opacity 0..1 (default from the tool)." },
|
|
426
426
|
brush: {
|
|
@@ -1692,13 +1692,13 @@ function normalizeBrushSpec(raw, problems = []) {
|
|
|
1692
1692
|
}
|
|
1693
1693
|
if (_optionalChain([brush, 'access', _26 => _26.marks, 'optionalAccess', _27 => _27.kind]) === "scatter") {
|
|
1694
1694
|
const surface = _optionalChain([brush, 'access', _28 => _28.behaviour, 'optionalAccess', _29 => _29.surface]);
|
|
1695
|
-
const why = brush.tip.shape === "bristle" ? "bristle tips lay their own marks" : surface === "wet" || surface === "thick" ? `${surface} paint is not sprayed` : _optionalChain([brush, 'access', _30 => _30.behaviour, 'optionalAccess', _31 => _31.exchange]) ? "
|
|
1695
|
+
const why = brush.tip.shape === "bristle" ? "bristle tips lay their own marks" : surface === "wet" || surface === "thick" ? `${surface} paint is not sprayed` : _optionalChain([brush, 'access', _30 => _30.behaviour, 'optionalAccess', _31 => _31.exchange, 'optionalAccess', _32 => _32.reservoir]) ? "the Mixer Brush is not sprayed" : null;
|
|
1696
1696
|
if (why) {
|
|
1697
1697
|
drop("marks", why);
|
|
1698
1698
|
delete brush.marks;
|
|
1699
1699
|
}
|
|
1700
1700
|
}
|
|
1701
|
-
if (_optionalChain([brush, 'access',
|
|
1701
|
+
if (_optionalChain([brush, 'access', _33 => _33.marks, 'optionalAccess', _34 => _34.kind]) === "objects" && brush.tip.shape !== "stamp") {
|
|
1702
1702
|
problems.push("marks objects lay stamps: tip.shape set to stamp.");
|
|
1703
1703
|
brush.tip.shape = "stamp";
|
|
1704
1704
|
}
|
|
@@ -1748,7 +1748,7 @@ function normalizeBrushSpec(raw, problems = []) {
|
|
|
1748
1748
|
if (b.exchange && kind === "tool" && !wetTool) {
|
|
1749
1749
|
drop("behaviour.exchange", `the ${brush.tool} does not pick paint up`);
|
|
1750
1750
|
delete b.exchange;
|
|
1751
|
-
} else if (b.exchange && (_optionalChain([brush, 'access',
|
|
1751
|
+
} else if (b.exchange && (_optionalChain([brush, 'access', _35 => _35.marks, 'optionalAccess', _36 => _36.kind]) === "particles" || _optionalChain([brush, 'access', _37 => _37.marks, 'optionalAccess', _38 => _38.kind]) === "objects" || brush.tip.shape === "bristle")) {
|
|
1752
1752
|
drop("behaviour.exchange", "particle, object and bristle marks do not pick paint up");
|
|
1753
1753
|
delete b.exchange;
|
|
1754
1754
|
}
|
|
@@ -2582,26 +2582,26 @@ function checkBrush(brush, profile) {
|
|
|
2582
2582
|
add("tool", "error", `${host} has no ${brush.tool} tool.`, profile.tools.length ? `Use one of: ${list(profile.tools)}.` : `${host} has no tools; use a mark brush.`);
|
|
2583
2583
|
}
|
|
2584
2584
|
if (!profile.tipShapes.includes(brush.tip.shape)) add("tip.shape", "error", `${host} can't lay a ${brush.tip.shape} tip.`, `Set tip.shape to one of: ${list(profile.tipShapes)}.`);
|
|
2585
|
-
const marks = _nullishCoalesce(_optionalChain([brush, 'access',
|
|
2585
|
+
const marks = _nullishCoalesce(_optionalChain([brush, 'access', _39 => _39.marks, 'optionalAccess', _40 => _40.kind]), () => ( "continuous"));
|
|
2586
2586
|
if (!profile.marks.includes(marks)) add("marks", "error", `${host} can't lay ${marks} marks.`, `Use marks ${list(profile.marks)} (remove marks for continuous dabs).`);
|
|
2587
|
-
const surface = _nullishCoalesce(_optionalChain([brush, 'access',
|
|
2587
|
+
const surface = _nullishCoalesce(_optionalChain([brush, 'access', _41 => _41.behaviour, 'optionalAccess', _42 => _42.surface]), () => ( "dry"));
|
|
2588
2588
|
if (brush.kind === "mark" && !profile.surfaces.includes(surface)) add("behaviour.surface", "error", `${host} has no ${surface} surface.`, `Set behaviour.surface to ${list(profile.surfaces)}.`);
|
|
2589
|
-
const ex = _optionalChain([brush, 'access',
|
|
2590
|
-
feature(profile.reservoir, !!_optionalChain([ex, 'optionalAccess',
|
|
2591
|
-
feature(profile.exchange, !_optionalChain([ex, 'optionalAccess',
|
|
2592
|
-
feature(profile.grain, nonZero(_optionalChain([brush, 'access',
|
|
2593
|
-
feature(profile.light, nonZero(_optionalChain([brush, 'access',
|
|
2589
|
+
const ex = _optionalChain([brush, 'access', _43 => _43.behaviour, 'optionalAccess', _44 => _44.exchange]);
|
|
2590
|
+
feature(profile.reservoir, !!_optionalChain([ex, 'optionalAccess', _45 => _45.reservoir]), "behaviour.exchange.reservoir", "a Mixer Brush reservoir", "Remove behaviour.exchange.reservoir.");
|
|
2591
|
+
feature(profile.exchange, !_optionalChain([ex, 'optionalAccess', _46 => _46.reservoir]) && (nonZero(_optionalChain([ex, 'optionalAccess', _47 => _47.pickup])) || !!_optionalChain([ex, 'optionalAccess', _48 => _48.dirty])), "behaviour.exchange", "picking paint up", "Remove behaviour.exchange.");
|
|
2592
|
+
feature(profile.grain, nonZero(_optionalChain([brush, 'access', _49 => _49.behaviour, 'optionalAccess', _50 => _50.grain])), "behaviour.grain", "paper grain", "Set behaviour.grain to 0.");
|
|
2593
|
+
feature(profile.light, nonZero(_optionalChain([brush, 'access', _51 => _51.light, 'optionalAccess', _52 => _52.amount])), "light", "light paint (glow and spill)", "Remove light (or set light.amount to 0).");
|
|
2594
2594
|
const m = brush.motion;
|
|
2595
2595
|
feature(profile.motion, !!m && (!!m.live || nonZero(m.waveSpeed) || m.fps !== void 0), "motion", "animation", "Remove motion.");
|
|
2596
2596
|
const d = _nullishCoalesce(brush.dynamics, () => ( {}));
|
|
2597
2597
|
feature(profile.velocity, nonZero(d.velocitySize) || nonZero(d.velocityOpacity), "dynamics.velocity", "velocity dynamics (its strokes carry no timing)", "Set dynamics.velocitySize and velocityOpacity to 0.");
|
|
2598
2598
|
feature(profile.tilt, nonZero(d.tiltSize) || nonZero(d.tiltRoundness) || nonZero(d.tiltOpacity), "dynamics.tilt", "tilt dynamics", "Set dynamics.tiltSize, tiltRoundness and tiltOpacity to 0.");
|
|
2599
2599
|
const colour = brush.colour;
|
|
2600
|
-
if (_optionalChain([colour, 'optionalAccess',
|
|
2600
|
+
if (_optionalChain([colour, 'optionalAccess', _53 => _53.default]) !== void 0) {
|
|
2601
2601
|
const kind = brushColourKind(colour.default);
|
|
2602
2602
|
if (!profile.colours.includes(kind)) add("colour.default", "error", `${host} can't paint ${kind} colours.`, `Use a ${list(profile.colours)} colour, or remove colour.default.`);
|
|
2603
2603
|
}
|
|
2604
|
-
const foreign = [...new Set((_nullishCoalesce(_optionalChain([colour, 'optionalAccess',
|
|
2604
|
+
const foreign = [...new Set((_nullishCoalesce(_optionalChain([colour, 'optionalAccess', _54 => _54.palette]), () => ( []))).map(brushColourKind).filter((k) => !profile.colours.includes(k)))];
|
|
2605
2605
|
if (foreign.length) add("colour.palette", "warning", `${host} skips the palette's ${list(foreign)} colours.`, `Nothing to do; or keep to ${list(profile.colours)} colours.`);
|
|
2606
2606
|
return { ok: !issues.some((i) => i.severity === "error"), issues };
|
|
2607
2607
|
}
|
|
@@ -2663,7 +2663,7 @@ function degrade(brush, profile) {
|
|
|
2663
2663
|
}
|
|
2664
2664
|
dropped.push(issue);
|
|
2665
2665
|
}
|
|
2666
|
-
if (_optionalChain([b, 'access',
|
|
2666
|
+
if (_optionalChain([b, 'access', _55 => _55.behaviour, 'optionalAccess', _56 => _56.exchange]) && !Object.keys(b.behaviour.exchange).length) delete b.behaviour.exchange;
|
|
2667
2667
|
const after = checkBrush(b, profile).issues.filter((i) => i.severity === "error");
|
|
2668
2668
|
return { brush: b, dropped, issues: after };
|
|
2669
2669
|
}
|
|
@@ -2693,7 +2693,7 @@ function parseBrushLibrary2(raw, problems = []) {
|
|
|
2693
2693
|
if (file && file.version !== void 0 && file.version !== 1 && file.version !== 2) {
|
|
2694
2694
|
throw new BrushLibraryError("invalid", `Brush library version ${JSON.stringify(file.version)} is not supported; this library reads versions 1 and 2.`);
|
|
2695
2695
|
}
|
|
2696
|
-
const v1File = _optionalChain([file, 'optionalAccess',
|
|
2696
|
+
const v1File = _optionalChain([file, 'optionalAccess', _57 => _57.version]) === 1;
|
|
2697
2697
|
const out = [];
|
|
2698
2698
|
items.forEach((item, i) => {
|
|
2699
2699
|
const at = `brushes[${i}]`;
|
|
@@ -2876,7 +2876,7 @@ function snapshotBrushLibrary(library, onChange) {
|
|
|
2876
2876
|
(list2) => {
|
|
2877
2877
|
entries = list2;
|
|
2878
2878
|
user = list2.filter((e) => !e.builtin).map((e) => e.brush);
|
|
2879
|
-
_optionalChain([onChange, 'optionalCall',
|
|
2879
|
+
_optionalChain([onChange, 'optionalCall', _58 => _58()]);
|
|
2880
2880
|
},
|
|
2881
2881
|
() => void 0
|
|
2882
2882
|
);
|
|
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
|
|
|
74
74
|
var round3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
75
75
|
var loading = null;
|
|
76
76
|
function loadCanvasBrushstrokeRenderer() {
|
|
77
|
-
loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-
|
|
77
|
+
loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-N6UPZSQS.cjs"))).catch((error) => {
|
|
78
78
|
loading = null;
|
|
79
79
|
throw error;
|
|
80
80
|
});
|