1 |
|
2 | .tinyColorMixin() {
|
3 | @functions: ~`(function() {
|
4 |
|
5 |
|
6 |
|
7 | var trimLeft = /^\s+/,
|
8 | trimRight = /\s+$/,
|
9 | tinyCounter = 0,
|
10 | mathRound = Math.round,
|
11 | mathMin = Math.min,
|
12 | mathMax = Math.max,
|
13 | mathRandom = Math.random;
|
14 |
|
15 | function tinycolor (color, opts) {
|
16 |
|
17 | color = (color) ? color : '';
|
18 | opts = opts || { };
|
19 |
|
20 |
|
21 | if (color instanceof tinycolor) {
|
22 | return color;
|
23 | }
|
24 |
|
25 | if (!(this instanceof tinycolor)) {
|
26 | return new tinycolor(color, opts);
|
27 | }
|
28 |
|
29 | var rgb = inputToRGB(color);
|
30 | this._originalInput = color,
|
31 | this._r = rgb.r,
|
32 | this._g = rgb.g,
|
33 | this._b = rgb.b,
|
34 | this._a = rgb.a,
|
35 | this._roundA = mathRound(100*this._a) / 100,
|
36 | this._format = opts.format || rgb.format;
|
37 | this._gradientType = opts.gradientType;
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | if (this._r < 1) { this._r = mathRound(this._r); }
|
44 | if (this._g < 1) { this._g = mathRound(this._g); }
|
45 | if (this._b < 1) { this._b = mathRound(this._b); }
|
46 |
|
47 | this._ok = rgb.ok;
|
48 | this._tc_id = tinyCounter++;
|
49 | }
|
50 |
|
51 | tinycolor.prototype = {
|
52 | isDark: function() {
|
53 | return this.getBrightness() < 128;
|
54 | },
|
55 | isLight: function() {
|
56 | return !this.isDark();
|
57 | },
|
58 | isValid: function() {
|
59 | return this._ok;
|
60 | },
|
61 | getOriginalInput: function() {
|
62 | return this._originalInput;
|
63 | },
|
64 | getFormat: function() {
|
65 | return this._format;
|
66 | },
|
67 | getAlpha: function() {
|
68 | return this._a;
|
69 | },
|
70 | getBrightness: function() {
|
71 |
|
72 | var rgb = this.toRgb();
|
73 | return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
|
74 | },
|
75 | getLuminance: function() {
|
76 |
|
77 | var rgb = this.toRgb();
|
78 | var RsRGB, GsRGB, BsRGB, R, G, B;
|
79 | RsRGB = rgb.r/255;
|
80 | GsRGB = rgb.g/255;
|
81 | BsRGB = rgb.b/255;
|
82 |
|
83 | if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}
|
84 | if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}
|
85 | if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}
|
86 | return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);
|
87 | },
|
88 | setAlpha: function(value) {
|
89 | this._a = boundAlpha(value);
|
90 | this._roundA = mathRound(100*this._a) / 100;
|
91 | return this;
|
92 | },
|
93 | toHsv: function() {
|
94 | var hsv = rgbToHsv(this._r, this._g, this._b);
|
95 | return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
|
96 | },
|
97 | toHsvString: function() {
|
98 | var hsv = rgbToHsv(this._r, this._g, this._b);
|
99 | var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
100 | return (this._a == 1) ?
|
101 | "hsv(" + h + ", " + s + "%, " + v + "%)" :
|
102 | "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
|
103 | },
|
104 | toHsl: function() {
|
105 | var hsl = rgbToHsl(this._r, this._g, this._b);
|
106 | return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
|
107 | },
|
108 | toHslString: function() {
|
109 | var hsl = rgbToHsl(this._r, this._g, this._b);
|
110 | var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
111 | return (this._a == 1) ?
|
112 | "hsl(" + h + ", " + s + "%, " + l + "%)" :
|
113 | "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
|
114 | },
|
115 | toHex: function(allow3Char) {
|
116 | return rgbToHex(this._r, this._g, this._b, allow3Char);
|
117 | },
|
118 | toHexString: function(allow3Char) {
|
119 | return '#' + this.toHex(allow3Char);
|
120 | },
|
121 | toHex8: function(allow4Char) {
|
122 | return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
|
123 | },
|
124 | toHex8String: function(allow4Char) {
|
125 | return '#' + this.toHex8(allow4Char);
|
126 | },
|
127 | toRgb: function() {
|
128 | return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
|
129 | },
|
130 | toRgbString: function() {
|
131 | return (this._a == 1) ?
|
132 | "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
|
133 | "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
|
134 | },
|
135 | toPercentageRgb: function() {
|
136 | return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
|
137 | },
|
138 | toPercentageRgbString: function() {
|
139 | return (this._a == 1) ?
|
140 | "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
|
141 | "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
|
142 | },
|
143 | toName: function() {
|
144 | if (this._a === 0) {
|
145 | return "transparent";
|
146 | }
|
147 |
|
148 | if (this._a < 1) {
|
149 | return false;
|
150 | }
|
151 |
|
152 | return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
|
153 | },
|
154 | toFilter: function(secondColor) {
|
155 | var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);
|
156 | var secondHex8String = hex8String;
|
157 | var gradientType = this._gradientType ? "GradientType = 1, " : "";
|
158 |
|
159 | if (secondColor) {
|
160 | var s = tinycolor(secondColor);
|
161 | secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);
|
162 | }
|
163 |
|
164 | return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
|
165 | },
|
166 | toString: function(format) {
|
167 | var formatSet = !!format;
|
168 | format = format || this._format;
|
169 |
|
170 | var formattedString = false;
|
171 | var hasAlpha = this._a < 1 && this._a >= 0;
|
172 | var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name");
|
173 |
|
174 | if (needsAlphaFormat) {
|
175 |
|
176 |
|
177 | if (format === "name" && this._a === 0) {
|
178 | return this.toName();
|
179 | }
|
180 | return this.toRgbString();
|
181 | }
|
182 | if (format === "rgb") {
|
183 | formattedString = this.toRgbString();
|
184 | }
|
185 | if (format === "prgb") {
|
186 | formattedString = this.toPercentageRgbString();
|
187 | }
|
188 | if (format === "hex" || format === "hex6") {
|
189 | formattedString = this.toHexString();
|
190 | }
|
191 | if (format === "hex3") {
|
192 | formattedString = this.toHexString(true);
|
193 | }
|
194 | if (format === "hex4") {
|
195 | formattedString = this.toHex8String(true);
|
196 | }
|
197 | if (format === "hex8") {
|
198 | formattedString = this.toHex8String();
|
199 | }
|
200 | if (format === "name") {
|
201 | formattedString = this.toName();
|
202 | }
|
203 | if (format === "hsl") {
|
204 | formattedString = this.toHslString();
|
205 | }
|
206 | if (format === "hsv") {
|
207 | formattedString = this.toHsvString();
|
208 | }
|
209 |
|
210 | return formattedString || this.toHexString();
|
211 | },
|
212 | clone: function() {
|
213 | return tinycolor(this.toString());
|
214 | },
|
215 |
|
216 | _applyModification: function(fn, args) {
|
217 | var color = fn.apply(null, [this].concat([].slice.call(args)));
|
218 | this._r = color._r;
|
219 | this._g = color._g;
|
220 | this._b = color._b;
|
221 | this.setAlpha(color._a);
|
222 | return this;
|
223 | },
|
224 | lighten: function() {
|
225 | return this._applyModification(lighten, arguments);
|
226 | },
|
227 | brighten: function() {
|
228 | return this._applyModification(brighten, arguments);
|
229 | },
|
230 | darken: function() {
|
231 | return this._applyModification(darken, arguments);
|
232 | },
|
233 | desaturate: function() {
|
234 | return this._applyModification(desaturate, arguments);
|
235 | },
|
236 | saturate: function() {
|
237 | return this._applyModification(saturate, arguments);
|
238 | },
|
239 | greyscale: function() {
|
240 | return this._applyModification(greyscale, arguments);
|
241 | },
|
242 | spin: function() {
|
243 | return this._applyModification(spin, arguments);
|
244 | },
|
245 |
|
246 | _applyCombination: function(fn, args) {
|
247 | return fn.apply(null, [this].concat([].slice.call(args)));
|
248 | },
|
249 | analogous: function() {
|
250 | return this._applyCombination(analogous, arguments);
|
251 | },
|
252 | complement: function() {
|
253 | return this._applyCombination(complement, arguments);
|
254 | },
|
255 | monochromatic: function() {
|
256 | return this._applyCombination(monochromatic, arguments);
|
257 | },
|
258 | splitcomplement: function() {
|
259 | return this._applyCombination(splitcomplement, arguments);
|
260 | },
|
261 | triad: function() {
|
262 | return this._applyCombination(triad, arguments);
|
263 | },
|
264 | tetrad: function() {
|
265 | return this._applyCombination(tetrad, arguments);
|
266 | }
|
267 | };
|
268 |
|
269 |
|
270 |
|
271 | tinycolor.fromRatio = function(color, opts) {
|
272 | if (typeof color == "object") {
|
273 | var newColor = {};
|
274 | for (var i in color) {
|
275 | if (color.hasOwnProperty(i)) {
|
276 | if (i === "a") {
|
277 | newColor[i] = color[i];
|
278 | }
|
279 | else {
|
280 | newColor[i] = convertToPercentage(color[i]);
|
281 | }
|
282 | }
|
283 | }
|
284 | color = newColor;
|
285 | }
|
286 |
|
287 | return tinycolor(color, opts);
|
288 | };
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 | function inputToRGB(color) {
|
306 |
|
307 | var rgb = { r: 0, g: 0, b: 0 };
|
308 | var a = 1;
|
309 | var s = null;
|
310 | var v = null;
|
311 | var l = null;
|
312 | var ok = false;
|
313 | var format = false;
|
314 |
|
315 | if (typeof color == "string") {
|
316 | color = stringInputToObject(color);
|
317 | }
|
318 |
|
319 | if (typeof color == "object") {
|
320 | if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
|
321 | rgb = rgbToRgb(color.r, color.g, color.b);
|
322 | ok = true;
|
323 | format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
324 | }
|
325 | else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
|
326 | s = convertToPercentage(color.s);
|
327 | v = convertToPercentage(color.v);
|
328 | rgb = hsvToRgb(color.h, s, v);
|
329 | ok = true;
|
330 | format = "hsv";
|
331 | }
|
332 | else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
|
333 | s = convertToPercentage(color.s);
|
334 | l = convertToPercentage(color.l);
|
335 | rgb = hslToRgb(color.h, s, l);
|
336 | ok = true;
|
337 | format = "hsl";
|
338 | }
|
339 |
|
340 | if (color.hasOwnProperty("a")) {
|
341 | a = color.a;
|
342 | }
|
343 | }
|
344 |
|
345 | a = boundAlpha(a);
|
346 |
|
347 | return {
|
348 | ok: ok,
|
349 | format: color.format || format,
|
350 | r: mathMin(255, mathMax(rgb.r, 0)),
|
351 | g: mathMin(255, mathMax(rgb.g, 0)),
|
352 | b: mathMin(255, mathMax(rgb.b, 0)),
|
353 | a: a
|
354 | };
|
355 | }
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 | function rgbToRgb(r, g, b){
|
369 | return {
|
370 | r: bound01(r, 255) * 255,
|
371 | g: bound01(g, 255) * 255,
|
372 | b: bound01(b, 255) * 255
|
373 | };
|
374 | }
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 | function rgbToHsl(r, g, b) {
|
381 |
|
382 | r = bound01(r, 255);
|
383 | g = bound01(g, 255);
|
384 | b = bound01(b, 255);
|
385 |
|
386 | var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
387 | var h, s, l = (max + min) / 2;
|
388 |
|
389 | if(max == min) {
|
390 | h = s = 0;
|
391 | }
|
392 | else {
|
393 | var d = max - min;
|
394 | s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
395 | switch(max) {
|
396 | case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
397 | case g: h = (b - r) / d + 2; break;
|
398 | case b: h = (r - g) / d + 4; break;
|
399 | }
|
400 |
|
401 | h /= 6;
|
402 | }
|
403 |
|
404 | return { h: h, s: s, l: l };
|
405 | }
|
406 |
|
407 |
|
408 |
|
409 |
|
410 |
|
411 | function hslToRgb(h, s, l) {
|
412 | var r, g, b;
|
413 |
|
414 | h = bound01(h, 360);
|
415 | s = bound01(s, 100);
|
416 | l = bound01(l, 100);
|
417 |
|
418 | function hue2rgb(p, q, t) {
|
419 | if(t < 0) t += 1;
|
420 | if(t > 1) t -= 1;
|
421 | if(t < 1/6) return p + (q - p) * 6 * t;
|
422 | if(t < 1/2) return q;
|
423 | if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
424 | return p;
|
425 | }
|
426 |
|
427 | if(s === 0) {
|
428 | r = g = b = l;
|
429 | }
|
430 | else {
|
431 | var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
432 | var p = 2 * l - q;
|
433 | r = hue2rgb(p, q, h + 1/3);
|
434 | g = hue2rgb(p, q, h);
|
435 | b = hue2rgb(p, q, h - 1/3);
|
436 | }
|
437 |
|
438 | return { r: r * 255, g: g * 255, b: b * 255 };
|
439 | }
|
440 |
|
441 |
|
442 |
|
443 |
|
444 |
|
445 | function rgbToHsv(r, g, b) {
|
446 |
|
447 | r = bound01(r, 255);
|
448 | g = bound01(g, 255);
|
449 | b = bound01(b, 255);
|
450 |
|
451 | var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
452 | var h, s, v = max;
|
453 |
|
454 | var d = max - min;
|
455 | s = max === 0 ? 0 : d / max;
|
456 |
|
457 | if(max == min) {
|
458 | h = 0;
|
459 | }
|
460 | else {
|
461 | switch(max) {
|
462 | case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
463 | case g: h = (b - r) / d + 2; break;
|
464 | case b: h = (r - g) / d + 4; break;
|
465 | }
|
466 | h /= 6;
|
467 | }
|
468 | return { h: h, s: s, v: v };
|
469 | }
|
470 |
|
471 |
|
472 |
|
473 |
|
474 |
|
475 | function hsvToRgb(h, s, v) {
|
476 |
|
477 | h = bound01(h, 360) * 6;
|
478 | s = bound01(s, 100);
|
479 | v = bound01(v, 100);
|
480 |
|
481 | var i = Math.floor(h),
|
482 | f = h - i,
|
483 | p = v * (1 - s),
|
484 | q = v * (1 - f * s),
|
485 | t = v * (1 - (1 - f) * s),
|
486 | mod = i % 6,
|
487 | r = [v, q, p, p, t, v][mod],
|
488 | g = [t, v, v, q, p, p][mod],
|
489 | b = [p, p, t, v, v, q][mod];
|
490 |
|
491 | return { r: r * 255, g: g * 255, b: b * 255 };
|
492 | }
|
493 |
|
494 |
|
495 |
|
496 |
|
497 |
|
498 | function rgbToHex(r, g, b, allow3Char) {
|
499 |
|
500 | var hex = [
|
501 | pad2(mathRound(r).toString(16)),
|
502 | pad2(mathRound(g).toString(16)),
|
503 | pad2(mathRound(b).toString(16))
|
504 | ];
|
505 |
|
506 |
|
507 | if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
|
508 | return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
509 | }
|
510 |
|
511 | return hex.join("");
|
512 | }
|
513 |
|
514 |
|
515 |
|
516 |
|
517 |
|
518 | function rgbaToHex(r, g, b, a, allow4Char) {
|
519 |
|
520 | var hex = [
|
521 | pad2(mathRound(r).toString(16)),
|
522 | pad2(mathRound(g).toString(16)),
|
523 | pad2(mathRound(b).toString(16)),
|
524 | pad2(convertDecimalToHex(a))
|
525 | ];
|
526 |
|
527 |
|
528 | if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {
|
529 | return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
|
530 | }
|
531 |
|
532 | return hex.join("");
|
533 | }
|
534 |
|
535 |
|
536 |
|
537 |
|
538 | function rgbaToArgbHex(r, g, b, a) {
|
539 |
|
540 | var hex = [
|
541 | pad2(convertDecimalToHex(a)),
|
542 | pad2(mathRound(r).toString(16)),
|
543 | pad2(mathRound(g).toString(16)),
|
544 | pad2(mathRound(b).toString(16))
|
545 | ];
|
546 |
|
547 | return hex.join("");
|
548 | }
|
549 |
|
550 |
|
551 |
|
552 | tinycolor.equals = function (color1, color2) {
|
553 | if (!color1 || !color2) { return false; }
|
554 | return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
|
555 | };
|
556 |
|
557 | tinycolor.random = function() {
|
558 | return tinycolor.fromRatio({
|
559 | r: mathRandom(),
|
560 | g: mathRandom(),
|
561 | b: mathRandom()
|
562 | });
|
563 | };
|
564 |
|
565 |
|
566 |
|
567 |
|
568 |
|
569 |
|
570 | function desaturate(color, amount) {
|
571 | amount = (amount === 0) ? 0 : (amount || 10);
|
572 | var hsl = tinycolor(color).toHsl();
|
573 | hsl.s -= amount / 100;
|
574 | hsl.s = clamp01(hsl.s);
|
575 | return tinycolor(hsl);
|
576 | }
|
577 |
|
578 | function saturate(color, amount) {
|
579 | amount = (amount === 0) ? 0 : (amount || 10);
|
580 | var hsl = tinycolor(color).toHsl();
|
581 | hsl.s += amount / 100;
|
582 | hsl.s = clamp01(hsl.s);
|
583 | return tinycolor(hsl);
|
584 | }
|
585 |
|
586 | function greyscale(color) {
|
587 | return tinycolor(color).desaturate(100);
|
588 | }
|
589 |
|
590 | function lighten (color, amount) {
|
591 | amount = (amount === 0) ? 0 : (amount || 10);
|
592 | var hsl = tinycolor(color).toHsl();
|
593 | hsl.l += amount / 100;
|
594 | hsl.l = clamp01(hsl.l);
|
595 | return tinycolor(hsl);
|
596 | }
|
597 |
|
598 | function brighten(color, amount) {
|
599 | amount = (amount === 0) ? 0 : (amount || 10);
|
600 | var rgb = tinycolor(color).toRgb();
|
601 | rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
|
602 | rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
|
603 | rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
|
604 | return tinycolor(rgb);
|
605 | }
|
606 |
|
607 | function darken (color, amount) {
|
608 | amount = (amount === 0) ? 0 : (amount || 10);
|
609 | var hsl = tinycolor(color).toHsl();
|
610 | hsl.l -= amount / 100;
|
611 | hsl.l = clamp01(hsl.l);
|
612 | return tinycolor(hsl);
|
613 | }
|
614 |
|
615 |
|
616 |
|
617 | function spin(color, amount) {
|
618 | var hsl = tinycolor(color).toHsl();
|
619 | var hue = (hsl.h + amount) % 360;
|
620 | hsl.h = hue < 0 ? 360 + hue : hue;
|
621 | return tinycolor(hsl);
|
622 | }
|
623 |
|
624 |
|
625 |
|
626 |
|
627 |
|
628 |
|
629 | function complement(color) {
|
630 | var hsl = tinycolor(color).toHsl();
|
631 | hsl.h = (hsl.h + 180) % 360;
|
632 | return tinycolor(hsl);
|
633 | }
|
634 |
|
635 | function triad(color) {
|
636 | var hsl = tinycolor(color).toHsl();
|
637 | var h = hsl.h;
|
638 | return [
|
639 | tinycolor(color),
|
640 | tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
641 | tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
642 | ];
|
643 | }
|
644 |
|
645 | function tetrad(color) {
|
646 | var hsl = tinycolor(color).toHsl();
|
647 | var h = hsl.h;
|
648 | return [
|
649 | tinycolor(color),
|
650 | tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
651 | tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
652 | tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
653 | ];
|
654 | }
|
655 |
|
656 | function splitcomplement(color) {
|
657 | var hsl = tinycolor(color).toHsl();
|
658 | var h = hsl.h;
|
659 | return [
|
660 | tinycolor(color),
|
661 | tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
662 | tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
663 | ];
|
664 | }
|
665 |
|
666 | function analogous(color, results, slices) {
|
667 | results = results || 6;
|
668 | slices = slices || 30;
|
669 |
|
670 | var hsl = tinycolor(color).toHsl();
|
671 | var part = 360 / slices;
|
672 | var ret = [tinycolor(color)];
|
673 |
|
674 | for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
|
675 | hsl.h = (hsl.h + part) % 360;
|
676 | ret.push(tinycolor(hsl));
|
677 | }
|
678 | return ret;
|
679 | }
|
680 |
|
681 | function monochromatic(color, results) {
|
682 | results = results || 6;
|
683 | var hsv = tinycolor(color).toHsv();
|
684 | var h = hsv.h, s = hsv.s, v = hsv.v;
|
685 | var ret = [];
|
686 | var modification = 1 / results;
|
687 |
|
688 | while (results--) {
|
689 | ret.push(tinycolor({ h: h, s: s, v: v}));
|
690 | v = (v + modification) % 1;
|
691 | }
|
692 |
|
693 | return ret;
|
694 | }
|
695 |
|
696 |
|
697 |
|
698 |
|
699 | tinycolor.mix = function(color1, color2, amount) {
|
700 | amount = (amount === 0) ? 0 : (amount || 50);
|
701 |
|
702 | var rgb1 = tinycolor(color1).toRgb();
|
703 | var rgb2 = tinycolor(color2).toRgb();
|
704 |
|
705 | var p = amount / 100;
|
706 |
|
707 | var rgba = {
|
708 | r: ((rgb2.r - rgb1.r) * p) + rgb1.r,
|
709 | g: ((rgb2.g - rgb1.g) * p) + rgb1.g,
|
710 | b: ((rgb2.b - rgb1.b) * p) + rgb1.b,
|
711 | a: ((rgb2.a - rgb1.a) * p) + rgb1.a
|
712 | };
|
713 |
|
714 | return tinycolor(rgba);
|
715 | };
|
716 |
|
717 |
|
718 |
|
719 |
|
720 |
|
721 |
|
722 |
|
723 | tinycolor.readability = function(color1, color2) {
|
724 | var c1 = tinycolor(color1);
|
725 | var c2 = tinycolor(color2);
|
726 | return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05);
|
727 | };
|
728 |
|
729 |
|
730 |
|
731 |
|
732 |
|
733 |
|
734 |
|
735 |
|
736 |
|
737 |
|
738 |
|
739 | tinycolor.isReadable = function(color1, color2, wcag2) {
|
740 | var readability = tinycolor.readability(color1, color2);
|
741 | var wcag2Parms, out;
|
742 |
|
743 | out = false;
|
744 |
|
745 | wcag2Parms = validateWCAG2Parms(wcag2);
|
746 | switch (wcag2Parms.level + wcag2Parms.size) {
|
747 | case "AAsmall":
|
748 | case "AAAlarge":
|
749 | out = readability >= 4.5;
|
750 | break;
|
751 | case "AAlarge":
|
752 | out = readability >= 3;
|
753 | break;
|
754 | case "AAAsmall":
|
755 | out = readability >= 7;
|
756 | break;
|
757 | }
|
758 | return out;
|
759 |
|
760 | };
|
761 |
|
762 |
|
763 |
|
764 |
|
765 |
|
766 |
|
767 |
|
768 |
|
769 |
|
770 |
|
771 | tinycolor.mostReadable = function(baseColor, colorList, args) {
|
772 | var bestColor = null;
|
773 | var bestScore = 0;
|
774 | var readability;
|
775 | var includeFallbackColors, level, size ;
|
776 | args = args || {};
|
777 | includeFallbackColors = args.includeFallbackColors ;
|
778 | level = args.level;
|
779 | size = args.size;
|
780 |
|
781 | for (var i= 0; i < colorList.length ; i++) {
|
782 | readability = tinycolor.readability(baseColor, colorList[i]);
|
783 | if (readability > bestScore) {
|
784 | bestScore = readability;
|
785 | bestColor = tinycolor(colorList[i]);
|
786 | }
|
787 | }
|
788 |
|
789 | if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) {
|
790 | return bestColor;
|
791 | }
|
792 | else {
|
793 | args.includeFallbackColors=false;
|
794 | return tinycolor.mostReadable(baseColor,["#fff", "#000"],args);
|
795 | }
|
796 | };
|
797 |
|
798 |
|
799 |
|
800 |
|
801 | var names = tinycolor.names = {
|
802 | aliceblue: "f0f8ff",
|
803 | antiquewhite: "faebd7",
|
804 | aqua: "0ff",
|
805 | aquamarine: "7fffd4",
|
806 | azure: "f0ffff",
|
807 | beige: "f5f5dc",
|
808 | bisque: "ffe4c4",
|
809 | black: "000",
|
810 | blanchedalmond: "ffebcd",
|
811 | blue: "00f",
|
812 | blueviolet: "8a2be2",
|
813 | brown: "a52a2a",
|
814 | burlywood: "deb887",
|
815 | burntsienna: "ea7e5d",
|
816 | cadetblue: "5f9ea0",
|
817 | chartreuse: "7fff00",
|
818 | chocolate: "d2691e",
|
819 | coral: "ff7f50",
|
820 | cornflowerblue: "6495ed",
|
821 | cornsilk: "fff8dc",
|
822 | crimson: "dc143c",
|
823 | cyan: "0ff",
|
824 | darkblue: "00008b",
|
825 | darkcyan: "008b8b",
|
826 | darkgoldenrod: "b8860b",
|
827 | darkgray: "a9a9a9",
|
828 | darkgreen: "006400",
|
829 | darkgrey: "a9a9a9",
|
830 | darkkhaki: "bdb76b",
|
831 | darkmagenta: "8b008b",
|
832 | darkolivegreen: "556b2f",
|
833 | darkorange: "ff8c00",
|
834 | darkorchid: "9932cc",
|
835 | darkred: "8b0000",
|
836 | darksalmon: "e9967a",
|
837 | darkseagreen: "8fbc8f",
|
838 | darkslateblue: "483d8b",
|
839 | darkslategray: "2f4f4f",
|
840 | darkslategrey: "2f4f4f",
|
841 | darkturquoise: "00ced1",
|
842 | darkviolet: "9400d3",
|
843 | deeppink: "ff1493",
|
844 | deepskyblue: "00bfff",
|
845 | dimgray: "696969",
|
846 | dimgrey: "696969",
|
847 | dodgerblue: "1e90ff",
|
848 | firebrick: "b22222",
|
849 | floralwhite: "fffaf0",
|
850 | forestgreen: "228b22",
|
851 | fuchsia: "f0f",
|
852 | gainsboro: "dcdcdc",
|
853 | ghostwhite: "f8f8ff",
|
854 | gold: "ffd700",
|
855 | goldenrod: "daa520",
|
856 | gray: "808080",
|
857 | green: "008000",
|
858 | greenyellow: "adff2f",
|
859 | grey: "808080",
|
860 | honeydew: "f0fff0",
|
861 | hotpink: "ff69b4",
|
862 | indianred: "cd5c5c",
|
863 | indigo: "4b0082",
|
864 | ivory: "fffff0",
|
865 | khaki: "f0e68c",
|
866 | lavender: "e6e6fa",
|
867 | lavenderblush: "fff0f5",
|
868 | lawngreen: "7cfc00",
|
869 | lemonchiffon: "fffacd",
|
870 | lightblue: "add8e6",
|
871 | lightcoral: "f08080",
|
872 | lightcyan: "e0ffff",
|
873 | lightgoldenrodyellow: "fafad2",
|
874 | lightgray: "d3d3d3",
|
875 | lightgreen: "90ee90",
|
876 | lightgrey: "d3d3d3",
|
877 | lightpink: "ffb6c1",
|
878 | lightsalmon: "ffa07a",
|
879 | lightseagreen: "20b2aa",
|
880 | lightskyblue: "87cefa",
|
881 | lightslategray: "789",
|
882 | lightslategrey: "789",
|
883 | lightsteelblue: "b0c4de",
|
884 | lightyellow: "ffffe0",
|
885 | lime: "0f0",
|
886 | limegreen: "32cd32",
|
887 | linen: "faf0e6",
|
888 | magenta: "f0f",
|
889 | maroon: "800000",
|
890 | mediumaquamarine: "66cdaa",
|
891 | mediumblue: "0000cd",
|
892 | mediumorchid: "ba55d3",
|
893 | mediumpurple: "9370db",
|
894 | mediumseagreen: "3cb371",
|
895 | mediumslateblue: "7b68ee",
|
896 | mediumspringgreen: "00fa9a",
|
897 | mediumturquoise: "48d1cc",
|
898 | mediumvioletred: "c71585",
|
899 | midnightblue: "191970",
|
900 | mintcream: "f5fffa",
|
901 | mistyrose: "ffe4e1",
|
902 | moccasin: "ffe4b5",
|
903 | navajowhite: "ffdead",
|
904 | navy: "000080",
|
905 | oldlace: "fdf5e6",
|
906 | olive: "808000",
|
907 | olivedrab: "6b8e23",
|
908 | orange: "ffa500",
|
909 | orangered: "ff4500",
|
910 | orchid: "da70d6",
|
911 | palegoldenrod: "eee8aa",
|
912 | palegreen: "98fb98",
|
913 | paleturquoise: "afeeee",
|
914 | palevioletred: "db7093",
|
915 | papayawhip: "ffefd5",
|
916 | peachpuff: "ffdab9",
|
917 | peru: "cd853f",
|
918 | pink: "ffc0cb",
|
919 | plum: "dda0dd",
|
920 | powderblue: "b0e0e6",
|
921 | purple: "800080",
|
922 | rebeccapurple: "663399",
|
923 | red: "f00",
|
924 | rosybrown: "bc8f8f",
|
925 | royalblue: "4169e1",
|
926 | saddlebrown: "8b4513",
|
927 | salmon: "fa8072",
|
928 | sandybrown: "f4a460",
|
929 | seagreen: "2e8b57",
|
930 | seashell: "fff5ee",
|
931 | sienna: "a0522d",
|
932 | silver: "c0c0c0",
|
933 | skyblue: "87ceeb",
|
934 | slateblue: "6a5acd",
|
935 | slategray: "708090",
|
936 | slategrey: "708090",
|
937 | snow: "fffafa",
|
938 | springgreen: "00ff7f",
|
939 | steelblue: "4682b4",
|
940 | tan: "d2b48c",
|
941 | teal: "008080",
|
942 | thistle: "d8bfd8",
|
943 | tomato: "ff6347",
|
944 | turquoise: "40e0d0",
|
945 | violet: "ee82ee",
|
946 | wheat: "f5deb3",
|
947 | white: "fff",
|
948 | whitesmoke: "f5f5f5",
|
949 | yellow: "ff0",
|
950 | yellowgreen: "9acd32"
|
951 | };
|
952 |
|
953 |
|
954 | var hexNames = tinycolor.hexNames = flip(names);
|
955 |
|
956 |
|
957 |
|
958 |
|
959 |
|
960 | function flip(o) {
|
961 | var flipped = { };
|
962 | for (var i in o) {
|
963 | if (o.hasOwnProperty(i)) {
|
964 | flipped[o[i]] = i;
|
965 | }
|
966 | }
|
967 | return flipped;
|
968 | }
|
969 |
|
970 |
|
971 | function boundAlpha(a) {
|
972 | a = parseFloat(a);
|
973 |
|
974 | if (isNaN(a) || a < 0 || a > 1) {
|
975 | a = 1;
|
976 | }
|
977 |
|
978 | return a;
|
979 | }
|
980 |
|
981 |
|
982 | function bound01(n, max) {
|
983 | if (isOnePointZero(n)) { n = "100%"; }
|
984 |
|
985 | var processPercent = isPercentage(n);
|
986 | n = mathMin(max, mathMax(0, parseFloat(n)));
|
987 |
|
988 |
|
989 | if (processPercent) {
|
990 | n = parseInt(n * max, 10) / 100;
|
991 | }
|
992 |
|
993 |
|
994 | if ((Math.abs(n - max) < 0.000001)) {
|
995 | return 1;
|
996 | }
|
997 |
|
998 |
|
999 | return (n % max) / parseFloat(max);
|
1000 | }
|
1001 |
|
1002 |
|
1003 | function clamp01(val) {
|
1004 | return mathMin(1, mathMax(0, val));
|
1005 | }
|
1006 |
|
1007 |
|
1008 | function parseIntFromHex(val) {
|
1009 | return parseInt(val, 16);
|
1010 | }
|
1011 |
|
1012 |
|
1013 |
|
1014 | function isOnePointZero(n) {
|
1015 | return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
1016 | }
|
1017 |
|
1018 |
|
1019 | function isPercentage(n) {
|
1020 | return typeof n === "string" && n.indexOf('%') != -1;
|
1021 | }
|
1022 |
|
1023 |
|
1024 | function pad2(c) {
|
1025 | return c.length == 1 ? '0' + c : '' + c;
|
1026 | }
|
1027 |
|
1028 |
|
1029 | function convertToPercentage(n) {
|
1030 | if (n <= 1) {
|
1031 | n = (n * 100) + "%";
|
1032 | }
|
1033 |
|
1034 | return n;
|
1035 | }
|
1036 |
|
1037 |
|
1038 | function convertDecimalToHex(d) {
|
1039 | return Math.round(parseFloat(d) * 255).toString(16);
|
1040 | }
|
1041 |
|
1042 | function convertHexToDecimal(h) {
|
1043 | return (parseIntFromHex(h) / 255);
|
1044 | }
|
1045 |
|
1046 | var matchers = (function() {
|
1047 |
|
1048 |
|
1049 | var CSS_INTEGER = "[-\\+]?\\d+%?";
|
1050 |
|
1051 |
|
1052 | var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
1053 |
|
1054 |
|
1055 | var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
|
1056 |
|
1057 |
|
1058 |
|
1059 |
|
1060 | var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
1061 | var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
1062 |
|
1063 | return {
|
1064 | CSS_UNIT: new RegExp(CSS_UNIT),
|
1065 | rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
|
1066 | rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
1067 | hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
1068 | hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
1069 | hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
1070 | hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
|
1071 | hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
1072 | hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
1073 | hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
1074 | hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
1075 | };
|
1076 | })();
|
1077 |
|
1078 |
|
1079 |
|
1080 |
|
1081 | function isValidCSSUnit(color) {
|
1082 | return !!matchers.CSS_UNIT.exec(color);
|
1083 | }
|
1084 |
|
1085 |
|
1086 |
|
1087 |
|
1088 | function stringInputToObject(color) {
|
1089 |
|
1090 | color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase();
|
1091 | var named = false;
|
1092 | if (names[color]) {
|
1093 | color = names[color];
|
1094 | named = true;
|
1095 | }
|
1096 | else if (color == 'transparent') {
|
1097 | return { r: 0, g: 0, b: 0, a: 0, format: "name" };
|
1098 | }
|
1099 |
|
1100 |
|
1101 |
|
1102 |
|
1103 |
|
1104 | var match;
|
1105 | if ((match = matchers.rgb.exec(color))) {
|
1106 | return { r: match[1], g: match[2], b: match[3] };
|
1107 | }
|
1108 | if ((match = matchers.rgba.exec(color))) {
|
1109 | return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
1110 | }
|
1111 | if ((match = matchers.hsl.exec(color))) {
|
1112 | return { h: match[1], s: match[2], l: match[3] };
|
1113 | }
|
1114 | if ((match = matchers.hsla.exec(color))) {
|
1115 | return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
1116 | }
|
1117 | if ((match = matchers.hsv.exec(color))) {
|
1118 | return { h: match[1], s: match[2], v: match[3] };
|
1119 | }
|
1120 | if ((match = matchers.hsva.exec(color))) {
|
1121 | return { h: match[1], s: match[2], v: match[3], a: match[4] };
|
1122 | }
|
1123 | if ((match = matchers.hex8.exec(color))) {
|
1124 | return {
|
1125 | r: parseIntFromHex(match[1]),
|
1126 | g: parseIntFromHex(match[2]),
|
1127 | b: parseIntFromHex(match[3]),
|
1128 | a: convertHexToDecimal(match[4]),
|
1129 | format: named ? "name" : "hex8"
|
1130 | };
|
1131 | }
|
1132 | if ((match = matchers.hex6.exec(color))) {
|
1133 | return {
|
1134 | r: parseIntFromHex(match[1]),
|
1135 | g: parseIntFromHex(match[2]),
|
1136 | b: parseIntFromHex(match[3]),
|
1137 | format: named ? "name" : "hex"
|
1138 | };
|
1139 | }
|
1140 | if ((match = matchers.hex4.exec(color))) {
|
1141 | return {
|
1142 | r: parseIntFromHex(match[1] + '' + match[1]),
|
1143 | g: parseIntFromHex(match[2] + '' + match[2]),
|
1144 | b: parseIntFromHex(match[3] + '' + match[3]),
|
1145 | a: convertHexToDecimal(match[4] + '' + match[4]),
|
1146 | format: named ? "name" : "hex8"
|
1147 | };
|
1148 | }
|
1149 | if ((match = matchers.hex3.exec(color))) {
|
1150 | return {
|
1151 | r: parseIntFromHex(match[1] + '' + match[1]),
|
1152 | g: parseIntFromHex(match[2] + '' + match[2]),
|
1153 | b: parseIntFromHex(match[3] + '' + match[3]),
|
1154 | format: named ? "name" : "hex"
|
1155 | };
|
1156 | }
|
1157 |
|
1158 | return false;
|
1159 | }
|
1160 |
|
1161 | function validateWCAG2Parms(parms) {
|
1162 |
|
1163 |
|
1164 | var level, size;
|
1165 | parms = parms || {"level":"AA", "size":"small"};
|
1166 | level = (parms.level || "AA").toUpperCase();
|
1167 | size = (parms.size || "small").toLowerCase();
|
1168 | if (level !== "AA" && level !== "AAA") {
|
1169 | level = "AA";
|
1170 | }
|
1171 | if (size !== "small" && size !== "large") {
|
1172 | size = "small";
|
1173 | }
|
1174 | return {"level":level, "size":size};
|
1175 | }
|
1176 |
|
1177 | this.tinycolor = tinycolor;
|
1178 |
|
1179 | })()`;
|
1180 | }
|
1181 |
|
1182 |
|
1183 | .tinyColorMixin();
|