5 Functions for colour handling and processing.
7 http://www.safalra.com/web-design/javascript/colour-handling-and-processing/
9 The author of this program, Safalra (Stephen Morley), irrevocably releases all
10 rights to this program, with the intention of it becoming part of the public
11 domain. Because this program is released into the public domain, it comes with
12 no warranty either expressed or implied, to the extent permitted by law.
14 For more free and public domain JavaScript code by the same author, visit:
15 http://www.safalra.com/web-design/javascript/
20 /* An abstract Colour implementation. Concrete Colour implementations should use
21 * an instance of this function as their prototype, and implement the getRGB and
22 * getHSL functions. getRGB should return an object representing the RGB
23 * components of this Colour, with the red, green, and blue components in the
24 * range [0,255] and the alpha component in the range [0,100]. getHSL should
25 * return an object representing the HSL components of this Colour, with the hue
26 * component in the range [0,360), the saturation and lightness components in
27 * the range [0,100], and the alpha component in the range [0,1].
29 Roo.lib.Colour = function(){
31 /* Returns an object representing the RGBA components of this Colour. The red,
32 * green, and blue components are converted to integers in the range [0,255].
33 * The alpha is a value in the range [0,1].
35 this.getIntegerRGB = function(){
37 // get the RGB components of this colour
38 var rgb = this.getRGB();
40 // return the integer components
42 'r' : Math.round(rgb.r),
43 'g' : Math.round(rgb.g),
44 'b' : Math.round(rgb.b),
50 /* Returns an object representing the RGBA components of this Colour. The red,
51 * green, and blue components are converted to numbers in the range [0,100].
52 * The alpha is a value in the range [0,1].
54 this.getPercentageRGB = function(){
56 // get the RGB components of this colour
57 var rgb = this.getRGB();
59 // return the percentage components
61 'r' : 100 * rgb.r / 255,
62 'g' : 100 * rgb.g / 255,
63 'b' : 100 * rgb.b / 255,
69 /* Returns a string representing this Colour as a CSS hexadecimal RGB colour
70 * value - that is, a string of the form #RRGGBB where each of RR, GG, and BB
71 * are two-digit hexadecimal numbers.
73 this.getCSSHexadecimalRGB = function(){
75 // get the integer RGB components
76 var rgb = this.getIntegerRGB();
78 // determine the hexadecimal equivalents
79 var r16 = rgb.r.toString(16);
80 var g16 = rgb.g.toString(16);
81 var b16 = rgb.b.toString(16);
83 // return the CSS RGB colour value
85 + (r16.length == 2 ? r16 : '0' + r16)
86 + (g16.length == 2 ? g16 : '0' + g16)
87 + (b16.length == 2 ? b16 : '0' + b16);
91 /* Returns a string representing this Colour as a CSS integer RGB colour
92 * value - that is, a string of the form rgb(r,g,b) where each of r, g, and b
93 * are integers in the range [0,255].
95 this.getCSSIntegerRGB = function(){
97 // get the integer RGB components
98 var rgb = this.getIntegerRGB();
100 // return the CSS RGB colour value
101 return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
105 /* Returns a string representing this Colour as a CSS integer RGBA colour
106 * value - that is, a string of the form rgba(r,g,b,a) where each of r, g, and
107 * b are integers in the range [0,255] and a is in the range [0,1].
109 this.getCSSIntegerRGBA = function(){
111 // get the integer RGB components
112 var rgb = this.getIntegerRGB();
114 // return the CSS integer RGBA colour value
115 return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
119 /* Returns a string representing this Colour as a CSS percentage RGB colour
120 * value - that is, a string of the form rgb(r%,g%,b%) where each of r, g, and
121 * b are in the range [0,100].
123 this.getCSSPercentageRGB = function(){
125 // get the percentage RGB components
126 var rgb = this.getPercentageRGB();
128 // return the CSS RGB colour value
129 return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%)';
133 /* Returns a string representing this Colour as a CSS percentage RGBA colour
134 * value - that is, a string of the form rgba(r%,g%,b%,a) where each of r, g,
135 * and b are in the range [0,100] and a is in the range [0,1].
137 this.getCSSPercentageRGBA = function(){
139 // get the percentage RGB components
140 var rgb = this.getPercentageRGB();
142 // return the CSS percentage RGBA colour value
143 return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%,' + rgb.a + ')';
147 /* Returns a string representing this Colour as a CSS HSL colour value - that
148 * is, a string of the form hsl(h,s%,l%) where h is in the range [0,100] and
149 * s and l are in the range [0,100].
151 this.getCSSHSL = function(){
153 // get the HSL components
154 var hsl = this.getHSL();
156 // return the CSS HSL colour value
157 return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)';
161 /* Returns a string representing this Colour as a CSS HSLA colour value - that
162 * is, a string of the form hsla(h,s%,l%,a) where h is in the range [0,100],
163 * s and l are in the range [0,100], and a is in the range [0,1].
165 this.getCSSHSLA = function(){
167 // get the HSL components
168 var hsl = this.getHSL();
170 // return the CSS HSL colour value
171 return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%,' + hsl.a + ')';
175 /* Sets the colour of the specified node to this Colour. This functions sets
176 * the CSS 'color' property for the node. The parameter is:
178 * node - the node whose colour should be set
180 this.setNodeColour = function(node){
182 // set the colour of the node
183 node.style.color = this.getCSSHexadecimalRGB();
187 /* Sets the background colour of the specified node to this Colour. This
188 * functions sets the CSS 'background-color' property for the node. The
191 * node - the node whose background colour should be set
193 this.setNodeBackgroundColour = function(node){
195 // set the background colour of the node
196 node.style.backgroundColor = this.getCSSHexadecimalRGB();
199 // convert between formats..
200 this.toRGB= function()
202 var r = this.getIntegerRGB();
203 return new Roo.lib.RGBColour(r.r,r.g,r.b,r.a);
206 this.toHSL = function()
208 var hsl = this.getHSL();
209 // return the CSS HSL colour value
210 return new Roo.lib.HSLColour(hsl.h, hsl.s, hsl.l , hsl.a );
214 this.toHSV = function()
216 var rgb = this.toRGB();
217 var hsv = rgb.getHSV();
218 // return the CSS HSL colour value
219 return new Roo.lib.HSVColour(hsv.h, hsv.s, hsv.v , hsv.a );
223 // modify v = 0 ... 1 (eg. 0.5)
224 this.saturate = function(v)
226 var rgb = this.toRGB();
227 var hsv = rgb.getHSV();
228 return new Roo.lib.HSVColour(hsv.h, hsv.s * v, hsv.v , hsv.a );
239 /* Creates a colour specified in the RGB colour space, with an optional alpha
240 * component. The parameters are:
242 * r - the red component, clipped to the range [0,255]
243 * g - the green component, clipped to the range [0,255]
244 * b - the blue component, clipped to the range [0,255]
245 * a - the alpha component, clipped to the range [0,1] - this parameter is
246 * optional and defaults to 1
248 Roo.lib.RGBColour = function (r, g, b, a){
250 // store the alpha component after clipping it if necessary
251 var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
253 // store the RGB components after clipping them if necessary
256 'r' : Math.max(0, Math.min(255, r)),
257 'g' : Math.max(0, Math.min(255, g)),
258 'b' : Math.max(0, Math.min(255, b))
261 // initialise the HSV and HSL components to null
265 /* Returns the HSV or HSL hue component of this RGBColour. The hue is in the
266 * range [0,360). The parameters are:
268 * maximum - the maximum of the RGB component values
269 * range - the range of the RGB component values
271 function getHue(maximum, range){
273 // check whether the range is zero
276 // set the hue to zero (any hue is acceptable as the colour is grey)
281 // determine which of the components has the highest value and set the hue
284 // red has the highest value
286 var hue = (rgb.g - rgb.b) / range * 60;
287 if (hue < 0) hue += 360;
290 // green has the highest value
292 var hue = (rgb.b - rgb.r) / range * 60 + 120;
295 // blue has the highest value
297 var hue = (rgb.r - rgb.g) / range * 60 + 240;
309 /* Calculates and stores the HSV components of this RGBColour so that they can
310 * be returned be the getHSV function.
312 function calculateHSV(){
314 // get the maximum and range of the RGB component values
315 var maximum = Math.max(rgb.r, rgb.g, rgb.b);
316 var range = maximum - Math.min(rgb.r, rgb.g, rgb.b);
318 // store the HSV components
321 'h' : getHue(maximum, range),
322 's' : (maximum == 0 ? 0 : 100 * range / maximum),
328 /* Calculates and stores the HSL components of this RGBColour so that they can
329 * be returned be the getHSL function.
331 function calculateHSL(){
333 // get the maximum and range of the RGB component values
334 var maximum = Math.max(rgb.r, rgb.g, rgb.b);
335 var range = maximum - Math.min(rgb.r, rgb.g, rgb.b);
337 // determine the lightness in the range [0,1]
338 var l = maximum / 255 - range / 510;
340 // store the HSL components
343 'h' : getHue(maximum, range),
344 's' : (range == 0 ? 0 : range / 2.55 / (l < 0.5 ? l * 2 : 2 - l * 2)),
350 /* Returns the RGB and alpha components of this RGBColour as an object with r,
351 * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
354 this.getRGB = function(){
356 // return the RGB components
366 /* Returns the HSV and alpha components of this RGBColour as an object with h,
367 * s, v, and a properties. h is in the range [0,360), s and v are in the range
368 * [0,100], and a is in the range [0,1].
370 this.getHSV = function(){
372 // calculate the HSV components if necessary
373 if (hsv == null) calculateHSV();
375 // return the HSV components
385 /* Returns the HSL and alpha components of this RGBColour as an object with h,
386 * s, l, and a properties. h is in the range [0,360), s and l are in the range
387 * [0,100], and a is in the range [0,1].
389 this.getHSL = function(){
391 // calculate the HSV components if necessary
392 if (hsl == null) calculateHSL();
394 // return the HSL components
405 Roo.lib.RGBColour.prototype = new Roo.lib.Colour();
408 /* Creates a colour specified in the HSV colour space, with an optional alpha
409 * component. The parameters are:
411 * h - the hue component, wrapped to the range [0,360)
412 * s - the saturation component, clipped to the range [0,100]
413 * v - the value component, clipped to the range [0,100]
414 * a - the alpha component, clipped to the range [0,1] - this parameter is
415 * optional and defaults to 1
417 Roo.lib.HSVColour = function (h, s, v, a){
419 // store the alpha component after clipping it if necessary
420 var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
422 // store the HSV components after clipping or wrapping them if necessary
425 'h' : (h % 360 + 360) % 360,
426 's' : Math.max(0, Math.min(100, s)),
427 'v' : Math.max(0, Math.min(100, v))
430 // initialise the RGB and HSL components to null
434 /* Calculates and stores the RGB components of this HSVColour so that they can
435 * be returned be the getRGB function.
437 function calculateRGB(){
439 // check whether the saturation is zero
442 // set the colour to the appropriate shade of grey
449 // set some temporary values
450 var f = hsv.h / 60 - Math.floor(hsv.h / 60);
451 var p = hsv.v * (1 - hsv.s / 100);
452 var q = hsv.v * (1 - hsv.s / 100 * f);
453 var t = hsv.v * (1 - hsv.s / 100 * (1 - f));
455 // set the RGB colour components to their temporary values
456 switch (Math.floor(hsv.h / 60)){
457 case 0: var r = hsv.v; var g = t; var b = p; break;
458 case 1: var r = q; var g = hsv.v; var b = p; break;
459 case 2: var r = p; var g = hsv.v; var b = t; break;
460 case 3: var r = p; var g = q; var b = hsv.v; break;
461 case 4: var r = t; var g = p; var b = hsv.v; break;
462 case 5: var r = hsv.v; var g = p; var b = q; break;
467 // store the RGB components
477 /* Calculates and stores the HSL components of this HSVColour so that they can
478 * be returned be the getHSL function.
480 function calculateHSL(){
482 // determine the lightness in the range [0,100]
483 var l = (2 - hsv.s / 100) * hsv.v / 2;
485 // store the HSL components
489 's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
493 // correct a division-by-zero error
494 if (isNaN(hsl.s)) hsl.s = 0;
498 /* Returns the RGB and alpha components of this HSVColour as an object with r,
499 * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
502 this.getRGB = function(){
504 // calculate the RGB components if necessary
505 if (rgb == null) calculateRGB();
507 // return the RGB components
517 /* Returns the HSV and alpha components of this HSVColour as an object with h,
518 * s, v, and a properties. h is in the range [0,360), s and v are in the range
519 * [0,100], and a is in the range [0,1].
521 this.getHSV = function(){
523 // return the HSV components
533 /* Returns the HSL and alpha components of this HSVColour as an object with h,
534 * s, l, and a properties. h is in the range [0,360), s and l are in the range
535 * [0,100], and a is in the range [0,1].
537 this.getHSL = function(){
539 // calculate the HSL components if necessary
540 if (hsl == null) calculateHSL();
542 // return the HSL components
553 Roo.lib.HSVColour.prototype = new Roo.lib.Colour();
556 /* Creates a colour specified in the HSL colour space, with an optional alpha
557 * component. The parameters are:
559 * h - the hue component, wrapped to the range [0,360)
560 * s - the saturation component, clipped to the range [0,100]
561 * l - the lightness component, clipped to the range [0,100]
562 * a - the alpha component, clipped to the range [0,1] - this parameter is
563 * optional and defaults to 1
566 Roo.lib.HSLColour = function(h, s, l, a){
568 // store the alpha component after clipping it if necessary
569 var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
571 // store the HSL components after clipping or wrapping them if necessary
574 'h' : (h % 360 + 360) % 360,
575 's' : Math.max(0, Math.min(100, s)),
576 'l' : Math.max(0, Math.min(100, l))
579 // initialise the RGB and HSV components to null
583 /* Calculates and stores the RGB components of this HSLColour so that they can
584 * be returned be the getRGB function.
586 function calculateRGB(){
588 // check whether the saturation is zero
591 // store the RGB components representing the appropriate shade of grey
601 // set some temporary values
603 ? hsl.l * (1 + hsl.s / 100)
604 : hsl.l + hsl.s - hsl.l * hsl.s / 100;
605 var q = 2 * hsl.l - p;
607 // initialise the RGB components
610 'r' : (h + 120) / 60 % 6,
612 'b' : (h + 240) / 60 % 6
615 // loop over the RGB components
616 for (var key in rgb){
618 // ensure that the property is not inherited from the root object
619 if (rgb.hasOwnProperty(key)){
621 // set the component to its value in the range [0,100]
623 rgb[key] = q + (p - q) * rgb[key];
624 }else if (rgb[key] < 3){
626 }else if (rgb[key] < 4){
627 rgb[key] = q + (p - q) * (4 - rgb[key]);
632 // set the component to its value in the range [0,255]
643 /* Calculates and stores the HSV components of this HSLColour so that they can
644 * be returned be the getHSL function.
646 function calculateHSV(){
648 // set a temporary value
649 var t = hsl.s * (hsl.l < 50 ? hsl.l : 100 - hsl.l) / 100;
651 // store the HSV components
655 's' : 200 * t / (hsl.l + t),
659 // correct a division-by-zero error
660 if (isNaN(hsv.s)) hsv.s = 0;
664 /* Returns the RGB and alpha components of this HSLColour as an object with r,
665 * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
668 this.getRGB = function(){
670 // calculate the RGB components if necessary
671 if (rgb == null) calculateRGB();
673 // return the RGB components
683 /* Returns the HSV and alpha components of this HSLColour as an object with h,
684 * s, v, and a properties. h is in the range [0,360), s and v are in the range
685 * [0,100], and a is in the range [0,1].
687 this.getHSV = function(){
689 // calculate the HSV components if necessary
690 if (hsv == null) calculateHSV();
692 // return the HSV components
702 /* Returns the HSL and alpha components of this HSLColour as an object with h,
703 * s, l, and a properties. h is in the range [0,360), s and l are in the range
704 * [0,100], and a is in the range [0,1].
706 this.getHSL = function(){
708 // return the HSL components
719 Roo.lib.HSLColour.prototype = new Roo.lib.Colour();