1 /** 2 * @author Dennis Verhoeven 3 * @package Banana.Util 4 * @summary Color helper 5 */ 6 7 /** @namespace Banana.Util.Color */ 8 goog.provide('Banana.Util.Color'); 9 10 11 /** 12 * Helper class for working with colors. 13 * Easy shift from rgb to hsv and modify parameters. 14 * 15 * two ways to create a color class instance 16 * 17 var c1 = new Banana.Util.Color("#444444"); 18 19 var c2 = new Banana.Util.Color(255,255,56); 20 21 * 22 * @param {mixed} p1 hex representation or int red part 23 * @param {int} p2 24 * @param {int} p3 25 * 26 * @constructor 27 * 28 */ 29 Banana.Util.Color = function(p1, p2, p3) 30 { 31 var r; // Red, Green and Blue represent color in RGB space 32 var g; // Values are integers in range of 0..255 33 var b; 34 35 var h; // Hue, Saturation and Value represent color in HSV space 36 var s; // Values are floats in range of 0..1 37 var v; 38 39 /** 40 * 41 * @constructs 42 * @ignore 43 */ 44 var _init = function(obj) 45 { 46 if (typeof(p1)=='string') 47 { 48 obj.setValue(p1); 49 } 50 else if (typeof(p1)=='number') 51 { 52 obj.r=p1; 53 obj.g=p2; 54 obj.b=p3; 55 obj.computeHSV(); 56 } 57 else 58 { 59 obj.r=0; 60 obj.g=0; 61 obj.b=0; 62 obj.computeHSV(); 63 } 64 } 65 66 /** 67 * red part 68 * @return {int} 69 */ 70 this.getR = function() 71 { 72 return this.r; 73 } 74 75 /** 76 * red part 77 * @param {int} value 78 */ 79 this.setR = function(value) 80 { 81 this.r=value; 82 this.computeHSV(); 83 } 84 85 /** 86 * green part 87 * @return {int} 88 */ 89 this.getG = function () 90 { 91 return this.g; 92 } 93 94 /** 95 * green part 96 * @param {int} value 97 */ 98 this.setG = function(value) 99 { 100 this.g=value; 101 this.computeHSV(); 102 } 103 104 /** 105 * blue part 106 * @return {int} 107 */ 108 this.getB = function() 109 { 110 return this.b; 111 } 112 113 /** 114 * blue part 115 * @param {int} value 116 */ 117 this.setB = function(value) 118 { 119 this.b=value; 120 this.computeHSV(); 121 } 122 123 /** 124 * hue part 125 * @return {int} 126 */ 127 this.getH = function () 128 { 129 return this.h; 130 } 131 132 /** 133 * hue part 134 * @param {int} value 135 */ 136 this.setH = function(value) 137 { 138 this.h=value; 139 this.computeRGB(); 140 } 141 142 /** 143 * saturation part 144 * @return {int} 145 */ 146 this.getS = function() 147 { 148 return this.s; 149 } 150 151 /** 152 * saturation part 153 * @param {int} value 154 */ 155 this.setS = function(value) 156 { 157 this.s=value; 158 this.computeRGB(); 159 } 160 161 /** 162 * value part 163 * @return {int} 164 */ 165 this.getV = function() 166 { 167 return this.v; 168 } 169 170 /** 171 * value part 172 * @param {int} value 173 */ 174 this.setV = function(value) 175 { 176 this.v=value; 177 this.computeRGB(); 178 } 179 180 /** 181 * @ignore 182 * @param {int} value 183 * @returns {int} 184 */ 185 var dec2hex = function(value) 186 { 187 return (value<16 ? '0' : '') + value.toString(16); 188 } 189 190 /** 191 * @ignore 192 * @param {int} value 193 * @returns {int} 194 */ 195 var hex2dec = function(value) 196 { 197 return parseInt(value, 16); 198 } 199 200 /** 201 * changes the current colorspace value 202 * @param {mixed} either #xxxxxx or xxx,xxx,xxx format 203 */ 204 this.setValue = function(value) 205 { 206 if (value.substr(0, 1)==='#') 207 { 208 this.r=hex2dec(value.substr(1, 2)); 209 this.g=hex2dec(value.substr(3, 2)); 210 this.b=hex2dec(value.substr(5, 2)); 211 } 212 else 213 { 214 var digits = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(value); 215 this.r=parseInt(digits[1]); 216 this.g=parseInt(digits[2]); 217 this.b=parseInt(digits[3]); 218 } 219 220 this.computeHSV(); 221 } 222 223 /** 224 * @return {String} in #xxxxxx format 225 */ 226 this.getValue = function() 227 { 228 return '#'+dec2hex(this.r)+dec2hex(this.g)+dec2hex(this.b); 229 } 230 231 /** 232 * Computes the hsv values according the current r,g,b values 233 */ 234 this.computeHSV = function() 235 { 236 var r = this.r / 255; 237 var g = this.g / 255; 238 var b = this.b / 255; 239 240 var min = Math.min(r, g, b); 241 var max = Math.max(r, g, b); 242 var delta = max - min; 243 244 var h = 0; 245 var s = 0; 246 var v = max; 247 248 if (max != 0) 249 { 250 s = delta / max; 251 } 252 else 253 { 254 s = 0; 255 h = -1; 256 257 this.h=h; 258 this.s=s; 259 this.v=v; 260 261 return; 262 } 263 264 if (delta) 265 { 266 if (r == max) 267 { 268 h = (g - b) / delta; 269 } 270 else if (g == max) 271 { 272 h = 2 + (b - r) / delta; 273 } 274 else 275 { 276 h = 4 + (r - g) / delta; 277 } 278 } 279 else 280 { 281 h = 0; 282 } 283 284 h *= 60; 285 286 if (h < 0) 287 { 288 h += 360; 289 } 290 291 this.h=h; 292 this.s=s; 293 this.v=v; 294 } 295 296 /** 297 * Computes rgb values according the current h,s,v values 298 */ 299 this.computeRGB = function() 300 { 301 var h = this.h; 302 var s = this.s; 303 var v = this.v; 304 305 var i = 0; 306 var f = 0; 307 var p = 0; 308 var q = 0; 309 var t = 0; 310 var b = 0; 311 var g = 0; 312 313 if (s == 0) 314 { 315 r = g = b = v; 316 317 this.r=Math.round(r * 255); 318 this.g=Math.round(g * 255); 319 this.b=Math.round(b * 255); 320 321 return; 322 } 323 324 h %= 360; 325 h /= 60; 326 i = Math.floor(h); 327 f = h - i; 328 p = v * (1 - s); 329 q = v * (1 - s * f); 330 t = v * (1 - s * (1 - f)); 331 332 switch(i) 333 { 334 case 0: r = v; g = t; b = p; break; 335 case 1: r = q; g = v; b = p; break; 336 case 2: r = p; g = v; b = t; break; 337 case 3: r = p; g = q; b = v; break; 338 case 4: r = t; g = p; b = v; break; 339 default: r = v; g = p; b = q; break; 340 } 341 342 this.r=Math.round(r * 255); 343 this.g=Math.round(g * 255); 344 this.b=Math.round(b * 255); 345 } 346 347 _init(this); 348 }