3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * Represents an RGB color and provides helper functions get
17 * color components in HSL color space.
19 Ext.define('Ext.draw.Color', {
21 /* Begin Definitions */
25 colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/,
26 rgbRe: /\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
27 hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/,
30 * @cfg {Number} lightnessFactor
32 * The default factor to compute the lighter or darker color. Defaults to 0.2.
38 * @param {Number} red Red component (0..255)
39 * @param {Number} green Green component (0..255)
40 * @param {Number} blue Blue component (0..255)
42 constructor : function(red, green, blue) {
44 clamp = Ext.Number.constrain;
45 me.r = clamp(red, 0, 255);
46 me.g = clamp(green, 0, 255);
47 me.b = clamp(blue, 0, 255);
51 * Get the red component of the color, in the range 0..255.
59 * Get the green component of the color, in the range 0..255.
62 getGreen: function() {
67 * Get the blue component of the color, in the range 0..255.
80 return [me.r, me.g, me.b];
84 * Get the equivalent HSL components of the color.
92 max = Math.max(r, g, b),
93 min = Math.min(r, g, b),
97 l = 0.5 * (max + min);
99 // min==max means achromatic (hue is undefined)
101 s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min);
103 h = 60 * (g - b) / delta;
104 } else if (g == max) {
105 h = 120 + 60 * (b - r) / delta;
107 h = 240 + 60 * (r - g) / delta;
120 * Return a new color that is lighter than this color.
121 * @param {Number} factor Lighter factor (0..1), default to 0.2
122 * @return Ext.draw.Color
124 getLighter: function(factor) {
125 var hsl = this.getHSL();
126 factor = factor || this.lightnessFactor;
127 hsl[2] = Ext.Number.constrain(hsl[2] + factor, 0, 1);
128 return this.fromHSL(hsl[0], hsl[1], hsl[2]);
132 * Return a new color that is darker than this color.
133 * @param {Number} factor Darker factor (0..1), default to 0.2
134 * @return Ext.draw.Color
136 getDarker: function(factor) {
137 factor = factor || this.lightnessFactor;
138 return this.getLighter(-factor);
142 * Return the color in the hex format, i.e. '#rrggbb'.
145 toString: function() {
148 r = round(me.r).toString(16),
149 g = round(me.g).toString(16),
150 b = round(me.b).toString(16);
151 r = (r.length == 1) ? '0' + r : r;
152 g = (g.length == 1) ? '0' + g : g;
153 b = (b.length == 1) ? '0' + b : b;
154 return ['#', r, g, b].join('');
158 * Convert a color to hexadecimal format.
160 * **Note:** This method is both static and instance.
162 * @param {String/String[]} color The color value (i.e 'rgb(255, 255, 255)', 'color: #ffffff').
163 * Can also be an Array, in this case the function handles the first member.
164 * @returns {String} The color in hexadecimal format.
167 toHex: function(color) {
168 if (Ext.isArray(color)) {
171 if (!Ext.isString(color)) {
174 if (color.substr(0, 1) === '#') {
177 var digits = this.colorToHexRe.exec(color);
179 if (Ext.isArray(digits)) {
180 var red = parseInt(digits[2], 10),
181 green = parseInt(digits[3], 10),
182 blue = parseInt(digits[4], 10),
183 rgb = blue | (green << 8) | (red << 16);
184 return digits[1] + '#' + ("000000" + rgb.toString(16)).slice(-6);
192 * Parse the string and create a new color.
194 * Supported formats: '#rrggbb', '#rgb', and 'rgb(r,g,b)'.
196 * If the string is not recognized, an undefined will be returned instead.
198 * **Note:** This method is both static and instance.
200 * @param {String} str Color in string.
201 * @returns Ext.draw.Color
204 fromString: function(str) {
208 if ((str.length == 4 || str.length == 7) && str.substr(0, 1) === '#') {
209 values = str.match(this.hexRe);
211 r = parse(values[1], 16) >> 0;
212 g = parse(values[2], 16) >> 0;
213 b = parse(values[3], 16) >> 0;
214 if (str.length == 4) {
222 values = str.match(this.rgbRe);
230 return (typeof r == 'undefined') ? undefined : Ext.create('Ext.draw.Color', r, g, b);
234 * Returns the gray value (0 to 255) of the color.
236 * The gray value is calculated using the formula r*0.3 + g*0.59 + b*0.11.
240 getGrayscale: function() {
241 // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
242 return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;
246 * Create a new color based on the specified HSL values.
248 * **Note:** This method is both static and instance.
250 * @param {Number} h Hue component (0..359)
251 * @param {Number} s Saturation component (0..1)
252 * @param {Number} l Lightness component (0..1)
253 * @returns Ext.draw.Color
256 fromHSL: function(h, s, l) {
257 var C, X, m, i, rgb = [],
261 if (s == 0 || h == null) {
266 // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL
268 // X is the second largest component
269 // m is the lightness adjustment
271 C = s * (1 - abs(2 * l - 1));
272 X = C * (1 - abs(h - 2 * floor(h / 2) - 1));
294 rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m];
296 return Ext.create('Ext.draw.Color', rgb[0] * 255, rgb[1] * 255, rgb[2] * 255);
299 var prototype = this.prototype;
301 //These functions are both static and instance. TODO: find a more elegant way of copying them
303 fromHSL: function() {
304 return prototype.fromHSL.apply(prototype, arguments);
306 fromString: function() {
307 return prototype.fromString.apply(prototype, arguments);
310 return prototype.toHex.apply(prototype, arguments);