]> git.donarmstrong.com Git - x_full.git/blob - .mozilla/firefox/default/extensions/itsalltext@docwhat.gerf.org/chrome/content/Color.js
add itsalltext
[x_full.git] / .mozilla / firefox / default / extensions / itsalltext@docwhat.gerf.org / chrome / content / Color.js
1 /**
2  * Author: Lachlan Hunt
3  * Date: 2005-11-24
4  * Version: 1.0-cgh1
5  * Contributor: Christian G. Höltje
6  *
7  * Licence: Public Domain
8  * Attribution is considered ethical, but not required.
9  *
10  * Usage:
11  *   Color(255, 255, 255);
12  *   Color(255, 255, 255, 1.0);
13  *   Color("#FFF");
14  *   Color("#FFFFFF");
15  *   Color("rgb(255, 255, 255)");
16  *   Color("rgba(255, 255, 255, 1.0)");
17  *   Color("white"); - CSS 2.1 Color keywords only
18  */
19 var Color = function() {
20
21     // CSS 2.1 Colour Keywords
22         var keyword = {
23         maroon   : "#800000",
24         red      : "#ff0000",
25         orange   : "#ffA500",
26         yellow   : "#ffff00",
27         olive    : "#808000",
28         purple   : "#800080",
29         fuchsia  : "#ff00ff",
30         white    : "#ffffff",
31         lime     : "#00ff00",
32         green    : "#008000",
33         navy     : "#000080",
34         blue     : "#0000ff",
35         aqua     : "#00ffff",
36         teal     : "#008080",
37         black    : "#000000",
38         silver   : "#c0c0c0",
39         gray     : "#808080"
40     };
41
42     // CSS Functional Notations and Hex Patterns
43         var func = {
44         rgb   : /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\);?$/,
45         "rgb%"  : /^rgb\(\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\);?$/,
46         rgba  : /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*((?:\d+(?:\.\d+)?)|(?:\.\d+))\s*\);?$/,
47         "rgba%" : /^rgba\(\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,\s*((?:\d+(?:\.\d+)?)|(?:\.\d+))\s*\);?$/,
48         hex3  : /^#([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f]);?$/,
49         hex6  : /^#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2});?$/
50     };
51
52     /**
53          * Clamp the value between the low value and the high value
54      * @private
55          */
56         var clamp = function(value, low, high) {
57                 if (value < low) {
58                         value = low;
59                 }
60                 else if (value > high) {
61                         value = high;
62                 }
63                 return value;
64         };
65
66     /**
67      * @private
68      */
69     var alphaBlend = function(forground, background, alpha) {
70                 return Math.round(background * (1.0 - alpha) + forground * (alpha));
71         };
72
73         /*
74          * Return the colour in hexadecimal notation: #RRGGBB. e.g. #FF9933
75          * @param bg - Optional parameter used for calculating the colour if an alpha value less than 1.0 has been specified.
76          *             If not specified, the alpha value will be ignored.
77          */
78     this.hex = function(bg) {
79         var r, g, b;
80                 if (bg) {
81                         r = alphaBlend(this.red, bg.red, this.alpha);
82                         g = alphaBlend(this.green, bg.green, this.alpha);
83                         b = alphaBlend(this.blue, bg.blue, this.alpha);
84                 } else {
85                         r = this.red;
86                         g = this.green;
87                         b = this.blue;
88                 }
89                 
90                 var strHexR = r.toString(16).toUpperCase();
91                 var strHexG = g.toString(16).toUpperCase();
92                 var strHexB = b.toString(16).toUpperCase();
93         
94                 if (strHexR.length < 2) { strHexR = "0" + strHexR; }
95                 if (strHexG.length < 2) { strHexG = "0" + strHexG; }
96                 if (strHexB.length < 2) { strHexB = "0" + strHexB; }
97         
98                 return "#" + strHexR + strHexG + strHexB;
99         };
100
101     /**
102          * Return the colour in CSS rgb() functional notation, using integers 0-255: rgb(255, 255 255);
103          * @param bg - Optional parameter used for calculating the colour if an alpha value less than 1.0 has been specified.
104          *             If not specified, the alpha value will be ignored.
105          */
106         this.rgb = function(bg) {
107         var r, g, b;
108                 if (bg) {
109                         r = alphaBlend(this.red, bg.red, this.alpha);
110                         g = alphaBlend(this.green, bg.green, this.alpha);
111                         b = alphaBlend(this.blue, bg.blue, this.alpha);
112                 } else {
113                         r = this.red;
114                         g = this.green;
115                         b = this.blue;
116                 }
117         
118                 return "rgb(" + r + ", " + g + ", " + b + ")";
119         };
120
121     /**
122          * Return the colour in CSS rgba() functional notation, using integers 0-255 for color components: rgb(255, 255 255, 1.0);
123          * @param bg - Optional parameter used for calculating the colour if an alpha value less than 1.0 has been specified.
124          *             If not specified, and there is an alpha value, black will be used as the background colour.
125          */
126         this.rgba = function() {
127                 return "rgba(" + this.red + ", " + this.green + ", " + this.blue + ", " + this.alpha + ")";
128         };
129
130     /**
131      * Returns a Color object with the values inverted. Ignores alpha.
132      */
133     this.invert = function() {
134         return new Color("rgb(" + 
135                          (255 - this.red) + ", " + 
136                          (255 - this.green) + ", " + 
137                          (255 - this.blue) + ")");
138     };
139
140     /**
141          * Blend this colour with the colour specified and return a pallet with all the steps in between.
142          * @param color - The colour to blend with
143          * @param steps - The number of steps to take to reach the color.
144          */
145         this.blend = function(color, steps) {
146         var pallet = [];
147         var r, g, b, i;
148       
149         var step = {
150             red   : (alphaBlend(color.red, this.red, color.alpha) - this.red) / steps,
151             green : (alphaBlend(color.green, this.green, color.alpha) - this.green) / steps,
152             blue  : (alphaBlend(color.blue,  this.blue,  color.alpha) - this.blue) / steps
153         };
154         for (i = 0; i < steps + 1; i++) {
155             r = Math.round(this.red   + (step.red * i));
156             g = Math.round(this.green + (step.green * i));
157             b = Math.round(this.blue  + (step.blue * i));
158             pallet.push(new Color(r, g, b));
159         }
160         return pallet;
161         };
162      
163     /**
164          * Constructor function
165          */
166     this.toString = this.hex;
167     
168     var value;
169     var components, pattern;
170     var key, base, m;
171     var r, g, b, a;
172     if (arguments.length >= 3) {
173         /* r, g, b or r, g, b, a */
174         r = arguments[0];
175         g = arguments[1];
176         b = arguments[2];
177         a = arguments[3];
178       
179         this.red   = (!isNaN(r)) ? clamp(r, 0, 255) : 0;
180         this.green = (!isNaN(g)) ? clamp(g, 0, 255) : 0;
181         this.blue  = (!isNaN(b)) ? clamp(b, 0, 255) : 0;
182         this.alpha = (!isNaN(a)) ? clamp(a, 0.0, 1.0) : 1.0;
183     } else if (arguments.length == 1) {
184         /* CSS Colour keyword or value */
185         value = keyword[arguments[0]] ? keyword[arguments[0]] : arguments[0];
186       
187         for (key in func) {
188             if (func[key].test(value)) {
189                 pattern = key;
190             }
191         }
192
193         components = value.match(func[pattern]);
194         base = 10;
195         m = 1; // Multiplier for percentage values
196       
197         switch (pattern) {
198         case "rgb%":
199         case "rgba%":
200             m = 2.55;
201             base = 10;
202             break;
203         case "rgb":
204         case "rgba":
205             base = 10;
206             break;
207         case "hex3":
208             components[1] = components[1] + "" + components[1];
209             components[2] = components[2] + "" + components[2];
210             components[3] = components[3] + "" + components[3];
211             base = 16;
212             break;
213         case "hex6":
214             base = 16;
215             break;
216         default:
217             components = [0, "255", "255", "255", "1.0"];
218         }
219       
220         this.red   = clamp(Math.round(parseInt(components[1],base) * m), 0, 255);
221         this.green = clamp(Math.round(parseInt(components[2],base) * m), 0, 255);
222         this.blue  = clamp(Math.round(parseInt(components[3],base) * m), 0, 255);
223       
224         if (isNaN(components[4])) {
225             this.alpha = 1;
226         } else {
227             this.alpha = clamp(parseFloat("0" + components[4]), 0.0, 1.0);
228         }
229     }
230 };
231