@pixerate/editor 0.255.0 → 0.257.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 +40 -38
- package/dist/agent/index.js +9 -7
- package/dist/animation/index.cjs +4 -2
- package/dist/animation/index.js +4 -2
- package/dist/animation-editor/index.cjs +63 -61
- package/dist/animation-editor/index.js +7 -5
- package/dist/brushes/colour.d.cts +11 -0
- package/dist/brushes/colour.d.ts +11 -0
- package/dist/brushes/index.cjs +51 -30
- package/dist/brushes/index.d.cts +1 -0
- package/dist/brushes/index.d.ts +1 -0
- package/dist/brushes/index.js +25 -4
- package/dist/brushes/resolve.d.cts +2 -0
- package/dist/brushes/resolve.d.ts +2 -0
- package/dist/brushes/schema.d.cts +1 -0
- package/dist/brushes/schema.d.ts +1 -0
- package/dist/brushes/tools.d.cts +7 -0
- package/dist/brushes/tools.d.ts +7 -0
- package/dist/brushes/types.d.cts +10 -2
- package/dist/brushes/types.d.ts +10 -2
- package/dist/brushes/ui.d.cts +14 -3
- package/dist/brushes/ui.d.ts +14 -3
- package/dist/{brushstrokeRender-HCOQUSWW.js → brushstrokeRender-JI4W6F2G.js} +2 -2
- package/dist/{brushstrokeRender-ZZOXI5O5.cjs → brushstrokeRender-MQ6PSDM5.cjs} +11 -11
- package/dist/canvas/index.cjs +20 -18
- package/dist/canvas/index.js +7 -5
- package/dist/chart/index.cjs +159 -157
- package/dist/chart/index.js +9 -7
- package/dist/{chunk-7272D3K2.js → chunk-2EUW2XZX.js} +27 -276
- package/dist/{chunk-L6Y7TSQ4.js → chunk-2VJ6OVJV.js} +1 -1
- package/dist/{chunk-6ZZKRH7R.js → chunk-47V3WXDG.js} +2 -2
- package/dist/{chunk-H7ET2ISK.cjs → chunk-4IMD2TLY.cjs} +52 -52
- package/dist/{chunk-VUKUTT2W.js → chunk-4M4E3N6X.js} +1 -1
- package/dist/{chunk-TBAVCLEQ.cjs → chunk-5Q5MLXAD.cjs} +23 -23
- package/dist/{chunk-MONXNVZK.js → chunk-6I23ZCGK.js} +5 -3
- package/dist/{chunk-GOBOCZZI.js → chunk-6NQPKNUZ.js} +1 -1
- package/dist/{chunk-WYGSR3IJ.js → chunk-AORZ5M5C.js} +1 -1
- package/dist/chunk-AVTPZO4Z.cjs +142 -0
- package/dist/{chunk-WKMUBATU.js → chunk-C2WEIEUB.js} +1 -1
- package/dist/{chunk-P3K2JCJA.js → chunk-D5BXSOSU.js} +3 -3
- package/dist/chunk-E2V5DA3W.js +36 -0
- package/dist/{chunk-WZOGDKCQ.js → chunk-F7CPSRLN.js} +0 -133
- package/dist/chunk-FJBQTZS4.js +17 -0
- package/dist/{chunk-SOSBOS5T.cjs → chunk-G23BTQA5.cjs} +22 -22
- package/dist/{chunk-EUIDTZNQ.cjs → chunk-I3Y2Q3PM.cjs} +59 -308
- package/dist/{chunk-YHUMGBZD.js → chunk-ICTPLVSR.js} +22 -4
- package/dist/{chunk-LRNUZKWV.cjs → chunk-IPUTIUGQ.cjs} +1 -1
- package/dist/{chunk-6GRUVGKU.js → chunk-ITURMC2M.js} +3 -3
- package/dist/{chunk-HYWRU5VX.js → chunk-IXQZHCOF.js} +1 -1
- package/dist/chunk-J5UQHWVL.js +142 -0
- package/dist/{chunk-YBAPT7NL.js → chunk-JC2SHA4A.js} +1 -23
- package/dist/chunk-LRTR4ASZ.cjs +17 -0
- package/dist/{chunk-HUAISCUX.cjs → chunk-M2HG5DJ2.cjs} +18 -18
- package/dist/{chunk-N76AMOKE.cjs → chunk-MDLEGVEN.cjs} +42 -42
- package/dist/chunk-MEGSQUQO.cjs +36 -0
- package/dist/chunk-MLLTWAXH.cjs +276 -0
- package/dist/{chunk-RHPSE2YR.js → chunk-MQ6MGIQM.js} +2 -2
- package/dist/{chunk-PGPFWC35.cjs → chunk-MQGQTKVW.cjs} +51 -33
- package/dist/{chunk-5YWWQ36H.cjs → chunk-O3ZVZSNJ.cjs} +9 -9
- package/dist/{chunk-GCTUOTCW.cjs → chunk-P3PZ63M3.cjs} +35 -35
- package/dist/{chunk-WRZ6C4TU.cjs → chunk-P6WYDBTH.cjs} +4 -4
- package/dist/{chunk-CJ6TBL2N.cjs → chunk-RHEMMGCN.cjs} +16 -16
- package/dist/{chunk-HIMGBZAM.cjs → chunk-RSIKDWOP.cjs} +201 -38
- package/dist/{chunk-SABJMH6M.cjs → chunk-RVGP2XLF.cjs} +2 -135
- package/dist/{chunk-JVRLGV3C.js → chunk-SMTUQWGY.js} +184 -21
- package/dist/{chunk-DMTEQ6SH.js → chunk-SSFMWJDK.js} +4 -4
- package/dist/{chunk-TFF2GTGN.cjs → chunk-SXQHWXEL.cjs} +2 -24
- package/dist/{chunk-IWEVV63O.cjs → chunk-UEYLANO3.cjs} +18 -16
- package/dist/chunk-VR6OGHU5.js +276 -0
- package/dist/{chunk-AF23QK5F.js → chunk-YQ4PQTBB.js} +1 -1
- package/dist/{chunk-B7V34GIH.cjs → chunk-YSGW7VV4.cjs} +88 -88
- package/dist/{chunk-3NS5C7FB.cjs → chunk-YYBW6DF2.cjs} +76 -76
- package/dist/{chunk-UFEDHACQ.js → chunk-Z7BX4TWO.js} +2 -2
- package/dist/{chunk-RUONPPMC.cjs → chunk-ZSE25IZA.cjs} +8 -8
- package/dist/color/index.cjs +7 -3
- package/dist/color/index.js +18 -14
- package/dist/export/index.cjs +8 -6
- package/dist/export/index.js +7 -5
- package/dist/extensions/index.cjs +11 -9
- package/dist/extensions/index.js +10 -8
- package/dist/gradient/index.cjs +33 -31
- package/dist/gradient/index.js +5 -3
- package/dist/image-editor/brush-presets.d.cts +4 -1
- package/dist/image-editor/brush-presets.d.ts +4 -1
- package/dist/image-editor/controller.d.cts +10 -5
- package/dist/image-editor/controller.d.ts +10 -5
- package/dist/image-editor/index.cjs +1090 -1073
- package/dist/image-editor/index.js +37 -20
- package/dist/index.cjs +17 -15
- package/dist/index.js +11 -9
- package/dist/paint-editor/brushes.d.cts +18 -1
- package/dist/paint-editor/brushes.d.ts +18 -1
- package/dist/paint-editor/collaboration-tools.d.cts +19 -0
- package/dist/paint-editor/collaboration-tools.d.ts +19 -0
- package/dist/paint-editor/collaboration.d.cts +180 -0
- package/dist/paint-editor/collaboration.d.ts +180 -0
- package/dist/paint-editor/controller.d.cts +83 -0
- package/dist/paint-editor/controller.d.ts +83 -0
- package/dist/paint-editor/engine.d.cts +7 -0
- package/dist/paint-editor/engine.d.ts +7 -0
- package/dist/paint-editor/index.cjs +2027 -1331
- package/dist/paint-editor/index.d.cts +2 -0
- package/dist/paint-editor/index.d.ts +2 -0
- package/dist/paint-editor/index.js +1671 -975
- package/dist/paint-editor/mark-settings.d.cts +1 -1
- package/dist/paint-editor/mark-settings.d.ts +1 -1
- package/dist/paint-editor/procedural.d.cts +4 -2
- package/dist/paint-editor/procedural.d.ts +4 -2
- package/dist/paint-editor/stamp-tip.d.cts +45 -0
- package/dist/paint-editor/stamp-tip.d.ts +45 -0
- package/dist/paint-editor/stroke.d.cts +2 -0
- package/dist/paint-editor/stroke.d.ts +2 -0
- package/dist/stickers/index.cjs +4 -2
- package/dist/stickers/index.js +6 -4
- package/dist/typography/index.cjs +3 -2
- package/dist/typography/index.js +2 -1
- package/dist/vector/index.cjs +971 -969
- package/dist/vector/index.js +8 -6
- package/dist/video-editor/index.cjs +4 -2
- package/dist/video-editor/index.js +4 -2
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +21 -11
- package/skills/pixerate-brushes-design/SKILL.md +6 -2
- package/skills/pixerate-brushes-design/evals/canvas-chalk.json +8 -8
- package/skills/pixerate-canvas/SKILL.md +3 -2
- package/skills/pixerate-image-editor/SKILL.md +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +35 -47
- package/skills/pixerate-paint-editor/references/painting-alongside.md +19 -0
- package/skills/pixerate-vector/SKILL.md +1 -1
|
@@ -75,7 +75,13 @@ var DEFAULT_PARTICLE = {
|
|
|
75
75
|
dotRotation: "random"
|
|
76
76
|
};
|
|
77
77
|
function normalizeParticle(raw = {}, base = DEFAULT_PARTICLE) {
|
|
78
|
-
const
|
|
78
|
+
const texture = (t) => {
|
|
79
|
+
if (typeof t !== "string") return null;
|
|
80
|
+
const bare = t.startsWith("editor:") ? t.slice(7) : t;
|
|
81
|
+
if (STAMP_KINDS.includes(bare)) return bare;
|
|
82
|
+
return /^[^:\s]+:\S+$/.test(t) && t.length <= 200 ? t : null;
|
|
83
|
+
};
|
|
84
|
+
const textures = Array.isArray(raw.dotTextures) ? raw.dotTextures.map(texture).filter((t) => t !== null).slice(0, MAX_DOT_TEXTURES) : [...base.dotTextures ?? []];
|
|
79
85
|
return {
|
|
80
86
|
kind: oneOf(raw.kind, PARTICLE_KINDS, base.kind),
|
|
81
87
|
render: oneOf(raw.render, PARTICLE_RENDERS, base.render),
|
|
@@ -204,6 +210,20 @@ function normalizeBehavior(raw = {}, base = DEFAULT_BEHAVIOR) {
|
|
|
204
210
|
multicolor: normalizeMultiColor(raw.multicolor ?? {}, base.multicolor)
|
|
205
211
|
};
|
|
206
212
|
}
|
|
213
|
+
var DEFAULT_SPRAY = { density: 0.5, size: 0.12 };
|
|
214
|
+
function readStamp(raw, base) {
|
|
215
|
+
if (raw === null) return null;
|
|
216
|
+
if (typeof raw !== "string") return base;
|
|
217
|
+
if (STAMP_KINDS.includes(raw)) return `editor:${raw}`;
|
|
218
|
+
return /^[^:\s]+:\S+$/.test(raw) && raw.length <= 200 ? raw : base;
|
|
219
|
+
}
|
|
220
|
+
function readSpray(raw, base) {
|
|
221
|
+
if (raw === null) return null;
|
|
222
|
+
if (!raw || typeof raw !== "object") return base;
|
|
223
|
+
const r = raw;
|
|
224
|
+
const b = base ?? DEFAULT_SPRAY;
|
|
225
|
+
return { density: unit2(r.density, b.density), size: range(r.size, 0.02, 1, b.size) };
|
|
226
|
+
}
|
|
207
227
|
function isWetCapable(brush) {
|
|
208
228
|
return brush.engine === "dab" || brush.engine === "mixer" || brush.engine === "wet" || brush.engine === "impasto";
|
|
209
229
|
}
|
|
@@ -305,6 +325,8 @@ function normalizePaintBrush(raw = {}, base) {
|
|
|
305
325
|
bristle: normalizeBristle(raw.bristle ?? {}, b.bristle ?? DEFAULT_BRISTLE),
|
|
306
326
|
sticker: normalizeStickerSettings(raw.sticker ?? {}, b.sticker ?? DEFAULT_STICKER),
|
|
307
327
|
light: normalizeLight(raw.light ?? {}, b.light ?? DEFAULT_LIGHT),
|
|
328
|
+
stamp: readStamp(raw.stamp, b.stamp ?? null),
|
|
329
|
+
spray: readSpray(raw.spray, b.spray ?? null),
|
|
308
330
|
paint,
|
|
309
331
|
...raw.builtin ? { builtin: true } : {}
|
|
310
332
|
};
|
|
@@ -330,6 +352,8 @@ var BASE_BRUSH = {
|
|
|
330
352
|
bristle: { ...DEFAULT_BRISTLE },
|
|
331
353
|
sticker: { ...DEFAULT_STICKER, stamps: [...DEFAULT_STICKER.stamps] },
|
|
332
354
|
light: { ...DEFAULT_LIGHT },
|
|
355
|
+
stamp: null,
|
|
356
|
+
spray: null,
|
|
333
357
|
paint: null
|
|
334
358
|
};
|
|
335
359
|
var builtin = (init) => ({ ...normalizePaintBrush(init), builtin: true });
|
|
@@ -959,6 +983,53 @@ var BUILTIN_BRUSHES = [
|
|
|
959
983
|
engine: "wet",
|
|
960
984
|
tip: { size: 40, hardness: 0.5, spacing: 0.12, opacity: 1, flow: 1, smoothing: 0.2, pressureSize: false, pressureOpacity: true },
|
|
961
985
|
wet: { tool: "blot", strength: 0.7 }
|
|
986
|
+
}),
|
|
987
|
+
// Pens, crayon, chalk and the spray can (their facets: `@pixerate/editor/brushes` presets).
|
|
988
|
+
builtin({
|
|
989
|
+
id: "ballpoint",
|
|
990
|
+
name: "Ballpoint",
|
|
991
|
+
category: "ink",
|
|
992
|
+
tip: { size: 3, hardness: 0.95, spacing: 0.05, opacity: 0.9, smoothing: 0.35, pressureOpacity: true },
|
|
993
|
+
grain: 0.15,
|
|
994
|
+
pressureSmoothing: 0.3,
|
|
995
|
+
dynamics: { minSize: 0.7, opacityJitter: 0.08 }
|
|
996
|
+
}),
|
|
997
|
+
builtin({
|
|
998
|
+
id: "gel-pen",
|
|
999
|
+
name: "Gel pen",
|
|
1000
|
+
category: "ink",
|
|
1001
|
+
tip: { size: 4, spacing: 0.04, smoothing: 0.3 },
|
|
1002
|
+
pressureSmoothing: 0.3,
|
|
1003
|
+
dynamics: { minSize: 0.8 }
|
|
1004
|
+
}),
|
|
1005
|
+
builtin({
|
|
1006
|
+
id: "fineliner",
|
|
1007
|
+
name: "Fineliner",
|
|
1008
|
+
category: "ink",
|
|
1009
|
+
tip: { size: 2, spacing: 0.05, smoothing: 0.4, pressureSize: false }
|
|
1010
|
+
}),
|
|
1011
|
+
builtin({
|
|
1012
|
+
id: "crayon",
|
|
1013
|
+
name: "Crayon",
|
|
1014
|
+
category: "pastel",
|
|
1015
|
+
tip: { size: 14, hardness: 0.7, spacing: 0.06, opacity: 0.9, flow: 0.85, smoothing: 0.2 },
|
|
1016
|
+
grain: 0.9,
|
|
1017
|
+
dynamics: { minSize: 0.6, tiltSize: 0.6, sizeJitter: 0.1, opacityJitter: 0.1 }
|
|
1018
|
+
}),
|
|
1019
|
+
builtin({
|
|
1020
|
+
id: "chalk",
|
|
1021
|
+
name: "Chalk",
|
|
1022
|
+
category: "pastel",
|
|
1023
|
+
tip: { size: 18, hardness: 0.6, spacing: 0.05, opacity: 0.95, flow: 0.8, smoothing: 0.2 },
|
|
1024
|
+
grain: 1,
|
|
1025
|
+
dynamics: { minSize: 0.5, tiltSize: 0.8, sizeJitter: 0.12, scatter: 0.05 }
|
|
1026
|
+
}),
|
|
1027
|
+
builtin({
|
|
1028
|
+
id: "spray-can",
|
|
1029
|
+
name: "Spray can",
|
|
1030
|
+
category: "airbrush",
|
|
1031
|
+
tip: { size: 60, hardness: 0.9, spacing: 0.08, opacity: 0.9, smoothing: 0.2, pressureSize: false, pressureOpacity: true },
|
|
1032
|
+
spray: { density: 0.7, size: 0.04 }
|
|
962
1033
|
})
|
|
963
1034
|
];
|
|
964
1035
|
var DEFAULT_BRUSH_ID = "pencil-6b";
|
|
@@ -998,12 +1069,16 @@ var EDITOR_STAMPS = {
|
|
|
998
1069
|
toEngine: (v) => v.flatMap((ref) => {
|
|
999
1070
|
try {
|
|
1000
1071
|
const stamp = editorStampOf(ref);
|
|
1001
|
-
return stamp ? [stamp] : [];
|
|
1072
|
+
return stamp ? [stamp] : ref.includes(":") ? [ref] : [];
|
|
1002
1073
|
} catch {
|
|
1003
1074
|
return [];
|
|
1004
1075
|
}
|
|
1005
1076
|
}),
|
|
1006
|
-
toFacet: (v) => v.map((stamp) => `editor:${stamp}`)
|
|
1077
|
+
toFacet: (v) => v.map((stamp) => stamp.includes(":") ? stamp : `editor:${stamp}`)
|
|
1078
|
+
};
|
|
1079
|
+
var ONE_STAMP = {
|
|
1080
|
+
toEngine: (v) => v[0] ?? null,
|
|
1081
|
+
toFacet: (v) => v ? [v] : void 0
|
|
1007
1082
|
};
|
|
1008
1083
|
var f = (facet, engine, engines = ALL, extra = {}) => ({ facet, engine, engines, ...extra });
|
|
1009
1084
|
var each = (facetPrefix, enginePrefix, keys, engines) => keys.map((k) => f(`${facetPrefix}.${k}`, `${enginePrefix}.${k}`, engines));
|
|
@@ -1047,6 +1122,9 @@ var BRUSH_FIELDS = [
|
|
|
1047
1122
|
f("tip.stamps", "particle.dotTextures", ["particle"], { shapes: ["stamp"], map: EDITOR_STAMPS }),
|
|
1048
1123
|
f("motion.waveSpeed", "particle.waveSpeed", ["particle"]),
|
|
1049
1124
|
f("tip.stamps", "sticker.stamps", ["sticker"], { shapes: ["stamp"] }),
|
|
1125
|
+
f("tip.stamps", "stamp", ["dab"], { shapes: ["stamp"], map: ONE_STAMP }),
|
|
1126
|
+
f("marks.density", "spray.density", ["dab"], { marks: ["scatter"] }),
|
|
1127
|
+
f("marks.size", "spray.size", ["dab"], { marks: ["scatter"] }),
|
|
1050
1128
|
...each("marks", "sticker", ["density", "sizeJitter", "rotationJitter", "scatter"], ["sticker"]),
|
|
1051
1129
|
f("marks.colourJitter", "sticker.colorJitter", ["sticker"]),
|
|
1052
1130
|
...each("tip.bristle", "bristle", ["count", "stiffness", "splay", "thickness", "load", "jitter"], ["bristle"])
|
|
@@ -1086,6 +1164,8 @@ var VARIETY_CATEGORY = {
|
|
|
1086
1164
|
pastel: "pastel",
|
|
1087
1165
|
"soft-pastel": "pastel",
|
|
1088
1166
|
"oil-pastel": "pastel",
|
|
1167
|
+
crayon: "pastel",
|
|
1168
|
+
chalk: "pastel",
|
|
1089
1169
|
charcoal: "charcoal",
|
|
1090
1170
|
airbrush: "airbrush",
|
|
1091
1171
|
marker: "marker"
|
|
@@ -1118,10 +1198,11 @@ function resolveBrush(brush, options = {}) {
|
|
|
1118
1198
|
const engine = resolveEngine(brush);
|
|
1119
1199
|
const input = { id: brush.id, name: brush.name, category: resolveCategory(brush, engine), engine };
|
|
1120
1200
|
for (const field of BRUSH_FIELDS) {
|
|
1121
|
-
if (!field.engines.includes(engine) || field.shapes && !field.shapes.includes(brush.tip.shape)) continue;
|
|
1201
|
+
if (!field.engines.includes(engine) || field.shapes && !field.shapes.includes(brush.tip.shape) || field.marks && !field.marks.includes(brush.marks?.kind ?? "continuous")) continue;
|
|
1122
1202
|
const v = getPath(brush, field.facet);
|
|
1123
1203
|
if (v !== void 0) setPath(input, field.engine, field.map ? field.map.toEngine(v) : copy(v));
|
|
1124
1204
|
}
|
|
1205
|
+
if (engine === "dab" && brush.marks?.kind === "scatter") input.spray = { ...input.spray ?? {} };
|
|
1125
1206
|
if (engine === "wet") {
|
|
1126
1207
|
setPath(input, "wet.tool", brush.kind === "tool" ? WET_TOOL_OF[brush.tool] : "paint");
|
|
1127
1208
|
const medium = resolveWetMedium(brush);
|
|
@@ -1147,7 +1228,7 @@ var CATEGORY_MEDIUM = {
|
|
|
1147
1228
|
};
|
|
1148
1229
|
function tipShape(b) {
|
|
1149
1230
|
if (b.engine === "bristle") return "bristle";
|
|
1150
|
-
if (b.engine === "sticker" || b.engine === "particle" && b.particle.dotTextures.length > 0) return "stamp";
|
|
1231
|
+
if (b.engine === "sticker" || b.engine === "particle" && b.particle.dotTextures.length > 0 || b.engine === "dab" && b.stamp) return "stamp";
|
|
1151
1232
|
if (b.tip.roundness >= 1) return "round";
|
|
1152
1233
|
return Math.abs(Math.abs(b.tip.angle % 180) - 45) < 1e-9 || Math.abs(Math.abs(b.tip.angle % 180) - 135) < 1e-9 ? "chisel" : "flat";
|
|
1153
1234
|
}
|
|
@@ -1173,7 +1254,7 @@ function skeleton(b) {
|
|
|
1173
1254
|
return { ...brush, marks: { kind: "objects" } };
|
|
1174
1255
|
default: {
|
|
1175
1256
|
const [medium, variety] = CATEGORY_MEDIUM[b.category] ?? [];
|
|
1176
|
-
return { ...brush, ...medium ? { medium } : {}, ...variety ? { variety } : {} };
|
|
1257
|
+
return { ...brush, ...medium ? { medium } : {}, ...variety ? { variety } : {}, ...b.engine === "dab" && b.spray ? { marks: { kind: "scatter" } } : {} };
|
|
1177
1258
|
}
|
|
1178
1259
|
}
|
|
1179
1260
|
}
|
|
@@ -1183,7 +1264,7 @@ function migrateBrushV1(raw) {
|
|
|
1183
1264
|
const brush = skeleton(b);
|
|
1184
1265
|
const defaults = resolveBrush(brush);
|
|
1185
1266
|
for (const field of BRUSH_FIELDS) {
|
|
1186
|
-
if (!field.engines.includes(b.engine) || field.shapes && !field.shapes.includes(brush.tip.shape)) continue;
|
|
1267
|
+
if (!field.engines.includes(b.engine) || field.shapes && !field.shapes.includes(brush.tip.shape) || field.marks && !field.marks.includes(brush.marks?.kind ?? "continuous")) continue;
|
|
1187
1268
|
const v = getPath(b, field.engine);
|
|
1188
1269
|
if (!equal(v, getPath(defaults, field.engine))) setPath(brush, field.facet, field.map ? field.map.toFacet(v) : copy2(v));
|
|
1189
1270
|
}
|
|
@@ -1196,7 +1277,7 @@ var BRUSH_KINDS = ["mark", "tool"];
|
|
|
1196
1277
|
var BRUSH_MEDIA = ["paint", "ink", "dry", "spray"];
|
|
1197
1278
|
var BRUSH_TOOLS = ["eraser", "blender", "smudge", "water", "dryer", "blow", "blot", "wet-blend", "wet-drag"];
|
|
1198
1279
|
var BRUSH_TIP_SHAPES = ["round", "flat", "chisel", "bristle", "stamp"];
|
|
1199
|
-
var BRUSH_MARKS_KINDS = ["continuous", "particles", "objects"];
|
|
1280
|
+
var BRUSH_MARKS_KINDS = ["continuous", "scatter", "particles", "objects"];
|
|
1200
1281
|
var BRUSH_SURFACES = ["dry", "wet", "thick"];
|
|
1201
1282
|
|
|
1202
1283
|
// src/brushes/schema.ts
|
|
@@ -1284,6 +1365,15 @@ var PARTICLES = object(
|
|
|
1284
1365
|
},
|
|
1285
1366
|
["kind"]
|
|
1286
1367
|
);
|
|
1368
|
+
var SCATTER = object(
|
|
1369
|
+
"A spray (a spray can): each dab lays a seeded scatter of droplets across the tip; jitter and size come from dynamics and the tip. Missing fields take their defaults.",
|
|
1370
|
+
{
|
|
1371
|
+
kind: { type: "string", const: "scatter", description: 'Always "scatter".' },
|
|
1372
|
+
density: unit3("Droplets per dab: 1 + density \xD7 31 (default 0.5)."),
|
|
1373
|
+
size: num(0.02, 1, "Droplet size as a fraction of the tip size (default 0.12).")
|
|
1374
|
+
},
|
|
1375
|
+
["kind"]
|
|
1376
|
+
);
|
|
1287
1377
|
var OBJECTS = object(
|
|
1288
1378
|
"Each mark stays an editable object (a sticker) on a sticker layer; needs a stamp tip. Missing fields take their defaults.",
|
|
1289
1379
|
{
|
|
@@ -1423,7 +1513,7 @@ var BRUSH_JSON_SCHEMA = object(
|
|
|
1423
1513
|
"Tools: eraser removes paint; blender mixes the colours under the tip; smudge drags paint along; water lays clear water (lifts dried paint with behaviour.wet.rewet); dryer dries wet paint; blow pushes water along; blot takes wet paint up; wet-blend evens out wet pigment; wet-drag drags wet paint."
|
|
1424
1514
|
),
|
|
1425
1515
|
tip: TIP,
|
|
1426
|
-
marks: { description: "How the tip is laid along the path (default continuous).", oneOf: [CONTINUOUS, PARTICLES, OBJECTS] },
|
|
1516
|
+
marks: { description: "How the tip is laid along the path (default continuous): continuous dabs, a scatter of spray droplets, particles, or objects (editable stickers).", oneOf: [CONTINUOUS, SCATTER, PARTICLES, OBJECTS] },
|
|
1427
1517
|
dynamics: DYNAMICS,
|
|
1428
1518
|
behaviour: BEHAVIOUR,
|
|
1429
1519
|
light: LIGHT,
|
|
@@ -1434,7 +1524,7 @@ var BRUSH_JSON_SCHEMA = object(
|
|
|
1434
1524
|
);
|
|
1435
1525
|
var BRUSH_FACET_SCHEMAS = {
|
|
1436
1526
|
tip: TIP,
|
|
1437
|
-
marks: { continuous: CONTINUOUS, particles: PARTICLES, objects: OBJECTS },
|
|
1527
|
+
marks: { continuous: CONTINUOUS, scatter: SCATTER, particles: PARTICLES, objects: OBJECTS },
|
|
1438
1528
|
dynamics: DYNAMICS,
|
|
1439
1529
|
behaviour: BEHAVIOUR,
|
|
1440
1530
|
light: LIGHT,
|
|
@@ -1562,7 +1652,7 @@ function normalizeBrushSpec(raw, problems = []) {
|
|
|
1562
1652
|
if (rawMarks !== void 0) {
|
|
1563
1653
|
const k = isObject(rawMarks) ? rawMarks.kind : void 0;
|
|
1564
1654
|
const schema = BRUSH_FACET_SCHEMAS.marks[k];
|
|
1565
|
-
if (!schema) problems.push(`marks.kind ${JSON.stringify(k)} is not valid; use continuous, particles or objects. marks dropped.`);
|
|
1655
|
+
if (!schema) problems.push(`marks.kind ${JSON.stringify(k)} is not valid; use continuous, scatter, particles or objects. marks dropped.`);
|
|
1566
1656
|
else brush.marks = readObject(rawMarks, schema, "brush.marks", problems);
|
|
1567
1657
|
}
|
|
1568
1658
|
if (rawColour !== void 0) {
|
|
@@ -1600,6 +1690,14 @@ function normalizeBrushSpec(raw, problems = []) {
|
|
|
1600
1690
|
delete brush.marks;
|
|
1601
1691
|
}
|
|
1602
1692
|
}
|
|
1693
|
+
if (brush.marks?.kind === "scatter") {
|
|
1694
|
+
const surface = brush.behaviour?.surface;
|
|
1695
|
+
const why = brush.tip.shape === "bristle" ? "bristle tips lay their own marks" : surface === "wet" || surface === "thick" ? `${surface} paint is not sprayed` : brush.behaviour?.exchange ? "a spray does not pick paint up" : null;
|
|
1696
|
+
if (why) {
|
|
1697
|
+
drop("marks", why);
|
|
1698
|
+
delete brush.marks;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1603
1701
|
if (brush.marks?.kind === "objects" && brush.tip.shape !== "stamp") {
|
|
1604
1702
|
problems.push("marks objects lay stamps: tip.shape set to stamp.");
|
|
1605
1703
|
brush.tip.shape = "stamp";
|
|
@@ -1613,15 +1711,7 @@ function normalizeBrushSpec(raw, problems = []) {
|
|
|
1613
1711
|
delete brush.tip.stamps;
|
|
1614
1712
|
}
|
|
1615
1713
|
if (brush.tip.stamps) {
|
|
1616
|
-
const
|
|
1617
|
-
const stamps = brush.tip.stamps.flatMap((s) => {
|
|
1618
|
-
const ref = normalizeStickerRef(s);
|
|
1619
|
-
if (particles && !editorStampOf(ref)) {
|
|
1620
|
-
problems.push(`brush.tip.stamps "${ref}" dropped: particle marks lay only the editor's stamps (editor:star, editor:dot\u2026).`);
|
|
1621
|
-
return [];
|
|
1622
|
-
}
|
|
1623
|
-
return [ref];
|
|
1624
|
-
});
|
|
1714
|
+
const stamps = brush.tip.stamps.map((s) => normalizeStickerRef(s));
|
|
1625
1715
|
if (stamps.length) brush.tip.stamps = stamps;
|
|
1626
1716
|
else {
|
|
1627
1717
|
drop("tip.stamps", "none of the stamps can be laid");
|
|
@@ -2123,7 +2213,8 @@ var BRUSH_PRESETS = [
|
|
|
2123
2213
|
variety: "neon",
|
|
2124
2214
|
tip: { shape: "round", size: 10, hardness: 0.9, spacing: 0.04 },
|
|
2125
2215
|
dynamics: { smoothing: 0.45, pressureSize: false },
|
|
2126
|
-
light: { amount: 1 }
|
|
2216
|
+
light: { amount: 1 },
|
|
2217
|
+
colour: { palette: ["#f0abfc", "#22d3ee", "#a3e635", "#fb7185", "#fde047"] }
|
|
2127
2218
|
},
|
|
2128
2219
|
{
|
|
2129
2220
|
id: "light-airbrush",
|
|
@@ -2340,6 +2431,77 @@ var BRUSH_PRESETS = [
|
|
|
2340
2431
|
tip: { shape: "round", size: 40, hardness: 0.5, spacing: 0.12 },
|
|
2341
2432
|
dynamics: { smoothing: 0.2, pressureSize: false, pressureOpacity: true },
|
|
2342
2433
|
behaviour: { strength: 0.7 }
|
|
2434
|
+
},
|
|
2435
|
+
// --- Pens, crayon, chalk and the spray can -------------------------------------------
|
|
2436
|
+
// A ballpoint: a fine, hard, even line that lightens with a light touch.
|
|
2437
|
+
{
|
|
2438
|
+
id: "ballpoint",
|
|
2439
|
+
name: "Ballpoint",
|
|
2440
|
+
kind: "mark",
|
|
2441
|
+
medium: "ink",
|
|
2442
|
+
variety: "ballpoint",
|
|
2443
|
+
tip: { shape: "round", size: 3, hardness: 0.95, spacing: 0.05, opacity: 0.9 },
|
|
2444
|
+
dynamics: { smoothing: 0.35, pressureSmoothing: 0.3, pressureOpacity: true, minSize: 0.7, opacityJitter: 0.08 },
|
|
2445
|
+
behaviour: { grain: 0.15 },
|
|
2446
|
+
colour: { default: "#1e3a8a", palette: ["#1e3a8a", "#111827", "#b91c1c", "#166534"] }
|
|
2447
|
+
},
|
|
2448
|
+
// A gel pen: an even, opaque, saturated line.
|
|
2449
|
+
{
|
|
2450
|
+
id: "gel-pen",
|
|
2451
|
+
name: "Gel pen",
|
|
2452
|
+
kind: "mark",
|
|
2453
|
+
medium: "ink",
|
|
2454
|
+
variety: "gel",
|
|
2455
|
+
tip: { shape: "round", size: 4, spacing: 0.04 },
|
|
2456
|
+
dynamics: { smoothing: 0.3, pressureSmoothing: 0.3, minSize: 0.8 },
|
|
2457
|
+
colour: { default: "#111827", palette: ["#111827", "#7c3aed", "#db2777", "#0891b2", "#16a34a", "#f59e0b"] }
|
|
2458
|
+
},
|
|
2459
|
+
// A fineliner: one width, whatever the pressure.
|
|
2460
|
+
{
|
|
2461
|
+
id: "fineliner",
|
|
2462
|
+
name: "Fineliner",
|
|
2463
|
+
kind: "mark",
|
|
2464
|
+
medium: "ink",
|
|
2465
|
+
variety: "fineliner",
|
|
2466
|
+
tip: { shape: "round", size: 2, spacing: 0.05 },
|
|
2467
|
+
dynamics: { smoothing: 0.4, pressureSize: false },
|
|
2468
|
+
colour: { default: "#111827" }
|
|
2469
|
+
},
|
|
2470
|
+
// A wax crayon: waxy, catching the paper's peaks, a little uneven.
|
|
2471
|
+
{
|
|
2472
|
+
id: "crayon",
|
|
2473
|
+
name: "Crayon",
|
|
2474
|
+
kind: "mark",
|
|
2475
|
+
medium: "dry",
|
|
2476
|
+
variety: "crayon",
|
|
2477
|
+
tip: { shape: "round", size: 14, hardness: 0.7, spacing: 0.06, opacity: 0.9, flow: 0.85 },
|
|
2478
|
+
dynamics: { smoothing: 0.2, minSize: 0.6, tiltSize: 0.6, sizeJitter: 0.1, opacityJitter: 0.1 },
|
|
2479
|
+
behaviour: { grain: 0.9 },
|
|
2480
|
+
colour: { default: "#dc2626", palette: ["#dc2626", "#f59e0b", "#facc15", "#16a34a", "#2563eb", "#7c3aed"] }
|
|
2481
|
+
},
|
|
2482
|
+
// Chalk: broad, powdery and grainy. Its default colour is light on dark paper and dark on light.
|
|
2483
|
+
{
|
|
2484
|
+
id: "chalk",
|
|
2485
|
+
name: "Chalk",
|
|
2486
|
+
kind: "mark",
|
|
2487
|
+
medium: "dry",
|
|
2488
|
+
variety: "chalk",
|
|
2489
|
+
tip: { shape: "round", size: 18, hardness: 0.6, spacing: 0.05, opacity: 0.95, flow: 0.8 },
|
|
2490
|
+
dynamics: { smoothing: 0.2, minSize: 0.5, tiltSize: 0.8, sizeJitter: 0.12, scatter: 0.05 },
|
|
2491
|
+
behaviour: { grain: 1 },
|
|
2492
|
+
colour: { default: { light: "#475569", dark: "#f8fafc" }, palette: [{ light: "#475569", dark: "#f8fafc" }, "#fca5a5", "#fde68a", "#93c5fd"] }
|
|
2493
|
+
},
|
|
2494
|
+
// A spray can: a mist of hard droplets, denser the slower it passes.
|
|
2495
|
+
{
|
|
2496
|
+
id: "spray-can",
|
|
2497
|
+
name: "Spray can",
|
|
2498
|
+
kind: "mark",
|
|
2499
|
+
medium: "spray",
|
|
2500
|
+
variety: "spraycan",
|
|
2501
|
+
tip: { shape: "round", size: 60, hardness: 0.9, spacing: 0.08, opacity: 0.9 },
|
|
2502
|
+
marks: { kind: "scatter", density: 0.7, size: 0.04 },
|
|
2503
|
+
dynamics: { smoothing: 0.2, pressureSize: false, pressureOpacity: true },
|
|
2504
|
+
colour: { palette: ["#ef4444", "#f97316", "#facc15", "#22c55e", "#3b82f6", "#a855f7", "#111827", "#f8fafc"] }
|
|
2343
2505
|
}
|
|
2344
2506
|
];
|
|
2345
2507
|
|
|
@@ -2771,6 +2933,7 @@ export {
|
|
|
2771
2933
|
BRUSH_ID,
|
|
2772
2934
|
normalizeMultiColor,
|
|
2773
2935
|
normalizeBehavior,
|
|
2936
|
+
DEFAULT_SPRAY,
|
|
2774
2937
|
isWetCapable,
|
|
2775
2938
|
isWetBrush,
|
|
2776
2939
|
usesPaintExchange,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseCssColor
|
|
3
|
-
} from "./chunk-3CI7FRMK.js";
|
|
4
1
|
import {
|
|
5
2
|
boxMean,
|
|
6
3
|
createSelectionMask,
|
|
@@ -11,6 +8,9 @@ import {
|
|
|
11
8
|
hashMaskContent,
|
|
12
9
|
resizeSelection
|
|
13
10
|
} from "./chunk-ZNA3IQZF.js";
|
|
11
|
+
import {
|
|
12
|
+
parseCssColor
|
|
13
|
+
} from "./chunk-3CI7FRMK.js";
|
|
14
14
|
import {
|
|
15
15
|
DEFAULT_GLOBAL_LIGHT,
|
|
16
16
|
DeepCompositor,
|
|
@@ -106,7 +106,7 @@ import {
|
|
|
106
106
|
transformTextRect,
|
|
107
107
|
translateMatrix,
|
|
108
108
|
warpPresetMesh
|
|
109
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-YQ4PQTBB.js";
|
|
110
110
|
import {
|
|
111
111
|
bezierPathBounds,
|
|
112
112
|
outlineStroke,
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
|
|
@@ -123,26 +121,6 @@ function normalizeColor(input) {
|
|
|
123
121
|
return parsed ? formatHex(parsed) : null;
|
|
124
122
|
}
|
|
125
123
|
|
|
126
|
-
// src/color/suggest.ts
|
|
127
|
-
function suggestAccessibleForeground(foreground, background, options = {}) {
|
|
128
|
-
const large = _nullishCoalesce(options.large, () => ( false));
|
|
129
|
-
const lch = _chunk5UEFBM2Mcjs.oklabToOklch.call(void 0, _chunk5UEFBM2Mcjs.rgbToOklab.call(void 0, foreground));
|
|
130
|
-
const asHex = (l) => _chunk5UEFBM2Mcjs.parseColor.call(void 0, formatHex(toSrgbGamut(_chunk5UEFBM2Mcjs.oklabToRgb.call(void 0, _chunk5UEFBM2Mcjs.oklchToOklab.call(void 0, { ...lch, l })))));
|
|
131
|
-
for (let d = 0.01; d <= 1; d += 0.01) {
|
|
132
|
-
const downCand = asHex(Math.max(0, lch.l - d));
|
|
133
|
-
const upCand = asHex(Math.min(1, lch.l + d));
|
|
134
|
-
const downRatio = _chunk5UEFBM2Mcjs.contrastRatio.call(void 0, downCand, background);
|
|
135
|
-
const upRatio = _chunk5UEFBM2Mcjs.contrastRatio.call(void 0, upCand, background);
|
|
136
|
-
const downPass = _chunk5UEFBM2Mcjs.contrastLevel.call(void 0, downRatio, { large }) !== "fail";
|
|
137
|
-
const upPass = _chunk5UEFBM2Mcjs.contrastLevel.call(void 0, upRatio, { large }) !== "fail";
|
|
138
|
-
if (downPass && upPass) return formatHex(downRatio >= upRatio ? downCand : upCand);
|
|
139
|
-
if (downPass) return formatHex(downCand);
|
|
140
|
-
if (upPass) return formatHex(upCand);
|
|
141
|
-
}
|
|
142
|
-
return void 0;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
124
|
|
|
147
125
|
|
|
148
126
|
|
|
@@ -150,4 +128,4 @@ function suggestAccessibleForeground(foreground, background, options = {}) {
|
|
|
150
128
|
|
|
151
129
|
|
|
152
130
|
|
|
153
|
-
exports.inSrgbGamut = inSrgbGamut; exports.deltaEOK = deltaEOK; exports.toSrgbGamut = toSrgbGamut; exports.formatHex = formatHex; exports.formatColor = formatColor; exports.normalizeColor = normalizeColor;
|
|
131
|
+
exports.inSrgbGamut = inSrgbGamut; exports.deltaEOK = deltaEOK; exports.toSrgbGamut = toSrgbGamut; exports.formatHex = formatHex; exports.formatColor = formatColor; exports.normalizeColor = normalizeColor;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
+
var _chunkI3Y2Q3PMcjs = require('./chunk-I3Y2Q3PM.cjs');
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
var _chunkEUIDTZNQcjs = require('./chunk-EUIDTZNQ.cjs');
|
|
8
8
|
|
|
9
|
+
var _chunkMLLTWAXHcjs = require('./chunk-MLLTWAXH.cjs');
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
|
|
14
|
+
var _chunkSXQHWXELcjs = require('./chunk-SXQHWXEL.cjs');
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
|
|
@@ -70,9 +72,9 @@ function normalizeGradient(input) {
|
|
|
70
72
|
const rawStop = s;
|
|
71
73
|
let normColor = null;
|
|
72
74
|
if (typeof rawStop.color === "string" || rawStop.color && typeof rawStop.color === "object") {
|
|
73
|
-
const dual =
|
|
75
|
+
const dual = _chunkMLLTWAXHcjs.normalizeDualColor.call(void 0, rawStop.color);
|
|
74
76
|
if (dual) {
|
|
75
|
-
normColor =
|
|
77
|
+
normColor = _chunkMLLTWAXHcjs.formatDualColor.call(void 0, dual);
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
if (!normColor) {
|
|
@@ -142,7 +144,7 @@ function createGradient(colorsOrOptions, options) {
|
|
|
142
144
|
const stops = resolvedColors.map((color, i) => ({
|
|
143
145
|
id: `s${i + 1}`,
|
|
144
146
|
offset: i / (resolvedColors.length - 1),
|
|
145
|
-
color:
|
|
147
|
+
color: _chunkMLLTWAXHcjs.formatDualColor.call(void 0, _nullishCoalesce(_chunkMLLTWAXHcjs.normalizeDualColor.call(void 0, color), () => ( { light: "#000000", dark: "#000000" })))
|
|
146
148
|
}));
|
|
147
149
|
const res2 = normalizeGradient({
|
|
148
150
|
...options,
|
|
@@ -194,7 +196,7 @@ function isDualColorValue(val) {
|
|
|
194
196
|
if (typeof val === "string") {
|
|
195
197
|
return val.trim().toLowerCase().startsWith("light-dark(");
|
|
196
198
|
}
|
|
197
|
-
if (
|
|
199
|
+
if (_chunkMLLTWAXHcjs.isDualColor.call(void 0, val)) {
|
|
198
200
|
return val.light !== val.dark;
|
|
199
201
|
}
|
|
200
202
|
return false;
|
|
@@ -208,7 +210,7 @@ function resolveGradient(g, scheme) {
|
|
|
208
210
|
center: g.center ? { ...g.center } : void 0,
|
|
209
211
|
stops: g.stops.map((s) => ({
|
|
210
212
|
...s,
|
|
211
|
-
color: _nullishCoalesce(
|
|
213
|
+
color: _nullishCoalesce(_chunkMLLTWAXHcjs.resolveColor.call(void 0, s.color, scheme), () => ( s.color))
|
|
212
214
|
}))
|
|
213
215
|
};
|
|
214
216
|
}
|
|
@@ -236,7 +238,7 @@ function sampleGradient(g, t, scheme = "light") {
|
|
|
236
238
|
if (s0.midpoint !== void 0) {
|
|
237
239
|
u = gradientMidpointRemap(u, s0.midpoint);
|
|
238
240
|
}
|
|
239
|
-
const mixed =
|
|
241
|
+
const mixed = _chunkI3Y2Q3PMcjs.mixColors.call(void 0, s0.color, s1.color, u, { space: _nullishCoalesce(g.interpolation, () => ( "oklab")) });
|
|
240
242
|
return _nullishCoalesce(mixed, () => ( s0.color));
|
|
241
243
|
}
|
|
242
244
|
function insertGradientStop(g, offset, color) {
|
|
@@ -575,12 +577,12 @@ ${stopsXml.join("\n")}
|
|
|
575
577
|
</linearGradient>`;
|
|
576
578
|
}
|
|
577
579
|
function checkGradient(g, options = {}) {
|
|
578
|
-
const dual = isDualGradient(g) ||
|
|
580
|
+
const dual = isDualGradient(g) || _chunkMLLTWAXHcjs.isDualColor.call(void 0, options.surface) || _chunkMLLTWAXHcjs.isDualColor.call(void 0, options.text);
|
|
579
581
|
if (dual) {
|
|
580
582
|
const lightG = resolveGradient(g, "light");
|
|
581
583
|
const darkG = resolveGradient(g, "dark");
|
|
582
|
-
const lightText = options.text ? _nullishCoalesce(
|
|
583
|
-
const darkText = options.text ? _nullishCoalesce(
|
|
584
|
+
const lightText = options.text ? _nullishCoalesce(_chunkMLLTWAXHcjs.resolveColor.call(void 0, options.text, "light"), () => ( void 0)) : void 0;
|
|
585
|
+
const darkText = options.text ? _nullishCoalesce(_chunkMLLTWAXHcjs.resolveColor.call(void 0, options.text, "dark"), () => ( void 0)) : void 0;
|
|
584
586
|
const checkScheme = (grad, txt, schemeName) => {
|
|
585
587
|
const issues2 = [];
|
|
586
588
|
for (let i = 0; i < grad.stops.length - 1; i++) {
|
|
@@ -591,7 +593,7 @@ function checkGradient(g, options = {}) {
|
|
|
591
593
|
const c1 = _chunk5UEFBM2Mcjs.parseColor.call(void 0, grad.stops[i].color);
|
|
592
594
|
const c2 = _chunk5UEFBM2Mcjs.parseColor.call(void 0, grad.stops[i + 1].color);
|
|
593
595
|
if (c1 && c2 && gap < 0.05) {
|
|
594
|
-
const dE =
|
|
596
|
+
const dE = _chunkSXQHWXELcjs.deltaEOK.call(void 0, c1, c2);
|
|
595
597
|
if (dE > 0.5) {
|
|
596
598
|
issues2.push(
|
|
597
599
|
`[${schemeName}] Banding risk between stops "${grad.stops[i].id}" and "${grad.stops[i + 1].id}" (\u0394EOK = ${dE.toFixed(2)} across gap ${gap.toFixed(3)}).`
|
|
@@ -601,7 +603,7 @@ function checkGradient(g, options = {}) {
|
|
|
601
603
|
}
|
|
602
604
|
for (const s of grad.stops) {
|
|
603
605
|
const c = _chunk5UEFBM2Mcjs.parseColor.call(void 0, s.color);
|
|
604
|
-
if (c && !
|
|
606
|
+
if (c && !_chunkSXQHWXELcjs.inSrgbGamut.call(void 0, c)) {
|
|
605
607
|
issues2.push(`[${schemeName}] Stop "${s.id}" colour ${s.color} is outside standard sRGB gamut.`);
|
|
606
608
|
}
|
|
607
609
|
}
|
|
@@ -638,7 +640,7 @@ function checkGradient(g, options = {}) {
|
|
|
638
640
|
const c1 = _chunk5UEFBM2Mcjs.parseColor.call(void 0, g.stops[i].color);
|
|
639
641
|
const c2 = _chunk5UEFBM2Mcjs.parseColor.call(void 0, g.stops[i + 1].color);
|
|
640
642
|
if (c1 && c2 && gap < 0.05) {
|
|
641
|
-
const dE =
|
|
643
|
+
const dE = _chunkSXQHWXELcjs.deltaEOK.call(void 0, c1, c2);
|
|
642
644
|
if (dE > 0.5) {
|
|
643
645
|
issues.push(
|
|
644
646
|
`Banding risk between stops "${g.stops[i].id}" and "${g.stops[i + 1].id}" (\u0394EOK = ${dE.toFixed(2)} across gap ${gap.toFixed(3)}).`
|
|
@@ -648,7 +650,7 @@ function checkGradient(g, options = {}) {
|
|
|
648
650
|
}
|
|
649
651
|
for (const s of g.stops) {
|
|
650
652
|
const c = _chunk5UEFBM2Mcjs.parseColor.call(void 0, s.color);
|
|
651
|
-
if (c && !
|
|
653
|
+
if (c && !_chunkSXQHWXELcjs.inSrgbGamut.call(void 0, c)) {
|
|
652
654
|
issues.push(`Stop "${s.id}" colour ${s.color} is outside standard sRGB gamut.`);
|
|
653
655
|
}
|
|
654
656
|
}
|
|
@@ -875,7 +877,7 @@ function fitGradientStops(samples, options = {}) {
|
|
|
875
877
|
}
|
|
876
878
|
const stops = at.map((i, k) => {
|
|
877
879
|
const [l, a, b, alpha] = lab[i].v;
|
|
878
|
-
const color =
|
|
880
|
+
const color = _chunkSXQHWXELcjs.formatHex.call(void 0, _chunk5UEFBM2Mcjs.oklabToRgb.call(void 0, { l, a, b, alpha: Math.min(1, Math.max(0, alpha)) }));
|
|
879
881
|
return { id: `s${k + 1}`, offset: k === 0 ? 0 : k === at.length - 1 ? 1 : Math.round(lab[i].t * 1e3) / 1e3, color };
|
|
880
882
|
});
|
|
881
883
|
return { stops, maxError: Math.round(maxErrorOf(lab, at) * 1e4) / 1e4 };
|