]> git.openstreetmap.org Git - rails.git/blob - public/lib/Rico/Color.js
Can now run tests that use composite_primary_keys in the fixtures. Adding a new test...
[rails.git] / public / lib / Rico / Color.js
1 Rico.Color = Class.create();
2
3 Rico.Color.prototype = {
4
5    initialize: function(red, green, blue) {
6       this.rgb = { r: red, g : green, b : blue };
7    },
8
9    setRed: function(r) {
10       this.rgb.r = r;
11    },
12
13    setGreen: function(g) {
14       this.rgb.g = g;
15    },
16
17    setBlue: function(b) {
18       this.rgb.b = b;
19    },
20
21    setHue: function(h) {
22
23       // get an HSB model, and set the new hue...
24       var hsb = this.asHSB();
25       hsb.h = h;
26
27       // convert back to RGB...
28       this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
29    },
30
31    setSaturation: function(s) {
32       // get an HSB model, and set the new hue...
33       var hsb = this.asHSB();
34       hsb.s = s;
35
36       // convert back to RGB and set values...
37       this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
38    },
39
40    setBrightness: function(b) {
41       // get an HSB model, and set the new hue...
42       var hsb = this.asHSB();
43       hsb.b = b;
44
45       // convert back to RGB and set values...
46       this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
47    },
48
49    darken: function(percent) {
50       var hsb  = this.asHSB();
51       this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
52    },
53
54    brighten: function(percent) {
55       var hsb  = this.asHSB();
56       this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
57    },
58
59    blend: function(other) {
60       this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
61       this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
62       this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
63    },
64
65    isBright: function() {
66       var hsb = this.asHSB();
67       return this.asHSB().b > 0.5;
68    },
69
70    isDark: function() {
71       return ! this.isBright();
72    },
73
74    asRGB: function() {
75       return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
76    },
77
78    asHex: function() {
79       return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
80    },
81
82    asHSB: function() {
83       return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
84    },
85
86    toString: function() {
87       return this.asHex();
88    }
89
90 };
91
92 Rico.Color.createFromHex = function(hexCode) {
93   if(hexCode.length==4) {
94     var shortHexCode = hexCode; 
95     var hexCode = '#';
96     for(var i=1;i<4;i++) hexCode += (shortHexCode.charAt(i) + 
97 shortHexCode.charAt(i));
98   }
99    if ( hexCode.indexOf('#') == 0 )
100       hexCode = hexCode.substring(1);
101    var red   = hexCode.substring(0,2);
102    var green = hexCode.substring(2,4);
103    var blue  = hexCode.substring(4,6);
104    return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
105 }
106
107 /**
108  * Factory method for creating a color from the background of
109  * an HTML element.
110  */
111 Rico.Color.createColorFromBackground = function(elem) {
112
113    var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");
114
115    if ( actualColor == "transparent" && elem.parentNode )
116       return Rico.Color.createColorFromBackground(elem.parentNode);
117
118    if ( actualColor == null )
119       return new Rico.Color(255,255,255);
120
121    if ( actualColor.indexOf("rgb(") == 0 ) {
122       var colors = actualColor.substring(4, actualColor.length - 1 );
123       var colorArray = colors.split(",");
124       return new Rico.Color( parseInt( colorArray[0] ),
125                             parseInt( colorArray[1] ),
126                             parseInt( colorArray[2] )  );
127
128    }
129    else if ( actualColor.indexOf("#") == 0 ) {
130       return Rico.Color.createFromHex(actualColor);
131    }
132    else
133       return new Rico.Color(255,255,255);
134 }
135
136 Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
137
138    var red   = 0;
139     var green = 0;
140     var blue  = 0;
141
142    if (saturation == 0) {
143       red = parseInt(brightness * 255.0 + 0.5);
144        green = red;
145        blue = red;
146     }
147     else {
148       var h = (hue - Math.floor(hue)) * 6.0;
149       var f = h - Math.floor(h);
150       var p = brightness * (1.0 - saturation);
151       var q = brightness * (1.0 - saturation * f);
152       var t = brightness * (1.0 - (saturation * (1.0 - f)));
153
154       switch (parseInt(h)) {
155          case 0:
156             red   = (brightness * 255.0 + 0.5);
157             green = (t * 255.0 + 0.5);
158             blue  = (p * 255.0 + 0.5);
159             break;
160          case 1:
161             red   = (q * 255.0 + 0.5);
162             green = (brightness * 255.0 + 0.5);
163             blue  = (p * 255.0 + 0.5);
164             break;
165          case 2:
166             red   = (p * 255.0 + 0.5);
167             green = (brightness * 255.0 + 0.5);
168             blue  = (t * 255.0 + 0.5);
169             break;
170          case 3:
171             red   = (p * 255.0 + 0.5);
172             green = (q * 255.0 + 0.5);
173             blue  = (brightness * 255.0 + 0.5);
174             break;
175          case 4:
176             red   = (t * 255.0 + 0.5);
177             green = (p * 255.0 + 0.5);
178             blue  = (brightness * 255.0 + 0.5);
179             break;
180           case 5:
181             red   = (brightness * 255.0 + 0.5);
182             green = (p * 255.0 + 0.5);
183             blue  = (q * 255.0 + 0.5);
184             break;
185         }
186     }
187
188    return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
189 }
190
191 Rico.Color.RGBtoHSB = function(r, g, b) {
192
193    var hue;
194    var saturation;
195    var brightness;
196
197    var cmax = (r > g) ? r : g;
198    if (b > cmax)
199       cmax = b;
200
201    var cmin = (r < g) ? r : g;
202    if (b < cmin)
203       cmin = b;
204
205    brightness = cmax / 255.0;
206    if (cmax != 0)
207       saturation = (cmax - cmin)/cmax;
208    else
209       saturation = 0;
210
211    if (saturation == 0)
212       hue = 0;
213    else {
214       var redc   = (cmax - r)/(cmax - cmin);
215         var greenc = (cmax - g)/(cmax - cmin);
216         var bluec  = (cmax - b)/(cmax - cmin);
217
218         if (r == cmax)
219            hue = bluec - greenc;
220         else if (g == cmax)
221            hue = 2.0 + redc - bluec;
222       else
223            hue = 4.0 + greenc - redc;
224
225         hue = hue / 6.0;
226         if (hue < 0)
227            hue = hue + 1.0;
228    }
229
230    return { h : hue, s : saturation, b : brightness };
231 }
232