@pixerate/editor 0.264.1 → 0.266.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 +4 -3
- package/dist/agent/index.js +3 -2
- package/dist/animation-editor/index.cjs +60 -61
- package/dist/animation-editor/index.js +4 -5
- package/dist/brushes/index.cjs +73 -60
- package/dist/brushes/index.d.cts +1 -0
- package/dist/brushes/index.d.ts +1 -0
- package/dist/brushes/index.js +17 -4
- package/dist/brushes/preview.d.cts +59 -0
- package/dist/brushes/preview.d.ts +59 -0
- package/dist/brushes/tools.d.cts +12 -5
- package/dist/brushes/tools.d.ts +12 -5
- package/dist/{brushstrokeRender-3MOI7PH4.js → brushstrokeRender-4UB6NRJW.js} +11 -4
- package/dist/{brushstrokeRender-SMMPIJF2.cjs → brushstrokeRender-JQ2XQRUD.cjs} +22 -15
- package/dist/canvas/brushstroke.d.cts +6 -1
- package/dist/canvas/brushstroke.d.ts +6 -1
- package/dist/canvas/index.cjs +18 -18
- package/dist/canvas/index.js +4 -4
- package/dist/{chunk-TMDDMJCR.js → chunk-472INMWH.js} +4 -2
- package/dist/chunk-55ALHYJY.js +289 -0
- package/dist/{chunk-F3KKR6DD.cjs → chunk-5OE4ZZ6V.cjs} +30 -30
- package/dist/{chunk-BY5EBP26.cjs → chunk-677777GH.cjs} +3 -3
- package/dist/{chunk-NHA26O5X.cjs → chunk-7KNW3WXZ.cjs} +14 -12
- package/dist/{chunk-G5ADO47G.cjs → chunk-7NQOGWLM.cjs} +3 -2
- package/dist/{chunk-WWI6FLH2.js → chunk-7PW6VCNW.js} +2 -2
- package/dist/{chunk-CECCP2V7.js → chunk-BLR4KWYQ.js} +1 -1
- package/dist/chunk-DEBIFWY6.cjs +77 -0
- package/dist/{chunk-KXNZNOEF.cjs → chunk-DGXTEPCU.cjs} +94 -94
- package/dist/{chunk-3CI7FRMK.js → chunk-DVPQFMH6.js} +13 -1
- package/dist/chunk-E2Z4UARJ.cjs +289 -0
- package/dist/chunk-HAEB3MZD.js +664 -0
- package/dist/{chunk-EE7SAYBF.js → chunk-J4SGJCPW.js} +3 -3
- package/dist/{chunk-A2IS7EHE.cjs → chunk-JBZRVLXV.cjs} +14 -2
- package/dist/chunk-KIJIONZF.cjs +664 -0
- package/dist/{chunk-V7MJ4HIN.cjs → chunk-NOP4Y5AB.cjs} +23 -23
- package/dist/{chunk-FQC5TDB6.cjs → chunk-O53MOGXG.cjs} +35 -35
- package/dist/{chunk-LPFQHVCO.js → chunk-PXXXRCME.js} +1 -284
- package/dist/{chunk-4OJC4MCD.js → chunk-Q6RVVJW6.js} +1 -1
- package/dist/{chunk-T7QSEKDY.cjs → chunk-QJVOJUTD.cjs} +4 -287
- package/dist/{chunk-HAUDEVMC.js → chunk-WY23AUCA.js} +2 -2
- package/dist/{chunk-JEML4FSA.js → chunk-XDNWQMHY.js} +3 -2
- package/dist/{chunk-ROBSFJ6F.js → chunk-Z2Z2OHRM.js} +1 -1
- package/dist/{chunk-USJX5SW4.cjs → chunk-ZHRVCW3M.cjs} +12 -12
- package/dist/chunk-ZS7LB2MV.js +77 -0
- package/dist/commands/index.cjs +26 -656
- package/dist/commands/index.js +18 -648
- package/dist/image-editor/index.cjs +788 -790
- package/dist/image-editor/index.js +6 -8
- package/dist/paint-editor/index.cjs +88 -84
- package/dist/paint-editor/index.js +12 -8
- package/dist/vector/contract.d.cts +52 -0
- package/dist/vector/contract.d.ts +52 -0
- package/dist/vector/index.cjs +1168 -971
- package/dist/vector/index.d.cts +1 -0
- package/dist/vector/index.d.ts +1 -0
- package/dist/vector/index.js +204 -7
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +7 -2
- package/dist/chunk-FJBQTZS4.js +0 -17
- package/dist/chunk-LRTR4ASZ.cjs +0 -17
package/dist/brushes/index.cjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunk5OE4ZZ6Vcjs = require('../chunk-5OE4ZZ6V.cjs');
|
|
12
12
|
require('../chunk-PE6YJMQT.cjs');
|
|
13
13
|
|
|
14
14
|
|
|
@@ -17,6 +17,7 @@ require('../chunk-PE6YJMQT.cjs');
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
var _chunkDEBIFWY6cjs = require('../chunk-DEBIFWY6.cjs');
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
|
|
@@ -61,14 +62,20 @@ require('../chunk-PE6YJMQT.cjs');
|
|
|
61
62
|
|
|
62
63
|
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
var _chunk677777GHcjs = require('../chunk-677777GH.cjs');
|
|
65
73
|
|
|
66
74
|
|
|
67
75
|
var _chunkOTN6VB5Scjs = require('../chunk-OTN6VB5S.cjs');
|
|
68
76
|
|
|
69
77
|
|
|
70
|
-
var
|
|
71
|
-
require('../chunk-A2IS7EHE.cjs');
|
|
78
|
+
var _chunkJBZRVLXVcjs = require('../chunk-JBZRVLXV.cjs');
|
|
72
79
|
require('../chunk-U67EN7GG.cjs');
|
|
73
80
|
require('../chunk-WOFXZ3XU.cjs');
|
|
74
81
|
|
|
@@ -115,20 +122,20 @@ var ARIA = {
|
|
|
115
122
|
"light.pressure": "Light follows pressure"
|
|
116
123
|
};
|
|
117
124
|
var aria = (path, label) => _nullishCoalesce(ARIA[path], () => ( `Brush ${label.toLowerCase()}`));
|
|
118
|
-
function brushEditorSections(brush, profile =
|
|
119
|
-
const resolved =
|
|
120
|
-
const engine =
|
|
121
|
-
const fieldOf = (facet) =>
|
|
122
|
-
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(
|
|
125
|
+
function brushEditorSections(brush, profile = _chunk677777GHcjs.PAINT_PROFILE) {
|
|
126
|
+
const resolved = _chunk677777GHcjs.resolveBrush.call(void 0, brush);
|
|
127
|
+
const engine = _chunk677777GHcjs.resolveEngine.call(void 0, brush);
|
|
128
|
+
const fieldOf = (facet) => _chunk677777GHcjs.BRUSH_FIELDS.find((f) => f.facet === facet && f.engines.includes(engine));
|
|
129
|
+
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(_chunk677777GHcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath && f.engines.includes(engine)), () => ( _chunk677777GHcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath)))), 'optionalAccess', _ => _.facet]);
|
|
123
130
|
const value = (path) => {
|
|
124
|
-
const own =
|
|
131
|
+
const own = _chunk677777GHcjs.getPath.call(void 0, brush, path);
|
|
125
132
|
if (own !== void 0) return own;
|
|
126
133
|
const field = fieldOf(path);
|
|
127
134
|
if (!field) return void 0;
|
|
128
|
-
const v =
|
|
135
|
+
const v = _chunk677777GHcjs.getPath.call(void 0, resolved, field.engine);
|
|
129
136
|
return field.map ? field.map.toFacet(v) : v;
|
|
130
137
|
};
|
|
131
|
-
const issues =
|
|
138
|
+
const issues = _chunk677777GHcjs.checkBrush.call(void 0, brush, profile).issues;
|
|
132
139
|
const warned = new Map(issues.filter((i) => i.severity === "warning").map((i) => [i.facet, i.reason]));
|
|
133
140
|
const refused = new Set(issues.filter((i) => i.severity === "error").map((i) => i.facet));
|
|
134
141
|
const full = (s) => s === "full";
|
|
@@ -157,18 +164,18 @@ function brushEditorSections(brush, profile = _chunkBY5EBP26cjs.PAINT_PROFILE) {
|
|
|
157
164
|
const exchangeFull = full(_optionalChain([brush, 'access', _9 => _9.behaviour, 'optionalAccess', _10 => _10.exchange, 'optionalAccess', _11 => _11.reservoir]) ? profile.reservoir : profile.exchange);
|
|
158
165
|
add("medium", "Medium", [
|
|
159
166
|
profile.kinds.length > 1 && profile.kinds.includes(brush.kind) && choice("kind", "Kind", options(profile.kinds, { mark: "Lays a material", tool: "Works on paint" })),
|
|
160
|
-
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(
|
|
167
|
+
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(_chunk677777GHcjs.BRUSH_MEDIA, MEDIUM_LABELS)], ""),
|
|
161
168
|
!isTool && withNote({ kind: "text", path: "variety", label: "Variety", ariaLabel: "Brush variety", value: _nullishCoalesce(brush.variety, () => ( "")), placeholder: "pencil, oil, highlighter\u2026" }),
|
|
162
169
|
isTool && !!brush.tool && profile.tools.includes(brush.tool) && choice("tool", "Tool", options(profile.tools, TOOL_LABELS))
|
|
163
170
|
]);
|
|
164
|
-
const engineControls =
|
|
165
|
-
const tipSliders =
|
|
171
|
+
const engineControls = _chunk5OE4ZZ6Vcjs.brushEngineControls.call(void 0, resolved);
|
|
172
|
+
const tipSliders = _chunk5OE4ZZ6Vcjs.BRUSH_SLIDERS.filter((c) => c.path.startsWith("tip.") && c.path !== "tip.smoothing");
|
|
166
173
|
add("shape", "Shape", [
|
|
167
174
|
!refused.has("tip.shape") && choice("tip.shape", "Tip", options(profile.tipShapes.filter((s) => !isTool || s !== "stamp"), SHAPE_LABELS)),
|
|
168
175
|
...tipSliders.map((c) => slider(c)),
|
|
169
176
|
engine === "dab" && choice("tip.blend", "Blend", _chunk2VX55NFMcjs.BLEND_MODES.map((m) => ({ value: m.id, label: m.label })), "normal"),
|
|
170
177
|
...shape === "bristle" && engineOk && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("bristle.")).map((c) => slider(c)) : [],
|
|
171
|
-
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ?
|
|
178
|
+
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ? _chunk677777GHcjs.MAX_DOT_TEXTURES : _chunk677777GHcjs.MAX_STICKER_STAMPS, options: STAMP_OPTIONS })
|
|
172
179
|
]);
|
|
173
180
|
if (!isTool && profile.marks.length > 1 && engineOk) {
|
|
174
181
|
const particles = marks === "particles" && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("particle.") && c.path !== "particle.waveSpeed") : [];
|
|
@@ -176,21 +183,21 @@ function brushEditorSections(brush, profile = _chunkBY5EBP26cjs.PAINT_PROFILE) {
|
|
|
176
183
|
const render = value("marks.render");
|
|
177
184
|
add("marks", "Marks", [
|
|
178
185
|
choice("marks.kind", "Laid as", options(profile.marks, MARKS_LABELS), "continuous"),
|
|
179
|
-
marks === "particles" && choice("marks.physics", "Particles", options(
|
|
180
|
-
marks === "particles" && choice("marks.render", "Drawn as", options(
|
|
181
|
-
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(
|
|
182
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(
|
|
183
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(
|
|
186
|
+
marks === "particles" && choice("marks.physics", "Particles", options(_chunk677777GHcjs.PARTICLE_KINDS, PHYSICS_LABELS)),
|
|
187
|
+
marks === "particles" && choice("marks.render", "Drawn as", options(_chunk677777GHcjs.PARTICLE_RENDERS, RENDER_LABELS)),
|
|
188
|
+
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(_chunk677777GHcjs.RIBBON_PAIRS, { adjacent: "Neighbours", "first-last": "Outermost" })),
|
|
189
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(_chunk677777GHcjs.DOT_TEXTURE_ORDERS, { sequence: "In turn", random: "Random" })),
|
|
190
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(_chunk677777GHcjs.DOT_ROTATIONS, { follow: "Follow motion", random: "Random", fixed: "Tip angle" })),
|
|
184
191
|
...particles.map((c) => slider(c)),
|
|
185
192
|
...objects.map((c) => slider(c))
|
|
186
193
|
]);
|
|
187
194
|
}
|
|
188
|
-
const feel =
|
|
195
|
+
const feel = _chunk5OE4ZZ6Vcjs.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)));
|
|
189
196
|
add("feel", "Feel", [
|
|
190
197
|
...feel.map((c) => slider(c)),
|
|
191
198
|
toggle("dynamics.pressureSize", "Pressure \u2192 size"),
|
|
192
199
|
toggle("dynamics.pressureOpacity", "Pressure \u2192 opacity"),
|
|
193
|
-
choice("dynamics.rotation", "Rotation", options(
|
|
200
|
+
choice("dynamics.rotation", "Rotation", options(_chunk677777GHcjs.BRUSH_ROTATIONS, ROTATION_LABELS))
|
|
194
201
|
]);
|
|
195
202
|
const surfaces = profile.surfaces;
|
|
196
203
|
const engineSliders = (engineOk ? _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _12 => _12.sliders]), () => ( [])) : []).filter((c) => !/^(bristle|particle|sticker)\./.test(c.path) && c.path !== "light.amount" && c.path !== "impasto.rim" && c.path !== "impasto.clarity");
|
|
@@ -198,8 +205,8 @@ function brushEditorSections(brush, profile = _chunkBY5EBP26cjs.PAINT_PROFILE) {
|
|
|
198
205
|
add("behaviour", _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _15 => _15.title]), () => ( "Behaviour")), [
|
|
199
206
|
!isTool && surfaces.length > 1 && !refused.has("behaviour.surface") && choice("behaviour.surface", "Surface", options(surfaces, SURFACE_LABELS), "dry"),
|
|
200
207
|
full(profile.grain) && slider({ path: "grain", label: "Grain", min: 0, max: 1, step: 0.01 }, "behaviour.grain"),
|
|
201
|
-
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(
|
|
202
|
-
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(
|
|
208
|
+
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(_chunk677777GHcjs.WET_MEDIA, WET_MEDIUM_LABELS), "watercolor"),
|
|
209
|
+
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(_chunk677777GHcjs.IMPASTO_TOOLS, APPLICATOR_LABELS), "brush"),
|
|
203
210
|
...engineSliders.map((c) => exchangeOk(facetOf(c.path)) ? slider(c) : null),
|
|
204
211
|
engineOk && _optionalChain([engineControls, 'optionalAccess', _16 => _16.mixingPath]) && (engine === "wet" || exchangeFull) && fieldOf("behaviour.mixing") && choice("behaviour.mixing", "Mixing", options(["pigment", "rgb"], { pigment: "Pigment", rgb: "RGB" })),
|
|
205
212
|
engineOk && _optionalChain([engineControls, 'optionalAccess', _17 => _17.dirty]) && exchangeFull && fieldOf("behaviour.exchange.dirty") && toggle("behaviour.exchange.dirty", "Dirty brush"),
|
|
@@ -217,17 +224,17 @@ function brushEditorSections(brush, profile = _chunkBY5EBP26cjs.PAINT_PROFILE) {
|
|
|
217
224
|
if (full(profile.motion) && engineOk && marks === "particles") add("motion", "Motion", [slider({ path: "particle.waveSpeed", label: "Wave speed", min: 0, max: 1, step: 0.01 })]);
|
|
218
225
|
if (!isTool) {
|
|
219
226
|
const own = _optionalChain([brush, 'access', _22 => _22.colour, 'optionalAccess', _23 => _23.default]);
|
|
220
|
-
const hex = (c) => typeof c === "string" ? _nullishCoalesce(
|
|
227
|
+
const hex = (c) => typeof c === "string" ? _nullishCoalesce(_chunkJBZRVLXVcjs.brushColourHex.call(void 0, c, "light"), () => ( null)) : null;
|
|
221
228
|
const pair = _chunkMLLTWAXHcjs.isDualColor.call(void 0, own) ? own : null;
|
|
222
229
|
add("colour", "Colour", [
|
|
223
|
-
!refused.has("colour.default") && withNote({ kind: "colour", path: "colour.default", label: "Default colour", ariaLabel: "Brush default colour", value: pair ? _nullishCoalesce(
|
|
230
|
+
!refused.has("colour.default") && withNote({ kind: "colour", path: "colour.default", label: "Default colour", ariaLabel: "Brush default colour", value: pair ? _nullishCoalesce(_chunkJBZRVLXVcjs.brushColourHex.call(void 0, pair, "light"), () => ( null)) : hex(own), dark: pair ? _nullishCoalesce(_chunkJBZRVLXVcjs.brushColourHex.call(void 0, pair, "dark"), () => ( null)) : null, gradient: own !== void 0 && typeof own === "object" && !pair }),
|
|
224
231
|
withNote({
|
|
225
232
|
kind: "palette",
|
|
226
233
|
path: "colour.palette",
|
|
227
234
|
label: "Palette",
|
|
228
235
|
ariaLabel: "Brush palette",
|
|
229
|
-
value: (_nullishCoalesce(_optionalChain([brush, 'access', _24 => _24.colour, 'optionalAccess', _25 => _25.palette]), () => ( []))).flatMap((c) => _chunkMLLTWAXHcjs.isDualColor.call(void 0, c) ? [{ light:
|
|
230
|
-
max:
|
|
236
|
+
value: (_nullishCoalesce(_optionalChain([brush, 'access', _24 => _24.colour, 'optionalAccess', _25 => _25.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)] : []),
|
|
237
|
+
max: _chunk677777GHcjs.MAX_BRUSH_PALETTE
|
|
231
238
|
}),
|
|
232
239
|
toggle("colour.own", "Always its own colour")
|
|
233
240
|
]);
|
|
@@ -261,15 +268,15 @@ function hiddenLabel(issue, b) {
|
|
|
261
268
|
case "dynamics.tilt":
|
|
262
269
|
return "tilt dynamics";
|
|
263
270
|
case "colour.default":
|
|
264
|
-
return `a ${
|
|
271
|
+
return `a ${_chunk677777GHcjs.brushColourKind.call(void 0, b.colour.default)} default colour`;
|
|
265
272
|
default:
|
|
266
273
|
return null;
|
|
267
274
|
}
|
|
268
275
|
}
|
|
269
276
|
var sentence = (words) => words.length < 2 ? _nullishCoalesce(words[0], () => ( "")) : `${words.slice(0, -1).join(", ")} and ${words.at(-1)}`;
|
|
270
|
-
function brushEditorScope(brush, profile =
|
|
277
|
+
function brushEditorScope(brush, profile = _chunk677777GHcjs.PAINT_PROFILE) {
|
|
271
278
|
const hidden = [];
|
|
272
|
-
for (const issue of
|
|
279
|
+
for (const issue of _chunk677777GHcjs.checkBrush.call(void 0, brush, profile).issues) {
|
|
273
280
|
const label = hiddenLabel(issue, brush);
|
|
274
281
|
if (label && !hidden.some((h) => h.label === label)) hidden.push({ facet: issue.facet, label });
|
|
275
282
|
}
|
|
@@ -282,17 +289,17 @@ function newBrushFor(profile, from, name = "New brush") {
|
|
|
282
289
|
const id = brushIdFromName(name);
|
|
283
290
|
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] } };
|
|
284
291
|
if (from) {
|
|
285
|
-
const stripped =
|
|
292
|
+
const stripped = _chunk677777GHcjs.degrade.call(void 0, from, profile, { ignored: true });
|
|
286
293
|
if (!stripped.issues.length) return { ...stripped.brush, id, name };
|
|
287
294
|
}
|
|
288
295
|
return base;
|
|
289
296
|
}
|
|
290
297
|
async function saveBrushEdit(library, options2) {
|
|
291
298
|
const { original, profile } = options2;
|
|
292
|
-
const check =
|
|
299
|
+
const check = _chunk677777GHcjs.checkBrushEdit.call(void 0, original, options2.brush, profile);
|
|
293
300
|
if (!check.ok) {
|
|
294
301
|
const errors = check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`);
|
|
295
|
-
throw new (0,
|
|
302
|
+
throw new (0, _chunk677777GHcjs.BrushLibraryError)("invalid", `${profile.name} can't use this brush: ${errors.join(" ")} Nothing was saved.`);
|
|
296
303
|
}
|
|
297
304
|
const inPlace = !!original && options2.name === void 0 && !library.isBuiltin(original.id) && original.id === options2.brush.id && !!await library.get(original.id);
|
|
298
305
|
let brush = options2.brush;
|
|
@@ -328,13 +335,13 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
328
335
|
if (value !== "bristle") delete next.tip.bristle;
|
|
329
336
|
} else if (value === void 0 || value === "") {
|
|
330
337
|
const keys = path.split(".");
|
|
331
|
-
const parent =
|
|
338
|
+
const parent = _chunk677777GHcjs.getPath.call(void 0, next, keys.slice(0, -1).join("."));
|
|
332
339
|
if (keys.length === 1) delete next[keys[0]];
|
|
333
340
|
else if (parent) delete parent[keys[keys.length - 1]];
|
|
334
|
-
} else
|
|
341
|
+
} else _chunk677777GHcjs.setPath.call(void 0, next, path, value);
|
|
335
342
|
const problems = [];
|
|
336
343
|
try {
|
|
337
|
-
return { brush:
|
|
344
|
+
return { brush: _chunk677777GHcjs.normalizeBrushSpec.call(void 0, JSON.parse(JSON.stringify(next)), problems), problems };
|
|
338
345
|
} catch (e) {
|
|
339
346
|
return { brush, problems: [e.message] };
|
|
340
347
|
}
|
|
@@ -350,7 +357,7 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
350
357
|
const text = words([b.id, b.name, _nullishCoalesce(b.variety, () => ( "")), _nullishCoalesce(b.medium, () => ( "")), _nullishCoalesce(b.tool, () => ( "")), ..._nullishCoalesce(b.tags, () => ( []))].join(" "));
|
|
351
358
|
if (!wanted.every((w) => text.some((t) => t.startsWith(w)))) continue;
|
|
352
359
|
}
|
|
353
|
-
if (filter.profile && !
|
|
360
|
+
if (filter.profile && !_chunk677777GHcjs.checkBrush.call(void 0, b, filter.profile).ok) continue;
|
|
354
361
|
const id = b.kind === "tool" ? "tools" : _nullishCoalesce(b.medium, () => ( "other"));
|
|
355
362
|
let g = groups.get(id);
|
|
356
363
|
if (!g) groups.set(id, g = { id, title: id === "tools" ? "Tools" : id === "other" ? "Other" : MEDIUM_LABELS[id], varieties: [] });
|
|
@@ -372,11 +379,11 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
372
379
|
properties: {
|
|
373
380
|
id: { type: "string", description: "paint, image, canvas, vector\u2026" },
|
|
374
381
|
name: { type: "string", description: "Display name, used in messages." },
|
|
375
|
-
kinds: { type: "array", items: { type: "string", enum: [...
|
|
376
|
-
tools: { type: "array", items: { type: "string", enum: [...
|
|
377
|
-
tipShapes: { type: "array", items: { type: "string", enum: [...
|
|
378
|
-
marks: { type: "array", items: { type: "string", enum: [...
|
|
379
|
-
surfaces: { type: "array", items: { type: "string", enum: [...
|
|
382
|
+
kinds: { type: "array", items: { type: "string", enum: [..._chunk677777GHcjs.BRUSH_KINDS] }, description: "Brush kinds it has." },
|
|
383
|
+
tools: { type: "array", items: { type: "string", enum: [..._chunk677777GHcjs.BRUSH_TOOLS] }, description: "Tools it has (kind tool)." },
|
|
384
|
+
tipShapes: { type: "array", items: { type: "string", enum: [..._chunk677777GHcjs.BRUSH_TIP_SHAPES] }, description: "Tip shapes it renders." },
|
|
385
|
+
marks: { type: "array", items: { type: "string", enum: [..._chunk677777GHcjs.BRUSH_MARKS_KINDS] }, description: "Marks kinds it renders." },
|
|
386
|
+
surfaces: { type: "array", items: { type: "string", enum: [..._chunk677777GHcjs.BRUSH_SURFACES] }, description: "Surfaces it renders." },
|
|
380
387
|
exchange: { ...SUPPORT, description: "Picking paint up and mixing it in." },
|
|
381
388
|
reservoir: { ...SUPPORT, description: "The Mixer Brush reservoir." },
|
|
382
389
|
grain: { ...SUPPORT, description: "Paper grain response." },
|
|
@@ -401,7 +408,7 @@ var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
|
401
408
|
additionalProperties: false
|
|
402
409
|
};
|
|
403
410
|
function migrationInputs() {
|
|
404
|
-
const pick = (id) =>
|
|
411
|
+
const pick = (id) => _chunk677777GHcjs.brushToJSON.call(void 0, _chunk677777GHcjs.BUILTIN_BRUSHES.find((b) => b.id === id));
|
|
405
412
|
return [
|
|
406
413
|
{ id: "plain", name: "Plain" },
|
|
407
414
|
pick("pencil-6b"),
|
|
@@ -423,34 +430,34 @@ function migrationInputs() {
|
|
|
423
430
|
function editorSectionFixtures() {
|
|
424
431
|
const ids = ["highlighter", "chalk", "watercolor-wash", "hair-strands", "mixer-brush", "blender", "spray-can"];
|
|
425
432
|
return ids.flatMap(
|
|
426
|
-
(id) => Object.keys(
|
|
427
|
-
const brush =
|
|
428
|
-
return { brush: id, host, sections: brushEditorSections(brush,
|
|
433
|
+
(id) => Object.keys(_chunk677777GHcjs.BRUSH_HOST_PROFILES).map((host) => {
|
|
434
|
+
const brush = _chunk677777GHcjs.BRUSH_PRESETS.find((b) => b.id === id);
|
|
435
|
+
return { brush: id, host, sections: brushEditorSections(brush, _chunk677777GHcjs.BRUSH_HOST_PROFILES[host]) };
|
|
429
436
|
})
|
|
430
437
|
);
|
|
431
438
|
}
|
|
432
439
|
function toolDefinitions() {
|
|
433
|
-
const library =
|
|
434
|
-
const toolsFor = (host) =>
|
|
440
|
+
const library = _chunk677777GHcjs.createBrushLibrary.call(void 0, );
|
|
441
|
+
const toolsFor = (host) => _chunk5OE4ZZ6Vcjs.createBrushLibraryTools.call(void 0, library, { profile: _chunk677777GHcjs.BRUSH_HOST_PROFILES[host], renderPreview: () => ({ data: "", mimeType: "image/png" }) });
|
|
435
442
|
return {
|
|
436
443
|
tools: toolsFor("paint").map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations })),
|
|
437
|
-
hosts: Object.fromEntries(Object.keys(
|
|
444
|
+
hosts: Object.fromEntries(Object.keys(_chunk677777GHcjs.BRUSH_HOST_PROFILES).map((host) => [host, toolsFor(host).map((t) => t.name)]))
|
|
438
445
|
};
|
|
439
446
|
}
|
|
440
447
|
function brushContracts() {
|
|
441
|
-
const presets =
|
|
442
|
-
const resolved =
|
|
443
|
-
const profiles = Object.values(
|
|
444
|
-
const checks =
|
|
448
|
+
const presets = _chunk677777GHcjs.BRUSH_PRESETS.map((b) => JSON.parse(JSON.stringify(b)));
|
|
449
|
+
const resolved = _chunk677777GHcjs.BRUSH_PRESETS.map((b) => ({ id: b.id, engine: _chunk677777GHcjs.resolveEngine.call(void 0, b), category: _chunk677777GHcjs.resolveCategory.call(void 0, b), brush: _chunk677777GHcjs.brushToJSON.call(void 0, _chunk677777GHcjs.resolveBrush.call(void 0, b)) }));
|
|
450
|
+
const profiles = Object.values(_chunk677777GHcjs.BRUSH_HOST_PROFILES);
|
|
451
|
+
const checks = _chunk677777GHcjs.BRUSH_PRESETS.map((b) => ({
|
|
445
452
|
id: b.id,
|
|
446
453
|
hosts: Object.fromEntries(profiles.map((p) => {
|
|
447
|
-
const c =
|
|
454
|
+
const c = _chunk677777GHcjs.checkBrush.call(void 0, b, p);
|
|
448
455
|
return [p.id, { ok: c.ok, issues: c.issues.map(({ facet, severity }) => ({ facet, severity })) }];
|
|
449
456
|
}))
|
|
450
457
|
}));
|
|
451
|
-
const migrations = migrationInputs().map((input) => ({ input, output:
|
|
458
|
+
const migrations = migrationInputs().map((input) => ({ input, output: _chunk677777GHcjs.migrateBrushV1.call(void 0, input), resolved: _chunk677777GHcjs.brushToJSON.call(void 0, _chunk677777GHcjs.resolveBrush.call(void 0, _chunk677777GHcjs.migrateBrushV1.call(void 0, input))), engine: _chunk677777GHcjs.normalizePaintBrush.call(void 0, input).engine }));
|
|
452
459
|
const files = {
|
|
453
|
-
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ...
|
|
460
|
+
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ..._chunk677777GHcjs.BRUSH_JSON_SCHEMA },
|
|
454
461
|
"profile.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "profile.schema.json", ...BRUSH_PROFILE_JSON_SCHEMA },
|
|
455
462
|
"library-file.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "library-file.schema.json", ...BRUSH_LIBRARY_FILE_JSON_SCHEMA },
|
|
456
463
|
"presets.json": presets,
|
|
@@ -464,7 +471,7 @@ function brushContracts() {
|
|
|
464
471
|
files["manifest.json"] = {
|
|
465
472
|
domain: "brushes",
|
|
466
473
|
formatVersion: BRUSH_CONTRACT_FORMAT_VERSION,
|
|
467
|
-
limits: { maxPalette:
|
|
474
|
+
limits: { maxPalette: _chunk677777GHcjs.MAX_BRUSH_PALETTE },
|
|
468
475
|
counts: { presets: presets.length, profiles: profiles.length, migrations: migrations.length, editorSections: files["editor-sections.json"].length },
|
|
469
476
|
files: Object.keys(files).sort()
|
|
470
477
|
};
|
|
@@ -524,4 +531,10 @@ function brushContracts() {
|
|
|
524
531
|
|
|
525
532
|
|
|
526
533
|
|
|
527
|
-
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
exports.BRUSH_CONTRACT_FORMAT_VERSION = BRUSH_CONTRACT_FORMAT_VERSION; exports.BRUSH_FACET_SCHEMAS = _chunk677777GHcjs.BRUSH_FACET_SCHEMAS; exports.BRUSH_HOST_PROFILES = _chunk677777GHcjs.BRUSH_HOST_PROFILES; exports.BRUSH_JSON_SCHEMA = _chunk677777GHcjs.BRUSH_JSON_SCHEMA; exports.BRUSH_KINDS = _chunk677777GHcjs.BRUSH_KINDS; exports.BRUSH_LIBRARY_FILE_JSON_SCHEMA = BRUSH_LIBRARY_FILE_JSON_SCHEMA; exports.BRUSH_MARKS_KINDS = _chunk677777GHcjs.BRUSH_MARKS_KINDS; exports.BRUSH_MEDIA = _chunk677777GHcjs.BRUSH_MEDIA; exports.BRUSH_PATCH_PROPERTIES = _chunk5OE4ZZ6Vcjs.BRUSH_PATCH_PROPERTIES; exports.BRUSH_PRESETS = _chunk677777GHcjs.BRUSH_PRESETS; exports.BRUSH_PREVIEW_DARK_PAPER = _chunkDEBIFWY6cjs.BRUSH_PREVIEW_DARK_PAPER; exports.BRUSH_PREVIEW_FALLBACKS = _chunkDEBIFWY6cjs.BRUSH_PREVIEW_FALLBACKS; exports.BRUSH_PREVIEW_MIN_CONTRAST = _chunkDEBIFWY6cjs.BRUSH_PREVIEW_MIN_CONTRAST; exports.BRUSH_PROFILE_JSON_SCHEMA = BRUSH_PROFILE_JSON_SCHEMA; exports.BRUSH_SURFACES = _chunk677777GHcjs.BRUSH_SURFACES; exports.BRUSH_TIP_SHAPES = _chunk677777GHcjs.BRUSH_TIP_SHAPES; exports.BRUSH_TOOLS = _chunk677777GHcjs.BRUSH_TOOLS; exports.BRUSH_UNSET_PROPERTY = _chunk5OE4ZZ6Vcjs.BRUSH_UNSET_PROPERTY; exports.BRUSH_WORD = _chunk677777GHcjs.BRUSH_WORD; exports.BrushLibraryError = _chunk677777GHcjs.BrushLibraryError; exports.CANVAS_PROFILE = _chunk677777GHcjs.CANVAS_PROFILE; exports.IMAGE_PROFILE = _chunk677777GHcjs.IMAGE_PROFILE; exports.MAX_BRUSH_PALETTE = _chunk677777GHcjs.MAX_BRUSH_PALETTE; exports.PAINT_PROFILE = _chunk677777GHcjs.PAINT_PROFILE; exports.UNSETTABLE_BRUSH_FACETS = _chunk5OE4ZZ6Vcjs.UNSETTABLE_BRUSH_FACETS; exports.VECTOR_PROFILE = _chunk677777GHcjs.VECTOR_PROFILE; exports.WET_BRUSH_TOOLS = _chunk677777GHcjs.WET_BRUSH_TOOLS; exports.brushColourHex = _chunkJBZRVLXVcjs.brushColourHex; exports.brushColourKind = _chunk677777GHcjs.brushColourKind; exports.brushContracts = brushContracts; exports.brushEditorScope = brushEditorScope; exports.brushEditorSections = brushEditorSections; exports.brushIdFromName = brushIdFromName; exports.brushLibraryGroups = brushLibraryGroups; exports.brushPreviewColours = _chunkDEBIFWY6cjs.brushPreviewColours; exports.brushPreviewStrength = _chunkDEBIFWY6cjs.brushPreviewStrength; exports.brushPreviewsOnDark = _chunkDEBIFWY6cjs.brushPreviewsOnDark; exports.changedBrushPaths = _chunk5OE4ZZ6Vcjs.changedBrushPaths; exports.checkBrush = _chunk677777GHcjs.checkBrush; exports.checkBrushEdit = _chunk677777GHcjs.checkBrushEdit; exports.createBrushLibrary = _chunk677777GHcjs.createBrushLibrary; exports.createBrushLibraryToolProvider = _chunk5OE4ZZ6Vcjs.createBrushLibraryToolProvider; exports.createBrushLibraryTools = _chunk5OE4ZZ6Vcjs.createBrushLibraryTools; exports.degrade = _chunk677777GHcjs.degrade; exports.isBrushLibrary = _chunk677777GHcjs.isBrushLibrary; exports.listPresets = _chunk677777GHcjs.listPresets; exports.mergeBrushPatch = _chunk5OE4ZZ6Vcjs.mergeBrushPatch; exports.migrateBrushV1 = _chunk677777GHcjs.migrateBrushV1; exports.newBrushFor = newBrushFor; exports.normalizeBrushSpec = _chunk677777GHcjs.normalizeBrushSpec; exports.parseBrushLibrary = _chunk677777GHcjs.parseBrushLibrary2; exports.resolveBrush = _chunk677777GHcjs.resolveBrush; exports.resolveCategory = _chunk677777GHcjs.resolveCategory; exports.resolveEngine = _chunk677777GHcjs.resolveEngine; exports.resolveWetMedium = _chunk677777GHcjs.resolveWetMedium; exports.saveBrushEdit = saveBrushEdit; exports.setBrushEditorValue = setBrushEditorValue; exports.snapshotBrushLibrary = _chunk677777GHcjs.snapshotBrushLibrary; exports.withKeptIssues = _chunk677777GHcjs.withKeptIssues;
|
package/dist/brushes/index.d.cts
CHANGED
|
@@ -15,6 +15,7 @@ export { resolveBrush, resolveCategory, resolveEngine, resolveWetMedium, type Re
|
|
|
15
15
|
export { migrateBrushV1 } from './migrate.cjs';
|
|
16
16
|
export { BRUSH_PRESETS } from './presets.cjs';
|
|
17
17
|
export { brushColourHex } from './colour.cjs';
|
|
18
|
+
export { BRUSH_PREVIEW_DARK_PAPER, BRUSH_PREVIEW_FALLBACKS, BRUSH_PREVIEW_MIN_CONTRAST, brushPreviewColours, brushPreviewsOnDark, brushPreviewStrength, type BrushPreviewColours, type BrushPreviewColoursOptions } from './preview.cjs';
|
|
18
19
|
export { BRUSH_CONTRACT_FORMAT_VERSION, BRUSH_LIBRARY_FILE_JSON_SCHEMA, BRUSH_PROFILE_JSON_SCHEMA, brushContracts } from './contract.cjs';
|
|
19
20
|
export { BRUSH_HOST_PROFILES, brushColourKind, CANVAS_PROFILE, checkBrush, checkBrushEdit, degrade, withKeptIssues, IMAGE_PROFILE, listPresets, PAINT_PROFILE, VECTOR_PROFILE, type BrushCheck, type BrushEditCheck, type BrushColourKind, type BrushHostProfile, type BrushIssue, type BrushSupport, type DegradedBrush } from './profiles.cjs';
|
|
20
21
|
export { BrushLibraryError, createBrushLibrary, isBrushLibrary, parseBrushLibrary, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.cjs';
|
package/dist/brushes/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { resolveBrush, resolveCategory, resolveEngine, resolveWetMedium, type Re
|
|
|
15
15
|
export { migrateBrushV1 } from './migrate.js';
|
|
16
16
|
export { BRUSH_PRESETS } from './presets.js';
|
|
17
17
|
export { brushColourHex } from './colour.js';
|
|
18
|
+
export { BRUSH_PREVIEW_DARK_PAPER, BRUSH_PREVIEW_FALLBACKS, BRUSH_PREVIEW_MIN_CONTRAST, brushPreviewColours, brushPreviewsOnDark, brushPreviewStrength, type BrushPreviewColours, type BrushPreviewColoursOptions } from './preview.js';
|
|
18
19
|
export { BRUSH_CONTRACT_FORMAT_VERSION, BRUSH_LIBRARY_FILE_JSON_SCHEMA, BRUSH_PROFILE_JSON_SCHEMA, brushContracts } from './contract.js';
|
|
19
20
|
export { BRUSH_HOST_PROFILES, brushColourKind, CANVAS_PROFILE, checkBrush, checkBrushEdit, degrade, withKeptIssues, IMAGE_PROFILE, listPresets, PAINT_PROFILE, VECTOR_PROFILE, type BrushCheck, type BrushEditCheck, type BrushColourKind, type BrushHostProfile, type BrushIssue, type BrushSupport, type DegradedBrush } from './profiles.js';
|
|
20
21
|
export { BrushLibraryError, createBrushLibrary, isBrushLibrary, parseBrushLibrary, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.js';
|
package/dist/brushes/index.js
CHANGED
|
@@ -8,8 +8,16 @@ import {
|
|
|
8
8
|
createBrushLibraryToolProvider,
|
|
9
9
|
createBrushLibraryTools,
|
|
10
10
|
mergeBrushPatch
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-Q6RVVJW6.js";
|
|
12
12
|
import "../chunk-6JL2D5SG.js";
|
|
13
|
+
import {
|
|
14
|
+
BRUSH_PREVIEW_DARK_PAPER,
|
|
15
|
+
BRUSH_PREVIEW_FALLBACKS,
|
|
16
|
+
BRUSH_PREVIEW_MIN_CONTRAST,
|
|
17
|
+
brushPreviewColours,
|
|
18
|
+
brushPreviewStrength,
|
|
19
|
+
brushPreviewsOnDark
|
|
20
|
+
} from "../chunk-ZS7LB2MV.js";
|
|
13
21
|
import {
|
|
14
22
|
BRUSH_FACET_SCHEMAS,
|
|
15
23
|
BRUSH_FIELDS,
|
|
@@ -61,14 +69,13 @@ import {
|
|
|
61
69
|
setPath,
|
|
62
70
|
snapshotBrushLibrary,
|
|
63
71
|
withKeptIssues
|
|
64
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-J4SGJCPW.js";
|
|
65
73
|
import {
|
|
66
74
|
STAMP_KINDS
|
|
67
75
|
} from "../chunk-ACFSFUQH.js";
|
|
68
76
|
import {
|
|
69
77
|
brushColourHex
|
|
70
|
-
} from "../chunk-
|
|
71
|
-
import "../chunk-3CI7FRMK.js";
|
|
78
|
+
} from "../chunk-DVPQFMH6.js";
|
|
72
79
|
import "../chunk-SZTI6EER.js";
|
|
73
80
|
import "../chunk-V2ZCJRDM.js";
|
|
74
81
|
import {
|
|
@@ -481,6 +488,9 @@ export {
|
|
|
481
488
|
BRUSH_MEDIA,
|
|
482
489
|
BRUSH_PATCH_PROPERTIES,
|
|
483
490
|
BRUSH_PRESETS,
|
|
491
|
+
BRUSH_PREVIEW_DARK_PAPER,
|
|
492
|
+
BRUSH_PREVIEW_FALLBACKS,
|
|
493
|
+
BRUSH_PREVIEW_MIN_CONTRAST,
|
|
484
494
|
BRUSH_PROFILE_JSON_SCHEMA,
|
|
485
495
|
BRUSH_SURFACES,
|
|
486
496
|
BRUSH_TIP_SHAPES,
|
|
@@ -502,6 +512,9 @@ export {
|
|
|
502
512
|
brushEditorSections,
|
|
503
513
|
brushIdFromName,
|
|
504
514
|
brushLibraryGroups,
|
|
515
|
+
brushPreviewColours,
|
|
516
|
+
brushPreviewStrength,
|
|
517
|
+
brushPreviewsOnDark,
|
|
505
518
|
changedBrushPaths,
|
|
506
519
|
checkBrush,
|
|
507
520
|
checkBrushEdit,
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preview colours for brushes: what a preview is drawn on and the colour that reads on it.
|
|
3
|
+
* `brushPreviewColours` picks the background (the renderer's paper, or dark paper for brushes
|
|
4
|
+
* that give off light) and a stroke colour with at least 3:1 contrast against it: the brush's
|
|
5
|
+
* default colour, resolved for that background (a light / dark pair takes its side), else a
|
|
6
|
+
* colour for the medium. Multiply brushes preview on white rather than a dark surface. Previews
|
|
7
|
+
* only: it never sets anyone's paint colour.
|
|
8
|
+
*/
|
|
9
|
+
import { type ColorScheme, type DualColor } from '../color/dual.cjs';
|
|
10
|
+
import { type BrushHostProfile } from './profiles.cjs';
|
|
11
|
+
import type { Brush } from './types.cjs';
|
|
12
|
+
/** The paper behind brushes that give off light, so their glow reads. */
|
|
13
|
+
export declare const BRUSH_PREVIEW_DARK_PAPER = "#141414";
|
|
14
|
+
/** The contrast a preview colour keeps against its background (WCAG large-text / graphics). */
|
|
15
|
+
export declare const BRUSH_PREVIEW_MIN_CONTRAST = 3;
|
|
16
|
+
/** Preview colours for brushes with no solid default, by medium (`tools` for tool brushes). */
|
|
17
|
+
export declare const BRUSH_PREVIEW_FALLBACKS: Readonly<Record<string, DualColor>>;
|
|
18
|
+
/**
|
|
19
|
+
* Whether a brush that gives off `light` previews on dark paper: light paint glows on dark, but a
|
|
20
|
+
* multiply light brush (a highlighter) is a tint on paper and previews on light paper.
|
|
21
|
+
*/
|
|
22
|
+
export declare function brushPreviewsOnDark(brush: {
|
|
23
|
+
light?: {
|
|
24
|
+
amount?: number;
|
|
25
|
+
};
|
|
26
|
+
tip?: {
|
|
27
|
+
blend?: string;
|
|
28
|
+
};
|
|
29
|
+
}): boolean;
|
|
30
|
+
export interface BrushPreviewColours {
|
|
31
|
+
/** The colour the preview is drawn on (#rrggbb): the renderer's paper, or dark paper for light paint. */
|
|
32
|
+
background: string;
|
|
33
|
+
/** The stroke colour (#rrggbb), at least `BRUSH_PREVIEW_MIN_CONTRAST` against `background`. */
|
|
34
|
+
color: string;
|
|
35
|
+
/** The background's scheme: which side of a light / dark colour was used. */
|
|
36
|
+
scheme: ColorScheme;
|
|
37
|
+
}
|
|
38
|
+
export interface BrushPreviewColoursOptions {
|
|
39
|
+
/**
|
|
40
|
+
* What the renderer draws on (#rrggbb, default white): the paper for the paint engine
|
|
41
|
+
* (`DEFAULT_PAPER.color`), or the surface behind a transparent preview (the canvas renderer's).
|
|
42
|
+
*/
|
|
43
|
+
paper?: string;
|
|
44
|
+
/** The host (default the paint editor): only a host that renders light previews light brushes on dark paper. */
|
|
45
|
+
profile?: BrushHostProfile;
|
|
46
|
+
/** The preview can't change what is behind it (a swatch in a menu): `paper` is kept, even for multiply brushes. */
|
|
47
|
+
keepPaper?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* How much of its colour a brush lays in one pass, roughly: tip opacity, flow (soft brushes build
|
|
51
|
+
* up) and paper grain (dry media skip the paper's dips) all thin it.
|
|
52
|
+
*/
|
|
53
|
+
export declare function brushPreviewStrength(brush: Brush): number;
|
|
54
|
+
/**
|
|
55
|
+
* The background and stroke colour for a preview of `brush` (see the module comment). A
|
|
56
|
+
* highlighter's own colour (a multiply brush that gives off light) is kept as it is: a tint reads
|
|
57
|
+
* by its colour, not its lightness.
|
|
58
|
+
*/
|
|
59
|
+
export declare function brushPreviewColours(brush: Brush, options?: BrushPreviewColoursOptions): BrushPreviewColours;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preview colours for brushes: what a preview is drawn on and the colour that reads on it.
|
|
3
|
+
* `brushPreviewColours` picks the background (the renderer's paper, or dark paper for brushes
|
|
4
|
+
* that give off light) and a stroke colour with at least 3:1 contrast against it: the brush's
|
|
5
|
+
* default colour, resolved for that background (a light / dark pair takes its side), else a
|
|
6
|
+
* colour for the medium. Multiply brushes preview on white rather than a dark surface. Previews
|
|
7
|
+
* only: it never sets anyone's paint colour.
|
|
8
|
+
*/
|
|
9
|
+
import { type ColorScheme, type DualColor } from '../color/dual.js';
|
|
10
|
+
import { type BrushHostProfile } from './profiles.js';
|
|
11
|
+
import type { Brush } from './types.js';
|
|
12
|
+
/** The paper behind brushes that give off light, so their glow reads. */
|
|
13
|
+
export declare const BRUSH_PREVIEW_DARK_PAPER = "#141414";
|
|
14
|
+
/** The contrast a preview colour keeps against its background (WCAG large-text / graphics). */
|
|
15
|
+
export declare const BRUSH_PREVIEW_MIN_CONTRAST = 3;
|
|
16
|
+
/** Preview colours for brushes with no solid default, by medium (`tools` for tool brushes). */
|
|
17
|
+
export declare const BRUSH_PREVIEW_FALLBACKS: Readonly<Record<string, DualColor>>;
|
|
18
|
+
/**
|
|
19
|
+
* Whether a brush that gives off `light` previews on dark paper: light paint glows on dark, but a
|
|
20
|
+
* multiply light brush (a highlighter) is a tint on paper and previews on light paper.
|
|
21
|
+
*/
|
|
22
|
+
export declare function brushPreviewsOnDark(brush: {
|
|
23
|
+
light?: {
|
|
24
|
+
amount?: number;
|
|
25
|
+
};
|
|
26
|
+
tip?: {
|
|
27
|
+
blend?: string;
|
|
28
|
+
};
|
|
29
|
+
}): boolean;
|
|
30
|
+
export interface BrushPreviewColours {
|
|
31
|
+
/** The colour the preview is drawn on (#rrggbb): the renderer's paper, or dark paper for light paint. */
|
|
32
|
+
background: string;
|
|
33
|
+
/** The stroke colour (#rrggbb), at least `BRUSH_PREVIEW_MIN_CONTRAST` against `background`. */
|
|
34
|
+
color: string;
|
|
35
|
+
/** The background's scheme: which side of a light / dark colour was used. */
|
|
36
|
+
scheme: ColorScheme;
|
|
37
|
+
}
|
|
38
|
+
export interface BrushPreviewColoursOptions {
|
|
39
|
+
/**
|
|
40
|
+
* What the renderer draws on (#rrggbb, default white): the paper for the paint engine
|
|
41
|
+
* (`DEFAULT_PAPER.color`), or the surface behind a transparent preview (the canvas renderer's).
|
|
42
|
+
*/
|
|
43
|
+
paper?: string;
|
|
44
|
+
/** The host (default the paint editor): only a host that renders light previews light brushes on dark paper. */
|
|
45
|
+
profile?: BrushHostProfile;
|
|
46
|
+
/** The preview can't change what is behind it (a swatch in a menu): `paper` is kept, even for multiply brushes. */
|
|
47
|
+
keepPaper?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* How much of its colour a brush lays in one pass, roughly: tip opacity, flow (soft brushes build
|
|
51
|
+
* up) and paper grain (dry media skip the paper's dips) all thin it.
|
|
52
|
+
*/
|
|
53
|
+
export declare function brushPreviewStrength(brush: Brush): number;
|
|
54
|
+
/**
|
|
55
|
+
* The background and stroke colour for a preview of `brush` (see the module comment). A
|
|
56
|
+
* highlighter's own colour (a multiply brush that gives off light) is kept as it is: a tint reads
|
|
57
|
+
* by its colour, not its lightness.
|
|
58
|
+
*/
|
|
59
|
+
export declare function brushPreviewColours(brush: Brush, options?: BrushPreviewColoursOptions): BrushPreviewColours;
|
package/dist/brushes/tools.d.cts
CHANGED
|
@@ -16,11 +16,18 @@ export interface BrushPreviewImage {
|
|
|
16
16
|
mimeType: string;
|
|
17
17
|
}
|
|
18
18
|
/** Draws a sample stroke with a brush (the host's renderer: the paint engine, a canvas…). */
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
export interface BrushPreviewRenderer {
|
|
20
|
+
(brush: Brush, options: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
color: string;
|
|
24
|
+
}): BrushPreviewImage | Promise<BrushPreviewImage>;
|
|
25
|
+
/**
|
|
26
|
+
* What it draws on (#rrggbb), for `brushPreviewColours`: the paint engine's paper. Unset for a
|
|
27
|
+
* transparent preview, which shows whatever the UI puts behind it.
|
|
28
|
+
*/
|
|
29
|
+
readonly paper?: string;
|
|
30
|
+
}
|
|
24
31
|
export interface BrushLibraryToolProviderOptions {
|
|
25
32
|
/** What this host can render (default `PAINT_PROFILE`): lists are filtered by it and writes checked against it. */
|
|
26
33
|
profile?: BrushHostProfile;
|
package/dist/brushes/tools.d.ts
CHANGED
|
@@ -16,11 +16,18 @@ export interface BrushPreviewImage {
|
|
|
16
16
|
mimeType: string;
|
|
17
17
|
}
|
|
18
18
|
/** Draws a sample stroke with a brush (the host's renderer: the paint engine, a canvas…). */
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
export interface BrushPreviewRenderer {
|
|
20
|
+
(brush: Brush, options: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
color: string;
|
|
24
|
+
}): BrushPreviewImage | Promise<BrushPreviewImage>;
|
|
25
|
+
/**
|
|
26
|
+
* What it draws on (#rrggbb), for `brushPreviewColours`: the paint engine's paper. Unset for a
|
|
27
|
+
* transparent preview, which shows whatever the UI puts behind it.
|
|
28
|
+
*/
|
|
29
|
+
readonly paper?: string;
|
|
30
|
+
}
|
|
24
31
|
export interface BrushLibraryToolProviderOptions {
|
|
25
32
|
/** What this host can render (default `PAINT_PROFILE`): lists are filtered by it and writes checked against it. */
|
|
26
33
|
profile?: BrushHostProfile;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
brushPreviewColours
|
|
3
|
+
} from "./chunk-ZS7LB2MV.js";
|
|
1
4
|
import {
|
|
2
5
|
pathDataToPolyline
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XDNWQMHY.js";
|
|
4
7
|
import {
|
|
5
8
|
BRUSH_PRESETS,
|
|
6
9
|
BUILTIN_BRUSHES,
|
|
@@ -11,7 +14,7 @@ import {
|
|
|
11
14
|
normalizeBrushSpec,
|
|
12
15
|
resolveBrush,
|
|
13
16
|
resolveCategory
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-J4SGJCPW.js";
|
|
15
18
|
import "./chunk-ACFSFUQH.js";
|
|
16
19
|
import {
|
|
17
20
|
formatNumber,
|
|
@@ -20,7 +23,7 @@ import {
|
|
|
20
23
|
} from "./chunk-PWBZH3FK.js";
|
|
21
24
|
import {
|
|
22
25
|
parseCssColor
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-DVPQFMH6.js";
|
|
24
27
|
import "./chunk-SZTI6EER.js";
|
|
25
28
|
import "./chunk-V2ZCJRDM.js";
|
|
26
29
|
import {
|
|
@@ -160,6 +163,10 @@ function brushedShapeSvgNow(shape, size, scale, place = {}) {
|
|
|
160
163
|
const content = svg.transform && body ? `<g transform="${svg.transform}">${body}</g>` : body;
|
|
161
164
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${f(size.width)}" height="${f(size.height)}" viewBox="0 0 ${f(size.width)} ${f(size.height)}">${content}</svg>`;
|
|
162
165
|
}
|
|
166
|
+
function swatchColour(brush, background, spec) {
|
|
167
|
+
const facets = typeof brush !== "string" ? null : spec ? readCanvasBrushSpec(spec) : BRUSH_PRESETS.find((b) => b.id === brush);
|
|
168
|
+
return background && facets ? brushPreviewColours(facets, { paper: background, profile: CANVAS_PROFILE, keepPaper: true }).color : "#1f2937";
|
|
169
|
+
}
|
|
163
170
|
function brushSwatchNow(brush, options, spec) {
|
|
164
171
|
const w = options.width && options.width > 8 ? options.width : 96;
|
|
165
172
|
const h = options.height && options.height > 4 ? options.height : 24;
|
|
@@ -170,7 +177,7 @@ function brushSwatchNow(brush, options, spec) {
|
|
|
170
177
|
const pts = Array.from({ length: 9 }, (_, i) => [pad + (w - 2 * pad) * i / 8, h / 2 + Math.sin(i / 8 * Math.PI * 2) * (h / 2 - pad) * 0.6]);
|
|
171
178
|
const d = pts.map(([x, y], i) => `${i ? "L" : "M"}${x.toFixed(2)} ${y.toFixed(2)}`).join(" ");
|
|
172
179
|
const image = renderShapeBrushstrokeNow(
|
|
173
|
-
{ kind: "path", d, stroke: options.color ??
|
|
180
|
+
{ kind: "path", d, stroke: options.color ?? swatchColour(brush, options.background, spec), strokeWidth: size, brush: { brush, ...spec ? { spec } : {}, seed: 7, size, pressure: [0.35, 1, 0.5] } },
|
|
174
181
|
options.scale && options.scale > 0 ? options.scale : 2
|
|
175
182
|
);
|
|
176
183
|
return image?.href ?? "";
|