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/
21 * @class Roo.lib.Color
22 * An abstract Colour implementation. Concrete Colour implementations should use
23 * an instance of this function as their prototype, and implement the getRGB and
24 * getHSL functions. getRGB should return an object representing the RGB
25 * components of this Colour, with the red, green, and blue components in the
26 * range [0,255] and the alpha component in the range [0,100]. getHSL should
27 * return an object representing the HSL components of this Colour, with the hue
28 * component in the range [0,360), the saturation and lightness components in
29 * the range [0,100], and the alpha component in the range [0,1].
31 Roo.lib.Color = function(){
33 /* Returns an object representing the RGBA components of this Colour. The red,
34 * green, and blue components are converted to integers in the range [0,255].
35 * The alpha is a value in the range [0,1].
37 this.getIntegerRGB = function(){
39 // get the RGB components of this colour
40 var rgb = this.getRGB();
42 // return the integer components
44 'r' : Math.round(rgb.r),
45 'g' : Math.round(rgb.g),
46 'b' : Math.round(rgb.b),
52 /* Returns an object representing the RGBA components of this Colour. The red,
53 * green, and blue components are converted to numbers in the range [0,100].
54 * The alpha is a value in the range [0,1].
56 this.getPercentageRGB = function(){
58 // get the RGB components of this colour
59 var rgb = this.getRGB();
61 // return the percentage components
63 'r' : 100 * rgb.r / 255,
64 'g' : 100 * rgb.g / 255,
65 'b' : 100 * rgb.b / 255,
71 /* Returns a string representing this Colour as a CSS hexadecimal RGB colour
72 * value - that is, a string of the form #RRGGBB where each of RR, GG, and BB
73 * are two-digit hexadecimal numbers.
75 this.getCSSHexadecimalRGB = function(){
77 // get the integer RGB components
78 var rgb = this.getIntegerRGB();
80 // determine the hexadecimal equivalents
81 var r16 = rgb.r.toString(16);
82 var g16 = rgb.g.toString(16);
83 var b16 = rgb.b.toString(16);
85 // return the CSS RGB colour value
87 + (r16.length == 2 ? r16 : '0' + r16)
88 + (g16.length == 2 ? g16 : '0' + g16)
89 + (b16.length == 2 ? b16 : '0' + b16);
93 /* Returns a string representing this Colour as a CSS integer RGB colour
94 * value - that is, a string of the form rgb(r,g,b) where each of r, g, and b
95 * are integers in the range [0,255].
97 this.getCSSIntegerRGB = function(){
99 // get the integer RGB components
100 var rgb = this.getIntegerRGB();
102 // return the CSS RGB colour value
103 return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
107 /* Returns a string representing this Colour as a CSS integer RGBA colour
108 * value - that is, a string of the form rgba(r,g,b,a) where each of r, g, and
109 * b are integers in the range [0,255] and a is in the range [0,1].
111 this.getCSSIntegerRGBA = function(){
113 // get the integer RGB components
114 var rgb = this.getIntegerRGB();
116 // return the CSS integer RGBA colour value
117 return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
121 /* Returns a string representing this Colour as a CSS percentage RGB colour
122 * value - that is, a string of the form rgb(r%,g%,b%) where each of r, g, and
123 * b are in the range [0,100].
125 this.getCSSPercentageRGB = function(){
127 // get the percentage RGB components
128 var rgb = this.getPercentageRGB();
130 // return the CSS RGB colour value
131 return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%)';
135 /* Returns a string representing this Colour as a CSS percentage RGBA colour
136 * value - that is, a string of the form rgba(r%,g%,b%,a) where each of r, g,
137 * and b are in the range [0,100] and a is in the range [0,1].
139 this.getCSSPercentageRGBA = function(){
141 // get the percentage RGB components
142 var rgb = this.getPercentageRGB();
144 // return the CSS percentage RGBA colour value
145 return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%,' + rgb.a + ')';
149 /* Returns a string representing this Colour as a CSS HSL colour value - that
150 * is, a string of the form hsl(h,s%,l%) where h is in the range [0,100] and
151 * s and l are in the range [0,100].
153 this.getCSSHSL = function(){
155 // get the HSL components
156 var hsl = this.getHSL();
158 // return the CSS HSL colour value
159 return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)';
163 /* Returns a string representing this Colour as a CSS HSLA colour value - that
164 * is, a string of the form hsla(h,s%,l%,a) where h is in the range [0,100],
165 * s and l are in the range [0,100], and a is in the range [0,1].
167 this.getCSSHSLA = function(){
169 // get the HSL components
170 var hsl = this.getHSL();
172 // return the CSS HSL colour value
173 return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%,' + hsl.a + ')';
177 /* Sets the colour of the specified node to this Colour. This functions sets
178 * the CSS 'color' property for the node. The parameter is:
180 * node - the node whose colour should be set
182 this.setNodeColour = function(node){
184 // set the colour of the node
185 node.style.color = this.getCSSHexadecimalRGB();
189 /* Sets the background colour of the specified node to this Colour. This
190 * functions sets the CSS 'background-color' property for the node. The
193 * node - the node whose background colour should be set
195 this.setNodeBackgroundColour = function(node){
197 // set the background colour of the node
198 node.style.backgroundColor = this.getCSSHexadecimalRGB();
201 // convert between formats..
202 this.toRGB= function()
204 var r = this.getIntegerRGB();
205 return new Roo.lib.RGBColour(r.r,r.g,r.b,r.a);
208 this.toHSL = function()
210 var hsl = this.getHSL();
211 // return the CSS HSL colour value
212 return new Roo.lib.HSLColour(hsl.h, hsl.s, hsl.l , hsl.a );
216 this.toHSV = function()
218 var rgb = this.toRGB();
219 var hsv = rgb.getHSV();
220 // return the CSS HSL colour value
221 return new Roo.lib.HSVColour(hsv.h, hsv.s, hsv.v , hsv.a );
225 // modify v = 0 ... 1 (eg. 0.5)
226 this.saturate = function(v)
228 var rgb = this.toRGB();
229 var hsv = rgb.getHSV();
230 return new Roo.lib.HSVColour(hsv.h, hsv.s * v, hsv.v , hsv.a );
241 /* Creates a colour specified in the RGB colour space, with an optional alpha
242 * component. The parameters are:
244 * r - the red component, clipped to the range [0,255]
245 * g - the green component, clipped to the range [0,255]
246 * b - the blue component, clipped to the range [0,255]
247 * a - the alpha component, clipped to the range [0,1] - this parameter is
248 * optional and defaults to 1
250 Roo.lib.RGBColour = function (r, g, b, a){
252 // store the alpha component after clipping it if necessary
253 var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
255 // store the RGB components after clipping them if necessary
258 'r' : Math.max(0, Math.min(255, r)),
259 'g' : Math.max(0, Math.min(255, g)),
260 'b' : Math.max(0, Math.min(255, b))
263 // initialise the HSV and HSL components to null
267 /* Returns the HSV or HSL hue component of this RGBColour. The hue is in the
268 * range [0,360). The parameters are:
270 * maximum - the maximum of the RGB component values
271 * range - the range of the RGB component values
273 function getHue(maximum, range){
275 // check whether the range is zero
278 // set the hue to zero (any hue is acceptable as the colour is grey)
283 // determine which of the components has the highest value and set the hue
286 // red has the highest value
288 var hue = (rgb.g - rgb.b) / range * 60;
289 if (hue < 0) hue += 360;
292 // green has the highest value
294 var hue = (rgb.b - rgb.r) / range * 60 + 120;
297 // blue has the highest value
299 var hue = (rgb.r - rgb.g) / range * 60 + 240;
311 /* Calculates and stores the HSV components of this RGBColour so that they can
312 * be returned be the getHSV function.
314 function calculateHSV(){
316 // get the maximum and range of the RGB component values
317 var maximum = Math.max(rgb.r, rgb.g, rgb.b);
318 var range = maximum - Math.min(rgb.r, rgb.g, rgb.b);
320 // store the HSV components
323 'h' : getHue(maximum, range),
324 's' : (maximum == 0 ? 0 : 100 * range / maximum),
330 /* Calculates and stores the HSL components of this RGBColour so that they can
331 * be returned be the getHSL function.
333 function calculateHSL(){
335 // get the maximum and range of the RGB component values
336 var maximum = Math.max(rgb.r, rgb.g, rgb.b);
337 var range = maximum - Math.min(rgb.r, rgb.g, rgb.b);
339 // determine the lightness in the range [0,1]
340 var l = maximum / 255 - range / 510;
342 // store the HSL components
345 'h' : getHue(maximum, range),
346 's' : (range == 0 ? 0 : range / 2.55 / (l < 0.5 ? l * 2 : 2 - l * 2)),
352 /* Returns the RGB and alpha components of this RGBColour as an object with r,
353 * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
356 this.getRGB = function(){
358 // return the RGB components
368 /* Returns the HSV and alpha components of this RGBColour as an object with h,
369 * s, v, and a properties. h is in the range [0,360), s and v are in the range
370 * [0,100], and a is in the range [0,1].
372 this.getHSV = function(){
374 // calculate the HSV components if necessary
375 if (hsv == null) calculateHSV();
377 // return the HSV components
387 /* Returns the HSL and alpha components of this RGBColour as an object with h,
388 * s, l, and a properties. h is in the range [0,360), s and l are in the range
389 * [0,100], and a is in the range [0,1].
391 this.getHSL = function(){
393 // calculate the HSV components if necessary
394 if (hsl == null) calculateHSL();
396 // return the HSL components
407 Roo.lib.RGBColour.prototype = new Roo.lib.Colour();
410 /* Creates a colour specified in the HSV colour space, with an optional alpha
411 * component. The parameters are:
413 * h - the hue component, wrapped to the range [0,360)
414 * s - the saturation component, clipped to the range [0,100]
415 * v - the value component, clipped to the range [0,100]
416 * a - the alpha component, clipped to the range [0,1] - this parameter is
417 * optional and defaults to 1
419 Roo.lib.HSVColour = function (h, s, v, a){
421 // store the alpha component after clipping it if necessary
422 var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
424 // store the HSV components after clipping or wrapping them if necessary
427 'h' : (h % 360 + 360) % 360,
428 's' : Math.max(0, Math.min(100, s)),
429 'v' : Math.max(0, Math.min(100, v))
432 // initialise the RGB and HSL components to null
436 /* Calculates and stores the RGB components of this HSVColour so that they can
437 * be returned be the getRGB function.
439 function calculateRGB(){
441 // check whether the saturation is zero
444 // set the colour to the appropriate shade of grey
451 // set some temporary values
452 var f = hsv.h / 60 - Math.floor(hsv.h / 60);
453 var p = hsv.v * (1 - hsv.s / 100);
454 var q = hsv.v * (1 - hsv.s / 100 * f);
455 var t = hsv.v * (1 - hsv.s / 100 * (1 - f));
457 // set the RGB colour components to their temporary values
458 switch (Math.floor(hsv.h / 60)){
459 case 0: var r = hsv.v; var g = t; var b = p; break;
460 case 1: var r = q; var g = hsv.v; var b = p; break;
461 case 2: var r = p; var g = hsv.v; var b = t; break;
462 case 3: var r = p; var g = q; var b = hsv.v; break;
463 case 4: var r = t; var g = p; var b = hsv.v; break;
464 case 5: var r = hsv.v; var g = p; var b = q; break;
469 // store the RGB components
479 /* Calculates and stores the HSL components of this HSVColour so that they can
480 * be returned be the getHSL function.
482 function calculateHSL(){
484 // determine the lightness in the range [0,100]
485 var l = (2 - hsv.s / 100) * hsv.v / 2;
487 // store the HSL components
491 's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
495 // correct a division-by-zero error
496 if (isNaN(hsl.s)) hsl.s = 0;
500 /* Returns the RGB and alpha components of this HSVColour as an object with r,
501 * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
504 this.getRGB = function(){
506 // calculate the RGB components if necessary
507 if (rgb == null) calculateRGB();
509 // return the RGB components
519 /* Returns the HSV and alpha components of this HSVColour as an object with h,
520 * s, v, and a properties. h is in the range [0,360), s and v are in the range
521 * [0,100], and a is in the range [0,1].
523 this.getHSV = function(){
525 // return the HSV components
535 /* Returns the HSL and alpha components of this HSVColour as an object with h,
536 * s, l, and a properties. h is in the range [0,360), s and l are in the range
537 * [0,100], and a is in the range [0,1].
539 this.getHSL = function(){
541 // calculate the HSL components if necessary
542 if (hsl == null) calculateHSL();
544 // return the HSL components
555 Roo.lib.HSVColour.prototype = new Roo.lib.Colour();
558 /* Creates a colour specified in the HSL colour space, with an optional alpha
559 * component. The parameters are:
561 * h - the hue component, wrapped to the range [0,360)
562 * s - the saturation component, clipped to the range [0,100]
563 * l - the lightness component, clipped to the range [0,100]
564 * a - the alpha component, clipped to the range [0,1] - this parameter is
565 * optional and defaults to 1
568 Roo.lib.HSLColour = function(h, s, l, a){
570 // store the alpha component after clipping it if necessary
571 var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
573 // store the HSL components after clipping or wrapping them if necessary
576 'h' : (h % 360 + 360) % 360,
577 's' : Math.max(0, Math.min(100, s)),
578 'l' : Math.max(0, Math.min(100, l))
581 // initialise the RGB and HSV components to null
585 /* Calculates and stores the RGB components of this HSLColour so that they can
586 * be returned be the getRGB function.
588 function calculateRGB(){
590 // check whether the saturation is zero
593 // store the RGB components representing the appropriate shade of grey
603 // set some temporary values
605 ? hsl.l * (1 + hsl.s / 100)
606 : hsl.l + hsl.s - hsl.l * hsl.s / 100;
607 var q = 2 * hsl.l - p;
609 // initialise the RGB components
612 'r' : (h + 120) / 60 % 6,
614 'b' : (h + 240) / 60 % 6
617 // loop over the RGB components
618 for (var key in rgb){
620 // ensure that the property is not inherited from the root object
621 if (rgb.hasOwnProperty(key)){
623 // set the component to its value in the range [0,100]
625 rgb[key] = q + (p - q) * rgb[key];
626 }else if (rgb[key] < 3){
628 }else if (rgb[key] < 4){
629 rgb[key] = q + (p - q) * (4 - rgb[key]);
634 // set the component to its value in the range [0,255]
645 /* Calculates and stores the HSV components of this HSLColour so that they can
646 * be returned be the getHSL function.
648 function calculateHSV(){
650 // set a temporary value
651 var t = hsl.s * (hsl.l < 50 ? hsl.l : 100 - hsl.l) / 100;
653 // store the HSV components
657 's' : 200 * t / (hsl.l + t),
661 // correct a division-by-zero error
662 if (isNaN(hsv.s)) hsv.s = 0;
666 /* Returns the RGB and alpha components of this HSLColour as an object with r,
667 * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
670 this.getRGB = function(){
672 // calculate the RGB components if necessary
673 if (rgb == null) calculateRGB();
675 // return the RGB components
685 /* Returns the HSV and alpha components of this HSLColour as an object with h,
686 * s, v, and a properties. h is in the range [0,360), s and v are in the range
687 * [0,100], and a is in the range [0,1].
689 this.getHSV = function(){
691 // calculate the HSV components if necessary
692 if (hsv == null) calculateHSV();
694 // return the HSV components
704 /* Returns the HSL and alpha components of this HSLColour as an object with h,
705 * s, l, and a properties. h is in the range [0,360), s and l are in the range
706 * [0,100], and a is in the range [0,1].
708 this.getHSL = function(){
710 // return the HSL components
721 Roo.lib.HSLColour.prototype = new Roo.lib.Colour();