@pixerate/editor 0.275.0 → 0.276.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 +62 -62
- package/dist/animation-editor/index.js +6 -6
- package/dist/brushes/index.cjs +81 -70
- package/dist/brushes/index.js +17 -6
- package/dist/brushes/patch.d.cts +1 -1
- package/dist/brushes/patch.d.ts +1 -1
- package/dist/brushes/profiles.d.cts +2 -0
- package/dist/brushes/profiles.d.ts +2 -0
- package/dist/brushes/schema.d.cts +1 -0
- package/dist/brushes/schema.d.ts +1 -0
- package/dist/brushes/types.d.cts +22 -1
- package/dist/brushes/types.d.ts +22 -1
- package/dist/{brushstrokeRender-WGY4DZHF.js → brushstrokeRender-FK3ASUUJ.js} +5 -5
- package/dist/{brushstrokeRender-2RQL46WB.cjs → brushstrokeRender-I6MYFCOU.cjs} +21 -21
- package/dist/canvas/index.cjs +13 -13
- package/dist/canvas/index.js +1 -1
- package/dist/chart/contract.d.cts +3 -1
- package/dist/chart/contract.d.ts +3 -1
- package/dist/{chunk-Y2ISSVPH.js → chunk-4EM5NGCL.js} +167 -9
- package/dist/{chunk-Y354ETAE.cjs → chunk-5HR5CSLC.cjs} +49 -49
- package/dist/{chunk-LMG57L5A.js → chunk-CTHWXW5M.js} +121 -8
- package/dist/{chunk-43XJC3PP.js → chunk-CVBTJVRN.js} +1 -1
- package/dist/{chunk-RJGW3RQS.js → chunk-GHYJAMMS.js} +1 -1
- package/dist/{chunk-NIBFKXMD.cjs → chunk-IFWLZZCW.cjs} +619 -2
- package/dist/{chunk-G5TCMKX5.js → chunk-IJ6NSWKM.js} +2 -2
- package/dist/{chunk-C6VB7CPY.cjs → chunk-ISCAJBPQ.cjs} +1 -1
- package/dist/{chunk-W6JDUXP3.js → chunk-J23JOHPR.js} +1 -1
- package/dist/{chunk-IEEY5RJV.js → chunk-JNMNM3SL.js} +1 -1
- package/dist/{chunk-HVO6XCI4.js → chunk-JPB65KQ6.js} +1 -1
- package/dist/{chunk-ACTHSQOI.js → chunk-LDZOXESA.js} +618 -1
- package/dist/{chunk-DHC4E2DU.cjs → chunk-MITQGHN3.cjs} +121 -8
- package/dist/{chunk-STLTOISW.cjs → chunk-NPPMKMCU.cjs} +17 -17
- package/dist/{chunk-75SYKUOT.js → chunk-OS6OG7DN.js} +1 -1
- package/dist/{chunk-OLZXXAER.cjs → chunk-OY24XRYF.cjs} +408 -250
- package/dist/{chunk-6QNDGMK7.cjs → chunk-Q33V5PEF.cjs} +123 -42
- package/dist/{chunk-JDXWLCXF.cjs → chunk-QNNZA3V5.cjs} +2 -2
- package/dist/{chunk-T6KNJVBP.cjs → chunk-U26LUXCJ.cjs} +35 -35
- package/dist/{chunk-62MFUHSI.cjs → chunk-UQXULAMQ.cjs} +16 -16
- package/dist/{chunk-RAPNRK4R.cjs → chunk-X7XBEX3O.cjs} +88 -88
- package/dist/{chunk-MSWLJI4G.js → chunk-XMSH66VU.js} +2 -2
- package/dist/{chunk-ZM7IKQ4X.js → chunk-XVPQNX7O.js} +89 -8
- package/dist/{chunk-YYZC2EQO.cjs → chunk-ZIE6EJGR.cjs} +23 -23
- package/dist/image-editor/index.cjs +880 -852
- package/dist/image-editor/index.js +36 -8
- package/dist/paint/index.cjs +33 -5
- package/dist/paint/index.d.cts +1 -0
- package/dist/paint/index.d.ts +1 -0
- package/dist/paint/index.js +32 -4
- package/dist/paint/live-patterns.d.cts +149 -0
- package/dist/paint/live-patterns.d.ts +149 -0
- package/dist/paint/wet/world.d.cts +13 -0
- package/dist/paint/wet/world.d.ts +13 -0
- package/dist/paint-editor/brush-model.d.cts +7 -1
- package/dist/paint-editor/brush-model.d.ts +7 -1
- package/dist/paint-editor/controller.d.cts +52 -0
- package/dist/paint-editor/controller.d.ts +52 -0
- package/dist/paint-editor/index.cjs +850 -510
- package/dist/paint-editor/index.js +355 -15
- package/dist/paint-editor/ui.d.cts +5 -1
- package/dist/paint-editor/ui.d.ts +5 -1
- package/dist/paint-editor/wet-tools.d.cts +42 -0
- package/dist/paint-editor/wet-tools.d.ts +42 -0
- package/dist/paint-editor/wet.d.cts +22 -1
- package/dist/paint-editor/wet.d.ts +22 -1
- package/dist/vector/index.cjs +1002 -1002
- package/dist/vector/index.js +7 -7
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +1 -0
- package/skills/pixerate-paint-editor/SKILL.md +7 -1
- package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
- package/skills/pixerate-paint-editor/references/live-patterns.md +41 -0
- package/skills/pixerate-paint-watercolour/SKILL.md +8 -0
package/dist/brushes/index.cjs
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var _chunk5HR5CSLCcjs = require('../chunk-5HR5CSLC.cjs');
|
|
22
22
|
require('../chunk-PFHJS4HE.cjs');
|
|
23
23
|
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ require('../chunk-PFHJS4HE.cjs');
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
var
|
|
30
|
+
var _chunkQNNZA3V5cjs = require('../chunk-QNNZA3V5.cjs');
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
@@ -102,7 +102,7 @@ var _chunkJDXWLCXFcjs = require('../chunk-JDXWLCXF.cjs');
|
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
var
|
|
105
|
+
var _chunkQ33V5PEFcjs = require('../chunk-Q33V5PEF.cjs');
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
var _chunkRDFHWAHLcjs = require('../chunk-RDFHWAHL.cjs');
|
|
@@ -113,7 +113,8 @@ require('../chunk-U67EN7GG.cjs');
|
|
|
113
113
|
require('../chunk-WOFXZ3XU.cjs');
|
|
114
114
|
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
|
|
117
|
+
var _chunkIFWLZZCWcjs = require('../chunk-IFWLZZCW.cjs');
|
|
117
118
|
require('../chunk-3K6HWEXZ.cjs');
|
|
118
119
|
|
|
119
120
|
|
|
@@ -162,23 +163,24 @@ var ARIA = {
|
|
|
162
163
|
"behaviour.thick.applicator": "Impasto tool",
|
|
163
164
|
"light.pressure": "Light follows pressure",
|
|
164
165
|
"tip.grain.source": "Tip grain",
|
|
165
|
-
"dynamics.angleJitter": "Brush rotation jitter"
|
|
166
|
+
"dynamics.angleJitter": "Brush rotation jitter",
|
|
167
|
+
"livePatterns.pattern": "Live pattern"
|
|
166
168
|
};
|
|
167
169
|
var aria = (path, label) => _nullishCoalesce(ARIA[path], () => ( `Brush ${label.toLowerCase()}`));
|
|
168
|
-
function brushEditorSections(brush, profile =
|
|
169
|
-
const resolved =
|
|
170
|
-
const engine =
|
|
171
|
-
const fieldOf = (facet) =>
|
|
172
|
-
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(
|
|
170
|
+
function brushEditorSections(brush, profile = _chunkQ33V5PEFcjs.PAINT_PROFILE, context = {}) {
|
|
171
|
+
const resolved = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, brush);
|
|
172
|
+
const engine = _chunkQ33V5PEFcjs.resolveEngine.call(void 0, brush);
|
|
173
|
+
const fieldOf = (facet) => _chunkQ33V5PEFcjs.BRUSH_FIELDS.find((f) => f.facet === facet && f.engines.includes(engine));
|
|
174
|
+
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(_chunkQ33V5PEFcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath && f.engines.includes(engine)), () => ( _chunkQ33V5PEFcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath)))), 'optionalAccess', _ => _.facet]);
|
|
173
175
|
const value = (path) => {
|
|
174
|
-
const own =
|
|
176
|
+
const own = _chunkQ33V5PEFcjs.getPath.call(void 0, brush, path);
|
|
175
177
|
if (own !== void 0) return own;
|
|
176
178
|
const field = fieldOf(path);
|
|
177
179
|
if (!field) return void 0;
|
|
178
|
-
const v =
|
|
180
|
+
const v = _chunkQ33V5PEFcjs.getPath.call(void 0, resolved, field.engine);
|
|
179
181
|
return field.map ? field.map.toFacet(v) : v;
|
|
180
182
|
};
|
|
181
|
-
const issues =
|
|
183
|
+
const issues = _chunkQ33V5PEFcjs.checkBrush.call(void 0, brush, profile).issues;
|
|
182
184
|
const warned = new Map(issues.filter((i) => i.severity === "warning").map((i) => [i.facet, i.reason]));
|
|
183
185
|
const refused = new Set(issues.filter((i) => i.severity === "error").map((i) => i.facet));
|
|
184
186
|
const full = (s) => s === "full";
|
|
@@ -191,7 +193,7 @@ function brushEditorSections(brush, profile = _chunk6QNDGMK7cjs.PAINT_PROFILE, c
|
|
|
191
193
|
const slider = (c, path = facetOf(c.path)) => {
|
|
192
194
|
if (!path) return null;
|
|
193
195
|
const v = value(path);
|
|
194
|
-
return withNote({ kind: "slider", path, label: c.label, ariaLabel: aria(path, c.label), min: c.min, max: path === "tip.size" ? Math.min(c.max,
|
|
196
|
+
return withNote({ kind: "slider", path, label: c.label, ariaLabel: aria(path, c.label), min: c.min, max: path === "tip.size" ? Math.min(c.max, _chunkIFWLZZCWcjs.MAX_BRUSH_SIZE) : c.max, step: c.step, value: typeof v === "number" ? v : c.min });
|
|
195
197
|
};
|
|
196
198
|
const choice = (path, label, opts, fallback = _nullishCoalesce(_optionalChain([opts, 'access', _5 => _5[0], 'optionalAccess', _6 => _6.value]), () => ( ""))) => withNote({ kind: "choice", path, label, ariaLabel: aria(path, label), options: opts, value: String(_nullishCoalesce(value(path), () => ( fallback))) });
|
|
197
199
|
const toggle = (path, label) => withNote({ kind: "toggle", path, label, ariaLabel: aria(path, label), value: Boolean(value(path)) });
|
|
@@ -203,30 +205,30 @@ function brushEditorSections(brush, profile = _chunk6QNDGMK7cjs.PAINT_PROFILE, c
|
|
|
203
205
|
};
|
|
204
206
|
const isTool = brush.kind === "tool";
|
|
205
207
|
const shape = brush.tip.shape;
|
|
206
|
-
const sourceOptions = (_nullishCoalesce(context.sources, () => ( []))).map((x) => ({ value:
|
|
208
|
+
const sourceOptions = (_nullishCoalesce(context.sources, () => ( []))).map((x) => ({ value: _chunkQ33V5PEFcjs.brushSourceRef.call(void 0, x.id), label: x.name }));
|
|
207
209
|
const marks = _nullishCoalesce(_optionalChain([brush, 'access', _7 => _7.marks, 'optionalAccess', _8 => _8.kind]), () => ( "continuous"));
|
|
208
210
|
const exchangeFull = full(_optionalChain([brush, 'access', _9 => _9.behaviour, 'optionalAccess', _10 => _10.exchange, 'optionalAccess', _11 => _11.reservoir]) ? profile.reservoir : profile.exchange);
|
|
209
211
|
add("medium", "Medium", [
|
|
210
212
|
profile.kinds.length > 1 && profile.kinds.includes(brush.kind) && choice("kind", "Kind", options(profile.kinds, { mark: "Lays a material", tool: "Works on paint" })),
|
|
211
|
-
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(
|
|
213
|
+
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(_chunkQ33V5PEFcjs.BRUSH_MEDIA, MEDIUM_LABELS)], ""),
|
|
212
214
|
!isTool && withNote({ kind: "text", path: "variety", label: "Variety", ariaLabel: "Brush variety", value: _nullishCoalesce(brush.variety, () => ( "")), placeholder: "pencil, oil, highlighter\u2026" }),
|
|
213
215
|
isTool && !!brush.tool && profile.tools.includes(brush.tool) && choice("tool", "Tool", options(profile.tools, TOOL_LABELS))
|
|
214
216
|
]);
|
|
215
|
-
const engineControls =
|
|
216
|
-
const tipSliders =
|
|
217
|
+
const engineControls = _chunk5HR5CSLCcjs.brushEngineControls.call(void 0, resolved);
|
|
218
|
+
const tipSliders = _chunk5HR5CSLCcjs.BRUSH_SLIDERS.filter((c) => c.path.startsWith("tip.") && c.path !== "tip.smoothing");
|
|
217
219
|
add("shape", "Shape", [
|
|
218
220
|
!refused.has("tip.shape") && choice("tip.shape", "Tip", options(profile.tipShapes.filter((s) => !isTool || s !== "stamp"), SHAPE_LABELS)),
|
|
219
221
|
...tipSliders.map((c) => slider(c)),
|
|
220
222
|
engine === "dab" && choice("tip.blend", "Blend", _chunk2VX55NFMcjs.BLEND_MODES.map((m) => ({ value: m.id, label: m.label })), "normal"),
|
|
221
223
|
...shape === "bristle" && engineOk && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("bristle.")).map((c) => slider(c)) : [],
|
|
222
|
-
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ?
|
|
224
|
+
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ? _chunkQ33V5PEFcjs.MAX_DOT_TEXTURES : _chunkQ33V5PEFcjs.MAX_STICKER_STAMPS, options: marks === "objects" ? STAMP_OPTIONS : [...STAMP_OPTIONS, ...sourceOptions] })
|
|
223
225
|
]);
|
|
224
226
|
const dabs = DAB_ENGINES.has(engine) && engineOk && shape !== "bristle" && marks !== "particles" && marks !== "objects";
|
|
225
227
|
const grain = brush.tip.grain;
|
|
226
228
|
if (dabs && full(_nullishCoalesce(profile.tipGrain, () => ( "none")))) {
|
|
227
229
|
add("grain", "Tip grain", [
|
|
228
|
-
choice("tip.grain.source", "Texture", [{ value: "", label: "None" }, ...options(
|
|
229
|
-
!!grain && choice("tip.grain.mode", "Grain moves", options(
|
|
230
|
+
choice("tip.grain.source", "Texture", [{ value: "", label: "None" }, ...options(_chunkQ33V5PEFcjs.TIP_GRAIN_PATTERNS), ...sourceOptions], ""),
|
|
231
|
+
!!grain && choice("tip.grain.mode", "Grain moves", options(_chunkQ33V5PEFcjs.BRUSH_GRAIN_MODES, GRAIN_MODE_LABELS), "texturised"),
|
|
230
232
|
!!grain && withNote({ kind: "slider", path: "tip.grain.scale", label: "Grain scale", ariaLabel: "Brush grain scale", min: 0.1, max: 8, step: 0.05, value: _nullishCoalesce(grain.scale, () => ( 1)) }),
|
|
231
233
|
!!grain && withNote({ kind: "slider", path: "tip.grain.depth", label: "Grain depth", ariaLabel: "Brush grain depth", min: 0, max: 1, step: 0.01, value: _nullishCoalesce(grain.depth, () => ( 0.6)) }),
|
|
232
234
|
!!grain && withNote({ kind: "slider", path: "tip.grain.contrast", label: "Grain contrast", ariaLabel: "Brush grain contrast", min: 0, max: 3, step: 0.05, value: _nullishCoalesce(grain.contrast, () => ( 1)) }),
|
|
@@ -239,28 +241,28 @@ function brushEditorSections(brush, profile = _chunk6QNDGMK7cjs.PAINT_PROFILE, c
|
|
|
239
241
|
const render = value("marks.render");
|
|
240
242
|
add("marks", "Marks", [
|
|
241
243
|
choice("marks.kind", "Laid as", options(profile.marks, MARKS_LABELS), "continuous"),
|
|
242
|
-
marks === "particles" && choice("marks.physics", "Particles", options(
|
|
243
|
-
marks === "particles" && choice("marks.render", "Drawn as", options(
|
|
244
|
-
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(
|
|
245
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(
|
|
246
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(
|
|
244
|
+
marks === "particles" && choice("marks.physics", "Particles", options(_chunkQ33V5PEFcjs.PARTICLE_KINDS, PHYSICS_LABELS)),
|
|
245
|
+
marks === "particles" && choice("marks.render", "Drawn as", options(_chunkQ33V5PEFcjs.PARTICLE_RENDERS, RENDER_LABELS)),
|
|
246
|
+
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(_chunkQ33V5PEFcjs.RIBBON_PAIRS, { adjacent: "Neighbours", "first-last": "Outermost" })),
|
|
247
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(_chunkQ33V5PEFcjs.DOT_TEXTURE_ORDERS, { sequence: "In turn", random: "Random" })),
|
|
248
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(_chunkQ33V5PEFcjs.DOT_ROTATIONS, { follow: "Follow motion", random: "Random", fixed: "Tip angle" })),
|
|
247
249
|
...particles.map((c) => slider(c)),
|
|
248
250
|
...objects.map((c) => slider(c))
|
|
249
251
|
]);
|
|
250
252
|
}
|
|
251
|
-
const feel =
|
|
253
|
+
const feel = _chunk5HR5CSLCcjs.BRUSH_SLIDERS.filter((c) => ["tip.smoothing", "pressureSmoothing", "dynamics.minSize", "dynamics.tiltSize", "dynamics.velocitySize"].includes(c.path)).filter((c) => !(c.path === "dynamics.tiltSize" && !full(profile.tilt)) && !(c.path === "dynamics.velocitySize" && !full(profile.velocity)));
|
|
252
254
|
const stampDabs = dabs && shape === "stamp";
|
|
253
255
|
const jitter = (path, label, max = 1, step = 0.01) => withNote({ kind: "slider", path, label, ariaLabel: aria(path, label), min: 0, max, step, value: Number(_nullishCoalesce(value(path), () => ( 0))) });
|
|
254
256
|
add("feel", "Feel", [
|
|
255
257
|
...feel.map((c) => slider(c)),
|
|
256
258
|
toggle("dynamics.pressureSize", "Pressure \u2192 size"),
|
|
257
259
|
toggle("dynamics.pressureOpacity", "Pressure \u2192 opacity"),
|
|
258
|
-
choice("dynamics.rotation", "Rotation", options(
|
|
260
|
+
choice("dynamics.rotation", "Rotation", options(_chunkQ33V5PEFcjs.BRUSH_ROTATIONS, ROTATION_LABELS)),
|
|
259
261
|
stampDabs && full(_nullishCoalesce(profile.dabCount, () => ( "none"))) && withNote({ kind: "slider", path: "dynamics.count", label: "Count", ariaLabel: "Brush dab count", min: 1, max: 16, step: 1, value: _nullishCoalesce(_optionalChain([brush, 'access', _12 => _12.dynamics, 'optionalAccess', _13 => _13.count]), () => ( 1)) }),
|
|
260
262
|
stampDabs && jitter("dynamics.scatter", "Scatter", 4),
|
|
261
263
|
stampDabs && jitter("dynamics.angleJitter", "Rotation jitter"),
|
|
262
264
|
stampDabs && jitter("dynamics.sizeJitter", "Size jitter"),
|
|
263
|
-
stampDabs && choice("dynamics.flip", "Flip", options(
|
|
265
|
+
stampDabs && choice("dynamics.flip", "Flip", options(_chunkQ33V5PEFcjs.BRUSH_FLIPS, FLIP_LABELS), "none")
|
|
264
266
|
]);
|
|
265
267
|
const surfaces = profile.surfaces;
|
|
266
268
|
const engineSliders = (engineOk ? _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _14 => _14.sliders]), () => ( [])) : []).filter((c) => !/^(bristle|particle|sticker|iridescence)\./.test(c.path) && c.path !== "light.amount" && c.path !== "impasto.rim" && c.path !== "impasto.clarity");
|
|
@@ -268,12 +270,16 @@ function brushEditorSections(brush, profile = _chunk6QNDGMK7cjs.PAINT_PROFILE, c
|
|
|
268
270
|
add("behaviour", _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _17 => _17.title]), () => ( "Behaviour")), [
|
|
269
271
|
!isTool && surfaces.length > 1 && !refused.has("behaviour.surface") && choice("behaviour.surface", "Surface", options(surfaces, SURFACE_LABELS), "dry"),
|
|
270
272
|
full(profile.grain) && slider({ path: "grain", label: "Grain", min: 0, max: 1, step: 0.01 }, "behaviour.grain"),
|
|
271
|
-
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(
|
|
272
|
-
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(
|
|
273
|
+
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(_chunkQ33V5PEFcjs.WET_MEDIA, WET_MEDIUM_LABELS), "watercolor"),
|
|
274
|
+
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(_chunkQ33V5PEFcjs.IMPASTO_TOOLS, APPLICATOR_LABELS), "brush"),
|
|
273
275
|
...engineSliders.map((c) => exchangeOk(facetOf(c.path)) ? slider(c) : null),
|
|
274
276
|
engineOk && _optionalChain([engineControls, 'optionalAccess', _18 => _18.mixingPath]) && (engine === "wet" || exchangeFull) && fieldOf("behaviour.mixing") && choice("behaviour.mixing", "Mixing", options(["pigment", "rgb"], { pigment: "Pigment", rgb: "RGB" })),
|
|
275
277
|
engineOk && _optionalChain([engineControls, 'optionalAccess', _19 => _19.dirty]) && exchangeFull && fieldOf("behaviour.exchange.dirty") && toggle("behaviour.exchange.dirty", "Dirty brush"),
|
|
276
|
-
engine === "mixer" && engineOk && full(profile.reservoir) && toggle("behaviour.exchange.reservoir.refill", "Load each stroke")
|
|
278
|
+
engine === "mixer" && engineOk && full(profile.reservoir) && toggle("behaviour.exchange.reservoir.refill", "Load each stroke"),
|
|
279
|
+
engine === "wet" && engineOk && !isTool && full(_nullishCoalesce(profile.livePatterns, () => ( "none"))) && choice("livePatterns.pattern", "Live pattern", [{ value: "", label: "None" }, ...options(_chunkIFWLZZCWcjs.LIVE_PATTERN_KINDS)], ""),
|
|
280
|
+
engine === "wet" && engineOk && !isTool && full(_nullishCoalesce(profile.livePatterns, () => ( "none"))) && !!brush.livePatterns && withNote({ kind: "slider", path: "livePatterns.scale", label: "Pattern scale", ariaLabel: "Brush pattern scale", min: 0.5, max: 4, step: 0.1, value: _nullishCoalesce(brush.livePatterns.scale, () => ( 1)) }),
|
|
281
|
+
engine === "wet" && engineOk && !isTool && full(_nullishCoalesce(profile.livePatterns, () => ( "none"))) && !!brush.livePatterns && withNote({ kind: "slider", path: "livePatterns.contrast", label: "Pattern contrast", ariaLabel: "Brush pattern contrast", min: 0, max: 2, step: 0.05, value: _nullishCoalesce(brush.livePatterns.contrast, () => ( 1)) }),
|
|
282
|
+
engine === "wet" && engineOk && !isTool && full(_nullishCoalesce(profile.livePatterns, () => ( "none"))) && !!brush.livePatterns && withNote({ kind: "slider", path: "livePatterns.relief", label: "Pattern relief", ariaLabel: "Brush pattern relief", min: 0, max: 1, step: 0.05, value: _nullishCoalesce(brush.livePatterns.relief, () => ( 0)) })
|
|
277
283
|
]);
|
|
278
284
|
if (!isTool && full(profile.light) && engineOk && _optionalChain([engineControls, 'optionalAccess', _20 => _20.light])) {
|
|
279
285
|
add("light", "Light", [
|
|
@@ -307,7 +313,7 @@ function brushEditorSections(brush, profile = _chunk6QNDGMK7cjs.PAINT_PROFILE, c
|
|
|
307
313
|
label: "Palette",
|
|
308
314
|
ariaLabel: "Brush palette",
|
|
309
315
|
value: (_nullishCoalesce(_optionalChain([brush, 'access', _32 => _32.colour, 'optionalAccess', _33 => _33.palette]), () => ( []))).flatMap((c) => _chunkMLLTWAXHcjs.isDualColor.call(void 0, c) ? [{ light: _chunkJBZRVLXVcjs.brushColourHex.call(void 0, c, "light"), dark: _chunkJBZRVLXVcjs.brushColourHex.call(void 0, c, "dark") }] : hex(c) ? [hex(c)] : []),
|
|
310
|
-
max:
|
|
316
|
+
max: _chunkQ33V5PEFcjs.MAX_BRUSH_PALETTE
|
|
311
317
|
}),
|
|
312
318
|
toggle("colour.own", "Always its own colour")
|
|
313
319
|
]);
|
|
@@ -338,6 +344,8 @@ function hiddenLabel(issue, b) {
|
|
|
338
344
|
return "several dabs per step";
|
|
339
345
|
case "light":
|
|
340
346
|
return "light";
|
|
347
|
+
case "livePatterns":
|
|
348
|
+
return "live patterns";
|
|
341
349
|
case "fluorescence":
|
|
342
350
|
return "UV-fluorescent ink";
|
|
343
351
|
case "thermochromic":
|
|
@@ -355,15 +363,15 @@ function hiddenLabel(issue, b) {
|
|
|
355
363
|
case "dynamics.tilt":
|
|
356
364
|
return "tilt dynamics";
|
|
357
365
|
case "colour.default":
|
|
358
|
-
return `a ${
|
|
366
|
+
return `a ${_chunkQ33V5PEFcjs.brushColourKind.call(void 0, b.colour.default)} default colour`;
|
|
359
367
|
default:
|
|
360
368
|
return null;
|
|
361
369
|
}
|
|
362
370
|
}
|
|
363
371
|
var sentence = (words) => words.length < 2 ? _nullishCoalesce(words[0], () => ( "")) : `${words.slice(0, -1).join(", ")} and ${words.at(-1)}`;
|
|
364
|
-
function brushEditorScope(brush, profile =
|
|
372
|
+
function brushEditorScope(brush, profile = _chunkQ33V5PEFcjs.PAINT_PROFILE) {
|
|
365
373
|
const hidden = [];
|
|
366
|
-
for (const issue of
|
|
374
|
+
for (const issue of _chunkQ33V5PEFcjs.checkBrush.call(void 0, brush, profile).issues) {
|
|
367
375
|
const label = hiddenLabel(issue, brush);
|
|
368
376
|
if (label && !hidden.some((h) => h.label === label)) hidden.push({ facet: issue.facet, label });
|
|
369
377
|
}
|
|
@@ -376,17 +384,17 @@ function newBrushFor(profile, from, name = "New brush") {
|
|
|
376
384
|
const id = brushIdFromName(name);
|
|
377
385
|
const base = { id, name, kind: profile.kinds.includes("mark") ? "mark" : profile.kinds[0], ...profile.kinds.includes("mark") ? {} : { tool: profile.tools[0] }, tip: { shape: profile.tipShapes.includes("round") ? "round" : profile.tipShapes[0] } };
|
|
378
386
|
if (from) {
|
|
379
|
-
const stripped =
|
|
387
|
+
const stripped = _chunkQ33V5PEFcjs.degrade.call(void 0, from, profile, { ignored: true });
|
|
380
388
|
if (!stripped.issues.length) return { ...stripped.brush, id, name };
|
|
381
389
|
}
|
|
382
390
|
return base;
|
|
383
391
|
}
|
|
384
392
|
async function saveBrushEdit(library, options2) {
|
|
385
393
|
const { original, profile } = options2;
|
|
386
|
-
const check =
|
|
394
|
+
const check = _chunkQ33V5PEFcjs.checkBrushEdit.call(void 0, original, options2.brush, profile);
|
|
387
395
|
if (!check.ok) {
|
|
388
396
|
const errors = check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`);
|
|
389
|
-
throw new (0,
|
|
397
|
+
throw new (0, _chunkQ33V5PEFcjs.BrushLibraryError)("invalid", `${profile.name} can't use this brush: ${errors.join(" ")} Nothing was saved.`);
|
|
390
398
|
}
|
|
391
399
|
const inPlace = !!original && options2.name === void 0 && !library.isBuiltin(original.id) && original.id === options2.brush.id && !!await library.get(original.id);
|
|
392
400
|
let brush = options2.brush;
|
|
@@ -427,18 +435,20 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
427
435
|
else delete next.iridescence;
|
|
428
436
|
} else if (path === "tip.grain.source" && (value === void 0 || value === "")) {
|
|
429
437
|
delete next.tip.grain;
|
|
438
|
+
} else if (path === "livePatterns.pattern" && (value === void 0 || value === "")) {
|
|
439
|
+
delete next.livePatterns;
|
|
430
440
|
} else if (path === "tip.shape" && value !== "stamp") {
|
|
431
441
|
next.tip = { ...next.tip, shape: value, stamps: void 0 };
|
|
432
442
|
if (value !== "bristle") delete next.tip.bristle;
|
|
433
443
|
} else if (value === void 0 || value === "") {
|
|
434
444
|
const keys = path.split(".");
|
|
435
|
-
const parent =
|
|
445
|
+
const parent = _chunkQ33V5PEFcjs.getPath.call(void 0, next, keys.slice(0, -1).join("."));
|
|
436
446
|
if (keys.length === 1) delete next[keys[0]];
|
|
437
447
|
else if (parent) delete parent[keys[keys.length - 1]];
|
|
438
|
-
} else
|
|
448
|
+
} else _chunkQ33V5PEFcjs.setPath.call(void 0, next, path, value);
|
|
439
449
|
const problems = [];
|
|
440
450
|
try {
|
|
441
|
-
return { brush:
|
|
451
|
+
return { brush: _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, JSON.parse(JSON.stringify(next)), problems), problems };
|
|
442
452
|
} catch (e) {
|
|
443
453
|
return { brush, problems: [e.message] };
|
|
444
454
|
}
|
|
@@ -454,7 +464,7 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
454
464
|
const text = words([b.id, b.name, _nullishCoalesce(b.variety, () => ( "")), _nullishCoalesce(b.medium, () => ( "")), _nullishCoalesce(b.tool, () => ( "")), ..._nullishCoalesce(b.tags, () => ( []))].join(" "));
|
|
455
465
|
if (!wanted.every((w) => text.some((t) => t.startsWith(w)))) continue;
|
|
456
466
|
}
|
|
457
|
-
if (filter.profile && !
|
|
467
|
+
if (filter.profile && !_chunkQ33V5PEFcjs.checkBrush.call(void 0, b, filter.profile).ok) continue;
|
|
458
468
|
const id = b.kind === "tool" ? "tools" : _nullishCoalesce(b.medium, () => ( "other"));
|
|
459
469
|
let g = groups.get(id);
|
|
460
470
|
if (!g) groups.set(id, g = { id, title: id === "tools" ? "Tools" : id === "other" ? "Other" : MEDIUM_LABELS[id], varieties: [] });
|
|
@@ -470,7 +480,7 @@ async function imageFileToPngDataUrl(file) {
|
|
|
470
480
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
471
481
|
if (_chunkW5M3J7PVcjs.isPng.call(void 0, bytes)) return `data:image/png;base64,${_chunkW5M3J7PVcjs.bytesToBase64.call(void 0, bytes)}`;
|
|
472
482
|
const g = globalThis;
|
|
473
|
-
if (!g.createImageBitmap || !g.OffscreenCanvas) throw new (0,
|
|
483
|
+
if (!g.createImageBitmap || !g.OffscreenCanvas) throw new (0, _chunkQ33V5PEFcjs.BrushSourceError)("Only PNG images can be read here; convert the image to PNG.");
|
|
474
484
|
const bitmap = await g.createImageBitmap(file);
|
|
475
485
|
const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);
|
|
476
486
|
canvas.getContext("2d").drawImage(bitmap, 0, 0);
|
|
@@ -480,7 +490,7 @@ async function imageFileToPngDataUrl(file) {
|
|
|
480
490
|
async function addBrushSourceFromFile(library, file, options2 = {}) {
|
|
481
491
|
const name = (_nullishCoalesce(_nullishCoalesce(options2.name, () => ( _optionalChain([file, 'access', _38 => _38.name, 'optionalAccess', _39 => _39.replace, 'call', _40 => _40(/\.[a-z0-9]+$/i, "")]))), () => ( "Image"))).trim() || "Image";
|
|
482
492
|
const result = await library.addSource({ name, image: await imageFileToPngDataUrl(file), origin: file.name, ...options2.channel ? { channel: options2.channel } : {} });
|
|
483
|
-
return { ...result, ref:
|
|
493
|
+
return { ...result, ref: _chunkQ33V5PEFcjs.brushSourceRef.call(void 0, result.source.id) };
|
|
484
494
|
}
|
|
485
495
|
function withBrushSource(brush, ref, as) {
|
|
486
496
|
if (as === "grain") return setBrushEditorValue(brush, "tip.grain.source", ref);
|
|
@@ -498,11 +508,11 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
498
508
|
properties: {
|
|
499
509
|
id: { type: "string", description: "paint, image, canvas, vector\u2026" },
|
|
500
510
|
name: { type: "string", description: "Display name, used in messages." },
|
|
501
|
-
kinds: { type: "array", items: { type: "string", enum: [...
|
|
502
|
-
tools: { type: "array", items: { type: "string", enum: [...
|
|
503
|
-
tipShapes: { type: "array", items: { type: "string", enum: [...
|
|
504
|
-
marks: { type: "array", items: { type: "string", enum: [...
|
|
505
|
-
surfaces: { type: "array", items: { type: "string", enum: [...
|
|
511
|
+
kinds: { type: "array", items: { type: "string", enum: [..._chunkQ33V5PEFcjs.BRUSH_KINDS] }, description: "Brush kinds it has." },
|
|
512
|
+
tools: { type: "array", items: { type: "string", enum: [..._chunkQ33V5PEFcjs.BRUSH_TOOLS] }, description: "Tools it has (kind tool)." },
|
|
513
|
+
tipShapes: { type: "array", items: { type: "string", enum: [..._chunkQ33V5PEFcjs.BRUSH_TIP_SHAPES] }, description: "Tip shapes it renders." },
|
|
514
|
+
marks: { type: "array", items: { type: "string", enum: [..._chunkQ33V5PEFcjs.BRUSH_MARKS_KINDS] }, description: "Marks kinds it renders." },
|
|
515
|
+
surfaces: { type: "array", items: { type: "string", enum: [..._chunkQ33V5PEFcjs.BRUSH_SURFACES] }, description: "Surfaces it renders." },
|
|
506
516
|
exchange: { ...SUPPORT, description: "Picking paint up and mixing it in." },
|
|
507
517
|
reservoir: { ...SUPPORT, description: "The Mixer Brush reservoir." },
|
|
508
518
|
grain: { ...SUPPORT, description: "Paper grain response." },
|
|
@@ -513,6 +523,7 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
513
523
|
tilt: { ...SUPPORT, description: "Tilt dynamics." },
|
|
514
524
|
tipGrain: { ...SUPPORT, description: "Texture inside the tip (tip.grain); missing: none." },
|
|
515
525
|
dabCount: { ...SUPPORT, description: "Several dabs per spacing step (dynamics.count); missing: none." },
|
|
526
|
+
livePatterns: { ...SUPPORT, description: "Gray-Scott reaction-diffusion patterns in wet paint (livePatterns); missing: none." },
|
|
516
527
|
iridescence: { ...SUPPORT, description: "Thin-film iridescence (iridescence); missing: none." }
|
|
517
528
|
},
|
|
518
529
|
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
|
@@ -527,16 +538,16 @@ var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
|
527
538
|
brushes: { type: "array", items: { $ref: "brush.schema.json" }, description: "The brushes, each a facet brush (brush.schema.json)." },
|
|
528
539
|
sources: {
|
|
529
540
|
type: "array",
|
|
530
|
-
maxItems:
|
|
541
|
+
maxItems: _chunkQ33V5PEFcjs.MAX_BRUSH_SOURCES,
|
|
531
542
|
description: "The image sources the brushes name (source:<id> in tip.stamps or tip.grain.source), bytes included.",
|
|
532
543
|
items: {
|
|
533
544
|
type: "object",
|
|
534
545
|
description: "An image source: a grey mask, 255 paints (or is a grain peak).",
|
|
535
546
|
properties: {
|
|
536
|
-
id: { type: "string", pattern:
|
|
547
|
+
id: { type: "string", pattern: _chunkQ33V5PEFcjs.BRUSH_ID.source, description: "Source id." },
|
|
537
548
|
name: { type: "string", maxLength: 80, description: "Display name." },
|
|
538
|
-
width: { type: "integer", minimum: 1, maximum:
|
|
539
|
-
height: { type: "integer", minimum: 1, maximum:
|
|
549
|
+
width: { type: "integer", minimum: 1, maximum: _chunkQ33V5PEFcjs.MAX_BRUSH_SOURCE_SIZE, description: "Width in px." },
|
|
550
|
+
height: { type: "integer", minimum: 1, maximum: _chunkQ33V5PEFcjs.MAX_BRUSH_SOURCE_SIZE, description: "Height in px." },
|
|
540
551
|
image: { type: "string", pattern: "^data:image/png;base64,", description: "The mask as a greyscale PNG data: URL." },
|
|
541
552
|
licence: { type: "string", maxLength: 2e3, description: "The licence or terms it came with." },
|
|
542
553
|
origin: { type: "string", maxLength: 200, description: "Where it came from (a file or pack name)." }
|
|
@@ -550,7 +561,7 @@ var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
|
550
561
|
additionalProperties: false
|
|
551
562
|
};
|
|
552
563
|
function migrationInputs() {
|
|
553
|
-
const pick = (id) =>
|
|
564
|
+
const pick = (id) => _chunkQ33V5PEFcjs.brushToJSON.call(void 0, _chunkQ33V5PEFcjs.BUILTIN_BRUSHES.find((b) => b.id === id));
|
|
554
565
|
return [
|
|
555
566
|
{ id: "plain", name: "Plain" },
|
|
556
567
|
pick("pencil-6b"),
|
|
@@ -572,34 +583,34 @@ function migrationInputs() {
|
|
|
572
583
|
function editorSectionFixtures() {
|
|
573
584
|
const ids = ["highlighter", "chalk", "watercolor-wash", "hair-strands", "mixer-brush", "blender", "spray-can"];
|
|
574
585
|
return ids.flatMap(
|
|
575
|
-
(id) => Object.keys(
|
|
576
|
-
const brush =
|
|
577
|
-
return { brush: id, host, sections: brushEditorSections(brush,
|
|
586
|
+
(id) => Object.keys(_chunkQ33V5PEFcjs.BRUSH_HOST_PROFILES).map((host) => {
|
|
587
|
+
const brush = _chunkQ33V5PEFcjs.BRUSH_PRESETS.find((b) => b.id === id);
|
|
588
|
+
return { brush: id, host, sections: brushEditorSections(brush, _chunkQ33V5PEFcjs.BRUSH_HOST_PROFILES[host]) };
|
|
578
589
|
})
|
|
579
590
|
);
|
|
580
591
|
}
|
|
581
592
|
function toolDefinitions() {
|
|
582
|
-
const library =
|
|
583
|
-
const toolsFor = (host) =>
|
|
593
|
+
const library = _chunkQ33V5PEFcjs.createBrushLibrary.call(void 0, );
|
|
594
|
+
const toolsFor = (host) => _chunk5HR5CSLCcjs.createBrushLibraryTools.call(void 0, library, { profile: _chunkQ33V5PEFcjs.BRUSH_HOST_PROFILES[host], renderPreview: () => ({ data: "", mimeType: "image/png" }) });
|
|
584
595
|
return {
|
|
585
596
|
tools: toolsFor("paint").map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations })),
|
|
586
|
-
hosts: Object.fromEntries(Object.keys(
|
|
597
|
+
hosts: Object.fromEntries(Object.keys(_chunkQ33V5PEFcjs.BRUSH_HOST_PROFILES).map((host) => [host, toolsFor(host).map((t) => t.name)]))
|
|
587
598
|
};
|
|
588
599
|
}
|
|
589
600
|
function brushContracts() {
|
|
590
|
-
const presets =
|
|
591
|
-
const resolved =
|
|
592
|
-
const profiles = Object.values(
|
|
593
|
-
const checks =
|
|
601
|
+
const presets = _chunkQ33V5PEFcjs.BRUSH_PRESETS.map((b) => JSON.parse(JSON.stringify(b)));
|
|
602
|
+
const resolved = _chunkQ33V5PEFcjs.BRUSH_PRESETS.map((b) => ({ id: b.id, engine: _chunkQ33V5PEFcjs.resolveEngine.call(void 0, b), category: _chunkQ33V5PEFcjs.resolveCategory.call(void 0, b), brush: _chunkQ33V5PEFcjs.brushToJSON.call(void 0, _chunkQ33V5PEFcjs.resolveBrush.call(void 0, b)) }));
|
|
603
|
+
const profiles = Object.values(_chunkQ33V5PEFcjs.BRUSH_HOST_PROFILES);
|
|
604
|
+
const checks = _chunkQ33V5PEFcjs.BRUSH_PRESETS.map((b) => ({
|
|
594
605
|
id: b.id,
|
|
595
606
|
hosts: Object.fromEntries(profiles.map((p) => {
|
|
596
|
-
const c =
|
|
607
|
+
const c = _chunkQ33V5PEFcjs.checkBrush.call(void 0, b, p);
|
|
597
608
|
return [p.id, { ok: c.ok, issues: c.issues.map(({ facet, severity }) => ({ facet, severity })) }];
|
|
598
609
|
}))
|
|
599
610
|
}));
|
|
600
|
-
const migrations = migrationInputs().map((input) => ({ input, output:
|
|
611
|
+
const migrations = migrationInputs().map((input) => ({ input, output: _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, input), resolved: _chunkQ33V5PEFcjs.brushToJSON.call(void 0, _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, input))), engine: _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, input).engine }));
|
|
601
612
|
const files = {
|
|
602
|
-
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ...
|
|
613
|
+
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ..._chunkQ33V5PEFcjs.BRUSH_JSON_SCHEMA },
|
|
603
614
|
"profile.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "profile.schema.json", ...BRUSH_PROFILE_JSON_SCHEMA },
|
|
604
615
|
"library-file.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "library-file.schema.json", ...BRUSH_LIBRARY_FILE_JSON_SCHEMA },
|
|
605
616
|
"presets.json": presets,
|
|
@@ -613,7 +624,7 @@ function brushContracts() {
|
|
|
613
624
|
files["manifest.json"] = {
|
|
614
625
|
domain: "brushes",
|
|
615
626
|
formatVersion: BRUSH_CONTRACT_FORMAT_VERSION,
|
|
616
|
-
limits: { maxPalette:
|
|
627
|
+
limits: { maxPalette: _chunkQ33V5PEFcjs.MAX_BRUSH_PALETTE },
|
|
617
628
|
counts: { presets: presets.length, profiles: profiles.length, migrations: migrations.length, editorSections: files["editor-sections.json"].length },
|
|
618
629
|
files: Object.keys(files).sort()
|
|
619
630
|
};
|
|
@@ -714,4 +725,4 @@ function brushContracts() {
|
|
|
714
725
|
|
|
715
726
|
|
|
716
727
|
|
|
717
|
-
exports.AbrError =
|
|
728
|
+
exports.AbrError = _chunk5HR5CSLCcjs.AbrError; exports.BRUSH_CONTRACT_FORMAT_VERSION = BRUSH_CONTRACT_FORMAT_VERSION; exports.BRUSH_FACET_SCHEMAS = _chunkQ33V5PEFcjs.BRUSH_FACET_SCHEMAS; exports.BRUSH_FLIPS = _chunkQ33V5PEFcjs.BRUSH_FLIPS; exports.BRUSH_GRAIN_MODES = _chunkQ33V5PEFcjs.BRUSH_GRAIN_MODES; exports.BRUSH_GRAIN_SOURCE_PATTERN = _chunkQ33V5PEFcjs.BRUSH_GRAIN_SOURCE_PATTERN; exports.BRUSH_HOST_PROFILES = _chunkQ33V5PEFcjs.BRUSH_HOST_PROFILES; exports.BRUSH_JSON_SCHEMA = _chunkQ33V5PEFcjs.BRUSH_JSON_SCHEMA; exports.BRUSH_KINDS = _chunkQ33V5PEFcjs.BRUSH_KINDS; exports.BRUSH_LIBRARY_FILE_JSON_SCHEMA = BRUSH_LIBRARY_FILE_JSON_SCHEMA; exports.BRUSH_MARKS_KINDS = _chunkQ33V5PEFcjs.BRUSH_MARKS_KINDS; exports.BRUSH_MEDIA = _chunkQ33V5PEFcjs.BRUSH_MEDIA; exports.BRUSH_PACK_FORMATS = _chunk5HR5CSLCcjs.BRUSH_PACK_FORMATS; exports.BRUSH_PATCH_PROPERTIES = _chunk5HR5CSLCcjs.BRUSH_PATCH_PROPERTIES; exports.BRUSH_PRESETS = _chunkQ33V5PEFcjs.BRUSH_PRESETS; exports.BRUSH_PREVIEW_DARK_PAPER = _chunkQNNZA3V5cjs.BRUSH_PREVIEW_DARK_PAPER; exports.BRUSH_PREVIEW_FALLBACKS = _chunkQNNZA3V5cjs.BRUSH_PREVIEW_FALLBACKS; exports.BRUSH_PREVIEW_MIN_CONTRAST = _chunkQNNZA3V5cjs.BRUSH_PREVIEW_MIN_CONTRAST; exports.BRUSH_PROFILE_JSON_SCHEMA = BRUSH_PROFILE_JSON_SCHEMA; exports.BRUSH_SOURCE_CHANNELS = _chunkQ33V5PEFcjs.BRUSH_SOURCE_CHANNELS; exports.BRUSH_SOURCE_PROVIDER = _chunkQ33V5PEFcjs.BRUSH_SOURCE_PROVIDER; exports.BRUSH_SURFACES = _chunkQ33V5PEFcjs.BRUSH_SURFACES; exports.BRUSH_TIP_SHAPES = _chunkQ33V5PEFcjs.BRUSH_TIP_SHAPES; exports.BRUSH_TOOLS = _chunkQ33V5PEFcjs.BRUSH_TOOLS; exports.BRUSH_UNSET_PROPERTY = _chunk5HR5CSLCcjs.BRUSH_UNSET_PROPERTY; exports.BRUSH_WORD = _chunkQ33V5PEFcjs.BRUSH_WORD; exports.BrushLibraryError = _chunkQ33V5PEFcjs.BrushLibraryError; exports.BrushPackError = _chunk5HR5CSLCcjs.BrushPackError; exports.BrushSourceError = _chunkQ33V5PEFcjs.BrushSourceError; exports.CANVAS_PROFILE = _chunkQ33V5PEFcjs.CANVAS_PROFILE; exports.GHOST_TRIGGERS = _chunkQ33V5PEFcjs.GHOST_TRIGGERS2; exports.IMAGE_PROFILE = _chunkQ33V5PEFcjs.IMAGE_PROFILE; exports.MAX_BRUSH_PACK_BYTES = _chunk5HR5CSLCcjs.MAX_BRUSH_PACK_BYTES; exports.MAX_BRUSH_PALETTE = _chunkQ33V5PEFcjs.MAX_BRUSH_PALETTE; exports.MAX_BRUSH_SOURCES = _chunkQ33V5PEFcjs.MAX_BRUSH_SOURCES; exports.MAX_BRUSH_SOURCE_INPUT_PIXELS = _chunkQ33V5PEFcjs.MAX_BRUSH_SOURCE_INPUT_PIXELS; exports.MAX_BRUSH_SOURCE_SIZE = _chunkQ33V5PEFcjs.MAX_BRUSH_SOURCE_SIZE; exports.MAX_PACK_BRUSHES = _chunk5HR5CSLCcjs.MAX_PACK_BRUSHES; exports.PAINT_PROFILE = _chunkQ33V5PEFcjs.PAINT_PROFILE; exports.TIP_GRAIN_PATTERNS = _chunkQ33V5PEFcjs.TIP_GRAIN_PATTERNS; exports.UNSETTABLE_BRUSH_FACETS = _chunk5HR5CSLCcjs.UNSETTABLE_BRUSH_FACETS; exports.VECTOR_PROFILE = _chunkQ33V5PEFcjs.VECTOR_PROFILE; exports.WET_BRUSH_TOOLS = _chunkQ33V5PEFcjs.WET_BRUSH_TOOLS; exports.addBrushSourceFromFile = addBrushSourceFromFile; exports.brushColourHex = _chunkJBZRVLXVcjs.brushColourHex; exports.brushColourKind = _chunkQ33V5PEFcjs.brushColourKind; exports.brushContracts = brushContracts; exports.brushEditorScope = brushEditorScope; exports.brushEditorSections = brushEditorSections; exports.brushIdFromName = brushIdFromName; exports.brushLibraryGroups = brushLibraryGroups; exports.brushPackFormat = _chunk5HR5CSLCcjs.brushPackFormat; exports.brushPreviewColours = _chunkQNNZA3V5cjs.brushPreviewColours; exports.brushPreviewStrength = _chunkQNNZA3V5cjs.brushPreviewStrength; exports.brushPreviewsOnDark = _chunkQNNZA3V5cjs.brushPreviewsOnDark; exports.brushSourceFromMask = _chunkQ33V5PEFcjs.brushSourceFromMask; exports.brushSourceIdFromName = _chunkQ33V5PEFcjs.brushSourceIdFromName; exports.brushSourceIdOf = _chunkQ33V5PEFcjs.brushSourceIdOf; exports.brushSourceIds = _chunkQ33V5PEFcjs.brushSourceIds; exports.brushSourceRef = _chunkQ33V5PEFcjs.brushSourceRef; exports.changedBrushPaths = _chunk5HR5CSLCcjs.changedBrushPaths; exports.checkBrush = _chunkQ33V5PEFcjs.checkBrush; exports.checkBrushEdit = _chunkQ33V5PEFcjs.checkBrushEdit; exports.createBrushLibrary = _chunkQ33V5PEFcjs.createBrushLibrary; exports.createBrushLibraryToolProvider = _chunk5HR5CSLCcjs.createBrushLibraryToolProvider; exports.createBrushLibraryTools = _chunk5HR5CSLCcjs.createBrushLibraryTools; exports.decodeBrushSource = _chunkQ33V5PEFcjs.decodeBrushSource; exports.degrade = _chunkQ33V5PEFcjs.degrade; exports.imageFileToPngDataUrl = imageFileToPngDataUrl; exports.importBrushFile = _chunk5HR5CSLCcjs.importBrushFile; exports.importBrushPack = _chunk5HR5CSLCcjs.importBrushPack; exports.isBrushLibrary = _chunkQ33V5PEFcjs.isBrushLibrary; exports.isBrushSourceRef = _chunkQ33V5PEFcjs.isBrushSourceRef; exports.listPresets = _chunkQ33V5PEFcjs.listPresets; exports.makeBrushSource = _chunkQ33V5PEFcjs.makeBrushSource; exports.mergeBrushPatch = _chunk5HR5CSLCcjs.mergeBrushPatch; exports.migrateBrushV1 = _chunkQ33V5PEFcjs.migrateBrushV1; exports.newBrushFor = newBrushFor; exports.normalizeBrushSpec = _chunkQ33V5PEFcjs.normalizeBrushSpec; exports.parseBrushLibrary = _chunkQ33V5PEFcjs.parseBrushLibrary2; exports.parseBrushLibrarySources = _chunkQ33V5PEFcjs.parseBrushLibrarySources; exports.readAbr = _chunk5HR5CSLCcjs.readAbr; exports.readBrushPack = _chunk5HR5CSLCcjs.readBrushPack; exports.readBrushSource = _chunkQ33V5PEFcjs.readBrushSource; exports.resolveBrush = _chunkQ33V5PEFcjs.resolveBrush; exports.resolveCategory = _chunkQ33V5PEFcjs.resolveCategory; exports.resolveEngine = _chunkQ33V5PEFcjs.resolveEngine; exports.resolveWetMedium = _chunkQ33V5PEFcjs.resolveWetMedium; exports.saveBrushEdit = saveBrushEdit; exports.setBrushEditorValue = setBrushEditorValue; exports.snapshotBrushLibrary = _chunkQ33V5PEFcjs.snapshotBrushLibrary; exports.summarizeBrushSource = _chunkQ33V5PEFcjs.summarizeBrushSource; exports.withBrushSource = withBrushSource; exports.withKeptIssues = _chunkQ33V5PEFcjs.withKeptIssues;
|
package/dist/brushes/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
mergeBrushPatch,
|
|
19
19
|
readAbr,
|
|
20
20
|
readBrushPack
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-IJ6NSWKM.js";
|
|
22
22
|
import "../chunk-VE6UKYQ2.js";
|
|
23
23
|
import {
|
|
24
24
|
BRUSH_PREVIEW_DARK_PAPER,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
brushPreviewColours,
|
|
28
28
|
brushPreviewStrength,
|
|
29
29
|
brushPreviewsOnDark
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-GHYJAMMS.js";
|
|
31
31
|
import {
|
|
32
32
|
BRUSH_FACET_SCHEMAS,
|
|
33
33
|
BRUSH_FIELDS,
|
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
snapshotBrushLibrary,
|
|
103
103
|
summarizeBrushSource,
|
|
104
104
|
withKeptIssues
|
|
105
|
-
} from "../chunk-
|
|
105
|
+
} from "../chunk-XVPQNX7O.js";
|
|
106
106
|
import {
|
|
107
107
|
STAMP_KINDS
|
|
108
108
|
} from "../chunk-JL6YH5WD.js";
|
|
@@ -112,8 +112,9 @@ import {
|
|
|
112
112
|
import "../chunk-SZTI6EER.js";
|
|
113
113
|
import "../chunk-V2ZCJRDM.js";
|
|
114
114
|
import {
|
|
115
|
+
LIVE_PATTERN_KINDS,
|
|
115
116
|
MAX_BRUSH_SIZE
|
|
116
|
-
} from "../chunk-
|
|
117
|
+
} from "../chunk-LDZOXESA.js";
|
|
117
118
|
import "../chunk-4D6KP5BV.js";
|
|
118
119
|
import {
|
|
119
120
|
BLEND_MODES
|
|
@@ -162,7 +163,8 @@ var ARIA = {
|
|
|
162
163
|
"behaviour.thick.applicator": "Impasto tool",
|
|
163
164
|
"light.pressure": "Light follows pressure",
|
|
164
165
|
"tip.grain.source": "Tip grain",
|
|
165
|
-
"dynamics.angleJitter": "Brush rotation jitter"
|
|
166
|
+
"dynamics.angleJitter": "Brush rotation jitter",
|
|
167
|
+
"livePatterns.pattern": "Live pattern"
|
|
166
168
|
};
|
|
167
169
|
var aria = (path, label) => ARIA[path] ?? `Brush ${label.toLowerCase()}`;
|
|
168
170
|
function brushEditorSections(brush, profile = PAINT_PROFILE, context = {}) {
|
|
@@ -273,7 +275,11 @@ function brushEditorSections(brush, profile = PAINT_PROFILE, context = {}) {
|
|
|
273
275
|
...engineSliders.map((c) => exchangeOk(facetOf(c.path)) ? slider(c) : null),
|
|
274
276
|
engineOk && engineControls?.mixingPath && (engine === "wet" || exchangeFull) && fieldOf("behaviour.mixing") && choice("behaviour.mixing", "Mixing", options(["pigment", "rgb"], { pigment: "Pigment", rgb: "RGB" })),
|
|
275
277
|
engineOk && engineControls?.dirty && exchangeFull && fieldOf("behaviour.exchange.dirty") && toggle("behaviour.exchange.dirty", "Dirty brush"),
|
|
276
|
-
engine === "mixer" && engineOk && full(profile.reservoir) && toggle("behaviour.exchange.reservoir.refill", "Load each stroke")
|
|
278
|
+
engine === "mixer" && engineOk && full(profile.reservoir) && toggle("behaviour.exchange.reservoir.refill", "Load each stroke"),
|
|
279
|
+
engine === "wet" && engineOk && !isTool && full(profile.livePatterns ?? "none") && choice("livePatterns.pattern", "Live pattern", [{ value: "", label: "None" }, ...options(LIVE_PATTERN_KINDS)], ""),
|
|
280
|
+
engine === "wet" && engineOk && !isTool && full(profile.livePatterns ?? "none") && !!brush.livePatterns && withNote({ kind: "slider", path: "livePatterns.scale", label: "Pattern scale", ariaLabel: "Brush pattern scale", min: 0.5, max: 4, step: 0.1, value: brush.livePatterns.scale ?? 1 }),
|
|
281
|
+
engine === "wet" && engineOk && !isTool && full(profile.livePatterns ?? "none") && !!brush.livePatterns && withNote({ kind: "slider", path: "livePatterns.contrast", label: "Pattern contrast", ariaLabel: "Brush pattern contrast", min: 0, max: 2, step: 0.05, value: brush.livePatterns.contrast ?? 1 }),
|
|
282
|
+
engine === "wet" && engineOk && !isTool && full(profile.livePatterns ?? "none") && !!brush.livePatterns && withNote({ kind: "slider", path: "livePatterns.relief", label: "Pattern relief", ariaLabel: "Brush pattern relief", min: 0, max: 1, step: 0.05, value: brush.livePatterns.relief ?? 0 })
|
|
277
283
|
]);
|
|
278
284
|
if (!isTool && full(profile.light) && engineOk && engineControls?.light) {
|
|
279
285
|
add("light", "Light", [
|
|
@@ -338,6 +344,8 @@ function hiddenLabel(issue, b) {
|
|
|
338
344
|
return "several dabs per step";
|
|
339
345
|
case "light":
|
|
340
346
|
return "light";
|
|
347
|
+
case "livePatterns":
|
|
348
|
+
return "live patterns";
|
|
341
349
|
case "fluorescence":
|
|
342
350
|
return "UV-fluorescent ink";
|
|
343
351
|
case "thermochromic":
|
|
@@ -427,6 +435,8 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
427
435
|
else delete next.iridescence;
|
|
428
436
|
} else if (path === "tip.grain.source" && (value === void 0 || value === "")) {
|
|
429
437
|
delete next.tip.grain;
|
|
438
|
+
} else if (path === "livePatterns.pattern" && (value === void 0 || value === "")) {
|
|
439
|
+
delete next.livePatterns;
|
|
430
440
|
} else if (path === "tip.shape" && value !== "stamp") {
|
|
431
441
|
next.tip = { ...next.tip, shape: value, stamps: void 0 };
|
|
432
442
|
if (value !== "bristle") delete next.tip.bristle;
|
|
@@ -513,6 +523,7 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
513
523
|
tilt: { ...SUPPORT, description: "Tilt dynamics." },
|
|
514
524
|
tipGrain: { ...SUPPORT, description: "Texture inside the tip (tip.grain); missing: none." },
|
|
515
525
|
dabCount: { ...SUPPORT, description: "Several dabs per spacing step (dynamics.count); missing: none." },
|
|
526
|
+
livePatterns: { ...SUPPORT, description: "Gray-Scott reaction-diffusion patterns in wet paint (livePatterns); missing: none." },
|
|
516
527
|
iridescence: { ...SUPPORT, description: "Thin-film iridescence (iridescence); missing: none." }
|
|
517
528
|
},
|
|
518
529
|
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
package/dist/brushes/patch.d.cts
CHANGED
|
@@ -13,7 +13,7 @@ export type BrushPatch = {
|
|
|
13
13
|
/** The schema of every facet except `id` and `name`, as tool arguments (a patch may leave out `tip.shape`). */
|
|
14
14
|
export declare const BRUSH_PATCH_PROPERTIES: Readonly<Record<string, JsonSchema>>;
|
|
15
15
|
/** The facets a patch can remove (`unset`), back to the engine's defaults. */
|
|
16
|
-
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "colour"];
|
|
16
|
+
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "livePatterns", "colour"];
|
|
17
17
|
export type UnsettableBrushFacet = (typeof UNSETTABLE_BRUSH_FACETS)[number];
|
|
18
18
|
/** The `unset` argument of tools that take a patch. */
|
|
19
19
|
export declare const BRUSH_UNSET_PROPERTY: JsonSchema;
|
package/dist/brushes/patch.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type BrushPatch = {
|
|
|
13
13
|
/** The schema of every facet except `id` and `name`, as tool arguments (a patch may leave out `tip.shape`). */
|
|
14
14
|
export declare const BRUSH_PATCH_PROPERTIES: Readonly<Record<string, JsonSchema>>;
|
|
15
15
|
/** The facets a patch can remove (`unset`), back to the engine's defaults. */
|
|
16
|
-
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "colour"];
|
|
16
|
+
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "livePatterns", "colour"];
|
|
17
17
|
export type UnsettableBrushFacet = (typeof UNSETTABLE_BRUSH_FACETS)[number];
|
|
18
18
|
/** The `unset` argument of tools that take a patch. */
|
|
19
19
|
export declare const BRUSH_UNSET_PROPERTY: JsonSchema;
|
|
@@ -39,6 +39,8 @@ export interface BrushHostProfile {
|
|
|
39
39
|
tipGrain?: BrushSupport;
|
|
40
40
|
/** Several dabs per spacing step (`dynamics.count` above 1); missing: `none`. */
|
|
41
41
|
dabCount?: BrushSupport;
|
|
42
|
+
/** Gray-Scott reaction-diffusion patterns in wet paint (`livePatterns`); missing: `none`. */
|
|
43
|
+
livePatterns?: BrushSupport;
|
|
42
44
|
/** Structural colour (`iridescence`); missing: `none`. */
|
|
43
45
|
iridescence?: BrushSupport;
|
|
44
46
|
}
|
|
@@ -39,6 +39,8 @@ export interface BrushHostProfile {
|
|
|
39
39
|
tipGrain?: BrushSupport;
|
|
40
40
|
/** Several dabs per spacing step (`dynamics.count` above 1); missing: `none`. */
|
|
41
41
|
dabCount?: BrushSupport;
|
|
42
|
+
/** Gray-Scott reaction-diffusion patterns in wet paint (`livePatterns`); missing: `none`. */
|
|
43
|
+
livePatterns?: BrushSupport;
|
|
42
44
|
/** Structural colour (`iridescence`); missing: `none`. */
|
|
43
45
|
iridescence?: BrushSupport;
|
|
44
46
|
}
|
package/dist/brushes/schema.d.ts
CHANGED