| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- function roundFloat(number, decimalPoints) {
- const decimal = Math.pow(10, decimalPoints);
- return Math.round(number * decimal) / decimal;
- }
- export class RGBA {
- constructor(r, g, b, a = 1) {
- this._rgbaBrand = undefined;
- this.r = Math.min(255, Math.max(0, r)) | 0;
- this.g = Math.min(255, Math.max(0, g)) | 0;
- this.b = Math.min(255, Math.max(0, b)) | 0;
- this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
- }
- static equals(a, b) {
- return a.r === b.r && a.g === b.g && a.b === b.b && a.a === b.a;
- }
- }
- export class HSLA {
- constructor(h, s, l, a) {
- this._hslaBrand = undefined;
- this.h = Math.max(Math.min(360, h), 0) | 0;
- this.s = roundFloat(Math.max(Math.min(1, s), 0), 3);
- this.l = roundFloat(Math.max(Math.min(1, l), 0), 3);
- this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
- }
- static equals(a, b) {
- return a.h === b.h && a.s === b.s && a.l === b.l && a.a === b.a;
- }
- /**
- * Converts an RGB color value to HSL. Conversion formula
- * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
- * Assumes r, g, and b are contained in the set [0, 255] and
- * returns h in the set [0, 360], s, and l in the set [0, 1].
- */
- static fromRGBA(rgba) {
- const r = rgba.r / 255;
- const g = rgba.g / 255;
- const b = rgba.b / 255;
- const a = rgba.a;
- const max = Math.max(r, g, b);
- const min = Math.min(r, g, b);
- let h = 0;
- let s = 0;
- const l = (min + max) / 2;
- const chroma = max - min;
- if (chroma > 0) {
- s = Math.min((l <= 0.5 ? chroma / (2 * l) : chroma / (2 - (2 * l))), 1);
- switch (max) {
- case r:
- h = (g - b) / chroma + (g < b ? 6 : 0);
- break;
- case g:
- h = (b - r) / chroma + 2;
- break;
- case b:
- h = (r - g) / chroma + 4;
- break;
- }
- h *= 60;
- h = Math.round(h);
- }
- return new HSLA(h, s, l, a);
- }
- static _hue2rgb(p, q, t) {
- if (t < 0) {
- t += 1;
- }
- if (t > 1) {
- t -= 1;
- }
- if (t < 1 / 6) {
- return p + (q - p) * 6 * t;
- }
- if (t < 1 / 2) {
- return q;
- }
- if (t < 2 / 3) {
- return p + (q - p) * (2 / 3 - t) * 6;
- }
- return p;
- }
- /**
- * Converts an HSL color value to RGB. Conversion formula
- * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
- * Assumes h in the set [0, 360] s, and l are contained in the set [0, 1] and
- * returns r, g, and b in the set [0, 255].
- */
- static toRGBA(hsla) {
- const h = hsla.h / 360;
- const { s, l, a } = hsla;
- let r, g, b;
- if (s === 0) {
- r = g = b = l; // achromatic
- }
- else {
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
- const p = 2 * l - q;
- r = HSLA._hue2rgb(p, q, h + 1 / 3);
- g = HSLA._hue2rgb(p, q, h);
- b = HSLA._hue2rgb(p, q, h - 1 / 3);
- }
- return new RGBA(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a);
- }
- }
- export class HSVA {
- constructor(h, s, v, a) {
- this._hsvaBrand = undefined;
- this.h = Math.max(Math.min(360, h), 0) | 0;
- this.s = roundFloat(Math.max(Math.min(1, s), 0), 3);
- this.v = roundFloat(Math.max(Math.min(1, v), 0), 3);
- this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
- }
- static equals(a, b) {
- return a.h === b.h && a.s === b.s && a.v === b.v && a.a === b.a;
- }
- // from http://www.rapidtables.com/convert/color/rgb-to-hsv.htm
- static fromRGBA(rgba) {
- const r = rgba.r / 255;
- const g = rgba.g / 255;
- const b = rgba.b / 255;
- const cmax = Math.max(r, g, b);
- const cmin = Math.min(r, g, b);
- const delta = cmax - cmin;
- const s = cmax === 0 ? 0 : (delta / cmax);
- let m;
- if (delta === 0) {
- m = 0;
- }
- else if (cmax === r) {
- m = ((((g - b) / delta) % 6) + 6) % 6;
- }
- else if (cmax === g) {
- m = ((b - r) / delta) + 2;
- }
- else {
- m = ((r - g) / delta) + 4;
- }
- return new HSVA(Math.round(m * 60), s, cmax, rgba.a);
- }
- // from http://www.rapidtables.com/convert/color/hsv-to-rgb.htm
- static toRGBA(hsva) {
- const { h, s, v, a } = hsva;
- const c = v * s;
- const x = c * (1 - Math.abs((h / 60) % 2 - 1));
- const m = v - c;
- let [r, g, b] = [0, 0, 0];
- if (h < 60) {
- r = c;
- g = x;
- }
- else if (h < 120) {
- r = x;
- g = c;
- }
- else if (h < 180) {
- g = c;
- b = x;
- }
- else if (h < 240) {
- g = x;
- b = c;
- }
- else if (h < 300) {
- r = x;
- b = c;
- }
- else if (h <= 360) {
- r = c;
- b = x;
- }
- r = Math.round((r + m) * 255);
- g = Math.round((g + m) * 255);
- b = Math.round((b + m) * 255);
- return new RGBA(r, g, b, a);
- }
- }
- export class Color {
- constructor(arg) {
- if (!arg) {
- throw new Error('Color needs a value');
- }
- else if (arg instanceof RGBA) {
- this.rgba = arg;
- }
- else if (arg instanceof HSLA) {
- this._hsla = arg;
- this.rgba = HSLA.toRGBA(arg);
- }
- else if (arg instanceof HSVA) {
- this._hsva = arg;
- this.rgba = HSVA.toRGBA(arg);
- }
- else {
- throw new Error('Invalid color ctor argument');
- }
- }
- static fromHex(hex) {
- return Color.Format.CSS.parseHex(hex) || Color.red;
- }
- get hsla() {
- if (this._hsla) {
- return this._hsla;
- }
- else {
- return HSLA.fromRGBA(this.rgba);
- }
- }
- get hsva() {
- if (this._hsva) {
- return this._hsva;
- }
- return HSVA.fromRGBA(this.rgba);
- }
- equals(other) {
- return !!other && RGBA.equals(this.rgba, other.rgba) && HSLA.equals(this.hsla, other.hsla) && HSVA.equals(this.hsva, other.hsva);
- }
- /**
- * http://www.w3.org/TR/WCAG20/#relativeluminancedef
- * Returns the number in the set [0, 1]. O => Darkest Black. 1 => Lightest white.
- */
- getRelativeLuminance() {
- const R = Color._relativeLuminanceForComponent(this.rgba.r);
- const G = Color._relativeLuminanceForComponent(this.rgba.g);
- const B = Color._relativeLuminanceForComponent(this.rgba.b);
- const luminance = 0.2126 * R + 0.7152 * G + 0.0722 * B;
- return roundFloat(luminance, 4);
- }
- static _relativeLuminanceForComponent(color) {
- const c = color / 255;
- return (c <= 0.03928) ? c / 12.92 : Math.pow(((c + 0.055) / 1.055), 2.4);
- }
- /**
- * http://24ways.org/2010/calculating-color-contrast
- * Return 'true' if lighter color otherwise 'false'
- */
- isLighter() {
- const yiq = (this.rgba.r * 299 + this.rgba.g * 587 + this.rgba.b * 114) / 1000;
- return yiq >= 128;
- }
- isLighterThan(another) {
- const lum1 = this.getRelativeLuminance();
- const lum2 = another.getRelativeLuminance();
- return lum1 > lum2;
- }
- isDarkerThan(another) {
- const lum1 = this.getRelativeLuminance();
- const lum2 = another.getRelativeLuminance();
- return lum1 < lum2;
- }
- lighten(factor) {
- return new Color(new HSLA(this.hsla.h, this.hsla.s, this.hsla.l + this.hsla.l * factor, this.hsla.a));
- }
- darken(factor) {
- return new Color(new HSLA(this.hsla.h, this.hsla.s, this.hsla.l - this.hsla.l * factor, this.hsla.a));
- }
- transparent(factor) {
- const { r, g, b, a } = this.rgba;
- return new Color(new RGBA(r, g, b, a * factor));
- }
- isTransparent() {
- return this.rgba.a === 0;
- }
- isOpaque() {
- return this.rgba.a === 1;
- }
- opposite() {
- return new Color(new RGBA(255 - this.rgba.r, 255 - this.rgba.g, 255 - this.rgba.b, this.rgba.a));
- }
- toString() {
- if (!this._toString) {
- this._toString = Color.Format.CSS.format(this);
- }
- return this._toString;
- }
- static getLighterColor(of, relative, factor) {
- if (of.isLighterThan(relative)) {
- return of;
- }
- factor = factor ? factor : 0.5;
- const lum1 = of.getRelativeLuminance();
- const lum2 = relative.getRelativeLuminance();
- factor = factor * (lum2 - lum1) / lum2;
- return of.lighten(factor);
- }
- static getDarkerColor(of, relative, factor) {
- if (of.isDarkerThan(relative)) {
- return of;
- }
- factor = factor ? factor : 0.5;
- const lum1 = of.getRelativeLuminance();
- const lum2 = relative.getRelativeLuminance();
- factor = factor * (lum1 - lum2) / lum1;
- return of.darken(factor);
- }
- }
- Color.white = new Color(new RGBA(255, 255, 255, 1));
- Color.black = new Color(new RGBA(0, 0, 0, 1));
- Color.red = new Color(new RGBA(255, 0, 0, 1));
- Color.blue = new Color(new RGBA(0, 0, 255, 1));
- Color.green = new Color(new RGBA(0, 255, 0, 1));
- Color.cyan = new Color(new RGBA(0, 255, 255, 1));
- Color.lightgrey = new Color(new RGBA(211, 211, 211, 1));
- Color.transparent = new Color(new RGBA(0, 0, 0, 0));
- (function (Color) {
- let Format;
- (function (Format) {
- let CSS;
- (function (CSS) {
- function formatRGB(color) {
- if (color.rgba.a === 1) {
- return `rgb(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b})`;
- }
- return Color.Format.CSS.formatRGBA(color);
- }
- CSS.formatRGB = formatRGB;
- function formatRGBA(color) {
- return `rgba(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b}, ${+(color.rgba.a).toFixed(2)})`;
- }
- CSS.formatRGBA = formatRGBA;
- function formatHSL(color) {
- if (color.hsla.a === 1) {
- return `hsl(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%)`;
- }
- return Color.Format.CSS.formatHSLA(color);
- }
- CSS.formatHSL = formatHSL;
- function formatHSLA(color) {
- return `hsla(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%, ${color.hsla.a.toFixed(2)})`;
- }
- CSS.formatHSLA = formatHSLA;
- function _toTwoDigitHex(n) {
- const r = n.toString(16);
- return r.length !== 2 ? '0' + r : r;
- }
- /**
- * Formats the color as #RRGGBB
- */
- function formatHex(color) {
- return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}`;
- }
- CSS.formatHex = formatHex;
- /**
- * Formats the color as #RRGGBBAA
- * If 'compact' is set, colors without transparancy will be printed as #RRGGBB
- */
- function formatHexA(color, compact = false) {
- if (compact && color.rgba.a === 1) {
- return Color.Format.CSS.formatHex(color);
- }
- return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}${_toTwoDigitHex(Math.round(color.rgba.a * 255))}`;
- }
- CSS.formatHexA = formatHexA;
- /**
- * The default format will use HEX if opaque and RGBA otherwise.
- */
- function format(color) {
- if (color.isOpaque()) {
- return Color.Format.CSS.formatHex(color);
- }
- return Color.Format.CSS.formatRGBA(color);
- }
- CSS.format = format;
- /**
- * Converts an Hex color value to a Color.
- * returns r, g, and b are contained in the set [0, 255]
- * @param hex string (#RGB, #RGBA, #RRGGBB or #RRGGBBAA).
- */
- function parseHex(hex) {
- const length = hex.length;
- if (length === 0) {
- // Invalid color
- return null;
- }
- if (hex.charCodeAt(0) !== 35 /* CharCode.Hash */) {
- // Does not begin with a #
- return null;
- }
- if (length === 7) {
- // #RRGGBB format
- const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));
- const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));
- const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));
- return new Color(new RGBA(r, g, b, 1));
- }
- if (length === 9) {
- // #RRGGBBAA format
- const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));
- const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));
- const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));
- const a = 16 * _parseHexDigit(hex.charCodeAt(7)) + _parseHexDigit(hex.charCodeAt(8));
- return new Color(new RGBA(r, g, b, a / 255));
- }
- if (length === 4) {
- // #RGB format
- const r = _parseHexDigit(hex.charCodeAt(1));
- const g = _parseHexDigit(hex.charCodeAt(2));
- const b = _parseHexDigit(hex.charCodeAt(3));
- return new Color(new RGBA(16 * r + r, 16 * g + g, 16 * b + b));
- }
- if (length === 5) {
- // #RGBA format
- const r = _parseHexDigit(hex.charCodeAt(1));
- const g = _parseHexDigit(hex.charCodeAt(2));
- const b = _parseHexDigit(hex.charCodeAt(3));
- const a = _parseHexDigit(hex.charCodeAt(4));
- return new Color(new RGBA(16 * r + r, 16 * g + g, 16 * b + b, (16 * a + a) / 255));
- }
- // Invalid color
- return null;
- }
- CSS.parseHex = parseHex;
- function _parseHexDigit(charCode) {
- switch (charCode) {
- case 48 /* CharCode.Digit0 */: return 0;
- case 49 /* CharCode.Digit1 */: return 1;
- case 50 /* CharCode.Digit2 */: return 2;
- case 51 /* CharCode.Digit3 */: return 3;
- case 52 /* CharCode.Digit4 */: return 4;
- case 53 /* CharCode.Digit5 */: return 5;
- case 54 /* CharCode.Digit6 */: return 6;
- case 55 /* CharCode.Digit7 */: return 7;
- case 56 /* CharCode.Digit8 */: return 8;
- case 57 /* CharCode.Digit9 */: return 9;
- case 97 /* CharCode.a */: return 10;
- case 65 /* CharCode.A */: return 10;
- case 98 /* CharCode.b */: return 11;
- case 66 /* CharCode.B */: return 11;
- case 99 /* CharCode.c */: return 12;
- case 67 /* CharCode.C */: return 12;
- case 100 /* CharCode.d */: return 13;
- case 68 /* CharCode.D */: return 13;
- case 101 /* CharCode.e */: return 14;
- case 69 /* CharCode.E */: return 14;
- case 102 /* CharCode.f */: return 15;
- case 70 /* CharCode.F */: return 15;
- }
- return 0;
- }
- })(CSS = Format.CSS || (Format.CSS = {}));
- })(Format = Color.Format || (Color.Format = {}));
- })(Color || (Color = {}));
|