1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var _a;
|
4 | var formatting_1 = require("./utils/formatting");
|
5 | var math_1 = require("./utils/math");
|
6 | var RGB = 'rgb', HSL = 'hsl';
|
7 | var converters = (_a = {},
|
8 | _a[RGB + HSL] = RGBtoHSL,
|
9 | _a[HSL + RGB] = HSLtoRGB,
|
10 | _a);
|
11 |
|
12 |
|
13 |
|
14 | var maxChannelValues = {
|
15 | r: 255,
|
16 | g: 255,
|
17 | b: 255,
|
18 | h: 360,
|
19 | s: 1,
|
20 | l: 1,
|
21 | a: 1
|
22 | };
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | function color(value) {
|
28 | return parseHexCode(value) || parseColorFunction(value) || rgb(255, 0, 0);
|
29 | }
|
30 | exports.color = color;
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | function hsl(hue, saturation, lightness, alpha) {
|
39 | return new ColorHelper(HSL, modDegrees(hue), formatting_1.ensurePercent(saturation), formatting_1.ensurePercent(lightness), (alpha === undefined ? 1 : formatting_1.ensurePercent(alpha)), alpha !== undefined );
|
40 | }
|
41 | exports.hsl = hsl;
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | function hsla(hue, saturation, lightness, alpha) {
|
50 | return new ColorHelper(HSL, modDegrees(hue), formatting_1.ensurePercent(saturation), formatting_1.ensurePercent(lightness), formatting_1.ensurePercent(alpha), true);
|
51 | }
|
52 | exports.hsla = hsla;
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | function rgb(red, blue, green, alpha) {
|
61 | return new ColorHelper(RGB, red, blue, green, (alpha === undefined ? 1 : formatting_1.ensurePercent(alpha)), alpha !== undefined );
|
62 | }
|
63 | exports.rgb = rgb;
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 | function rgba(red, blue, green, alpha) {
|
72 | return new ColorHelper(RGB, red, blue, green, formatting_1.ensurePercent(alpha), true);
|
73 | }
|
74 | exports.rgba = rgba;
|
75 | function convertHelper(toFormat, helper, forceAlpha) {
|
76 | var fromFormat = helper.f, r = helper.r, g = helper.g, b = helper.b, a = helper.a;
|
77 | var newAlpha = forceAlpha === undefined ? helper.o : forceAlpha;
|
78 | if (fromFormat !== toFormat) {
|
79 | return converters[fromFormat + toFormat](r, g, b, a, newAlpha);
|
80 | }
|
81 | return forceAlpha === undefined ? helper : new ColorHelper(fromFormat, r, g, b, a, newAlpha);
|
82 | }
|
83 |
|
84 |
|
85 |
|
86 | var ColorHelper = (function () {
|
87 | function ColorHelper(format, r, g, b, a, hasAlpha) {
|
88 | var self = this;
|
89 | self.f = format;
|
90 | self.o = hasAlpha;
|
91 | var isHSL = format === HSL;
|
92 | self.r = clampColor(isHSL ? 'h' : 'r', r);
|
93 | self.g = clampColor(isHSL ? 's' : 'g', g);
|
94 | self.b = clampColor(isHSL ? 'l' : 'b', b);
|
95 | self.a = clampColor('a', a);
|
96 | }
|
97 | |
98 |
|
99 |
|
100 | ColorHelper.prototype.toString = function () {
|
101 | var _a = this, hasAlpha = _a.o, format = _a.f, r = _a.r, g = _a.g, b = _a.b, a = _a.a;
|
102 | var fnName;
|
103 | var params;
|
104 |
|
105 | if (format === RGB) {
|
106 | fnName = hasAlpha ? 'rgba' : RGB;
|
107 | params = [math_1.round(r), math_1.round(g), math_1.round(b)];
|
108 | }
|
109 | else if (format === HSL) {
|
110 | fnName = hasAlpha ? 'hsla' : HSL;
|
111 | params = [math_1.round(r), formatting_1.formatPercent(math_1.roundFloat(g, 100)), formatting_1.formatPercent(math_1.roundFloat(b, 100))];
|
112 | }
|
113 | else {
|
114 | throw new Error('Invalid color format');
|
115 | }
|
116 |
|
117 | if (hasAlpha) {
|
118 | params.push(formatting_1.formatFloat(math_1.roundFloat(a, 100000)));
|
119 | }
|
120 |
|
121 | return formatting_1.cssFunction(fnName, params);
|
122 | };
|
123 | |
124 |
|
125 |
|
126 | ColorHelper.prototype.toHexString = function () {
|
127 | var color = convertHelper(RGB, this);
|
128 | return '#' + (toHex(color.r) + toHex(color.g) + toHex(color.b)).toUpperCase();
|
129 | };
|
130 | |
131 |
|
132 |
|
133 | ColorHelper.prototype.toHSL = function () {
|
134 | return convertHelper(HSL, this, false);
|
135 | };
|
136 | |
137 |
|
138 |
|
139 | ColorHelper.prototype.toHSLA = function () {
|
140 | return convertHelper(HSL, this, true);
|
141 | };
|
142 | |
143 |
|
144 |
|
145 | ColorHelper.prototype.toRGB = function () {
|
146 | return convertHelper(RGB, this, false);
|
147 | };
|
148 | |
149 |
|
150 |
|
151 | ColorHelper.prototype.toRGBA = function () {
|
152 | return convertHelper(RGB, this, true);
|
153 | };
|
154 | ColorHelper.prototype.red = function () {
|
155 | var _ = this;
|
156 | return (_.f === RGB ? _ : _.toRGB()).r;
|
157 | };
|
158 | ColorHelper.prototype.green = function () {
|
159 | var _ = this;
|
160 | return (_.f === RGB ? _ : _.toRGB()).g;
|
161 | };
|
162 | ColorHelper.prototype.blue = function () {
|
163 | var _ = this;
|
164 | return (_.f === RGB ? _ : _.toRGB()).b;
|
165 | };
|
166 | ColorHelper.prototype.hue = function () {
|
167 | var _ = this;
|
168 | return (_.f === HSL ? _ : _.toHSL()).r;
|
169 | };
|
170 | ColorHelper.prototype.saturation = function () {
|
171 | var _ = this;
|
172 | return (_.f === HSL ? _ : _.toHSL()).g;
|
173 | };
|
174 | ColorHelper.prototype.lightness = function () {
|
175 | var _ = this;
|
176 | return (_.f === HSL ? _ : _.toHSL()).b;
|
177 | };
|
178 | ColorHelper.prototype.alpha = function () {
|
179 | return this.a;
|
180 | };
|
181 | ColorHelper.prototype.opacity = function () {
|
182 | return this.a;
|
183 | };
|
184 | ColorHelper.prototype.invert = function () {
|
185 | var _ = this;
|
186 | var color2 = convertHelper(RGB, _);
|
187 | return convertHelper(_.f, new ColorHelper(RGB, 255 - color2.r, 255 - color2.g, 255 - color2.b, _.a, _.o));
|
188 | };
|
189 | ColorHelper.prototype.lighten = function (percent, relative) {
|
190 | var _ = this;
|
191 | var color2 = convertHelper(HSL, _);
|
192 | var max = maxChannelValues.l;
|
193 | var l = color2.b + (relative ? max - color2.b : max) * formatting_1.ensurePercent(percent);
|
194 | return convertHelper(_.f, new ColorHelper(HSL, color2.r, color2.g, l, _.a, _.o));
|
195 | };
|
196 | ColorHelper.prototype.darken = function (percent, relative) {
|
197 | var _ = this;
|
198 | var color2 = convertHelper(HSL, _);
|
199 | var l = color2.b - (relative ? color2.b : maxChannelValues.l) * formatting_1.ensurePercent(percent);
|
200 | return convertHelper(_.f, new ColorHelper(HSL, color2.r, color2.g, l, _.a, _.o));
|
201 | };
|
202 | ColorHelper.prototype.saturate = function (percent, relative) {
|
203 | var _ = this;
|
204 | var color2 = convertHelper(HSL, _);
|
205 | var max = maxChannelValues.s;
|
206 | var s = color2.g + (relative ? max - color2.g : max) * formatting_1.ensurePercent(percent);
|
207 | return convertHelper(_.f, new ColorHelper(HSL, color2.r, s, color2.b, _.a, _.o));
|
208 | };
|
209 | ColorHelper.prototype.desaturate = function (percent, relative) {
|
210 | var _ = this;
|
211 | var color2 = convertHelper(HSL, _);
|
212 | var max = maxChannelValues.s;
|
213 | var s = color2.g - (relative ? color2.g : max) * formatting_1.ensurePercent(percent);
|
214 | return convertHelper(_.f, new ColorHelper(HSL, color2.r, s, color2.b, _.a, _.o));
|
215 | };
|
216 | ColorHelper.prototype.grayscale = function () {
|
217 | return this.desaturate(1);
|
218 | };
|
219 | ColorHelper.prototype.fade = function (percent) {
|
220 | var _ = this;
|
221 | var a = clampColor('a', formatting_1.ensurePercent(percent));
|
222 | return convertHelper(_.f, new ColorHelper(_.f, _.r, _.g, _.b, a, true));
|
223 | };
|
224 | ColorHelper.prototype.fadeOut = function (percent, relative) {
|
225 | var _ = this;
|
226 | var max = 1;
|
227 | var a = clampColor('a', _.a - (relative ? _.a : max) * formatting_1.ensurePercent(percent));
|
228 | return convertHelper(_.f, new ColorHelper(_.f, _.r, _.g, _.b, a, true));
|
229 | };
|
230 | ColorHelper.prototype.fadeIn = function (percent, relative) {
|
231 | var _ = this;
|
232 | var max = 1;
|
233 | var a = clampColor('a', _.a + (relative ? _.a : max) * formatting_1.ensurePercent(percent));
|
234 | return convertHelper(_.f, new ColorHelper(_.f, _.r, _.g, _.b, a, true));
|
235 | };
|
236 | ColorHelper.prototype.mix = function (mixin, weight) {
|
237 | var _ = this;
|
238 | var color2 = ensureColor(mixin);
|
239 | var g = convertHelper(RGB, _);
|
240 | var b = convertHelper(RGB, color2);
|
241 | var p = weight === undefined ? 0.5 : weight;
|
242 | var w = 2 * p - 1;
|
243 | var a = Math.abs(g.a - b.a);
|
244 | var w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
|
245 | var w2 = 1 - w1;
|
246 | var helper = new ColorHelper(RGB, math_1.round(g.r * w1 + b.r * w2), math_1.round(g.g * w1 + b.g * w2), math_1.round(g.b * w1 + b.b * w2), g.a * p + b.a * (1 - p), _.o || color2.o);
|
247 | return convertHelper(this.f, helper);
|
248 | };
|
249 | ColorHelper.prototype.tint = function (weight) {
|
250 | return rgb(255, 255, 255).mix(this, weight);
|
251 | };
|
252 | ColorHelper.prototype.shade = function (weight) {
|
253 | return rgb(0, 0, 0).mix(this, weight);
|
254 | };
|
255 | ColorHelper.prototype.spin = function (degrees) {
|
256 | var _ = this;
|
257 | var color2 = convertHelper(HSL, _);
|
258 | return convertHelper(_.f, new ColorHelper(HSL, modDegrees(color2.r + degrees), color2.g, color2.b, _.a, _.o));
|
259 | };
|
260 | return ColorHelper;
|
261 | }());
|
262 | exports.ColorHelper = ColorHelper;
|
263 | function toHex(n) {
|
264 | var i = math_1.round(n);
|
265 | return (i < 16 ? '0' : '') + i.toString(16);
|
266 | }
|
267 | function modDegrees(n) {
|
268 |
|
269 | return ((n < 0 ? 360 : 0) + n % 360) % 360;
|
270 | }
|
271 | function RGBtoHSL(r, g, b, a, hasAlpha) {
|
272 | var newR = r / 255;
|
273 | var newG = g / 255;
|
274 | var newB = b / 255;
|
275 | var min = Math.min(newR, newG, newB);
|
276 | var max = Math.max(newR, newG, newB);
|
277 | var l = (min + max) / 2;
|
278 | var delta = max - min;
|
279 | var h;
|
280 | if (max === min) {
|
281 | h = 0;
|
282 | }
|
283 | else if (newR === max) {
|
284 | h = (newG - newB) / delta;
|
285 | }
|
286 | else if (newG === max) {
|
287 | h = 2 + (newB - newR) / delta;
|
288 | }
|
289 | else if (newB === max) {
|
290 | h = 4 + (newR - newG) / delta;
|
291 | }
|
292 | else {
|
293 | h = 0;
|
294 | }
|
295 | h = Math.min(h * 60, 360);
|
296 | if (h < 0) {
|
297 | h += 360;
|
298 | }
|
299 | var s;
|
300 | if (max === min) {
|
301 | s = 0;
|
302 | }
|
303 | else if (l <= 0.5) {
|
304 | s = delta / (max + min);
|
305 | }
|
306 | else {
|
307 | s = delta / (2 - max - min);
|
308 | }
|
309 | return new ColorHelper(HSL, h, s, l, a, hasAlpha);
|
310 | }
|
311 | function HSLtoRGB(r, g, b, a, hasAlpha) {
|
312 | var newH = r / 360;
|
313 | var newS = g;
|
314 | var newL = b;
|
315 | if (newS === 0) {
|
316 | var val = newL * 255;
|
317 | return new ColorHelper(RGB, val, val, val, a, hasAlpha);
|
318 | }
|
319 | var t2 = newL < 0.5 ? newL * (1 + newS) : newL + newS - newL * newS;
|
320 | var t1 = 2 * newL - t2;
|
321 | var newR = 0, newG = 0, newB = 0;
|
322 | for (var i = 0; i < 3; i++) {
|
323 | var t3 = newH + 1 / 3 * -(i - 1);
|
324 | if (t3 < 0) {
|
325 | t3++;
|
326 | }
|
327 | if (t3 > 1) {
|
328 | t3--;
|
329 | }
|
330 | var val = void 0;
|
331 | if (6 * t3 < 1) {
|
332 | val = t1 + (t2 - t1) * 6 * t3;
|
333 | }
|
334 | else if (2 * t3 < 1) {
|
335 | val = t2;
|
336 | }
|
337 | else if (3 * t3 < 2) {
|
338 | val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
|
339 | }
|
340 | else {
|
341 | val = t1;
|
342 | }
|
343 | val *= 255;
|
344 |
|
345 | if (i === 0) {
|
346 | newR = val;
|
347 | }
|
348 | else if (i === 1) {
|
349 | newG = val;
|
350 | }
|
351 | else {
|
352 | newB = val;
|
353 | }
|
354 | }
|
355 | return new ColorHelper(RGB, newR, newG, newB, a, hasAlpha);
|
356 | }
|
357 | function clampColor(channel, value) {
|
358 | var min = 0;
|
359 | var max = maxChannelValues[channel];
|
360 | return value < min ? min : value > max ? max : value;
|
361 | }
|
362 | function ensureColor(c) {
|
363 | return c instanceof ColorHelper ? c : color(c);
|
364 | }
|
365 | function parseHexCode(stringValue) {
|
366 | var match = stringValue.match(/#(([a-f0-9]{6})|([a-f0-9]{3}))$/i);
|
367 | if (!match) {
|
368 | return undefined;
|
369 | }
|
370 | var hex = match[1];
|
371 | var hexColor = parseInt(hex.length === 3 ? hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] : hex, 16);
|
372 | var r = (hexColor >> 16) & 0xff;
|
373 | var b = (hexColor >> 8) & 0xff;
|
374 | var g = hexColor & 0xff;
|
375 | return new ColorHelper(RGB, r, b, g, 1, false);
|
376 | }
|
377 | function parseColorFunction(colorString) {
|
378 | var cssParts = formatting_1.parseCSSFunction(colorString);
|
379 | if (!cssParts || !(cssParts.length === 4 || cssParts.length === 5)) {
|
380 | return undefined;
|
381 | }
|
382 | var fn = cssParts[0];
|
383 | var isRGBA = fn === 'rgba';
|
384 | var isHSLA = fn === 'hsla';
|
385 | var isRGB = fn === RGB;
|
386 | var isHSL = fn === HSL;
|
387 | var hasAlpha = isHSLA || isRGBA;
|
388 | var type;
|
389 | if (isRGB || isRGBA) {
|
390 | type = RGB;
|
391 | }
|
392 | else if (isHSL || isHSLA) {
|
393 | type = HSL;
|
394 | }
|
395 | else {
|
396 | throw new Error('unsupported color string');
|
397 | }
|
398 | var r = formatting_1.toFloat(cssParts[1]);
|
399 | var g = isRGB || isRGBA ? formatting_1.toFloat(cssParts[2]) : formatting_1.ensurePercent(cssParts[2]);
|
400 | var b = isRGB || isRGBA ? formatting_1.toFloat(cssParts[3]) : formatting_1.ensurePercent(cssParts[3]);
|
401 | var a = hasAlpha ? formatting_1.toFloat(cssParts[4]) : 1;
|
402 | return new ColorHelper(type, r, g, b, a, hasAlpha);
|
403 | }
|