1 | "use strict";
|
2 |
|
3 | const rHex3 = /^#[0-9a-f]{3}$/;
|
4 | const rHex6 = /^#[0-9a-f]{6}$/;
|
5 | const rRGB = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,?\s*(0?\.?\d+)?\s*\)$/;
|
6 | const rHSL = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,?\s*(0?\.?\d+)?\s*\)$/;
|
7 |
|
8 | const colorNames = {
|
9 | aliceblue: { r: 240, g: 248, b: 255, a: 1 },
|
10 | antiquewhite: { r: 250, g: 235, b: 215, a: 1 },
|
11 | aqua: { r: 0, g: 255, b: 255, a: 1 },
|
12 | aquamarine: { r: 127, g: 255, b: 212, a: 1 },
|
13 | azure: { r: 240, g: 255, b: 255, a: 1 },
|
14 | beige: { r: 245, g: 245, b: 220, a: 1 },
|
15 | bisque: { r: 255, g: 228, b: 196, a: 1 },
|
16 | black: { r: 0, g: 0, b: 0, a: 1 },
|
17 | blanchedalmond: { r: 255, g: 235, b: 205, a: 1 },
|
18 | blue: { r: 0, g: 0, b: 255, a: 1 },
|
19 | blueviolet: { r: 138, g: 43, b: 226, a: 1 },
|
20 | brown: { r: 165, g: 42, b: 42, a: 1 },
|
21 | burlywood: { r: 222, g: 184, b: 135, a: 1 },
|
22 | cadetblue: { r: 95, g: 158, b: 160, a: 1 },
|
23 | chartreuse: { r: 127, g: 255, b: 0, a: 1 },
|
24 | chocolate: { r: 210, g: 105, b: 30, a: 1 },
|
25 | coral: { r: 255, g: 127, b: 80, a: 1 },
|
26 | cornflowerblue: { r: 100, g: 149, b: 237, a: 1 },
|
27 | cornsilk: { r: 255, g: 248, b: 220, a: 1 },
|
28 | crimson: { r: 220, g: 20, b: 60, a: 1 },
|
29 | cyan: { r: 0, g: 255, b: 255, a: 1 },
|
30 | darkblue: { r: 0, g: 0, b: 139, a: 1 },
|
31 | darkcyan: { r: 0, g: 139, b: 139, a: 1 },
|
32 | darkgoldenrod: { r: 184, g: 134, b: 11, a: 1 },
|
33 | darkgray: { r: 169, g: 169, b: 169, a: 1 },
|
34 | darkgreen: { r: 0, g: 100, b: 0, a: 1 },
|
35 | darkgrey: { r: 169, g: 169, b: 169, a: 1 },
|
36 | darkkhaki: { r: 189, g: 183, b: 107, a: 1 },
|
37 | darkmagenta: { r: 139, g: 0, b: 139, a: 1 },
|
38 | darkolivegreen: { r: 85, g: 107, b: 47, a: 1 },
|
39 | darkorange: { r: 255, g: 140, b: 0, a: 1 },
|
40 | darkorchid: { r: 153, g: 50, b: 204, a: 1 },
|
41 | darkred: { r: 139, g: 0, b: 0, a: 1 },
|
42 | darksalmon: { r: 233, g: 150, b: 122, a: 1 },
|
43 | darkseagreen: { r: 143, g: 188, b: 143, a: 1 },
|
44 | darkslateblue: { r: 72, g: 61, b: 139, a: 1 },
|
45 | darkslategray: { r: 47, g: 79, b: 79, a: 1 },
|
46 | darkslategrey: { r: 47, g: 79, b: 79, a: 1 },
|
47 | darkturquoise: { r: 0, g: 206, b: 209, a: 1 },
|
48 | darkviolet: { r: 148, g: 0, b: 211, a: 1 },
|
49 | deeppink: { r: 255, g: 20, b: 147, a: 1 },
|
50 | deepskyblue: { r: 0, g: 191, b: 255, a: 1 },
|
51 | dimgray: { r: 105, g: 105, b: 105, a: 1 },
|
52 | dimgrey: { r: 105, g: 105, b: 105, a: 1 },
|
53 | dodgerblue: { r: 30, g: 144, b: 255, a: 1 },
|
54 | firebrick: { r: 178, g: 34, b: 34, a: 1 },
|
55 | floralwhite: { r: 255, g: 250, b: 240, a: 1 },
|
56 | forestgreen: { r: 34, g: 139, b: 34, a: 1 },
|
57 | fuchsia: { r: 255, g: 0, b: 255, a: 1 },
|
58 | gainsboro: { r: 220, g: 220, b: 220, a: 1 },
|
59 | ghostwhite: { r: 248, g: 248, b: 255, a: 1 },
|
60 | gold: { r: 255, g: 215, b: 0, a: 1 },
|
61 | goldenrod: { r: 218, g: 165, b: 32, a: 1 },
|
62 | gray: { r: 128, g: 128, b: 128, a: 1 },
|
63 | green: { r: 0, g: 128, b: 0, a: 1 },
|
64 | greenyellow: { r: 173, g: 255, b: 47, a: 1 },
|
65 | grey: { r: 128, g: 128, b: 128, a: 1 },
|
66 | honeydew: { r: 240, g: 255, b: 240, a: 1 },
|
67 | hotpink: { r: 255, g: 105, b: 180, a: 1 },
|
68 | indianred: { r: 205, g: 92, b: 92, a: 1 },
|
69 | indigo: { r: 75, g: 0, b: 130, a: 1 },
|
70 | ivory: { r: 255, g: 255, b: 240, a: 1 },
|
71 | khaki: { r: 240, g: 230, b: 140, a: 1 },
|
72 | lavender: { r: 230, g: 230, b: 250, a: 1 },
|
73 | lavenderblush: { r: 255, g: 240, b: 245, a: 1 },
|
74 | lawngreen: { r: 124, g: 252, b: 0, a: 1 },
|
75 | lemonchiffon: { r: 255, g: 250, b: 205, a: 1 },
|
76 | lightblue: { r: 173, g: 216, b: 230, a: 1 },
|
77 | lightcoral: { r: 240, g: 128, b: 128, a: 1 },
|
78 | lightcyan: { r: 224, g: 255, b: 255, a: 1 },
|
79 | lightgoldenrodyellow: { r: 250, g: 250, b: 210, a: 1 },
|
80 | lightgray: { r: 211, g: 211, b: 211, a: 1 },
|
81 | lightgreen: { r: 144, g: 238, b: 144, a: 1 },
|
82 | lightgrey: { r: 211, g: 211, b: 211, a: 1 },
|
83 | lightpink: { r: 255, g: 182, b: 193, a: 1 },
|
84 | lightsalmon: { r: 255, g: 160, b: 122, a: 1 },
|
85 | lightseagreen: { r: 32, g: 178, b: 170, a: 1 },
|
86 | lightskyblue: { r: 135, g: 206, b: 250, a: 1 },
|
87 | lightslategray: { r: 119, g: 136, b: 153, a: 1 },
|
88 | lightslategrey: { r: 119, g: 136, b: 153, a: 1 },
|
89 | lightsteelblue: { r: 176, g: 196, b: 222, a: 1 },
|
90 | lightyellow: { r: 255, g: 255, b: 224, a: 1 },
|
91 | lime: { r: 0, g: 255, b: 0, a: 1 },
|
92 | limegreen: { r: 50, g: 205, b: 50, a: 1 },
|
93 | linen: { r: 250, g: 240, b: 230, a: 1 },
|
94 | magenta: { r: 255, g: 0, b: 255, a: 1 },
|
95 | maroon: { r: 128, g: 0, b: 0, a: 1 },
|
96 | mediumaquamarine: { r: 102, g: 205, b: 170, a: 1 },
|
97 | mediumblue: { r: 0, g: 0, b: 205, a: 1 },
|
98 | mediumorchid: { r: 186, g: 85, b: 211, a: 1 },
|
99 | mediumpurple: { r: 147, g: 112, b: 219, a: 1 },
|
100 | mediumseagreen: { r: 60, g: 179, b: 113, a: 1 },
|
101 | mediumslateblue: { r: 123, g: 104, b: 238, a: 1 },
|
102 | mediumspringgreen: { r: 0, g: 250, b: 154, a: 1 },
|
103 | mediumturquoise: { r: 72, g: 209, b: 204, a: 1 },
|
104 | mediumvioletred: { r: 199, g: 21, b: 133, a: 1 },
|
105 | midnightblue: { r: 25, g: 25, b: 112, a: 1 },
|
106 | mintcream: { r: 245, g: 255, b: 250, a: 1 },
|
107 | mistyrose: { r: 255, g: 228, b: 225, a: 1 },
|
108 | moccasin: { r: 255, g: 228, b: 181, a: 1 },
|
109 | navajowhite: { r: 255, g: 222, b: 173, a: 1 },
|
110 | navy: { r: 0, g: 0, b: 128, a: 1 },
|
111 | oldlace: { r: 253, g: 245, b: 230, a: 1 },
|
112 | olive: { r: 128, g: 128, b: 0, a: 1 },
|
113 | olivedrab: { r: 107, g: 142, b: 35, a: 1 },
|
114 | orange: { r: 255, g: 165, b: 0, a: 1 },
|
115 | orangered: { r: 255, g: 69, b: 0, a: 1 },
|
116 | orchid: { r: 218, g: 112, b: 214, a: 1 },
|
117 | palegoldenrod: { r: 238, g: 232, b: 170, a: 1 },
|
118 | palegreen: { r: 152, g: 251, b: 152, a: 1 },
|
119 | paleturquoise: { r: 175, g: 238, b: 238, a: 1 },
|
120 | palevioletred: { r: 219, g: 112, b: 147, a: 1 },
|
121 | papayawhip: { r: 255, g: 239, b: 213, a: 1 },
|
122 | peachpuff: { r: 255, g: 218, b: 185, a: 1 },
|
123 | peru: { r: 205, g: 133, b: 63, a: 1 },
|
124 | pink: { r: 255, g: 192, b: 203, a: 1 },
|
125 | plum: { r: 221, g: 160, b: 221, a: 1 },
|
126 | powderblue: { r: 176, g: 224, b: 230, a: 1 },
|
127 | purple: { r: 128, g: 0, b: 128, a: 1 },
|
128 | red: { r: 255, g: 0, b: 0, a: 1 },
|
129 | rosybrown: { r: 188, g: 143, b: 143, a: 1 },
|
130 | royalblue: { r: 65, g: 105, b: 225, a: 1 },
|
131 | saddlebrown: { r: 139, g: 69, b: 19, a: 1 },
|
132 | salmon: { r: 250, g: 128, b: 114, a: 1 },
|
133 | sandybrown: { r: 244, g: 164, b: 96, a: 1 },
|
134 | seagreen: { r: 46, g: 139, b: 87, a: 1 },
|
135 | seashell: { r: 255, g: 245, b: 238, a: 1 },
|
136 | sienna: { r: 160, g: 82, b: 45, a: 1 },
|
137 | silver: { r: 192, g: 192, b: 192, a: 1 },
|
138 | skyblue: { r: 135, g: 206, b: 235, a: 1 },
|
139 | slateblue: { r: 106, g: 90, b: 205, a: 1 },
|
140 | slategray: { r: 112, g: 128, b: 144, a: 1 },
|
141 | slategrey: { r: 112, g: 128, b: 144, a: 1 },
|
142 | snow: { r: 255, g: 250, b: 250, a: 1 },
|
143 | springgreen: { r: 0, g: 255, b: 127, a: 1 },
|
144 | steelblue: { r: 70, g: 130, b: 180, a: 1 },
|
145 | tan: { r: 210, g: 180, b: 140, a: 1 },
|
146 | teal: { r: 0, g: 128, b: 128, a: 1 },
|
147 | thistle: { r: 216, g: 191, b: 216, a: 1 },
|
148 | tomato: { r: 255, g: 99, b: 71, a: 1 },
|
149 | turquoise: { r: 64, g: 224, b: 208, a: 1 },
|
150 | violet: { r: 238, g: 130, b: 238, a: 1 },
|
151 | wheat: { r: 245, g: 222, b: 179, a: 1 },
|
152 | white: { r: 255, g: 255, b: 255, a: 1 },
|
153 | whitesmoke: { r: 245, g: 245, b: 245, a: 1 },
|
154 | yellow: { r: 255, g: 255, b: 0, a: 1 },
|
155 | yellowgreen: { r: 154, g: 205, b: 50, a: 1 }
|
156 | };
|
157 | const convertHue = (p, q, h) => {
|
158 | if (h < 0)
|
159 | h++;
|
160 | if (h > 1)
|
161 | h--;
|
162 | let color;
|
163 | if (h * 6 < 1) {
|
164 | color = p + ((q - p) * h * 6);
|
165 | }
|
166 | else if (h * 2 < 1) {
|
167 | color = q;
|
168 | }
|
169 | else if (h * 3 < 2) {
|
170 | color = p + ((q - p) * ((2 / 3) - h) * 6);
|
171 | }
|
172 | else {
|
173 | color = p;
|
174 | }
|
175 | return Math.round(color * 255);
|
176 | };
|
177 | const convertRGB = (value) => {
|
178 | const str = value.toString(16);
|
179 | if (value < 16)
|
180 | return `0${str}`;
|
181 | return str;
|
182 | };
|
183 | const mixValue = (a, b, ratio) => a + ((b - a) * ratio);
|
184 | class Color {
|
185 | |
186 |
|
187 |
|
188 | constructor(color) {
|
189 | if (typeof color === 'string') {
|
190 | this._parse(color);
|
191 | }
|
192 | else if (color != null && typeof color === 'object') {
|
193 | this.r = color.r | 0;
|
194 | this.g = color.g | 0;
|
195 | this.b = color.b | 0;
|
196 | this.a = +color.a;
|
197 | }
|
198 | else {
|
199 | throw new TypeError('color is required!');
|
200 | }
|
201 | if (this.r < 0 || this.r > 255
|
202 | || this.g < 0 || this.g > 255
|
203 | || this.b < 0 || this.b > 255
|
204 | || this.a < 0 || this.a > 1) {
|
205 | throw new RangeError(`{r: ${this.r}, g: ${this.g}, b: ${this.b}, a: ${this.a}} is invalid.`);
|
206 | }
|
207 | }
|
208 | |
209 |
|
210 |
|
211 | _parse(color) {
|
212 | color = color.toLowerCase();
|
213 | if (Object.prototype.hasOwnProperty.call(colorNames, color)) {
|
214 | const obj = colorNames[color];
|
215 | this.r = obj.r;
|
216 | this.g = obj.g;
|
217 | this.b = obj.b;
|
218 | this.a = obj.a;
|
219 | return;
|
220 | }
|
221 | if (rHex3.test(color)) {
|
222 | const txt = color.substring(1);
|
223 | const code = parseInt(txt, 16);
|
224 | this.r = ((code & 0xF00) >> 8) * 17;
|
225 | this.g = ((code & 0xF0) >> 4) * 17;
|
226 | this.b = (code & 0xF) * 17;
|
227 | this.a = 1;
|
228 | return;
|
229 | }
|
230 | if (rHex6.test(color)) {
|
231 | const txt = color.substring(1);
|
232 | const code = parseInt(txt, 16);
|
233 | this.r = (code & 0xFF0000) >> 16;
|
234 | this.g = (code & 0xFF00) >> 8;
|
235 | this.b = code & 0xFF;
|
236 | this.a = 1;
|
237 | return;
|
238 | }
|
239 | let match = color.match(rRGB);
|
240 | if (match) {
|
241 | this.r = Number(match[1]) | 0;
|
242 | this.g = Number(match[2]) | 0;
|
243 | this.b = Number(match[3]) | 0;
|
244 | this.a = match[4] ? +match[4] : 1;
|
245 | return;
|
246 | }
|
247 | match = color.match(rHSL);
|
248 | if (match) {
|
249 | const h = +match[1] / 360;
|
250 | const s = +match[2] / 100;
|
251 | const l = +match[3] / 100;
|
252 | this.a = match[4] ? +match[4] : 1;
|
253 | if (!s) {
|
254 | this.r = l * 255;
|
255 | this.g = this.r;
|
256 | this.b = this.r;
|
257 | }
|
258 | const q = l < 0.5 ? l * (1 + s) : l + s - (l * s);
|
259 | const p = (2 * l) - q;
|
260 | const rt = h + (1 / 3);
|
261 | const gt = h;
|
262 | const bt = h - (1 / 3);
|
263 | this.r = convertHue(p, q, rt);
|
264 | this.g = convertHue(p, q, gt);
|
265 | this.b = convertHue(p, q, bt);
|
266 | return;
|
267 | }
|
268 | throw new Error(`${color} is not a supported color format.`);
|
269 | }
|
270 | toString() {
|
271 | if (this.a === 1) {
|
272 | const r = convertRGB(this.r);
|
273 | const g = convertRGB(this.g);
|
274 | const b = convertRGB(this.b);
|
275 | if (this.r % 17 || this.g % 17 || this.b % 17) {
|
276 | return `#${r}${g}${b}`;
|
277 | }
|
278 | return `#${r[0]}${g[0]}${b[0]}`;
|
279 | }
|
280 | return `rgba(${this.r}, ${this.g}, ${this.b}, ${parseFloat(this.a.toFixed(2))})`;
|
281 | }
|
282 | |
283 |
|
284 |
|
285 |
|
286 | mix(color, ratio) {
|
287 | if (ratio > 1 || ratio < 0) {
|
288 | throw new RangeError('Valid numbers is only between 0 and 1.');
|
289 | }
|
290 | switch (ratio) {
|
291 | case 0:
|
292 | return new Color(this);
|
293 | case 1:
|
294 | return new Color(color);
|
295 | }
|
296 | return new Color({
|
297 | r: Math.round(mixValue(this.r, color.r, ratio)),
|
298 | g: Math.round(mixValue(this.g, color.g, ratio)),
|
299 | b: Math.round(mixValue(this.b, color.b, ratio)),
|
300 | a: mixValue(this.a, color.a, ratio)
|
301 | });
|
302 | }
|
303 | }
|
304 | module.exports = Color;
|
305 |
|
\ | No newline at end of file |