UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

669 lines (563 loc) 17 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) * Andreas Ecker (ecker) * Christian Hagendorn (cs) ************************************************************************ */ /** * Methods to convert colors between different color spaces. * * @ignore(qx.theme.*) * @ignore(qx.Class) * @ignore(qx.Class.*) */ qx.Bootstrap.define("qx.util.ColorUtil", { statics : { /** * Regular expressions for color strings */ REGEXP : { hex3 : /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, hex6 : /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, rgb : /^rgb\(\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*,\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*,\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*\)$/, rgba : /^rgba\(\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*,\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*,\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*,\s*([0-9]{1,3}\.{0,1}[0-9]*)\s*\)$/ }, /** * CSS3 system color names. */ SYSTEM : { activeborder : true, activecaption : true, appworkspace : true, background : true, buttonface : true, buttonhighlight : true, buttonshadow : true, buttontext : true, captiontext : true, graytext : true, highlight : true, highlighttext : true, inactiveborder : true, inactivecaption : true, inactivecaptiontext : true, infobackground : true, infotext : true, menu : true, menutext : true, scrollbar : true, threeddarkshadow : true, threedface : true, threedhighlight : true, threedlightshadow : true, threedshadow : true, window : true, windowframe : true, windowtext : true }, /** * Named colors, only the 16 basic colors plus the following ones: * transparent, grey, magenta, orange and brown */ NAMED : { black : [ 0, 0, 0 ], silver : [ 192, 192, 192 ], gray : [ 128, 128, 128 ], white : [ 255, 255, 255 ], maroon : [ 128, 0, 0 ], red : [ 255, 0, 0 ], purple : [ 128, 0, 128 ], fuchsia : [ 255, 0, 255 ], green : [ 0, 128, 0 ], lime : [ 0, 255, 0 ], olive : [ 128, 128, 0 ], yellow : [ 255, 255, 0 ], navy : [ 0, 0, 128 ], blue : [ 0, 0, 255 ], teal : [ 0, 128, 128 ], aqua : [ 0, 255, 255 ], // Additional values transparent : [ -1, -1, -1 ], magenta : [ 255, 0, 255 ], // alias for fuchsia orange : [ 255, 165, 0 ], brown : [ 165, 42, 42 ] }, /** * Whether the incoming value is a named color. * * @param value {String} the color value to test * @return {Boolean} true if the color is a named color */ isNamedColor : function(value) { return this.NAMED[value] !== undefined; }, /** * Whether the incoming value is a system color. * * @param value {String} the color value to test * @return {Boolean} true if the color is a system color */ isSystemColor : function(value) { return this.SYSTEM[value] !== undefined; }, /** * Whether the color theme manager is loaded. Generally * part of the GUI of qooxdoo. * * @return {Boolean} <code>true</code> when color theme support is ready. **/ supportsThemes : function() { if (qx.Class) { return qx.Class.isDefined("qx.theme.manager.Color"); } return false; }, /** * Whether the incoming value is a themed color. * * @param value {String} the color value to test * @return {Boolean} true if the color is a themed color */ isThemedColor : function(value) { if (!this.supportsThemes()) { return false; } if (qx.theme && qx.theme.manager && qx.theme.manager.Color) { return qx.theme.manager.Color.getInstance().isDynamic(value); } return false; }, /** * Try to convert an incoming string to an RGB array. * Supports themed, named and system colors, but also RGB strings, * hex3 and hex6 values. * * @param str {String} any string * @return {Array} returns an array of red, green, blue on a successful transformation * @throws {Error} if the string could not be parsed */ stringToRgb : function(str) { if (this.supportsThemes() && this.isThemedColor(str)) { str = qx.theme.manager.Color.getInstance().resolveDynamic(str); } if (this.isNamedColor(str)) { return this.NAMED[str].concat(); } else if (this.isSystemColor(str)) { throw new Error("Could not convert system colors to RGB: " + str); } else if (this.isRgbaString(str)) { return this.__rgbaStringToRgb(str); } else if (this.isRgbString(str)) { return this.__rgbStringToRgb(); } else if (this.isHex3String(str)) { return this.__hex3StringToRgb(); } else if (this.isHex6String(str)) { return this.__hex6StringToRgb(); } throw new Error("Could not parse color: " + str); }, /** * Try to convert an incoming string to an RGB array. * Support named colors, RGB strings, hex3 and hex6 values. * * @param str {String} any string * @return {Array} returns an array of red, green, blue on a successful transformation * @throws {Error} if the string could not be parsed */ cssStringToRgb : function(str) { if (this.isNamedColor(str)) { return this.NAMED[str]; } else if (this.isSystemColor(str)) { throw new Error("Could not convert system colors to RGB: " + str); } else if (this.isRgbString(str)) { return this.__rgbStringToRgb(); } else if (this.isRgbaString(str)) { return this.__rgbaStringToRgb(); } else if (this.isHex3String(str)) { return this.__hex3StringToRgb(); } else if (this.isHex6String(str)) { return this.__hex6StringToRgb(); } throw new Error("Could not parse color: " + str); }, /** * Try to convert an incoming string to an RGB string, which can be used * for all color properties. * Supports themed, named and system colors, but also RGB strings, * hex3 and hex6 values. * * @param str {String} any string * @return {String} a RGB string * @throws {Error} if the string could not be parsed */ stringToRgbString : function(str) { return this.rgbToRgbString(this.stringToRgb(str)); }, /** * Converts a RGB array to an RGB string * * @param rgb {Array} an array with red, green and blue values and optionally * an alpha value * @return {String} an RGB string */ rgbToRgbString : function(rgb) { return "rgb" + (rgb[3] !== undefined ? "a" : "") + "(" + rgb.join(",") + ")"; }, /** * Converts a RGB array to an hex6 string * * @param rgb {Array} an array with red, green and blue * @return {String} a hex6 string (#xxxxxx) */ rgbToHexString : function(rgb) { return ( "#" + qx.lang.String.pad(rgb[0].toString(16).toUpperCase(), 2) + qx.lang.String.pad(rgb[1].toString(16).toUpperCase(), 2) + qx.lang.String.pad(rgb[2].toString(16).toUpperCase(), 2) ); }, /** * Detects if a string is a valid qooxdoo color * * @param str {String} any string * @return {Boolean} true when the incoming value is a valid qooxdoo color */ isValidPropertyValue : function(str) { return ( this.isThemedColor(str) || this.isNamedColor(str) || this.isHex3String(str) || this.isHex6String(str) || this.isRgbString(str) || this.isRgbaString(str)); }, /** * Detects if a string is a valid CSS color string * * @param str {String} any string * @return {Boolean} true when the incoming value is a valid CSS color string */ isCssString : function(str) { return ( this.isSystemColor(str) || this.isNamedColor(str) || this.isHex3String(str) || this.isHex6String(str) || this.isRgbString(str) || this.isRgbaString(str)); }, /** * Detects if a string is a valid hex3 string * * @param str {String} any string * @return {Boolean} true when the incoming value is a valid hex3 string */ isHex3String : function(str) { return this.REGEXP.hex3.test(str); }, /** * Detects if a string is a valid hex6 string * * @param str {String} any string * @return {Boolean} true when the incoming value is a valid hex6 string */ isHex6String : function(str) { return this.REGEXP.hex6.test(str); }, /** * Detects if a string is a valid RGB string * * @param str {String} any string * @return {Boolean} true when the incoming value is a valid RGB string */ isRgbString : function(str) { return this.REGEXP.rgb.test(str); }, /** * Detects if a string is a valid RGBA string * * @param str {String} any string * @return {Boolean} true when the incoming value is a valid RGBA string */ isRgbaString : function(str) { return this.REGEXP.rgba.test(str); }, /** * Converts a regexp object match of a rgb string to an RGB array. * * @return {Array} an array with red, green, blue */ __rgbStringToRgb : function() { var red = parseInt(RegExp.$1, 10); var green = parseInt(RegExp.$2, 10); var blue = parseInt(RegExp.$3, 10); return [red, green, blue]; }, /** * Converts a regexp object match of a rgba string to an RGB array. * * @return {Array} an array with red, green, blue */ __rgbaStringToRgb : function() { var red = parseInt(RegExp.$1, 10); var green = parseInt(RegExp.$2, 10); var blue = parseInt(RegExp.$3, 10); var alpha = parseFloat(RegExp.$4, 10); if (red === 0 && green === 0 & blue === 0 && alpha === 0) { return [-1, -1, -1]; } return [red, green, blue]; }, /** * Converts a regexp object match of a hex3 string to an RGB array. * * @return {Array} an array with red, green, blue */ __hex3StringToRgb : function() { var red = parseInt(RegExp.$1, 16) * 17; var green = parseInt(RegExp.$2, 16) * 17; var blue = parseInt(RegExp.$3, 16) * 17; return [red, green, blue]; }, /** * Converts a regexp object match of a hex6 string to an RGB array. * * @return {Array} an array with red, green, blue */ __hex6StringToRgb : function() { var red = (parseInt(RegExp.$1, 16) * 16) + parseInt(RegExp.$2, 16); var green = (parseInt(RegExp.$3, 16) * 16) + parseInt(RegExp.$4, 16); var blue = (parseInt(RegExp.$5, 16) * 16) + parseInt(RegExp.$6, 16); return [red, green, blue]; }, /** * Converts a hex3 string to an RGB array * * @param value {String} a hex3 (#xxx) string * @return {Array} an array with red, green, blue */ hex3StringToRgb : function(value) { if (this.isHex3String(value)) { return this.__hex3StringToRgb(value); } throw new Error("Invalid hex3 value: " + value); }, /** * Converts a hex3 (#xxx) string to a hex6 (#xxxxxx) string. * * @param value {String} a hex3 (#xxx) string * @return {String} The hex6 (#xxxxxx) string or the passed value when the * passed value is not an hex3 (#xxx) value. */ hex3StringToHex6String : function(value) { if (this.isHex3String(value)) { return this.rgbToHexString(this.hex3StringToRgb(value)); } return value; }, /** * Converts a hex6 string to an RGB array * * @param value {String} a hex6 (#xxxxxx) string * @return {Array} an array with red, green, blue */ hex6StringToRgb : function(value) { if (this.isHex6String(value)) { return this.__hex6StringToRgb(value); } throw new Error("Invalid hex6 value: " + value); }, /** * Converts a hex string to an RGB array * * @param value {String} a hex3 (#xxx) or hex6 (#xxxxxx) string * @return {Array} an array with red, green, blue */ hexStringToRgb : function(value) { if (this.isHex3String(value)) { return this.__hex3StringToRgb(value); } if (this.isHex6String(value)) { return this.__hex6StringToRgb(value); } throw new Error("Invalid hex value: " + value); }, /** * Convert RGB colors to HSB * * @param rgb {Number[]} red, blue and green as array * @return {Array} an array with hue, saturation and brightness */ rgbToHsb : function(rgb) { var hue, saturation, brightness; var red = rgb[0]; var green = rgb[1]; var blue = rgb[2]; var cmax = (red > green) ? red : green; if (blue > cmax) { cmax = blue; } var cmin = (red < green) ? red : green; if (blue < cmin) { cmin = blue; } brightness = cmax / 255.0; if (cmax != 0) { saturation = (cmax - cmin) / cmax; } else { saturation = 0; } if (saturation == 0) { hue = 0; } else { var redc = (cmax - red) / (cmax - cmin); var greenc = (cmax - green) / (cmax - cmin); var bluec = (cmax - blue) / (cmax - cmin); if (red == cmax) { hue = bluec - greenc; } else if (green == cmax) { hue = 2.0 + redc - bluec; } else { hue = 4.0 + greenc - redc; } hue = hue / 6.0; if (hue < 0) { hue = hue + 1.0; } } return [ Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100) ]; }, /** * Convert HSB colors to RGB * * @param hsb {Number[]} an array with hue, saturation and brightness * @return {Integer[]} an array with red, green, blue */ hsbToRgb : function(hsb) { var i, f, p, r, t; var hue = hsb[0] / 360; var saturation = hsb[1] / 100; var brightness = hsb[2] / 100; if (hue >= 1.0) { hue %= 1.0; } if (saturation > 1.0) { saturation = 1.0; } if (brightness > 1.0) { brightness = 1.0; } var tov = Math.floor(255 * brightness); var rgb = {}; if (saturation == 0.0) { rgb.red = rgb.green = rgb.blue = tov; } else { hue *= 6.0; i = Math.floor(hue); f = hue - i; p = Math.floor(tov * (1.0 - saturation)); r = Math.floor(tov * (1.0 - (saturation * f))); t = Math.floor(tov * (1.0 - (saturation * (1.0 - f)))); switch(i) { case 0: rgb.red = tov; rgb.green = t; rgb.blue = p; break; case 1: rgb.red = r; rgb.green = tov; rgb.blue = p; break; case 2: rgb.red = p; rgb.green = tov; rgb.blue = t; break; case 3: rgb.red = p; rgb.green = r; rgb.blue = tov; break; case 4: rgb.red = t; rgb.green = p; rgb.blue = tov; break; case 5: rgb.red = tov; rgb.green = p; rgb.blue = r; break; } } return [rgb.red, rgb.green, rgb.blue]; }, /** * Creates a random color. * * @return {String} a valid qooxdoo/CSS rgb color string. */ randomColor : function() { var r = Math.round(Math.random() * 255); var g = Math.round(Math.random() * 255); var b = Math.round(Math.random() * 255); return this.rgbToRgbString([r, g, b]); } } });