coral-spectrum/coral-component-colorinput/src/scripts/Color.js
- /**
- * Copyright 2019 Adobe. All rights reserved.
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
- * OF ANY KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-
- import {transform} from '../../../coral-utils';
-
- // try to stay in same color space as long as possible (because of conversions being not 100% accurate ...)
- /** @ignore */
- const colorSpace = {
- RGB: 'rgb',
- HEX: 'hex',
- CMYK: 'cmyk',
- HSB: 'hsb',
- HSL: 'hsl'
- };
-
- /**
- Transforms part of a color (r,g,b) into a hex value.
-
- @static
- @param {Number} x
- value between 0-255
-
- @return {String} Hex representation
- @ignore
- */
- function _hex(x) {
- return `0${x.toString(16)}`.slice(-2);
- }
-
- /** @ignore */
- function _slice(str, startStr) {
- let sliced = [];
-
- str = transform.string(str).toLowerCase();
- startStr = transform.string(startStr).toLowerCase();
-
- if (str.indexOf(startStr) !== -1) {
- sliced = str.substring(str.indexOf(startStr) + startStr.length, str.lastIndexOf(')')).split(/,\s*/);
- }
-
- return sliced;
- }
-
- /**
- Parse an rgb value into an object.
- e.g.: 'rgb(0,0,0)' => {r:0, g:0, b:0}
-
- @static
- @param {String} rgbStr
- The string representing the rgb value
-
- @return {Object} {r, g, b} Returns null if string could not be parsed
- @ignore
- */
- function _parseRGB(rgbStr) {
- const sliced = _slice(rgbStr, 'rgb(');
-
- if (sliced.length !== 3) {
- return null;
- }
-
- const r = parseInt(sliced[0], 10);
- const g = parseInt(sliced[1], 10);
- const b = parseInt(sliced[2], 10);
-
- if (isNaN(r) || isNaN(g) || isNaN(b)) {
- return null;
- }
-
- if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
- return null;
- }
-
- return {r, g, b};
- }
-
- /**
- Serialize an rgb object into a string.
- e.g.: {r:0, g:0, b:0} => 'rgb(0,0,0)'
-
- @static
- @param {Object} rgb
- @return {String} rgbStr The string representing the rgb value
- @ignore
- */
- function _serializeRGB(rgb) {
- if (rgb) {
- return `rgb(${rgb.r},${rgb.g},${rgb.b})`;
- }
-
- return '';
- }
-
- /**
- Parse an rgba value into an object.
- e.g.: 'rgba(0,0,0,0.5)' => {r:0, g:0, b:0, a:0.5}
-
- @static
- @param {String} rgbaStr
- The string representing the rgba value.
-
- @return {Object} {r, g, b, a} Returns null if string could not be parsed
- @ignore
- */
- function _parseRGBA(rgbaStr) {
- const sliced = _slice(rgbaStr, 'rgba(');
-
- if (sliced.length !== 4) {
- return null;
- }
-
- const r = parseInt(sliced[0], 10);
- const g = parseInt(sliced[1], 10);
- const b = parseInt(sliced[2], 10);
- const a = parseFloat(sliced[3]);
-
- if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(a)) {
- return null;
- }
-
- if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 1) {
- return null;
- }
-
- return {r, g, b, a};
- }
-
- /**
- Serialize an rgba object into a string.
- e.g.: {r:0, g:0, b:0, a:0.5} => 'rgb(0,0,0,0.5)'
-
- @static
- @param {Object} rgba
- @return {String} rgbaStr The string representing the rgba value
- @ignore
- */
- function _serializeRGBA(rgba) {
- if (rgba) {
- return `rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a})`;
- }
- return '';
- }
-
- /**
- Parse an cmyk value into an object.
- e.g.: 'cmyk(0, 100, 50, 0)' => {c:0, m:100, y:50, k:0}
-
- @static
- @param {String} cmykStr
- The string representing the cmyk value.
-
- @return {Object} {c, m, y, k} Returns null if string could not be parsed
- @ignore
- */
- function _parseCMYK(cmykStr) {
- const sliced = _slice(cmykStr, 'cmyk(');
-
- if (sliced.length !== 4) {
- return null;
- }
-
- const c = parseFloat(sliced[0]);
- const m = parseFloat(sliced[1]);
- const y = parseFloat(sliced[2]);
- const k = parseFloat(sliced[3]);
-
- if (isNaN(c) || isNaN(m) || isNaN(y) || isNaN(k)) {
- return null;
- }
-
- if (c < 0 || c > 100 || m < 0 || m > 100 || y < 0 || y > 100 || k < 0 || k > 100) {
- return null;
- }
-
- return {c, m, y, k};
- }
-
- /**
- Serialize an cmyk object into a string.
- e.g.: {c:0, m:100, y:50, k:0} => 'cmyk(0, 100, 50, 0)'
-
- @static
- @param {Object} cmyk
- @return {String} cmykStr The string representing the cmyk value
- @ignore
- */
- function _serializeCMYK(cmyk) {
- if (cmyk) {
- // make sure there are not more than 2 digits after dot
- const c = parseFloat(cmyk.c.toFixed(2));
- const m = parseFloat(cmyk.m.toFixed(2));
- const y = parseFloat(cmyk.y.toFixed(2));
- const k = parseFloat(cmyk.k.toFixed(2));
-
- return `cmyk(${c},${m},${y},${k})`;
- }
- return '';
- }
-
- /**
- Parse an hex value into a number. Corrects a hex value, if it is represented by 3 or 6 characters with or without
- '#'.
-
- @static
- @param {String} hexStr The string representing the hex value
- @return {Number} Returns a number representing the parsed hex value
- @ignore
- */
- function _parseHex(hexStr) {
- hexStr = transform.string(hexStr).replace('#', '');
-
- if (hexStr.length === 3) {
- hexStr = hexStr.charAt(0) + hexStr.charAt(0) +
- hexStr.charAt(1) + hexStr.charAt(1) +
- hexStr.charAt(2) + hexStr.charAt(2);
- }
-
- // test if this could be a hex value
- const isOk = (/^[0-9A-F]{6}$/i).test(hexStr);
- if (!isOk) {
- return null;
- }
-
- return parseInt(hexStr, 16);
- }
-
- /**
- Transforms a hex color into RGB representation.
-
- @static
- @param {Number} hex
- The color hex representation.
-
- @return {Object} {r, g, b}
- @ignore
- */
- function _hexToRgb(hex) {
- // explicitly test null (0 is valid)
- if (hex !== null) {
- return {
- r: hex >> 16,
- // eslint-disable-next-line no-extra-parens
- g: (hex & 0x00FF00) >> 8,
- // eslint-disable-next-line no-extra-parens
- b: (hex & 0x0000FF)
- };
- }
- return null;
- }
-
- /**
- Serialize a hex number into a string.
-
- @static
- @param {Number} hex
- @return {String}
- @ignore
- */
- function _serializeHex(hex) {
- // explicitly test null (0 is valid)
- if (hex !== null) {
- const rgb = _hexToRgb(hex);
- return `#${_hex(rgb.r) + _hex(rgb.g) + _hex(rgb.b)}`;
- }
-
- return '';
- }
-
- /**
- Transforms a RGB color into HEX representation.
-
- @static
- @param {Object} rgb
- @return {Number} hex The color hex representation
- @ignore
- */
- function _rgbToHex(rgb) {
- if (rgb) {
- return _parseHex(_hex(rgb.r) + _hex(rgb.g) + _hex(rgb.b));
- }
- return null;
- }
-
- /**
- Transforms a cmyk color into RGB representation. Converting CMYK to RGB will incur slight loss because both color
- spaces are not absolute and there will be some round-off error in the conversion process.
-
- @static
- @param {Object} cmyk
- @return {Object} {r, g, b}
- @ignore
- */
- function _cmykToRgb(cmyk) {
- if (!cmyk) {
- return null;
- }
-
- const result = {
- r: 0,
- g: 0,
- b: 0
- };
-
- const c = parseFloat(cmyk.c) / 100;
- const m = parseFloat(cmyk.m) / 100;
- const y = parseFloat(cmyk.y) / 100;
- const k = parseFloat(cmyk.k) / 100;
-
- result.r = 1 - Math.min(1, c * (1 - k) + k);
- result.g = 1 - Math.min(1, m * (1 - k) + k);
- result.b = 1 - Math.min(1, y * (1 - k) + k);
-
- result.r = Math.round(result.r * 255);
- result.g = Math.round(result.g * 255);
- result.b = Math.round(result.b * 255);
-
- return result;
- }
-
- /**
- Transforms a rgb color into cmyk representation. Converting CMYK to RGB will incur slight loss because both color
- spaces are not absolute and there will be some round-off error in the conversion process.
-
- @static
- @param {Object} rgb
- @return {Object} {c, m, y, k}
- @ignore
- */
- function _rgbToCmyk(rgb) {
- if (!rgb) {
- return null;
- }
-
- const result = {
- c: 0,
- m: 0,
- y: 0,
- k: 0
- };
-
- if (rgb.r === 0 && rgb.g === 0 && rgb.b === 0) {
- result.k = 100;
- return result;
- }
-
- const r = rgb.r / 255;
- const g = rgb.g / 255;
- const b = rgb.b / 255;
-
- result.k = Math.min(1 - r, 1 - g, 1 - b);
- result.c = (1 - r - result.k) / (1 - result.k);
- result.m = (1 - g - result.k) / (1 - result.k);
- result.y = (1 - b - result.k) / (1 - result.k);
-
- result.c = Math.round(result.c * 100);
- result.m = Math.round(result.m * 100);
- result.y = Math.round(result.y * 100);
- result.k = Math.round(result.k * 100);
-
- return result;
- }
-
- /**
- Parse an hsb value into an object.
- e.g.: 'hsb(360,100,0)' => {h:360, s:100, b:0}
-
- @static
- @param {String} hsbStr
- The string representing the hsb value.
-
- @return {Object} {h, s, b} Returns null if string could not be parsed
- @ignore
- */
- function _parseHSB(hsbStr) {
- const sliced = _slice(hsbStr, 'hsb(');
-
- if (sliced.length !== 3) {
- return null;
- }
-
- // make sure there are not more than 2 digits after dot
- const h = parseFloat(sliced[0]);
- const s = parseFloat(sliced[1]);
- const b = parseFloat(sliced[2]);
-
- if (isNaN(h) || isNaN(s) || isNaN(b)) {
- return null;
- }
-
- if (h < 0 || h > 360 || s < 0 || s > 100 || b < 0 || b > 100) {
- return null;
- }
-
- return {h, s, b};
- }
-
- /**
- Serialize an hsb object into a string.
- e.g.: {h:0, s:0, b:0} => 'hsb(0,0,0)'
-
- @static
- @param {Object} hsb
- @return {String} hsb The string representing the hsb value
- @ignore
- */
- function _serializeHSB(hsb) {
- if (hsb) {
- // make sure there are not more than 2 digits after dot
- const h = parseFloat(hsb.h.toFixed(2));
- const s = parseFloat(hsb.s.toFixed(2));
- const b = parseFloat(hsb.b.toFixed(2));
-
- return `hsb(${h},${s},${b})`;
- }
-
- return '';
- }
-
- /**
- Transforms a HSB (same as HSV) color into RGB representation.
- h (hue has value between 0-360 degree)
- s (saturation has a value between 0-100 percent)
- b (brightness has a value between 0-100 percent)
-
- @static
- @param {Object} hsb
- @return {Object} {r, g, b}
- @ignore
- */
- function _hsbToRgb(hsb) {
- if (!hsb) {
- return null;
- }
-
- const h = hsb.h / 360;
- const s = hsb.s / 100;
- const v = hsb.b / 100;
-
- let r, g, b;
- const i = Math.floor(h * 6);
- const f = h * 6 - i;
- const p = v * (1 - s);
- const q = v * (1 - f * s);
- const t = v * (1 - (1 - f) * s);
- switch (i % 6) {
- case 0:
- r = v;
- g = t;
- b = p;
- break;
- case 1:
- r = q;
- g = v;
- b = p;
- break;
- case 2:
- r = p;
- g = v;
- b = t;
- break;
- case 3:
- r = p;
- g = q;
- b = v;
- break;
- case 4:
- r = t;
- g = p;
- b = v;
- break;
- case 5:
- r = v;
- g = p;
- b = q;
- break;
- }
- return {
- r: Math.round(r * 255),
- g: Math.round(g * 255),
- b: Math.round(b * 255)
- };
- }
-
- /**
- Transforms a RGB color into HSB (same as HSV) representation.
-
- @static
- @param {Object} rgb
- @return {Object} {h, s, b}
- @ignore
- */
- function _rgbToHsb(rgb) {
- if (!rgb) {
- return null;
- }
-
- const r = rgb.r;
- const g = rgb.g;
- const b = rgb.b;
-
- const max = Math.max(r, g, b);
- const min = Math.min(r, g, b);
- const d = max - min;
- let h;
- const s = max === 0 ? 0 : d / max;
- const v = max / 255;
-
- switch (max) {
- case min:
- h = 0;
- break;
- case r:
- h = g - b + d * (g < b ? 6 : 0);
- h /= 6 * d;
- break;
- case g:
- h = b - r + d * 2;
- h /= 6 * d;
- break;
- case b:
- h = r - g + d * 4;
- h /= 6 * d;
- break;
- }
-
- return {
- h: h * 360,
- s: s * 100,
- b: v * 100
- };
- }
-
- /**
- Parse an hsl value into an object.
- e.g.: 'hsl(360,100,0)' => {h:360, s:100, b:0}
-
- @static
- @param {String} hslStr
- The string representing the hsl value.
-
- @return {Object} {h, s, l} Returns null if string could not be parsed
- @ignore
- */
- function _parseHSL(hslStr) {
- const sliced = _slice(hslStr, 'hsl(');
-
- if (sliced.length !== 3) {
- return null;
- }
-
- // make sure there are not more than 2 digits after dot
- const h = parseFloat(sliced[0]);
- const s = parseFloat(sliced[1]);
- const l = parseFloat(sliced[2]);
-
- if (isNaN(h) || isNaN(s) || isNaN(l)) {
- return null;
- }
-
- if (h < 0 || h > 360 || s < 0 || s > 100 || l < 0 || l > 100) {
- return null;
- }
-
- return {h, s, l};
- }
-
- /**
- Serialize an hsl object into a string.
- e.g.: {h:0, s:0, l:0} => 'hsl(0,0%,0%)'
-
- @static
- @param {Object} hsl
- @return {String} hsb The string representing the hsb value
- @ignore
- */
- function _serializeHSL(hsl) {
- if (hsl) {
- // make sure there are not more than 2 digits after dot
- const h = parseFloat(hsl.h.toFixed(2));
- const s = parseFloat(hsl.s.toFixed(2));
- const l = parseFloat(hsl.l.toFixed(2));
-
- return `hsl(${h},${s}%,${l}%)`;
- }
-
- return '';
- }
-
- /**
- Transforms a HSL color into RGB representation.
- h (hue has value between 0-360 degree)
- s (saturation has a value between 0-100 percent)
- l (lightness has a value between 0-100 percent)
-
- @static
- @param {Object} hsl
- @return {Object} {r, g, b}
- @ignore
- */
- function _hslToRgb(hsl) {
- if (!hsl) {
- return null;
- }
-
- const h = hsl.h / 360;
- const s = hsl.s / 100;
- const l = hsl.l / 100;
-
- let r;
- let g;
- let b;
-
- if (s === 0) {
- // achromatic
- r = g = b = l;
- } else {
- const 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;
- };
-
- const qValue = l < 0.5 ? l * (1 + s) : l + s - l * s;
- const pValue = 2 * l - qValue;
- r = hue2rgb(pValue, qValue, h + 1 / 3);
- g = hue2rgb(pValue, qValue, h);
- b = hue2rgb(pValue, qValue, h - 1 / 3);
- }
-
- return {
- r: Math.round(r * 255),
- g: Math.round(g * 255),
- b: Math.round(b * 255)
- };
- }
-
- /**
- Transforms an RGB color into HSL representation.
-
- @static
- @param {Object} rgb
- @return {Object} {h, s, l}
- @ignore
- */
- function _rgbToHsl(rgb) {
- if (!rgb) {
- return null;
- }
-
- const r = rgb.r / 255;
- const g = rgb.g / 255;
- const b = rgb.b / 255;
-
- const max = Math.max(r, g, b);
- const min = Math.min(r, g, b);
- let h;
- let s;
- const l = (max + min) / 2;
-
- if (max === min) {
- // achromatic
- h = s = 0;
- } else {
- const d = max - min;
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
- switch (max) {
- case r:
- h = (g - b) / d + (g < b ? 6 : 0);
- break;
- case g:
- h = (b - r) / d + 2;
- break;
- case b:
- h = (r - g) / d + 4;
- break;
- }
- h /= 6;
- }
-
- return {
- h: h * 360,
- s: s * 100,
- l: l * 100
- };
- }
-
- /**
- Parse an hsla value into an object.
- e.g.: 'hsla(360,100%,0%,0.5)' => {h:360, s:100, l:0, 0.5}
-
- @static
- @param {String} hslaStr
- The string representing the hsl value.
-
- @return {Object} {h, s, l, a} Returns null if string could not be parsed
- @ignore
- */
- function _parseHSLA(hslaStr) {
- const sliced = _slice(hslaStr, 'hsla(');
-
- if (sliced.length !== 4) {
- return null;
- }
-
- // make sure there are not more than 2 digits after dot
- const h = parseFloat(sliced[0]);
- const s = parseFloat(sliced[1]);
- const l = parseFloat(sliced[2]);
- const a = parseFloat(sliced[3]);
-
- if (isNaN(h) || isNaN(s) || isNaN(l)) {
- return null;
- }
-
- if (h < 0 || h > 360 || s < 0 || s > 100 || l < 0 || l > 100 || a < 0 || a > 1) {
- return null;
- }
-
- return {h, s, l, a};
- }
-
- /**
- Serialize an hsla object into a string.
- e.g.: {h:0, s:0, l:0, a:0.5} => 'hsl(0,0%,0%,0.5)'
-
- @static
- @param {Object} hsla
- @return {String} hsb The string representing the hsb value
- @ignore
- */
- function _serializeHSLA(hsla) {
- if (hsla) {
- // make sure there are not more than 2 digits after dot
- const h = parseFloat(hsla.h.toFixed(2));
- const s = parseFloat(hsla.s.toFixed(2));
- const l = parseFloat(hsla.l.toFixed(2));
- const a = parseFloat(hsla.a.toFixed(2));
-
- return `hsla(${h},${s}%,${l}%,${a})`;
- }
-
- return '';
- }
-
- /**
- Color is used to get a color in different color spaces, calculate tints and shades etc.
- */
- class Color {
- /** @ignore */
- constructor() {
- // Set defaults
- this._colorSpace = colorSpace.HEX;
- this._value = '';
- this._alpha = 1;
- }
-
- /**
- The value of the color. This value can be set in different formats (HEX, RGB, RGBA, HSB, HSL, HSLA and CMYK).
- Corrects a hex value, if it is represented by 3 or 6 characters with or without '#'.
-
- e.g:
- HEX: #FFFFFF
- RGB: rgb(16,16,16)
- RGBA: rgba(215,40,40,0.9)
- HSB: hsb(360,100,100)
- HSL: hsl(360,100%,100%)
- HSLA: hsla(360,100%,100%,0.9)
- CMYK: cmyk(0,100,50,0)
-
- @type {String}
- @default ""
- */
- get value() {
- return this._value;
- }
-
- set value(value) {
- // Two color formats with alpha values
- const rgba = _parseRGBA(value);
- const hsla = _parseHSLA(value);
-
- const rgb = _parseRGB(value);
- const cmyk = _parseCMYK(value);
- const hsb = _parseHSB(value);
- const hsl = _parseHSL(value);
- const hex = _parseHex(value);
-
- if (rgba !== null) {
- this._colorSpace = colorSpace.RGB;
- this.alpha = rgba.a;
- value = _serializeRGB({
- r: rgba.r,
- g: rgba.g,
- b: rgba.b
- });
- } else if (hsla !== null) {
- this._colorSpace = colorSpace.HSL;
- this.alpha = hsla.a;
- value = _serializeHSL({
- h: hsla.h,
- s: hsla.s,
- l: hsla.l
- });
- } else if (rgb !== null) {
- this._colorSpace = colorSpace.RGB;
- } else if (cmyk !== null) {
- this._colorSpace = colorSpace.CMYK;
- } else if (hsb !== null) {
- this._colorSpace = colorSpace.HSB;
- } else if (hsl !== null) {
- this._colorSpace = colorSpace.HSL;
- } else if (hex !== null) {
- this._colorSpace = colorSpace.HEX;
- } else {
- // restore defaults
- this._colorSpace = colorSpace.HEX;
- value = '';
- }
-
- this._value = value;
- }
-
- /**
- The alpha value of the color (value between 0-1).
-
- @type {Number}
- @default 1
- */
- get alpha() {
- return this._alpha;
- }
-
- set alpha(value) {
- if (isNaN(value) || value < 0 || value > 1) {
- return;
- }
- this._alpha = transform.number(value);
- }
-
- /**
- The rgb values of the color (value between 0-255).
- e.g.: {r:0, g:0, b:0}
-
- @type {Object}
- @default null
- */
- get rgb() {
- let rgb = null;
- if (this._colorSpace === colorSpace.RGB) {
- rgb = _parseRGB(this.value);
- } else if (this._colorSpace === colorSpace.HEX) {
- const hex = _parseHex(this.value);
- rgb = _hexToRgb(hex);
- } else if (this._colorSpace === colorSpace.CMYK) {
- const cmyk = _parseCMYK(this.value);
- rgb = _cmykToRgb(cmyk);
- } else if (this._colorSpace === colorSpace.HSB) {
- const hsb = _parseHSB(this.value);
- rgb = _hsbToRgb(hsb);
- } else if (this._colorSpace === colorSpace.HSL) {
- const hsl = _parseHSL(this.value);
- rgb = _hslToRgb(hsl);
- }
- return rgb;
- }
-
- set rgb(value) {
- this.value = _serializeRGB(value);
- }
-
- /**
- The serialized rgb values of the color (r,g,b values between 0-255).
- e.g: 'rgb(0,0,0)'
-
- @type {String}
- @default ""
- */
- get rgbValue() {
- return _serializeRGB(this.rgb);
- }
-
- set rgbValue(value) {
- this.value = value;
- }
-
- /**
- The rgba values of the color (r,g,b values between 0-255 and a between 0-1).
- e.g: {r:0, g:0, b:0, a:1}
-
- @type {Object}
- @default null
- */
- get rgba() {
- const rgb = this.rgb;
- if (rgb) {
- return {
- r: rgb.r,
- g: rgb.g,
- b: rgb.b,
- a: this.alpha
- };
- }
-
- return null;
- }
-
- set rgba(value) {
- this.value = _serializeRGBA(value);
- }
-
- /**
- The serialized rgba values of the color (r,g,b values between 0-255 and alpha between 0-1).
- e.g: 'rgba(0,0,0,1)'
-
- @type {String}
- @default ""
- */
- get rgbaValue() {
- return _serializeRGBA(this.rgba);
- }
-
- set rgbaValue(value) {
- this.value = value;
- }
-
- /**
- The hex value of the color.
-
- @type {Number}
- @default null
- */
- get hex() {
- // as hex color space is essentially just the same as rgb and there is no loss in conversion, we can do it this way
- return _rgbToHex(this.rgb);
- }
-
- set hex(value) {
- this.value = _serializeHex(value);
- }
-
- /**
- The serialized hex value of the color.
- e.g: '#94CD4B'
-
- @type {String}
- @default ""
- */
- get hexValue() {
- return _serializeHex(this.hex);
- }
-
- set hexValue(value) {
- this.value = value;
- }
-
- /**
- The cmyk values of the color (all values between 0-100).
- e.g: {c:0, m:100, y:0, k:100}
-
- @type {Object}
- @default null
- */
- get cmyk() {
- let cmyk = null;
- let rgb = null;
- if (this._colorSpace === colorSpace.RGB) {
- rgb = _parseRGB(this.value);
- cmyk = _rgbToCmyk(rgb);
- } else if (this._colorSpace === colorSpace.HEX) {
- const hex = _parseHex(this.value);
- rgb = _hexToRgb(hex);
- cmyk = _rgbToCmyk(rgb);
- } else if (this._colorSpace === colorSpace.CMYK) {
- cmyk = _parseCMYK(this.value);
- } else if (this._colorSpace === colorSpace.HSB) {
- const hsb = _parseHSB(this.value);
- rgb = _hsbToRgb(hsb);
- cmyk = _rgbToCmyk(rgb);
- } else if (this._colorSpace === colorSpace.HSL) {
- const hsl = _parseHSL(this.value);
- rgb = _hslToRgb(hsl);
- cmyk = _rgbToCmyk(rgb);
- }
- return cmyk;
- }
-
- set cmyk(value) {
- this.value = _serializeCMYK(value);
- }
-
- /**
- The serialized cmyk values of the color (all values between 0-100).
- e.g: 'cmyk(100,100,100,100)'
-
- @type {String}
- @default ""
- */
- get cmykValue() {
- return _serializeCMYK(this.cmyk);
- }
-
- set cmykValue(value) {
- this.value = value;
- }
-
- /**
- The hsb values of the color.
- h (hue has value between 0-360 degree)
- s (saturation has a value between 0-100 percent)
- b (brightness has a value between 0-100 percent)
-
- @type {Object}
- @default null
- */
- get hsb() {
- let hsb = null;
- let rgb = null;
- if (this._colorSpace === colorSpace.RGB) {
- rgb = _parseRGB(this.value);
- hsb = _rgbToHsb(rgb);
- } else if (this._colorSpace === colorSpace.HEX) {
- const hex = _parseHex(this.value);
- rgb = _hexToRgb(hex);
- hsb = _rgbToHsb(rgb);
- } else if (this._colorSpace === colorSpace.CMYK) {
- const cmyk = _parseCMYK(this.value);
- rgb = _cmykToRgb(cmyk);
- hsb = _rgbToHsb(rgb);
- } else if (this._colorSpace === colorSpace.HSB) {
- hsb = _parseHSB(this.value);
- } else if (this._colorSpace === colorSpace.HSL) {
- const hsl = _parseHSL(this.value);
- rgb = _hslToRgb(hsl);
- hsb = _rgbToHsb(rgb);
- }
- return hsb;
- }
-
- set hsb(value) {
- this.value = _serializeHSB(value);
- }
-
- /**
- The serialized hsb values of the color (s and b values between 0-100, h between 0-360).
- e.g: 'hsb(360,100,100)'
-
- @type {String}
- @default ""
- */
- get hsbValue() {
- return _serializeHSB(this.hsb);
- }
-
- set hsbValue(value) {
- this.value = value;
- }
-
- /*
- The hsl values of the color.
- h (hue has value between 0-360 degree)
- s (saturation has a value between 0-100 percent)
- l (lightness has a value between 0-100 percent)
-
- @type {Object}
- @default null
- */
- get hsl() {
- let hsl = null;
- let rgb = null;
- if (this._colorSpace === colorSpace.RGB) {
- rgb = _parseRGB(this.value);
- hsl = _rgbToHsl(rgb);
- } else if (this._colorSpace === colorSpace.HEX) {
- const hex = _parseHex(this.value);
- rgb = _hexToRgb(hex);
- hsl = _rgbToHsl(rgb);
- } else if (this._colorSpace === colorSpace.CMYK) {
- const cmyk = _parseCMYK(this.value);
- rgb = _cmykToRgb(cmyk);
- hsl = _rgbToHsl(rgb);
- } else if (this._colorSpace === colorSpace.HSB) {
- const hsb = _parseHSB(this.value);
- rgb = _hsbToRgb(hsb);
- hsl = _rgbToHsl(rgb);
- } else if (this._colorSpace === colorSpace.HSL) {
- hsl = _parseHSL(this.value);
- }
- return hsl;
- }
-
- set hsl(value) {
- this.value = _serializeHSL(value);
- }
-
- /**
- The serialized hsl values of the color (s and l values between 0-100 in percent, h between 0-360).
- e.g: 'hsl(360,100%,100%)'
-
- @type {String}
- @default ""
- */
- get hslValue() {
- return _serializeHSL(this.hsl);
- }
-
- set hslValue(value) {
- this.value = value;
- }
-
- /**
- The hsla values of the color.
- h (hue has value between 0-360 degree)
- s (saturation has a value between 0-100 percent)
- l (lightness has a value between 0-100 percent)
- a (alpha has a value between 0-1)
-
- @type {Object}
- @default null
- */
- get hsla() {
- const hsl = this.hsl;
- if (hsl) {
- return {
- h: hsl.h,
- s: hsl.s,
- l: hsl.l,
- a: this.alpha
- };
- }
-
- return null;
- }
-
- set hsla(value) {
- this.value = _serializeHSLA(value);
- }
-
- /**
- The serialized hsla values of the color.
- h (hue has value between 0-360 degree)
- s (saturation has a value between 0-100 percent)
- l (lightness has a value between 0-100 percent)
- a (alpha has a value between 0-1)
- e.g: 'hsla(360,50%,50%,0.9)'
-
- @type {String}
- @default ""
- */
- get hslaValue() {
- return _serializeHSLA(this.hsla);
- }
-
- set hslaValue(value) {
- this.value = value;
- }
-
- /**
- Clone this color.
-
- @type {Color}
- */
- clone() {
- const clone = new this.constructor();
- clone.value = this.value;
- clone.alpha = this.alpha;
- return clone;
- }
-
- /**
- Test if this Color is similar to another color.
-
- @type {Boolean}
- @param {Color} compareColor
- The color to compare this color too.
-
- @param {Boolean} [allowSlightColorDifference=true]
- While converting between color spaces slight loses might happen => we should normally consider colors equal,
- even if they are minimally different.
-
- */
- isSimilarTo(compareColor, allowSlightColorDifference) {
- if (this.rgb === null && (!compareColor || compareColor.rgb === null)) {
- // Consider an rgb of null equal to a null object (or another value of null)
- return true;
- }
-
- if (!compareColor || compareColor.rgb === null || this.rgb === null) {
- return false;
- }
-
- let allowedRgbDifference = 1;
- let allowedAlphaDifference = 0.01;
-
- if (allowSlightColorDifference === false) {
- allowedRgbDifference = 0;
- allowedAlphaDifference = 0;
- }
-
- const rgb = this.rgb;
- const rgb2 = compareColor.rgb;
-
- const rDiff = Math.abs(rgb2.r - rgb.r);
- const gDiff = Math.abs(rgb2.g - rgb.g);
- const bDiff = Math.abs(rgb2.b - rgb.b);
- const aDiff = Math.abs(this.alpha - compareColor.alpha);
-
- if (rDiff <= allowedRgbDifference && gDiff <= allowedRgbDifference && bDiff <= allowedRgbDifference && aDiff <= allowedAlphaDifference) {
- return true;
- }
-
- return false;
- }
-
- /**
- Calculates an array of lighter colors.
-
- @type {Array<Coral.Color>}
- @param {Number} amount
- Amount of tint colors to generate.
-
- */
- calculateTintColors(amount) {
- const tintColors = [];
- let tintColor = null;
-
- const rgb = this.rgb;
- if (rgb) {
- const r = rgb.r;
- const g = rgb.g;
- const b = rgb.b;
-
- let tintFactor = 1;
-
- for (let i = 1 ; i <= amount ; i++) {
- tintFactor = i / (amount + 1);
- tintColor = this.clone();
- // alpha value kept from original
- tintColor.rgb = {
- r: r + (255 - r) * tintFactor,
- g: g + (255 - g) * tintFactor,
- b: b + (255 - b) * tintFactor
- };
-
- tintColors.push(tintColor);
- }
- }
-
- return tintColors;
- }
-
- /**
- Calculates an array of darker colors.
-
- @type {Array<Coral.Color>}
- @param {Number} amount
- Amount of shade colors to generate.
-
- */
- calculateShadeColors(amount) {
- const shadeColors = [];
- let shadeColor = null;
-
- const rgb = this.rgb;
- if (rgb) {
- const r = rgb.r;
- const g = rgb.g;
- const b = rgb.b;
-
- let shadeFactor = 1;
-
- for (let i = 1 ; i <= amount ; i++) {
- shadeFactor = i / (amount + 1);
- shadeColor = this.clone();
- // alpha value kept from original
- shadeColor.rgb = {
- r: r * (1 - shadeFactor),
- g: g * (1 - shadeFactor),
- b: b * (1 - shadeFactor)
- };
-
- shadeColors.push(shadeColor);
- }
- }
-
- return shadeColors;
- }
- }
-
- export default Color;