roojs-all.js
[roojs1] / Roo / lib / Color.js
1 /*
2
3 Color.js
4
5 Functions for Color handling and processing.
6
7 http://www.safalra.com/web-design/javascript/Color-handling-and-processing/
8
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.
13
14 For more free and public domain JavaScript code by the same author, visit:
15 http://www.safalra.com/web-design/javascript/
16
17 */
18
19
20 /*
21  * @class Roo.lib.Color
22  * @constructor
23  * An abstract Color implementation. Concrete Color implementations should use
24  * an instance of this function as their prototype, and implement the getRGB and
25  * getHSL functions. getRGB should return an object representing the RGB
26  * components of this Color, with the red, green, and blue components in the
27  * range [0,255] and the alpha component in the range [0,100]. getHSL should
28  * return an object representing the HSL components of this Color, with the hue
29  * component in the range [0,360), the saturation and lightness components in
30  * the range [0,100], and the alpha component in the range [0,1].
31  */
32 Roo.lib.Color = function() { }
33
34
35 Roo.apply(Roo.lib.Color.prototype, {
36   /**
37    * @returns an object representing the RGBA components of this Color. The red,
38    * green, and blue components are converted to integers in the range [0,255].
39    * The alpha is a value in the range [0,1].
40    */
41   getIntegerRGB : function(){
42
43     // get the RGB components of this Color
44     var rgb = this.getRGB();
45
46     // return the integer components
47     return {
48       'r' : Math.round(rgb.r),
49       'g' : Math.round(rgb.g),
50       'b' : Math.round(rgb.b),
51       'a' : rgb.a
52     };
53
54   },
55
56   /**
57    * @returns an object representing the RGBA components of this Color. The red,
58    * green, and blue components are converted to numbers in the range [0,100].
59    * The alpha is a value in the range [0,1].
60    */
61   getPercentageRGB : function(){
62
63     // get the RGB components of this Color
64     var rgb = this.getRGB();
65
66     // return the percentage components
67     return {
68       'r' : 100 * rgb.r / 255,
69       'g' : 100 * rgb.g / 255,
70       'b' : 100 * rgb.b / 255,
71       'a' : rgb.a
72     };
73
74   },
75
76   /**
77    * @returns a string representing this Color as a CSS hexadecimal RGB Color
78    * value - that is, a string of the form #RRGGBB where each of RR, GG, and BB
79    * are two-digit hexadecimal numbers.
80    */
81   getCSSHexadecimalRGB : function()
82   {
83
84     // get the integer RGB components
85     var rgb = this.getIntegerRGB();
86
87     // determine the hexadecimal equivalents
88     var r16 = rgb.r.toString(16);
89     var g16 = rgb.g.toString(16);
90     var b16 = rgb.b.toString(16);
91
92     // return the CSS RGB Color value
93     return '#'
94         + (r16.length == 2 ? r16 : '0' + r16)
95         + (g16.length == 2 ? g16 : '0' + g16)
96         + (b16.length == 2 ? b16 : '0' + b16);
97
98   },
99
100   /**
101    * @returns a string representing this Color as a CSS integer RGB Color
102    * value - that is, a string of the form rgb(r,g,b) where each of r, g, and b
103    * are integers in the range [0,255].
104    */
105   getCSSIntegerRGB : function(){
106
107     // get the integer RGB components
108     var rgb = this.getIntegerRGB();
109
110     // return the CSS RGB Color value
111     return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
112
113   },
114
115   /**
116    * @returns Returns a string representing this Color as a CSS integer RGBA Color
117    * value - that is, a string of the form rgba(r,g,b,a) where each of r, g, and
118    * b are integers in the range [0,255] and a is in the range [0,1].
119    */
120   getCSSIntegerRGBA : function(){
121
122     // get the integer RGB components
123     var rgb = this.getIntegerRGB();
124
125     // return the CSS integer RGBA Color value
126     return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
127
128   },
129
130   /**
131    * @returns a string representing this Color as a CSS percentage RGB Color
132    * value - that is, a string of the form rgb(r%,g%,b%) where each of r, g, and
133    * b are in the range [0,100].
134    */
135   getCSSPercentageRGB : function(){
136
137     // get the percentage RGB components
138     var rgb = this.getPercentageRGB();
139
140     // return the CSS RGB Color value
141     return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%)';
142
143   },
144
145   /**
146    * @returns a string representing this Color as a CSS percentage RGBA Color
147    * value - that is, a string of the form rgba(r%,g%,b%,a) where each of r, g,
148    * and b are in the range [0,100] and a is in the range [0,1].
149    */
150   getCSSPercentageRGBA : function(){
151
152     // get the percentage RGB components
153     var rgb = this.getPercentageRGB();
154
155     // return the CSS percentage RGBA Color value
156     return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%,' + rgb.a + ')';
157
158   },
159
160   /**
161    * @returns a string representing this Color as a CSS HSL Color value - that
162    * is, a string of the form hsl(h,s%,l%) where h is in the range [0,100] and
163    * s and l are in the range [0,100].
164    */
165   getCSSHSL : function(){
166
167     // get the HSL components
168     var hsl = this.getHSL();
169
170     // return the CSS HSL Color value
171     return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)';
172
173   },
174
175   /**
176    * @returns a string representing this Color as a CSS HSLA Color value - that
177    * is, a string of the form hsla(h,s%,l%,a) where h is in the range [0,100],
178    * s and l are in the range [0,100], and a is in the range [0,1].
179    */
180   getCSSHSLA : function(){
181
182     // get the HSL components
183     var hsl = this.getHSL();
184
185     // return the CSS HSL Color value
186     return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%,' + hsl.a + ')';
187
188   },
189
190   /**
191    * Sets the Color of the specified node to this Color. This functions sets
192    * the CSS 'color' property for the node. The parameter is:
193    * 
194    * @param {DomElement} node - the node whose Color should be set
195    */
196   setNodeColor : function(node){
197
198     // set the Color of the node
199     node.style.color = this.getCSSHexadecimalRGB();
200
201   },
202
203   /**
204    * Sets the background Color of the specified node to this Color. This
205    * functions sets the CSS 'background-color' property for the node. The
206    * parameter is:
207    *
208    * @param {DomElement} node - the node whose background Color should be set
209    */
210   setNodeBackgroundColor : function(node){
211
212     // set the background Color of the node
213     node.style.backgroundColor = this.getCSSHexadecimalRGB();
214
215   },
216   // convert between formats..
217   toRGB: function()
218   {
219     var r = this.getIntegerRGB();
220     return new Roo.lib.RGBColor(r.r,r.g,r.b,r.a);
221     
222   },
223   toHSL : function()
224   {
225      var hsl = this.getHSL();
226   // return the CSS HSL Color value
227     return new Roo.lib.HSLColor(hsl.h,  hsl.s, hsl.l ,  hsl.a );
228     
229   },
230   
231   toHSV : function()
232   {
233     var rgb = this.toRGB();
234     var hsv = rgb.getHSV();
235    // return the CSS HSL Color value
236     return new Roo.lib.HSVColor(hsv.h,  hsv.s, hsv.v ,  hsv.a );
237     
238   },
239   
240   // modify  v = 0 ... 1 (eg. 0.5)
241   saturate : function(v)
242   {
243       var rgb = this.toRGB();
244       var hsv = rgb.getHSV();
245       return new Roo.lib.HSVColor(hsv.h,  hsv.s * v, hsv.v ,  hsv.a );
246       
247   
248   }
249   
250    
251   
252
253 });
254
255
256 /*
257  * @class Roo.lib.RGBColor
258  * @extends Roo.lib.Color
259  * Creates a Color specified in the RGB Color space, with an optional alpha
260  * component. The parameters are:
261  *
262  * r - the red component, clipped to the range [0,255]
263  * g - the green component, clipped to the range [0,255]
264  * b - the blue component, clipped to the range [0,255]
265  * a - the alpha component, clipped to the range [0,1] - this parameter is
266  *     optional and defaults to 1
267  */
268 Roo.lib.RGBColor = function (r, g, b, a){
269
270   // store the alpha component after clipping it if necessary
271   var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
272
273   // store the RGB components after clipping them if necessary
274   var rgb =
275       {
276         'r' : Math.max(0, Math.min(255, r)),
277         'g' : Math.max(0, Math.min(255, g)),
278         'b' : Math.max(0, Math.min(255, b))
279       };
280
281   // initialise the HSV and HSL components to null
282   var hsv = null;
283   var hsl = null;
284
285   /* 
286    * //private returns the HSV or HSL hue component of this RGBColor. The hue is in the
287    * range [0,360). The parameters are:
288    *
289    * maximum - the maximum of the RGB component values
290    * range   - the range of the RGB component values
291    */
292   function getHue(maximum, range){
293
294     // check whether the range is zero
295     if (range == 0){
296
297       // set the hue to zero (any hue is acceptable as the Color is grey)
298       var hue = 0;
299
300     }else{
301
302       // determine which of the components has the highest value and set the hue
303       switch (maximum){
304
305         // red has the highest value
306         case rgb.r:
307           var hue = (rgb.g - rgb.b) / range * 60;
308           if (hue < 0) hue += 360;
309           break;
310
311         // green has the highest value
312         case rgb.g:
313           var hue = (rgb.b - rgb.r) / range * 60 + 120;
314           break;
315
316         // blue has the highest value
317         case rgb.b:
318           var hue = (rgb.r - rgb.g) / range * 60 + 240;
319           break;
320
321       }
322
323     }
324
325     // return the hue
326     return hue;
327
328   }
329
330   /* //private Calculates and stores the HSV components of this RGBColor so that they can
331    * be returned be the getHSV function.
332    */
333   function calculateHSV(){
334
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);
338
339     // store the HSV components
340     hsv =
341         {
342           'h' : getHue(maximum, range),
343           's' : (maximum == 0 ? 0 : 100 * range / maximum),
344           'v' : maximum / 2.55
345         };
346
347   }
348
349   /* //private Calculates and stores the HSL components of this RGBColor so that they can
350    * be returned be the getHSL function.
351    */
352   function calculateHSL(){
353
354     // get the maximum and range of the RGB component values
355     var maximum = Math.max(rgb.r, rgb.g, rgb.b);
356     var range   = maximum - Math.min(rgb.r, rgb.g, rgb.b);
357
358     // determine the lightness in the range [0,1]
359     var l = maximum / 255 - range / 510;
360
361     // store the HSL components
362     hsl =
363         {
364           'h' : getHue(maximum, range),
365           's' : (range == 0 ? 0 : range / 2.55 / (l < 0.5 ? l * 2 : 2 - l * 2)),
366           'l' : 100 * l
367         };
368
369   }
370
371   /**
372    * @returns the RGB and alpha components of this RGBColor as an object with r,
373    * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
374    * the range [0,1].
375    */
376   this.getRGB = function(){
377
378     // return the RGB components
379     return {
380       'r' : rgb.r,
381       'g' : rgb.g,
382       'b' : rgb.b,
383       'a' : alpha
384     };
385
386   };
387
388   /**
389    * @returns the HSV and alpha components of this RGBColor as an object with h,
390    * s, v, and a properties. h is in the range [0,360), s and v are in the range
391    * [0,100], and a is in the range [0,1].
392    */
393   this.getHSV = function(){
394
395     // calculate the HSV components if necessary
396     if (hsv == null) calculateHSV();
397
398     // return the HSV components
399     return {
400       'h' : hsv.h,
401       's' : hsv.s,
402       'v' : hsv.v,
403       'a' : alpha
404     };
405
406   };
407
408   /**
409    * @returns the HSL and alpha components of this RGBColor as an object with h,
410    * s, l, and a properties. h is in the range [0,360), s and l are in the range
411    * [0,100], and a is in the range [0,1].
412    */
413   this.getHSL = function(){
414
415     // calculate the HSV components if necessary
416     if (hsl == null) calculateHSL();
417
418     // return the HSL components
419     return {
420       'h' : hsl.h,
421       's' : hsl.s,
422       'l' : hsl.l,
423       'a' : alpha
424     };
425
426   };
427
428 }
429 // this does an 'exteds'
430 Roo.lib.RGBColor.prototype = new Roo.lib.Color();
431
432
433 /*
434  * @class Roo.lib.HSVColor
435  * @extends Roo.lib.Color
436  * Creates a Color specified in the HSV Color space, with an optional alpha
437  * component. The parameters are:
438  *
439  * h - the hue component, wrapped to the range [0,360)
440  * s - the saturation component, clipped to the range [0,100]
441  * v - the value component, clipped to the range [0,100]
442  * a - the alpha component, clipped to the range [0,1] - this parameter is
443  *     optional and defaults to 1
444  */
445 Roo.lib.HSVColor = function (h, s, v, a){
446
447   // store the alpha component after clipping it if necessary
448   var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
449
450   // store the HSV components after clipping or wrapping them if necessary
451   var hsv =
452       {
453         'h' : (h % 360 + 360) % 360,
454         's' : Math.max(0, Math.min(100, s)),
455         'v' : Math.max(0, Math.min(100, v))
456       };
457
458   // initialise the RGB and HSL components to null
459   var rgb = null;
460   var hsl = null;
461
462   /* Calculates and stores the RGB components of this HSVColor so that they can
463    * be returned be the getRGB function.
464    */
465   function calculateRGB(){
466
467     // check whether the saturation is zero
468     if (hsv.s == 0){
469
470       // set the Color to the appropriate shade of grey
471       var r = hsv.v;
472       var g = hsv.v;
473       var b = hsv.v;
474
475     }else{
476
477       // set some temporary values
478       var f  = hsv.h / 60 - Math.floor(hsv.h / 60);
479       var p  = hsv.v * (1 - hsv.s / 100);
480       var q  = hsv.v * (1 - hsv.s / 100 * f);
481       var t  = hsv.v * (1 - hsv.s / 100 * (1 - f));
482
483       // set the RGB Color components to their temporary values
484       switch (Math.floor(hsv.h / 60)){
485         case 0: var r = hsv.v; var g = t; var b = p; break;
486         case 1: var r = q; var g = hsv.v; var b = p; break;
487         case 2: var r = p; var g = hsv.v; var b = t; break;
488         case 3: var r = p; var g = q; var b = hsv.v; break;
489         case 4: var r = t; var g = p; var b = hsv.v; break;
490         case 5: var r = hsv.v; var g = p; var b = q; break;
491       }
492
493     }
494
495     // store the RGB components
496     rgb =
497         {
498           'r' : r * 2.55,
499           'g' : g * 2.55,
500           'b' : b * 2.55
501         };
502
503   }
504
505   /* Calculates and stores the HSL components of this HSVColor so that they can
506    * be returned be the getHSL function.
507    */
508   function calculateHSL(){
509
510     // determine the lightness in the range [0,100]
511     var l = (2 - hsv.s / 100) * hsv.v / 2;
512
513     // store the HSL components
514     hsl =
515         {
516           'h' : hsv.h,
517           's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
518           'l' : l
519         };
520
521     // correct a division-by-zero error
522     if (isNaN(hsl.s)) hsl.s = 0;
523
524   }
525
526   /**
527    * @returns the RGB and alpha components of this HSVColor as an object with r,
528    * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
529    * the range [0,1].
530    */
531   this.getRGB = function(){
532
533     // calculate the RGB components if necessary
534     if (rgb == null) calculateRGB();
535
536     // return the RGB components
537     return {
538       'r' : rgb.r,
539       'g' : rgb.g,
540       'b' : rgb.b,
541       'a' : alpha
542     };
543
544   };
545
546   /**
547    * @returns the HSV and alpha components of this HSVColor as an object with h,
548    * s, v, and a properties. h is in the range [0,360), s and v are in the range
549    * [0,100], and a is in the range [0,1].
550    */
551   this.getHSV = function(){
552
553     // return the HSV components
554     return {
555       'h' : hsv.h,
556       's' : hsv.s,
557       'v' : hsv.v,
558       'a' : alpha
559     };
560
561   };
562
563   /**
564    * @returns the HSL and alpha components of this HSVColor as an object with h,
565    * s, l, and a properties. h is in the range [0,360), s and l are in the range
566    * [0,100], and a is in the range [0,1].
567    */
568   this.getHSL = function(){
569
570     // calculate the HSL components if necessary
571     if (hsl == null) calculateHSL();
572
573     // return the HSL components
574     return {
575       'h' : hsl.h,
576       's' : hsl.s,
577       'l' : hsl.l,
578       'a' : alpha
579     };
580
581   };
582
583 }
584 Roo.lib.HSVColor.prototype = new Roo.lib.Color();
585
586
587 /**
588  * @class Roo.lib.HSLColor
589  * @extends Roo.lib.Color
590  * 
591  * Creates a Color specified in the HSL Color space, with an optional alpha
592  * component. The parameters are:
593  *
594  * h - the hue component, wrapped to the range [0,360)
595  * s - the saturation component, clipped to the range [0,100]
596  * l - the lightness component, clipped to the range [0,100]
597  * a - the alpha component, clipped to the range [0,1] - this parameter is
598  *     optional and defaults to 1
599  */
600
601 Roo.lib.HSLColor = function(h, s, l, a){
602
603   // store the alpha component after clipping it if necessary
604   var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
605
606   // store the HSL components after clipping or wrapping them if necessary
607   var hsl =
608       {
609         'h' : (h % 360 + 360) % 360,
610         's' : Math.max(0, Math.min(100, s)),
611         'l' : Math.max(0, Math.min(100, l))
612       };
613
614   // initialise the RGB and HSV components to null
615   var rgb = null;
616   var hsv = null;
617
618   /* Calculates and stores the RGB components of this HSLColor so that they can
619    * be returned be the getRGB function.
620    */
621   function calculateRGB(){
622
623     // check whether the saturation is zero
624     if (hsl.s == 0){
625
626       // store the RGB components representing the appropriate shade of grey
627       rgb =
628           {
629             'r' : hsl.l * 2.55,
630             'g' : hsl.l * 2.55,
631             'b' : hsl.l * 2.55
632           };
633
634     }else{
635
636       // set some temporary values
637       var p = hsl.l < 50
638             ? hsl.l * (1 + hsl.s / 100)
639             : hsl.l + hsl.s - hsl.l * hsl.s / 100;
640       var q = 2 * hsl.l - p;
641
642       // initialise the RGB components
643       rgb =
644           {
645             'r' : (h + 120) / 60 % 6,
646             'g' : h / 60,
647             'b' : (h + 240) / 60 % 6
648           };
649
650       // loop over the RGB components
651       for (var key in rgb){
652
653         // ensure that the property is not inherited from the root object
654         if (rgb.hasOwnProperty(key)){
655
656           // set the component to its value in the range [0,100]
657           if (rgb[key] < 1){
658             rgb[key] = q + (p - q) * rgb[key];
659           }else if (rgb[key] < 3){
660             rgb[key] = p;
661           }else if (rgb[key] < 4){
662             rgb[key] = q + (p - q) * (4 - rgb[key]);
663           }else{
664             rgb[key] = q;
665           }
666
667           // set the component to its value in the range [0,255]
668           rgb[key] *= 2.55;
669
670         }
671
672       }
673
674     }
675
676   }
677
678   /* Calculates and stores the HSV components of this HSLColor so that they can
679    * be returned be the getHSL function.
680    */
681   function calculateHSV(){
682
683     // set a temporary value
684     var t = hsl.s * (hsl.l < 50 ? hsl.l : 100 - hsl.l) / 100;
685
686     // store the HSV components
687     hsv =
688         {
689           'h' : hsl.h,
690           's' : 200 * t / (hsl.l + t),
691           'v' : t + hsl.l
692         };
693
694     // correct a division-by-zero error
695     if (isNaN(hsv.s)) hsv.s = 0;
696
697   }
698
699   /**
700    * @returns the RGB and alpha components of this HSLColor as an object with r,
701    * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
702    * the range [0,1].
703    */
704   this.getRGB = function(){
705
706     // calculate the RGB components if necessary
707     if (rgb == null) calculateRGB();
708
709     // return the RGB components
710     return {
711       'r' : rgb.r,
712       'g' : rgb.g,
713       'b' : rgb.b,
714       'a' : alpha
715     };
716
717   };
718
719   /**
720    * @returns the HSV and alpha components of this HSLColor as an object with h,
721    * s, v, and a properties. h is in the range [0,360), s and v are in the range
722    * [0,100], and a is in the range [0,1].
723    */
724   this.getHSV = function(){
725
726     // calculate the HSV components if necessary
727     if (hsv == null) calculateHSV();
728
729     // return the HSV components
730     return {
731       'h' : hsv.h,
732       's' : hsv.s,
733       'v' : hsv.v,
734       'a' : alpha
735     };
736
737   };
738
739   /**
740    * @returns the HSL and alpha components of this HSLColor as an object with h,
741    * s, l, and a properties. h is in the range [0,360), s and l are in the range
742    * [0,100], and a is in the range [0,1].
743    */
744   this.getHSL = function(){
745
746     // return the HSL components
747     return {
748       'h' : hsl.h,
749       's' : hsl.s,
750       'l' : hsl.l,
751       'a' : alpha
752     };
753
754   };
755
756 }
757 Roo.lib.HSLColor.prototype = new Roo.lib.Color();