@pixerate/editor 0.161.0 → 0.162.1
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 +36 -35
- package/dist/agent/index.js +7 -6
- package/dist/animation/index.cjs +5 -4
- package/dist/animation/index.js +4 -3
- package/dist/animation-editor/index.cjs +63 -62
- package/dist/animation-editor/index.js +7 -6
- package/dist/{brushstrokeRender-Q4LI22QV.js → brushstrokeRender-7LXCU7PD.js} +2 -2
- package/dist/{brushstrokeRender-5WANQIG4.cjs → brushstrokeRender-VO4ZTWVA.cjs} +5 -5
- package/dist/canvas/index.cjs +40 -39
- package/dist/canvas/index.js +7 -6
- package/dist/chart/index.cjs +88 -87
- package/dist/chart/index.js +7 -6
- package/dist/{chunk-LQLZHP6F.js → chunk-36OKQDCF.js} +7 -4
- package/dist/{chunk-AKDWAWSY.cjs → chunk-3IHNXRUV.cjs} +45 -45
- package/dist/{chunk-72BGL3I2.js → chunk-3VLOOO3G.js} +1 -1
- package/dist/{chunk-TVO6W2Q6.cjs → chunk-4NGVHHJB.cjs} +17 -17
- package/dist/chunk-4VU4CP7R.js +769 -0
- package/dist/{chunk-MHEXLG3M.cjs → chunk-5AARIS3R.cjs} +37 -37
- package/dist/{chunk-DBIVICAO.js → chunk-7CKPUUN4.js} +1 -1
- package/dist/{chunk-57JLBGJ5.cjs → chunk-7YBDRJXT.cjs} +8 -8
- package/dist/{chunk-KY3FYKP3.js → chunk-BQWGN5WH.js} +1 -1
- package/dist/{chunk-LEUZ4FRC.cjs → chunk-CIPIESX4.cjs} +3 -3
- package/dist/chunk-CJE5MOIS.js +347 -0
- package/dist/{chunk-5QBRAIVK.js → chunk-CX6JLDFC.js} +3 -3
- package/dist/{chunk-R3QY7PPL.js → chunk-DTSTNRPH.js} +1 -1
- package/dist/{chunk-6LUYFHHN.cjs → chunk-EQ46F75O.cjs} +51 -51
- package/dist/{chunk-UKCJ43YL.cjs → chunk-ES3UEVUT.cjs} +130 -898
- package/dist/{chunk-UM3RPYC5.js → chunk-EVPZ5IKN.js} +1 -1
- package/dist/{chunk-XNQ5EFB4.cjs → chunk-EY22AY6R.cjs} +16 -16
- package/dist/chunk-FKUKJ3XA.cjs +347 -0
- package/dist/{chunk-YABNLNY7.js → chunk-GLMP22FT.js} +3 -3
- package/dist/{chunk-SUF6WRXR.cjs → chunk-GTELFJRE.cjs} +2 -2
- package/dist/{chunk-AY65VQSU.js → chunk-H3OEM3Q2.js} +1 -1
- package/dist/{chunk-4YWAEV4W.cjs → chunk-HDGBM7EA.cjs} +26 -26
- package/dist/{chunk-H5XX4KHB.js → chunk-HLOKB7WW.js} +5 -3
- package/dist/{chunk-QMI5HZWA.cjs → chunk-JCXMJUQO.cjs} +5 -5
- package/dist/{chunk-WPPJH6X4.cjs → chunk-LL3H5XUH.cjs} +6 -4
- package/dist/{chunk-4T44CJ5K.cjs → chunk-NA4UVVJ4.cjs} +15 -15
- package/dist/{chunk-Q6PA362P.js → chunk-NO5QQDHZ.js} +2 -2
- package/dist/{chunk-3YDQLQH2.cjs → chunk-PA3IMPPS.cjs} +81 -81
- package/dist/{chunk-WNAAWLZ5.js → chunk-QY4KUDMY.js} +2 -2
- package/dist/{chunk-AA34BA7G.js → chunk-QYZGBVNC.js} +30 -798
- package/dist/chunk-S6X2QRVU.cjs +769 -0
- package/dist/{chunk-6UPGM3JB.js → chunk-SET6KJOP.js} +2 -2
- package/dist/{chunk-GNK7SESQ.cjs → chunk-V7GWZIZK.cjs} +7 -4
- package/dist/{chunk-EYVVIZJ3.cjs → chunk-WTW7QRTS.cjs} +1 -1
- package/dist/{chunk-SSCL7QQ4.js → chunk-XDCFJEU7.js} +2 -2
- package/dist/{chunk-JGKCC5OF.cjs → chunk-YQ5C5BVK.cjs} +10 -9
- package/dist/{chunk-A5UCR2TO.js → chunk-YXKLVD56.js} +10 -9
- package/dist/{chunk-45XXVHVG.js → chunk-ZZGPYNS2.js} +1 -1
- package/dist/color/index.cjs +6 -2
- package/dist/color/index.d.cts +1 -0
- package/dist/color/index.d.ts +1 -0
- package/dist/color/index.js +28 -24
- package/dist/color/suggest.d.cts +12 -0
- package/dist/color/suggest.d.ts +12 -0
- package/dist/effects/index.cjs +37 -13
- package/dist/effects/index.js +29 -5
- package/dist/effects/ui.d.cts +20 -3
- package/dist/effects/ui.d.ts +20 -3
- package/dist/export/index.cjs +6 -5
- package/dist/export/index.js +5 -4
- package/dist/extensions/index.cjs +9 -8
- package/dist/extensions/index.js +8 -7
- package/dist/gradient/index.cjs +28 -26
- package/dist/gradient/index.js +7 -5
- package/dist/image-editor/index.cjs +641 -640
- package/dist/image-editor/index.js +7 -6
- package/dist/index.cjs +15 -14
- package/dist/index.js +9 -8
- package/dist/paint/index.cjs +2 -2
- package/dist/paint/index.js +1 -1
- package/dist/paint-editor/index.cjs +136 -135
- package/dist/paint-editor/index.js +8 -7
- package/dist/typography/accessibility.d.cts +44 -0
- package/dist/typography/accessibility.d.ts +44 -0
- package/dist/typography/catalog.d.cts +98 -0
- package/dist/typography/catalog.d.ts +98 -0
- package/dist/typography/index.cjs +1099 -0
- package/dist/typography/index.d.cts +16 -0
- package/dist/typography/index.d.ts +16 -0
- package/dist/typography/index.js +1099 -0
- package/dist/typography/metrics.d.cts +31 -0
- package/dist/typography/metrics.d.ts +31 -0
- package/dist/typography/picker.d.cts +132 -0
- package/dist/typography/picker.d.ts +132 -0
- package/dist/typography/registry.d.cts +66 -0
- package/dist/typography/registry.d.ts +66 -0
- package/dist/typography/scale.d.cts +62 -0
- package/dist/typography/scale.d.ts +62 -0
- package/dist/typography/segment.d.cts +26 -0
- package/dist/typography/segment.d.ts +26 -0
- package/dist/typography/stack.d.cts +26 -0
- package/dist/typography/stack.d.ts +26 -0
- package/dist/typography/tools.d.cts +34 -0
- package/dist/typography/tools.d.ts +34 -0
- package/dist/typography/types.d.cts +96 -0
- package/dist/typography/types.d.ts +96 -0
- package/dist/typography/weight.d.cts +13 -0
- package/dist/typography/weight.d.ts +13 -0
- package/dist/vector/index.cjs +951 -950
- package/dist/vector/index.js +6 -5
- package/dist/video-editor/index.cjs +5 -4
- package/dist/video-editor/index.js +4 -3
- package/package.json +13 -3
- package/skills/README.md +1 -0
- package/skills/pixerate-chart/SKILL.md +92 -9
- package/skills/pixerate-paint-editor/SKILL.md +0 -2
- package/skills/pixerate-typography/SKILL.md +91 -0
|
@@ -0,0 +1,769 @@
|
|
|
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
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkIPJ3TEYRcjs = require('./chunk-IPJ3TEYR.cjs');
|
|
9
|
+
|
|
10
|
+
// src/color/convert.ts
|
|
11
|
+
function srgbToLinear(v) {
|
|
12
|
+
const sign = Math.sign(v);
|
|
13
|
+
const abs = Math.abs(v);
|
|
14
|
+
return sign * (abs <= 0.04045 ? abs / 12.92 : ((abs + 0.055) / 1.055) ** 2.4);
|
|
15
|
+
}
|
|
16
|
+
function linearToSrgb(v) {
|
|
17
|
+
const sign = Math.sign(v);
|
|
18
|
+
const abs = Math.abs(v);
|
|
19
|
+
return sign * (abs <= 31308e-7 ? 12.92 * abs : 1.055 * abs ** (1 / 2.4) - 0.055);
|
|
20
|
+
}
|
|
21
|
+
function rgbToHsl(rgba) {
|
|
22
|
+
const { r, g, b, a } = rgba;
|
|
23
|
+
const max = Math.max(r, g, b);
|
|
24
|
+
const min = Math.min(r, g, b);
|
|
25
|
+
const d = max - min;
|
|
26
|
+
const l = (max + min) / 2;
|
|
27
|
+
let h = 0;
|
|
28
|
+
if (d > 0) {
|
|
29
|
+
if (max === r) h = 60 * ((g - b) / d % 6);
|
|
30
|
+
else if (max === g) h = 60 * ((b - r) / d + 2);
|
|
31
|
+
else h = 60 * ((r - g) / d + 4);
|
|
32
|
+
}
|
|
33
|
+
if (h < 0) h += 360;
|
|
34
|
+
const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
|
|
35
|
+
return { h, s, l, alpha: a };
|
|
36
|
+
}
|
|
37
|
+
function hslToRgb(hsla) {
|
|
38
|
+
const { h, s, l, alpha } = hsla;
|
|
39
|
+
const hh = (h % 360 + 360) % 360 / 60;
|
|
40
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
41
|
+
const x = c * (1 - Math.abs(hh % 2 - 1));
|
|
42
|
+
const m = l - c / 2;
|
|
43
|
+
let r = 0;
|
|
44
|
+
let g = 0;
|
|
45
|
+
let b = 0;
|
|
46
|
+
if (hh < 1) {
|
|
47
|
+
r = c;
|
|
48
|
+
g = x;
|
|
49
|
+
b = 0;
|
|
50
|
+
} else if (hh < 2) {
|
|
51
|
+
r = x;
|
|
52
|
+
g = c;
|
|
53
|
+
b = 0;
|
|
54
|
+
} else if (hh < 3) {
|
|
55
|
+
r = 0;
|
|
56
|
+
g = c;
|
|
57
|
+
b = x;
|
|
58
|
+
} else if (hh < 4) {
|
|
59
|
+
r = 0;
|
|
60
|
+
g = x;
|
|
61
|
+
b = c;
|
|
62
|
+
} else if (hh < 5) {
|
|
63
|
+
r = x;
|
|
64
|
+
g = 0;
|
|
65
|
+
b = c;
|
|
66
|
+
} else {
|
|
67
|
+
r = c;
|
|
68
|
+
g = 0;
|
|
69
|
+
b = x;
|
|
70
|
+
}
|
|
71
|
+
return { r: r + m, g: g + m, b: b + m, a: alpha };
|
|
72
|
+
}
|
|
73
|
+
function rgbToHsv(rgba) {
|
|
74
|
+
const { r, g, b, a } = rgba;
|
|
75
|
+
const max = Math.max(r, g, b);
|
|
76
|
+
const min = Math.min(r, g, b);
|
|
77
|
+
const d = max - min;
|
|
78
|
+
let h = 0;
|
|
79
|
+
if (d > 0) {
|
|
80
|
+
if (max === r) h = 60 * ((g - b) / d % 6);
|
|
81
|
+
else if (max === g) h = 60 * ((b - r) / d + 2);
|
|
82
|
+
else h = 60 * ((r - g) / d + 4);
|
|
83
|
+
}
|
|
84
|
+
if (h < 0) h += 360;
|
|
85
|
+
const s = max === 0 ? 0 : d / max;
|
|
86
|
+
return { h, s, v: max, alpha: a };
|
|
87
|
+
}
|
|
88
|
+
function hsvToRgb(hsva) {
|
|
89
|
+
const { h, s, v, alpha } = hsva;
|
|
90
|
+
const hh = (h % 360 + 360) % 360 / 60;
|
|
91
|
+
const c = v * s;
|
|
92
|
+
const x = c * (1 - Math.abs(hh % 2 - 1));
|
|
93
|
+
const m = v - c;
|
|
94
|
+
let r = 0;
|
|
95
|
+
let g = 0;
|
|
96
|
+
let b = 0;
|
|
97
|
+
if (hh < 1) {
|
|
98
|
+
r = c;
|
|
99
|
+
g = x;
|
|
100
|
+
b = 0;
|
|
101
|
+
} else if (hh < 2) {
|
|
102
|
+
r = x;
|
|
103
|
+
g = c;
|
|
104
|
+
b = 0;
|
|
105
|
+
} else if (hh < 3) {
|
|
106
|
+
r = 0;
|
|
107
|
+
g = c;
|
|
108
|
+
b = x;
|
|
109
|
+
} else if (hh < 4) {
|
|
110
|
+
r = 0;
|
|
111
|
+
g = x;
|
|
112
|
+
b = c;
|
|
113
|
+
} else if (hh < 5) {
|
|
114
|
+
r = x;
|
|
115
|
+
g = 0;
|
|
116
|
+
b = c;
|
|
117
|
+
} else {
|
|
118
|
+
r = c;
|
|
119
|
+
g = 0;
|
|
120
|
+
b = x;
|
|
121
|
+
}
|
|
122
|
+
return { r: r + m, g: g + m, b: b + m, a: alpha };
|
|
123
|
+
}
|
|
124
|
+
function rgbToOklab(rgba) {
|
|
125
|
+
const lr = srgbToLinear(rgba.r);
|
|
126
|
+
const lg = srgbToLinear(rgba.g);
|
|
127
|
+
const lb = srgbToLinear(rgba.b);
|
|
128
|
+
const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
|
|
129
|
+
const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
|
|
130
|
+
const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
|
|
131
|
+
return {
|
|
132
|
+
l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
|
|
133
|
+
a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
|
|
134
|
+
b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
|
|
135
|
+
alpha: rgba.a
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function oklabToRgb(lab) {
|
|
139
|
+
const l_ = lab.l + 0.3963377774 * lab.a + 0.2158037573 * lab.b;
|
|
140
|
+
const m_ = lab.l - 0.1055613458 * lab.a - 0.0638541728 * lab.b;
|
|
141
|
+
const s_ = lab.l - 0.0894841775 * lab.a - 1.291485548 * lab.b;
|
|
142
|
+
const l = l_ ** 3;
|
|
143
|
+
const m = m_ ** 3;
|
|
144
|
+
const s = s_ ** 3;
|
|
145
|
+
return {
|
|
146
|
+
r: linearToSrgb(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),
|
|
147
|
+
g: linearToSrgb(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),
|
|
148
|
+
b: linearToSrgb(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s),
|
|
149
|
+
a: lab.alpha
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function oklabToOklch(lab) {
|
|
153
|
+
const c = Math.hypot(lab.a, lab.b);
|
|
154
|
+
let h = 0;
|
|
155
|
+
if (c >= 1e-6) {
|
|
156
|
+
h = Math.atan2(lab.b, lab.a) * 180 / Math.PI;
|
|
157
|
+
if (h < 0) h += 360;
|
|
158
|
+
if (h >= 360) h -= 360;
|
|
159
|
+
}
|
|
160
|
+
return { l: lab.l, c, h, alpha: lab.alpha };
|
|
161
|
+
}
|
|
162
|
+
function oklchToOklab(lch) {
|
|
163
|
+
const rad = lch.h * Math.PI / 180;
|
|
164
|
+
return {
|
|
165
|
+
l: lch.l,
|
|
166
|
+
a: lch.c * Math.cos(rad),
|
|
167
|
+
b: lch.c * Math.sin(rad),
|
|
168
|
+
alpha: lch.alpha
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
var D65_XYZ = _chunkIPJ3TEYRcjs.xyToXyz.call(void 0, _chunkIPJ3TEYRcjs.D65_XY);
|
|
172
|
+
var SRGB_TO_XYZ = _chunkIPJ3TEYRcjs.rgbToXyzMatrix.call(void 0, [0.64, 0.33], [0.3, 0.6], [0.15, 0.06], D65_XYZ);
|
|
173
|
+
var P3_TO_XYZ = _chunkIPJ3TEYRcjs.rgbToXyzMatrix.call(void 0, [0.68, 0.32], [0.265, 0.69], [0.15, 0.06], D65_XYZ);
|
|
174
|
+
var XYZ_TO_SRGB = _chunkIPJ3TEYRcjs.invert.call(void 0, SRGB_TO_XYZ);
|
|
175
|
+
var XYZ_TO_P3 = _chunkIPJ3TEYRcjs.invert.call(void 0, P3_TO_XYZ);
|
|
176
|
+
var P3_TO_SRGB_MAT = _chunkIPJ3TEYRcjs.mul.call(void 0, XYZ_TO_SRGB, P3_TO_XYZ);
|
|
177
|
+
var SRGB_TO_P3_MAT = _chunkIPJ3TEYRcjs.mul.call(void 0, XYZ_TO_P3, SRGB_TO_XYZ);
|
|
178
|
+
function linearSrgbToDisplayP3(rgb) {
|
|
179
|
+
const out = _chunkIPJ3TEYRcjs.apply.call(void 0, SRGB_TO_P3_MAT, [rgb.r, rgb.g, rgb.b]);
|
|
180
|
+
return { r: out[0], g: out[1], b: out[2], a: rgb.a };
|
|
181
|
+
}
|
|
182
|
+
function displayP3ToLinearSrgb(rgb) {
|
|
183
|
+
const out = _chunkIPJ3TEYRcjs.apply.call(void 0, P3_TO_SRGB_MAT, [rgb.r, rgb.g, rgb.b]);
|
|
184
|
+
return { r: out[0], g: out[1], b: out[2], a: rgb.a };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/color/named.ts
|
|
188
|
+
var NAMED_COLORS = {
|
|
189
|
+
aliceblue: "#f0f8ff",
|
|
190
|
+
antiquewhite: "#faebd7",
|
|
191
|
+
aqua: "#00ffff",
|
|
192
|
+
aquamarine: "#7fffd4",
|
|
193
|
+
azure: "#f0ffff",
|
|
194
|
+
beige: "#f5f5dc",
|
|
195
|
+
bisque: "#ffe4c4",
|
|
196
|
+
black: "#000000",
|
|
197
|
+
blanchedalmond: "#ffebcd",
|
|
198
|
+
blue: "#0000ff",
|
|
199
|
+
blueviolet: "#8a2be2",
|
|
200
|
+
brown: "#a52a2a",
|
|
201
|
+
burlywood: "#deb887",
|
|
202
|
+
cadetblue: "#5f9ea0",
|
|
203
|
+
chartreuse: "#7fff00",
|
|
204
|
+
chocolate: "#d2691e",
|
|
205
|
+
coral: "#ff7f50",
|
|
206
|
+
cornflowerblue: "#6495ed",
|
|
207
|
+
cornsilk: "#fff8dc",
|
|
208
|
+
crimson: "#dc143c",
|
|
209
|
+
cyan: "#00ffff",
|
|
210
|
+
darkblue: "#00008b",
|
|
211
|
+
darkcyan: "#008b8b",
|
|
212
|
+
darkgoldenrod: "#b8860b",
|
|
213
|
+
darkgray: "#a9a9a9",
|
|
214
|
+
darkgreen: "#006400",
|
|
215
|
+
darkgrey: "#a9a9a9",
|
|
216
|
+
darkkhaki: "#bdb76b",
|
|
217
|
+
darkmagenta: "#8b008b",
|
|
218
|
+
darkolivegreen: "#556b2f",
|
|
219
|
+
darkorange: "#ff8c00",
|
|
220
|
+
darkorchid: "#9932cc",
|
|
221
|
+
darkred: "#8b0000",
|
|
222
|
+
darksalmon: "#e9967a",
|
|
223
|
+
darkseagreen: "#8fbc8f",
|
|
224
|
+
darkslateblue: "#483d8b",
|
|
225
|
+
darkslategray: "#2f4f4f",
|
|
226
|
+
darkslategrey: "#2f4f4f",
|
|
227
|
+
darkturquoise: "#00ced1",
|
|
228
|
+
darkviolet: "#9400d3",
|
|
229
|
+
deeppink: "#ff1493",
|
|
230
|
+
deepskyblue: "#00bfff",
|
|
231
|
+
dimgray: "#696969",
|
|
232
|
+
dimgrey: "#696969",
|
|
233
|
+
dodgerblue: "#1e90ff",
|
|
234
|
+
firebrick: "#b22222",
|
|
235
|
+
floralwhite: "#fffaf0",
|
|
236
|
+
forestgreen: "#228b22",
|
|
237
|
+
fuchsia: "#ff00ff",
|
|
238
|
+
gainsboro: "#dcdcdc",
|
|
239
|
+
ghostwhite: "#f8f8ff",
|
|
240
|
+
gold: "#ffd700",
|
|
241
|
+
goldenrod: "#daa520",
|
|
242
|
+
gray: "#808080",
|
|
243
|
+
green: "#008000",
|
|
244
|
+
greenyellow: "#adff2f",
|
|
245
|
+
grey: "#808080",
|
|
246
|
+
honeydew: "#f0fff0",
|
|
247
|
+
hotpink: "#ff69b4",
|
|
248
|
+
indianred: "#cd5c5c",
|
|
249
|
+
indigo: "#4b0082",
|
|
250
|
+
ivory: "#fffff0",
|
|
251
|
+
khaki: "#f0e68c",
|
|
252
|
+
lavender: "#e6e6fa",
|
|
253
|
+
lavenderblush: "#fff0f5",
|
|
254
|
+
lawngreen: "#7cfc00",
|
|
255
|
+
lemonchiffon: "#fffacd",
|
|
256
|
+
lightblue: "#add8e6",
|
|
257
|
+
lightcoral: "#f08080",
|
|
258
|
+
lightcyan: "#e0ffff",
|
|
259
|
+
lightgoldenrodyellow: "#fafad2",
|
|
260
|
+
lightgray: "#d3d3d3",
|
|
261
|
+
lightgreen: "#90ee90",
|
|
262
|
+
lightgrey: "#d3d3d3",
|
|
263
|
+
lightpink: "#ffb6c1",
|
|
264
|
+
lightsalmon: "#ffa07a",
|
|
265
|
+
lightseagreen: "#20b2aa",
|
|
266
|
+
lightskyblue: "#87cefa",
|
|
267
|
+
lightslategray: "#778899",
|
|
268
|
+
lightslategrey: "#778899",
|
|
269
|
+
lightsteelblue: "#b0c4de",
|
|
270
|
+
lightyellow: "#ffffe0",
|
|
271
|
+
lime: "#00ff00",
|
|
272
|
+
limegreen: "#32cd32",
|
|
273
|
+
linen: "#faf0e6",
|
|
274
|
+
magenta: "#ff00ff",
|
|
275
|
+
maroon: "#800000",
|
|
276
|
+
mediumaquamarine: "#66cdaa",
|
|
277
|
+
mediumblue: "#0000cd",
|
|
278
|
+
mediumorchid: "#ba55d3",
|
|
279
|
+
mediumpurple: "#9370db",
|
|
280
|
+
mediumseagreen: "#3cb371",
|
|
281
|
+
mediumslateblue: "#7b68ee",
|
|
282
|
+
mediumspringgreen: "#00fa9a",
|
|
283
|
+
mediumturquoise: "#48d1cc",
|
|
284
|
+
mediumvioletred: "#c71585",
|
|
285
|
+
midnightblue: "#191970",
|
|
286
|
+
mintcream: "#f5fffa",
|
|
287
|
+
mistyrose: "#ffe4e1",
|
|
288
|
+
moccasin: "#ffe4b5",
|
|
289
|
+
navajowhite: "#ffdead",
|
|
290
|
+
navy: "#000080",
|
|
291
|
+
oldlace: "#fdf5e6",
|
|
292
|
+
olive: "#808000",
|
|
293
|
+
olivedrab: "#6b8e23",
|
|
294
|
+
orange: "#ffa500",
|
|
295
|
+
orangered: "#ff4500",
|
|
296
|
+
orchid: "#da70d6",
|
|
297
|
+
palegoldenrod: "#eee8aa",
|
|
298
|
+
palegreen: "#98fb98",
|
|
299
|
+
paleturquoise: "#afeeee",
|
|
300
|
+
palevioletred: "#db7093",
|
|
301
|
+
papayawhip: "#ffefd5",
|
|
302
|
+
peachpuff: "#ffdab9",
|
|
303
|
+
peru: "#cd853f",
|
|
304
|
+
pink: "#ffc0cb",
|
|
305
|
+
plum: "#dda0dd",
|
|
306
|
+
powderblue: "#b0e0e6",
|
|
307
|
+
purple: "#800080",
|
|
308
|
+
rebeccapurple: "#663399",
|
|
309
|
+
red: "#ff0000",
|
|
310
|
+
rosybrown: "#bc8f8f",
|
|
311
|
+
royalblue: "#4169e1",
|
|
312
|
+
saddlebrown: "#8b4513",
|
|
313
|
+
salmon: "#fa8072",
|
|
314
|
+
sandybrown: "#f4a460",
|
|
315
|
+
seagreen: "#2e8b57",
|
|
316
|
+
seashell: "#fff5ee",
|
|
317
|
+
sienna: "#a0522d",
|
|
318
|
+
silver: "#c0c0c0",
|
|
319
|
+
skyblue: "#87ceeb",
|
|
320
|
+
slateblue: "#6a5acd",
|
|
321
|
+
slategray: "#708090",
|
|
322
|
+
slategrey: "#708090",
|
|
323
|
+
snow: "#fffafa",
|
|
324
|
+
springgreen: "#00ff7f",
|
|
325
|
+
steelblue: "#4682b4",
|
|
326
|
+
tan: "#d2b48c",
|
|
327
|
+
teal: "#008080",
|
|
328
|
+
thistle: "#d8bfd8",
|
|
329
|
+
tomato: "#ff6347",
|
|
330
|
+
transparent: "#00000000",
|
|
331
|
+
turquoise: "#40e0d0",
|
|
332
|
+
violet: "#ee82ee",
|
|
333
|
+
wheat: "#f5deb3",
|
|
334
|
+
white: "#ffffff",
|
|
335
|
+
whitesmoke: "#f5f5f5",
|
|
336
|
+
yellow: "#ffff00",
|
|
337
|
+
yellowgreen: "#9acd32"
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// src/color/parse.ts
|
|
341
|
+
var HEX_RE = /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
342
|
+
var RGB_RE = /^rgba?\(([^()]*)\)$/i;
|
|
343
|
+
var HSL_RE = /^hsla?\(([^()]*)\)$/i;
|
|
344
|
+
var OKLAB_RE = /^oklab\(([^()]*)\)$/i;
|
|
345
|
+
var OKLCH_RE = /^oklch\(([^()]*)\)$/i;
|
|
346
|
+
var COLOR_FN_RE = /^color\(([^()]*)\)$/i;
|
|
347
|
+
function parsePercentOrNumber(v, scale) {
|
|
348
|
+
const text = v.trim();
|
|
349
|
+
const isPct = text.endsWith("%");
|
|
350
|
+
const num = Number(isPct ? text.slice(0, -1) : text);
|
|
351
|
+
if (!Number.isFinite(num)) return null;
|
|
352
|
+
return isPct ? num / 100 : num / scale;
|
|
353
|
+
}
|
|
354
|
+
function parseAlpha(v) {
|
|
355
|
+
if (v === void 0 || v.trim() === "") return 1;
|
|
356
|
+
const text = v.trim();
|
|
357
|
+
const isPct = text.endsWith("%");
|
|
358
|
+
const num = Number(isPct ? text.slice(0, -1) : text);
|
|
359
|
+
if (!Number.isFinite(num)) return null;
|
|
360
|
+
return isPct ? num / 100 : num;
|
|
361
|
+
}
|
|
362
|
+
function parseAngle(v) {
|
|
363
|
+
const text = v.trim().toLowerCase();
|
|
364
|
+
if (text.endsWith("deg")) {
|
|
365
|
+
const num2 = Number(text.slice(0, -3));
|
|
366
|
+
return Number.isFinite(num2) ? num2 : null;
|
|
367
|
+
}
|
|
368
|
+
if (text.endsWith("turn")) {
|
|
369
|
+
const num2 = Number(text.slice(0, -4));
|
|
370
|
+
return Number.isFinite(num2) ? num2 * 360 : null;
|
|
371
|
+
}
|
|
372
|
+
if (text.endsWith("rad")) {
|
|
373
|
+
const num2 = Number(text.slice(0, -3));
|
|
374
|
+
return Number.isFinite(num2) ? num2 * 180 / Math.PI : null;
|
|
375
|
+
}
|
|
376
|
+
const num = Number(text);
|
|
377
|
+
return Number.isFinite(num) ? num : null;
|
|
378
|
+
}
|
|
379
|
+
function splitParts(inner) {
|
|
380
|
+
const slashIndex = inner.indexOf("/");
|
|
381
|
+
let mainStr = inner;
|
|
382
|
+
let alphaPart;
|
|
383
|
+
if (slashIndex !== -1) {
|
|
384
|
+
mainStr = inner.slice(0, slashIndex);
|
|
385
|
+
alphaPart = inner.slice(slashIndex + 1);
|
|
386
|
+
}
|
|
387
|
+
const parts = mainStr.trim().split(/[\s,]+/).filter(Boolean);
|
|
388
|
+
return { parts, alphaPart };
|
|
389
|
+
}
|
|
390
|
+
function parseColor(input) {
|
|
391
|
+
if (typeof input === "string") {
|
|
392
|
+
const text = input.trim();
|
|
393
|
+
if (text.length === 0 || text.length > 200) return null;
|
|
394
|
+
const lower = text.toLowerCase();
|
|
395
|
+
const namedHex = NAMED_COLORS[lower];
|
|
396
|
+
if (namedHex) {
|
|
397
|
+
return parseHex(namedHex);
|
|
398
|
+
}
|
|
399
|
+
const hexMatch = HEX_RE.exec(text);
|
|
400
|
+
if (hexMatch) {
|
|
401
|
+
return parseHex(hexMatch[0]);
|
|
402
|
+
}
|
|
403
|
+
const rgbMatch = RGB_RE.exec(text);
|
|
404
|
+
if (rgbMatch) {
|
|
405
|
+
const { parts, alphaPart } = splitParts(rgbMatch[1]);
|
|
406
|
+
let alphaVal = 1;
|
|
407
|
+
if (alphaPart !== void 0) {
|
|
408
|
+
alphaVal = parseAlpha(alphaPart);
|
|
409
|
+
} else if (parts.length === 4) {
|
|
410
|
+
alphaVal = parseAlpha(parts.pop());
|
|
411
|
+
}
|
|
412
|
+
if (parts.length !== 3 || alphaVal === null) return null;
|
|
413
|
+
const r = parsePercentOrNumber(parts[0], 255);
|
|
414
|
+
const g = parsePercentOrNumber(parts[1], 255);
|
|
415
|
+
const b = parsePercentOrNumber(parts[2], 255);
|
|
416
|
+
if (r === null || g === null || b === null) return null;
|
|
417
|
+
return { r, g, b, a: alphaVal };
|
|
418
|
+
}
|
|
419
|
+
const hslMatch = HSL_RE.exec(text);
|
|
420
|
+
if (hslMatch) {
|
|
421
|
+
const { parts, alphaPart } = splitParts(hslMatch[1]);
|
|
422
|
+
let alphaVal = 1;
|
|
423
|
+
if (alphaPart !== void 0) {
|
|
424
|
+
alphaVal = parseAlpha(alphaPart);
|
|
425
|
+
} else if (parts.length === 4) {
|
|
426
|
+
alphaVal = parseAlpha(parts.pop());
|
|
427
|
+
}
|
|
428
|
+
if (parts.length !== 3 || alphaVal === null) return null;
|
|
429
|
+
const h = parseAngle(parts[0]);
|
|
430
|
+
const s = parsePercentOrNumber(parts[1], 100);
|
|
431
|
+
const l = parsePercentOrNumber(parts[2], 100);
|
|
432
|
+
if (h === null || s === null || l === null) return null;
|
|
433
|
+
return hslToRgb({ h, s, l, alpha: alphaVal });
|
|
434
|
+
}
|
|
435
|
+
const oklabMatch = OKLAB_RE.exec(text);
|
|
436
|
+
if (oklabMatch) {
|
|
437
|
+
const { parts, alphaPart } = splitParts(oklabMatch[1]);
|
|
438
|
+
let alphaVal = 1;
|
|
439
|
+
if (alphaPart !== void 0) {
|
|
440
|
+
alphaVal = parseAlpha(alphaPart);
|
|
441
|
+
} else if (parts.length === 4) {
|
|
442
|
+
alphaVal = parseAlpha(parts.pop());
|
|
443
|
+
}
|
|
444
|
+
if (parts.length !== 3 || alphaVal === null) return null;
|
|
445
|
+
const l = parsePercentOrNumber(parts[0], 1);
|
|
446
|
+
const a = parsePercentOrNumber(parts[1], 1);
|
|
447
|
+
const b = parsePercentOrNumber(parts[2], 1);
|
|
448
|
+
if (l === null || a === null || b === null) return null;
|
|
449
|
+
return oklabToRgb({ l, a, b, alpha: alphaVal });
|
|
450
|
+
}
|
|
451
|
+
const oklchMatch = OKLCH_RE.exec(text);
|
|
452
|
+
if (oklchMatch) {
|
|
453
|
+
const { parts, alphaPart } = splitParts(oklchMatch[1]);
|
|
454
|
+
let alphaVal = 1;
|
|
455
|
+
if (alphaPart !== void 0) {
|
|
456
|
+
alphaVal = parseAlpha(alphaPart);
|
|
457
|
+
} else if (parts.length === 4) {
|
|
458
|
+
alphaVal = parseAlpha(parts.pop());
|
|
459
|
+
}
|
|
460
|
+
if (parts.length !== 3 || alphaVal === null) return null;
|
|
461
|
+
const l = parsePercentOrNumber(parts[0], 1);
|
|
462
|
+
const c = parsePercentOrNumber(parts[1], 1);
|
|
463
|
+
const h = parseAngle(parts[2]);
|
|
464
|
+
if (l === null || c === null || h === null) return null;
|
|
465
|
+
return oklabToRgb(oklchToOklab({ l, c, h, alpha: alphaVal }));
|
|
466
|
+
}
|
|
467
|
+
const colorMatch = COLOR_FN_RE.exec(text);
|
|
468
|
+
if (colorMatch) {
|
|
469
|
+
const { parts, alphaPart } = splitParts(colorMatch[1]);
|
|
470
|
+
if (parts.length < 4) return null;
|
|
471
|
+
const space = parts[0].toLowerCase();
|
|
472
|
+
let alphaVal = 1;
|
|
473
|
+
if (alphaPart !== void 0) {
|
|
474
|
+
alphaVal = parseAlpha(alphaPart);
|
|
475
|
+
} else if (parts.length === 5) {
|
|
476
|
+
alphaVal = parseAlpha(parts.pop());
|
|
477
|
+
}
|
|
478
|
+
if (parts.length !== 4 || alphaVal === null) return null;
|
|
479
|
+
const c1 = parsePercentOrNumber(parts[1], 1);
|
|
480
|
+
const c2 = parsePercentOrNumber(parts[2], 1);
|
|
481
|
+
const c3 = parsePercentOrNumber(parts[3], 1);
|
|
482
|
+
if (c1 === null || c2 === null || c3 === null) return null;
|
|
483
|
+
if (space === "srgb") {
|
|
484
|
+
return { r: c1, g: c2, b: c3, a: alphaVal };
|
|
485
|
+
}
|
|
486
|
+
if (space === "srgb-linear") {
|
|
487
|
+
return {
|
|
488
|
+
r: linearToSrgb(c1),
|
|
489
|
+
g: linearToSrgb(c2),
|
|
490
|
+
b: linearToSrgb(c3),
|
|
491
|
+
a: alphaVal
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (space === "display-p3") {
|
|
495
|
+
const linP3R = srgbToLinear(c1);
|
|
496
|
+
const linP3G = srgbToLinear(c2);
|
|
497
|
+
const linP3B = srgbToLinear(c3);
|
|
498
|
+
const linSrgb = displayP3ToLinearSrgb({ r: linP3R, g: linP3G, b: linP3B, a: alphaVal });
|
|
499
|
+
return {
|
|
500
|
+
r: linearToSrgb(linSrgb.r),
|
|
501
|
+
g: linearToSrgb(linSrgb.g),
|
|
502
|
+
b: linearToSrgb(linSrgb.b),
|
|
503
|
+
a: alphaVal
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
if (typeof input === "object" && input !== null) {
|
|
511
|
+
const obj = input;
|
|
512
|
+
if (Array.isArray(obj.components)) {
|
|
513
|
+
const space = obj.colorSpace;
|
|
514
|
+
if (space === void 0 || space === "srgb") {
|
|
515
|
+
const [r2, g2, b2] = obj.components;
|
|
516
|
+
const a2 = typeof obj.alpha === "number" && Number.isFinite(obj.alpha) ? obj.alpha : 1;
|
|
517
|
+
if ([r2, g2, b2].every((v) => typeof v === "number" && Number.isFinite(v))) {
|
|
518
|
+
return { r: r2, g: g2, b: b2, a: a2 };
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (typeof obj.hex === "string") {
|
|
522
|
+
const base = parseColor(obj.hex);
|
|
523
|
+
if (!base) return null;
|
|
524
|
+
const a2 = typeof obj.alpha === "number" && Number.isFinite(obj.alpha) ? obj.alpha : 1;
|
|
525
|
+
return { r: base.r, g: base.g, b: base.b, a: a2 };
|
|
526
|
+
}
|
|
527
|
+
return null;
|
|
528
|
+
}
|
|
529
|
+
const { r, g, b } = obj;
|
|
530
|
+
const a = obj.a === void 0 ? 1 : obj.a;
|
|
531
|
+
if ([r, g, b, a].every((v) => typeof v === "number" && Number.isFinite(v))) {
|
|
532
|
+
return { r, g, b, a };
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
function parseHex(hex) {
|
|
538
|
+
let raw = hex.trim();
|
|
539
|
+
if (raw.startsWith("#")) raw = raw.slice(1);
|
|
540
|
+
if (raw.length === 3 || raw.length === 4) {
|
|
541
|
+
raw = [...raw].map((c) => c + c).join("");
|
|
542
|
+
}
|
|
543
|
+
if (raw.length !== 6 && raw.length !== 8) return null;
|
|
544
|
+
const r = parseInt(raw.slice(0, 2), 16) / 255;
|
|
545
|
+
const g = parseInt(raw.slice(2, 4), 16) / 255;
|
|
546
|
+
const b = parseInt(raw.slice(4, 6), 16) / 255;
|
|
547
|
+
const a = raw.length === 8 ? parseInt(raw.slice(6, 8), 16) / 255 : 1;
|
|
548
|
+
return { r, g, b, a };
|
|
549
|
+
}
|
|
550
|
+
function isColor(input) {
|
|
551
|
+
return parseColor(input) !== null;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// src/color/gamut.ts
|
|
555
|
+
var clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
556
|
+
function inSrgbGamut(c, epsilon = 1e-5) {
|
|
557
|
+
return c.r >= -epsilon && c.r <= 1 + epsilon && c.g >= -epsilon && c.g <= 1 + epsilon && c.b >= -epsilon && c.b <= 1 + epsilon;
|
|
558
|
+
}
|
|
559
|
+
function deltaEOK(a, b) {
|
|
560
|
+
const la = rgbToOklab(a);
|
|
561
|
+
const lb = rgbToOklab(b);
|
|
562
|
+
return Math.hypot(la.l - lb.l, la.a - lb.a, la.b - lb.b);
|
|
563
|
+
}
|
|
564
|
+
function toSrgbGamut(c) {
|
|
565
|
+
const lch = oklabToOklch(rgbToOklab(c));
|
|
566
|
+
if (lch.l >= 1) return { r: 1, g: 1, b: 1, a: c.a };
|
|
567
|
+
if (lch.l <= 0) return { r: 0, g: 0, b: 0, a: c.a };
|
|
568
|
+
if (inSrgbGamut(c)) {
|
|
569
|
+
return { r: clamp01(c.r), g: clamp01(c.g), b: clamp01(c.b), a: c.a };
|
|
570
|
+
}
|
|
571
|
+
let low = 0;
|
|
572
|
+
let high = lch.c;
|
|
573
|
+
let clippedCandidate = { r: clamp01(c.r), g: clamp01(c.g), b: clamp01(c.b), a: c.a };
|
|
574
|
+
const JND = 0.02;
|
|
575
|
+
const EPS = 1e-4;
|
|
576
|
+
for (let i = 0; i < 30; i++) {
|
|
577
|
+
const mid = (low + high) / 2;
|
|
578
|
+
const candidate = oklabToRgb(oklchToOklab({ l: lch.l, c: mid, h: lch.h, alpha: c.a }));
|
|
579
|
+
const clipped = {
|
|
580
|
+
r: clamp01(candidate.r),
|
|
581
|
+
g: clamp01(candidate.g),
|
|
582
|
+
b: clamp01(candidate.b),
|
|
583
|
+
a: c.a
|
|
584
|
+
};
|
|
585
|
+
clippedCandidate = clipped;
|
|
586
|
+
const dE = deltaEOK(candidate, clipped);
|
|
587
|
+
if (dE < JND) {
|
|
588
|
+
if (JND - dE < EPS) {
|
|
589
|
+
return clipped;
|
|
590
|
+
}
|
|
591
|
+
low = mid;
|
|
592
|
+
} else {
|
|
593
|
+
high = mid;
|
|
594
|
+
}
|
|
595
|
+
if (high - low < 1e-4) {
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return clippedCandidate;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// src/color/format.ts
|
|
603
|
+
var clamp012 = (v) => Math.min(1, Math.max(0, v));
|
|
604
|
+
var byte = (v) => Math.round(clamp012(v) * 255);
|
|
605
|
+
var hex2 = (n) => n.toString(16).padStart(2, "0");
|
|
606
|
+
var round2 = (n) => (Math.round(n * 100) / 100).toString();
|
|
607
|
+
function formatHex(c) {
|
|
608
|
+
const mapped = toSrgbGamut(c);
|
|
609
|
+
const head = `#${hex2(byte(mapped.r))}${hex2(byte(mapped.g))}${hex2(byte(mapped.b))}`;
|
|
610
|
+
const alpha = byte(mapped.a);
|
|
611
|
+
return alpha === 255 ? head : head + hex2(alpha);
|
|
612
|
+
}
|
|
613
|
+
function formatColor(c, format) {
|
|
614
|
+
switch (format) {
|
|
615
|
+
case "hex":
|
|
616
|
+
return formatHex(c);
|
|
617
|
+
case "rgb": {
|
|
618
|
+
const inGamut = toSrgbGamut(c);
|
|
619
|
+
const r = byte(inGamut.r);
|
|
620
|
+
const g = byte(inGamut.g);
|
|
621
|
+
const b = byte(inGamut.b);
|
|
622
|
+
return c.a < 1 ? `rgb(${r} ${g} ${b} / ${round2(c.a)})` : `rgb(${r} ${g} ${b})`;
|
|
623
|
+
}
|
|
624
|
+
case "hsl": {
|
|
625
|
+
const hsl = rgbToHsl(toSrgbGamut(c));
|
|
626
|
+
const h = (Math.round(hsl.h * 100) / 100).toString();
|
|
627
|
+
const s = (Math.round(hsl.s * 1e4) / 100).toString();
|
|
628
|
+
const l = (Math.round(hsl.l * 1e4) / 100).toString();
|
|
629
|
+
return c.a < 1 ? `hsl(${h} ${s}% ${l}% / ${round2(c.a)})` : `hsl(${h} ${s}% ${l}%)`;
|
|
630
|
+
}
|
|
631
|
+
case "oklch": {
|
|
632
|
+
const lch = oklabToOklch(rgbToOklab(c));
|
|
633
|
+
const l = (lch.l * 100).toFixed(2);
|
|
634
|
+
const ch = lch.c.toFixed(4);
|
|
635
|
+
const h = lch.h.toFixed(2);
|
|
636
|
+
return c.a < 1 ? `oklch(${l}% ${ch} ${h} / ${round2(c.a)})` : `oklch(${l}% ${ch} ${h})`;
|
|
637
|
+
}
|
|
638
|
+
case "oklab": {
|
|
639
|
+
const lab = rgbToOklab(c);
|
|
640
|
+
const l = (lab.l * 100).toFixed(2);
|
|
641
|
+
const a = lab.a.toFixed(4);
|
|
642
|
+
const b = lab.b.toFixed(4);
|
|
643
|
+
return c.a < 1 ? `oklab(${l}% ${a} ${b} / ${round2(c.a)})` : `oklab(${l}% ${a} ${b})`;
|
|
644
|
+
}
|
|
645
|
+
case "p3": {
|
|
646
|
+
const linSrgb = {
|
|
647
|
+
r: srgbToLinear(c.r),
|
|
648
|
+
g: srgbToLinear(c.g),
|
|
649
|
+
b: srgbToLinear(c.b),
|
|
650
|
+
a: c.a
|
|
651
|
+
};
|
|
652
|
+
const linP3 = linearSrgbToDisplayP3(linSrgb);
|
|
653
|
+
const r = linearToSrgb(linP3.r).toFixed(4);
|
|
654
|
+
const g = linearToSrgb(linP3.g).toFixed(4);
|
|
655
|
+
const b = linearToSrgb(linP3.b).toFixed(4);
|
|
656
|
+
return c.a < 1 ? `color(display-p3 ${r} ${g} ${b} / ${round2(c.a)})` : `color(display-p3 ${r} ${g} ${b})`;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function normalizeColor(input) {
|
|
661
|
+
const parsed = parseColor(input);
|
|
662
|
+
return parsed ? formatHex(parsed) : null;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// src/color/contrast.ts
|
|
666
|
+
var BLACK = { r: 0, g: 0, b: 0, a: 1 };
|
|
667
|
+
var WHITE = { r: 1, g: 1, b: 1, a: 1 };
|
|
668
|
+
function composite(fg, bg) {
|
|
669
|
+
const a = fg.a + bg.a * (1 - fg.a);
|
|
670
|
+
if (a === 0) return { r: 0, g: 0, b: 0, a: 0 };
|
|
671
|
+
return {
|
|
672
|
+
r: (fg.r * fg.a + bg.r * bg.a * (1 - fg.a)) / a,
|
|
673
|
+
g: (fg.g * fg.a + bg.g * bg.a * (1 - fg.a)) / a,
|
|
674
|
+
b: (fg.b * fg.a + bg.b * bg.a * (1 - fg.a)) / a,
|
|
675
|
+
a
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function relativeLuminance(c) {
|
|
679
|
+
const r = srgbToLinear(c.r);
|
|
680
|
+
const g = srgbToLinear(c.g);
|
|
681
|
+
const b = srgbToLinear(c.b);
|
|
682
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
683
|
+
}
|
|
684
|
+
function contrastRatio(foreground, background) {
|
|
685
|
+
let bg = background;
|
|
686
|
+
if (bg.a < 1) {
|
|
687
|
+
bg = composite(bg, WHITE);
|
|
688
|
+
}
|
|
689
|
+
let fg = foreground;
|
|
690
|
+
if (fg.a < 1) {
|
|
691
|
+
fg = composite(fg, bg);
|
|
692
|
+
}
|
|
693
|
+
const lum1 = relativeLuminance(fg);
|
|
694
|
+
const lum2 = relativeLuminance(bg);
|
|
695
|
+
const brighter = Math.max(lum1, lum2);
|
|
696
|
+
const darker = Math.min(lum1, lum2);
|
|
697
|
+
return (brighter + 0.05) / (darker + 0.05);
|
|
698
|
+
}
|
|
699
|
+
function contrastLevel(ratio, options) {
|
|
700
|
+
const large = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.large]), () => ( false));
|
|
701
|
+
if (large) {
|
|
702
|
+
if (ratio >= 4.5) return "AAA";
|
|
703
|
+
if (ratio >= 3) return "AA";
|
|
704
|
+
return "fail";
|
|
705
|
+
}
|
|
706
|
+
if (ratio >= 7) return "AAA";
|
|
707
|
+
if (ratio >= 4.5) return "AA";
|
|
708
|
+
return "fail";
|
|
709
|
+
}
|
|
710
|
+
function readableTextColor(background, candidates = [BLACK, WHITE]) {
|
|
711
|
+
let bestCandidate = _nullishCoalesce(candidates[0], () => ( BLACK));
|
|
712
|
+
let bestRatio = -1;
|
|
713
|
+
for (const candidate of candidates) {
|
|
714
|
+
const ratio = contrastRatio(candidate, background);
|
|
715
|
+
if (ratio > bestRatio) {
|
|
716
|
+
bestRatio = ratio;
|
|
717
|
+
bestCandidate = candidate;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return bestCandidate;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// src/color/suggest.ts
|
|
724
|
+
function suggestAccessibleForeground(foreground, background, options = {}) {
|
|
725
|
+
const large = _nullishCoalesce(options.large, () => ( false));
|
|
726
|
+
const lch = oklabToOklch(rgbToOklab(foreground));
|
|
727
|
+
const asHex = (l) => parseColor(formatHex(toSrgbGamut(oklabToRgb(oklchToOklab({ ...lch, l })))));
|
|
728
|
+
for (let d = 0.01; d <= 1; d += 0.01) {
|
|
729
|
+
const downCand = asHex(Math.max(0, lch.l - d));
|
|
730
|
+
const upCand = asHex(Math.min(1, lch.l + d));
|
|
731
|
+
const downRatio = contrastRatio(downCand, background);
|
|
732
|
+
const upRatio = contrastRatio(upCand, background);
|
|
733
|
+
const downPass = contrastLevel(downRatio, { large }) !== "fail";
|
|
734
|
+
const upPass = contrastLevel(upRatio, { large }) !== "fail";
|
|
735
|
+
if (downPass && upPass) return formatHex(downRatio >= upRatio ? downCand : upCand);
|
|
736
|
+
if (downPass) return formatHex(downCand);
|
|
737
|
+
if (upPass) return formatHex(upCand);
|
|
738
|
+
}
|
|
739
|
+
return void 0;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.rgbToHsl = rgbToHsl; exports.hslToRgb = hslToRgb; exports.rgbToHsv = rgbToHsv; exports.hsvToRgb = hsvToRgb; exports.rgbToOklab = rgbToOklab; exports.oklabToRgb = oklabToRgb; exports.oklabToOklch = oklabToOklch; exports.oklchToOklab = oklchToOklab; exports.linearSrgbToDisplayP3 = linearSrgbToDisplayP3; exports.displayP3ToLinearSrgb = displayP3ToLinearSrgb; exports.NAMED_COLORS = NAMED_COLORS; exports.parseColor = parseColor; exports.isColor = isColor; exports.inSrgbGamut = inSrgbGamut; exports.deltaEOK = deltaEOK; exports.toSrgbGamut = toSrgbGamut; exports.formatHex = formatHex; exports.formatColor = formatColor; exports.normalizeColor = normalizeColor; exports.relativeLuminance = relativeLuminance; exports.contrastRatio = contrastRatio; exports.contrastLevel = contrastLevel; exports.readableTextColor = readableTextColor; exports.suggestAccessibleForeground = suggestAccessibleForeground;
|