testing/mochitest/MochiKit/Color.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /***
michael@0 2
michael@0 3 MochiKit.Color 1.4
michael@0 4
michael@0 5 See <http://mochikit.com/> for documentation, downloads, license, etc.
michael@0 6
michael@0 7 (c) 2005 Bob Ippolito and others. All rights Reserved.
michael@0 8
michael@0 9 ***/
michael@0 10
michael@0 11 if (typeof(dojo) != 'undefined') {
michael@0 12 dojo.provide('MochiKit.Color');
michael@0 13 dojo.require('MochiKit.Base');
michael@0 14 dojo.require('MochiKit.DOM');
michael@0 15 dojo.require('MochiKit.Style');
michael@0 16 }
michael@0 17
michael@0 18 if (typeof(JSAN) != 'undefined') {
michael@0 19 JSAN.use("MochiKit.Base", []);
michael@0 20 JSAN.use("MochiKit.DOM", []);
michael@0 21 JSAN.use("MochiKit.Style", []);
michael@0 22 }
michael@0 23
michael@0 24 try {
michael@0 25 if (typeof(MochiKit.Base) == 'undefined') {
michael@0 26 throw "";
michael@0 27 }
michael@0 28 } catch (e) {
michael@0 29 throw "MochiKit.Color depends on MochiKit.Base";
michael@0 30 }
michael@0 31
michael@0 32 try {
michael@0 33 if (typeof(MochiKit.Base) == 'undefined') {
michael@0 34 throw "";
michael@0 35 }
michael@0 36 } catch (e) {
michael@0 37 throw "MochiKit.Color depends on MochiKit.DOM";
michael@0 38 }
michael@0 39
michael@0 40 try {
michael@0 41 if (typeof(MochiKit.Base) == 'undefined') {
michael@0 42 throw "";
michael@0 43 }
michael@0 44 } catch (e) {
michael@0 45 throw "MochiKit.Color depends on MochiKit.Style";
michael@0 46 }
michael@0 47
michael@0 48 if (typeof(MochiKit.Color) == "undefined") {
michael@0 49 MochiKit.Color = {};
michael@0 50 }
michael@0 51
michael@0 52 MochiKit.Color.NAME = "MochiKit.Color";
michael@0 53 MochiKit.Color.VERSION = "1.4";
michael@0 54
michael@0 55 MochiKit.Color.__repr__ = function () {
michael@0 56 return "[" + this.NAME + " " + this.VERSION + "]";
michael@0 57 };
michael@0 58
michael@0 59 MochiKit.Color.toString = function () {
michael@0 60 return this.__repr__();
michael@0 61 };
michael@0 62
michael@0 63
michael@0 64 /** @id MochiKit.Color.Color */
michael@0 65 MochiKit.Color.Color = function (red, green, blue, alpha) {
michael@0 66 if (typeof(alpha) == 'undefined' || alpha === null) {
michael@0 67 alpha = 1.0;
michael@0 68 }
michael@0 69 this.rgb = {
michael@0 70 r: red,
michael@0 71 g: green,
michael@0 72 b: blue,
michael@0 73 a: alpha
michael@0 74 };
michael@0 75 };
michael@0 76
michael@0 77
michael@0 78 // Prototype methods
michael@0 79
michael@0 80 MochiKit.Color.Color.prototype = {
michael@0 81
michael@0 82 __class__: MochiKit.Color.Color,
michael@0 83
michael@0 84 /** @id MochiKit.Color.Color.prototype.colorWithAlpha */
michael@0 85 colorWithAlpha: function (alpha) {
michael@0 86 var rgb = this.rgb;
michael@0 87 var m = MochiKit.Color;
michael@0 88 return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha);
michael@0 89 },
michael@0 90
michael@0 91 /** @id MochiKit.Color.Color.prototype.colorWithHue */
michael@0 92 colorWithHue: function (hue) {
michael@0 93 // get an HSL model, and set the new hue...
michael@0 94 var hsl = this.asHSL();
michael@0 95 hsl.h = hue;
michael@0 96 var m = MochiKit.Color;
michael@0 97 // convert back to RGB...
michael@0 98 return m.Color.fromHSL(hsl);
michael@0 99 },
michael@0 100
michael@0 101 /** @id MochiKit.Color.Color.prototype.colorWithSaturation */
michael@0 102 colorWithSaturation: function (saturation) {
michael@0 103 // get an HSL model, and set the new hue...
michael@0 104 var hsl = this.asHSL();
michael@0 105 hsl.s = saturation;
michael@0 106 var m = MochiKit.Color;
michael@0 107 // convert back to RGB...
michael@0 108 return m.Color.fromHSL(hsl);
michael@0 109 },
michael@0 110
michael@0 111 /** @id MochiKit.Color.Color.prototype.colorWithLightness */
michael@0 112 colorWithLightness: function (lightness) {
michael@0 113 // get an HSL model, and set the new hue...
michael@0 114 var hsl = this.asHSL();
michael@0 115 hsl.l = lightness;
michael@0 116 var m = MochiKit.Color;
michael@0 117 // convert back to RGB...
michael@0 118 return m.Color.fromHSL(hsl);
michael@0 119 },
michael@0 120
michael@0 121 /** @id MochiKit.Color.Color.prototype.darkerColorWithLevel */
michael@0 122 darkerColorWithLevel: function (level) {
michael@0 123 var hsl = this.asHSL();
michael@0 124 hsl.l = Math.max(hsl.l - level, 0);
michael@0 125 var m = MochiKit.Color;
michael@0 126 return m.Color.fromHSL(hsl);
michael@0 127 },
michael@0 128
michael@0 129 /** @id MochiKit.Color.Color.prototype.lighterColorWithLevel */
michael@0 130 lighterColorWithLevel: function (level) {
michael@0 131 var hsl = this.asHSL();
michael@0 132 hsl.l = Math.min(hsl.l + level, 1);
michael@0 133 var m = MochiKit.Color;
michael@0 134 return m.Color.fromHSL(hsl);
michael@0 135 },
michael@0 136
michael@0 137 /** @id MochiKit.Color.Color.prototype.blendedColor */
michael@0 138 blendedColor: function (other, /* optional */ fraction) {
michael@0 139 if (typeof(fraction) == 'undefined' || fraction === null) {
michael@0 140 fraction = 0.5;
michael@0 141 }
michael@0 142 var sf = 1.0 - fraction;
michael@0 143 var s = this.rgb;
michael@0 144 var d = other.rgb;
michael@0 145 var df = fraction;
michael@0 146 return MochiKit.Color.Color.fromRGB(
michael@0 147 (s.r * sf) + (d.r * df),
michael@0 148 (s.g * sf) + (d.g * df),
michael@0 149 (s.b * sf) + (d.b * df),
michael@0 150 (s.a * sf) + (d.a * df)
michael@0 151 );
michael@0 152 },
michael@0 153
michael@0 154 /** @id MochiKit.Color.Color.prototype.compareRGB */
michael@0 155 compareRGB: function (other) {
michael@0 156 var a = this.asRGB();
michael@0 157 var b = other.asRGB();
michael@0 158 return MochiKit.Base.compare(
michael@0 159 [a.r, a.g, a.b, a.a],
michael@0 160 [b.r, b.g, b.b, b.a]
michael@0 161 );
michael@0 162 },
michael@0 163
michael@0 164 /** @id MochiKit.Color.Color.prototype.isLight */
michael@0 165 isLight: function () {
michael@0 166 return this.asHSL().b > 0.5;
michael@0 167 },
michael@0 168
michael@0 169 /** @id MochiKit.Color.Color.prototype.isDark */
michael@0 170 isDark: function () {
michael@0 171 return (!this.isLight());
michael@0 172 },
michael@0 173
michael@0 174 /** @id MochiKit.Color.Color.prototype.toHSLString */
michael@0 175 toHSLString: function () {
michael@0 176 var c = this.asHSL();
michael@0 177 var ccc = MochiKit.Color.clampColorComponent;
michael@0 178 var rval = this._hslString;
michael@0 179 if (!rval) {
michael@0 180 var mid = (
michael@0 181 ccc(c.h, 360).toFixed(0)
michael@0 182 + "," + ccc(c.s, 100).toPrecision(4) + "%"
michael@0 183 + "," + ccc(c.l, 100).toPrecision(4) + "%"
michael@0 184 );
michael@0 185 var a = c.a;
michael@0 186 if (a >= 1) {
michael@0 187 a = 1;
michael@0 188 rval = "hsl(" + mid + ")";
michael@0 189 } else {
michael@0 190 if (a <= 0) {
michael@0 191 a = 0;
michael@0 192 }
michael@0 193 rval = "hsla(" + mid + "," + a + ")";
michael@0 194 }
michael@0 195 this._hslString = rval;
michael@0 196 }
michael@0 197 return rval;
michael@0 198 },
michael@0 199
michael@0 200 /** @id MochiKit.Color.Color.prototype.toRGBString */
michael@0 201 toRGBString: function () {
michael@0 202 var c = this.rgb;
michael@0 203 var ccc = MochiKit.Color.clampColorComponent;
michael@0 204 var rval = this._rgbString;
michael@0 205 if (!rval) {
michael@0 206 var mid = (
michael@0 207 ccc(c.r, 255).toFixed(0)
michael@0 208 + "," + ccc(c.g, 255).toFixed(0)
michael@0 209 + "," + ccc(c.b, 255).toFixed(0)
michael@0 210 );
michael@0 211 if (c.a != 1) {
michael@0 212 rval = "rgba(" + mid + "," + c.a + ")";
michael@0 213 } else {
michael@0 214 rval = "rgb(" + mid + ")";
michael@0 215 }
michael@0 216 this._rgbString = rval;
michael@0 217 }
michael@0 218 return rval;
michael@0 219 },
michael@0 220
michael@0 221 /** @id MochiKit.Color.Color.prototype.asRGB */
michael@0 222 asRGB: function () {
michael@0 223 return MochiKit.Base.clone(this.rgb);
michael@0 224 },
michael@0 225
michael@0 226 /** @id MochiKit.Color.Color.prototype.toHexString */
michael@0 227 toHexString: function () {
michael@0 228 var m = MochiKit.Color;
michael@0 229 var c = this.rgb;
michael@0 230 var ccc = MochiKit.Color.clampColorComponent;
michael@0 231 var rval = this._hexString;
michael@0 232 if (!rval) {
michael@0 233 rval = ("#" +
michael@0 234 m.toColorPart(ccc(c.r, 255)) +
michael@0 235 m.toColorPart(ccc(c.g, 255)) +
michael@0 236 m.toColorPart(ccc(c.b, 255))
michael@0 237 );
michael@0 238 this._hexString = rval;
michael@0 239 }
michael@0 240 return rval;
michael@0 241 },
michael@0 242
michael@0 243 /** @id MochiKit.Color.Color.prototype.asHSV */
michael@0 244 asHSV: function () {
michael@0 245 var hsv = this.hsv;
michael@0 246 var c = this.rgb;
michael@0 247 if (typeof(hsv) == 'undefined' || hsv === null) {
michael@0 248 hsv = MochiKit.Color.rgbToHSV(this.rgb);
michael@0 249 this.hsv = hsv;
michael@0 250 }
michael@0 251 return MochiKit.Base.clone(hsv);
michael@0 252 },
michael@0 253
michael@0 254 /** @id MochiKit.Color.Color.prototype.asHSL */
michael@0 255 asHSL: function () {
michael@0 256 var hsl = this.hsl;
michael@0 257 var c = this.rgb;
michael@0 258 if (typeof(hsl) == 'undefined' || hsl === null) {
michael@0 259 hsl = MochiKit.Color.rgbToHSL(this.rgb);
michael@0 260 this.hsl = hsl;
michael@0 261 }
michael@0 262 return MochiKit.Base.clone(hsl);
michael@0 263 },
michael@0 264
michael@0 265 /** @id MochiKit.Color.Color.prototype.toString */
michael@0 266 toString: function () {
michael@0 267 return this.toRGBString();
michael@0 268 },
michael@0 269
michael@0 270 /** @id MochiKit.Color.Color.prototype.repr */
michael@0 271 repr: function () {
michael@0 272 var c = this.rgb;
michael@0 273 var col = [c.r, c.g, c.b, c.a];
michael@0 274 return this.__class__.NAME + "(" + col.join(", ") + ")";
michael@0 275 }
michael@0 276
michael@0 277 };
michael@0 278
michael@0 279 // Constructor methods
michael@0 280
michael@0 281 MochiKit.Base.update(MochiKit.Color.Color, {
michael@0 282 /** @id MochiKit.Color.Color.fromRGB */
michael@0 283 fromRGB: function (red, green, blue, alpha) {
michael@0 284 // designated initializer
michael@0 285 var Color = MochiKit.Color.Color;
michael@0 286 if (arguments.length == 1) {
michael@0 287 var rgb = red;
michael@0 288 red = rgb.r;
michael@0 289 green = rgb.g;
michael@0 290 blue = rgb.b;
michael@0 291 if (typeof(rgb.a) == 'undefined') {
michael@0 292 alpha = undefined;
michael@0 293 } else {
michael@0 294 alpha = rgb.a;
michael@0 295 }
michael@0 296 }
michael@0 297 return new Color(red, green, blue, alpha);
michael@0 298 },
michael@0 299
michael@0 300 /** @id MochiKit.Color.Color.fromHSL */
michael@0 301 fromHSL: function (hue, saturation, lightness, alpha) {
michael@0 302 var m = MochiKit.Color;
michael@0 303 return m.Color.fromRGB(m.hslToRGB.apply(m, arguments));
michael@0 304 },
michael@0 305
michael@0 306 /** @id MochiKit.Color.Color.fromHSV */
michael@0 307 fromHSV: function (hue, saturation, value, alpha) {
michael@0 308 var m = MochiKit.Color;
michael@0 309 return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments));
michael@0 310 },
michael@0 311
michael@0 312 /** @id MochiKit.Color.Color.fromName */
michael@0 313 fromName: function (name) {
michael@0 314 var Color = MochiKit.Color.Color;
michael@0 315 // Opera 9 seems to "quote" named colors(?!)
michael@0 316 if (name.charAt(0) == '"') {
michael@0 317 name = name.substr(1, name.length - 2);
michael@0 318 }
michael@0 319 var htmlColor = Color._namedColors[name.toLowerCase()];
michael@0 320 if (typeof(htmlColor) == 'string') {
michael@0 321 return Color.fromHexString(htmlColor);
michael@0 322 } else if (name == "transparent") {
michael@0 323 return Color.transparentColor();
michael@0 324 }
michael@0 325 return null;
michael@0 326 },
michael@0 327
michael@0 328 /** @id MochiKit.Color.Color.fromString */
michael@0 329 fromString: function (colorString) {
michael@0 330 var self = MochiKit.Color.Color;
michael@0 331 var three = colorString.substr(0, 3);
michael@0 332 if (three == "rgb") {
michael@0 333 return self.fromRGBString(colorString);
michael@0 334 } else if (three == "hsl") {
michael@0 335 return self.fromHSLString(colorString);
michael@0 336 } else if (colorString.charAt(0) == "#") {
michael@0 337 return self.fromHexString(colorString);
michael@0 338 }
michael@0 339 return self.fromName(colorString);
michael@0 340 },
michael@0 341
michael@0 342
michael@0 343 /** @id MochiKit.Color.Color.fromHexString */
michael@0 344 fromHexString: function (hexCode) {
michael@0 345 if (hexCode.charAt(0) == '#') {
michael@0 346 hexCode = hexCode.substring(1);
michael@0 347 }
michael@0 348 var components = [];
michael@0 349 var i, hex;
michael@0 350 if (hexCode.length == 3) {
michael@0 351 for (i = 0; i < 3; i++) {
michael@0 352 hex = hexCode.substr(i, 1);
michael@0 353 components.push(parseInt(hex + hex, 16) / 255.0);
michael@0 354 }
michael@0 355 } else {
michael@0 356 for (i = 0; i < 6; i += 2) {
michael@0 357 hex = hexCode.substr(i, 2);
michael@0 358 components.push(parseInt(hex, 16) / 255.0);
michael@0 359 }
michael@0 360 }
michael@0 361 var Color = MochiKit.Color.Color;
michael@0 362 return Color.fromRGB.apply(Color, components);
michael@0 363 },
michael@0 364
michael@0 365
michael@0 366 _fromColorString: function (pre, method, scales, colorCode) {
michael@0 367 // parses either HSL or RGB
michael@0 368 if (colorCode.indexOf(pre) === 0) {
michael@0 369 colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1);
michael@0 370 }
michael@0 371 var colorChunks = colorCode.split(/\s*,\s*/);
michael@0 372 var colorFloats = [];
michael@0 373 for (var i = 0; i < colorChunks.length; i++) {
michael@0 374 var c = colorChunks[i];
michael@0 375 var val;
michael@0 376 var three = c.substring(c.length - 3);
michael@0 377 if (c.charAt(c.length - 1) == '%') {
michael@0 378 val = 0.01 * parseFloat(c.substring(0, c.length - 1));
michael@0 379 } else if (three == "deg") {
michael@0 380 val = parseFloat(c) / 360.0;
michael@0 381 } else if (three == "rad") {
michael@0 382 val = parseFloat(c) / (Math.PI * 2);
michael@0 383 } else {
michael@0 384 val = scales[i] * parseFloat(c);
michael@0 385 }
michael@0 386 colorFloats.push(val);
michael@0 387 }
michael@0 388 return this[method].apply(this, colorFloats);
michael@0 389 },
michael@0 390
michael@0 391 /** @id MochiKit.Color.Color.fromComputedStyle */
michael@0 392 fromComputedStyle: function (elem, style) {
michael@0 393 var d = MochiKit.DOM;
michael@0 394 var cls = MochiKit.Color.Color;
michael@0 395 for (elem = d.getElement(elem); elem; elem = elem.parentNode) {
michael@0 396 var actualColor = MochiKit.Style.computedStyle.apply(d, arguments);
michael@0 397 if (!actualColor) {
michael@0 398 continue;
michael@0 399 }
michael@0 400 var color = cls.fromString(actualColor);
michael@0 401 if (!color) {
michael@0 402 break;
michael@0 403 }
michael@0 404 if (color.asRGB().a > 0) {
michael@0 405 return color;
michael@0 406 }
michael@0 407 }
michael@0 408 return null;
michael@0 409 },
michael@0 410
michael@0 411 /** @id MochiKit.Color.Color.fromBackground */
michael@0 412 fromBackground: function (elem) {
michael@0 413 var cls = MochiKit.Color.Color;
michael@0 414 return cls.fromComputedStyle(
michael@0 415 elem, "backgroundColor", "background-color") || cls.whiteColor();
michael@0 416 },
michael@0 417
michael@0 418 /** @id MochiKit.Color.Color.fromText */
michael@0 419 fromText: function (elem) {
michael@0 420 var cls = MochiKit.Color.Color;
michael@0 421 return cls.fromComputedStyle(
michael@0 422 elem, "color", "color") || cls.blackColor();
michael@0 423 },
michael@0 424
michael@0 425 /** @id MochiKit.Color.Color.namedColors */
michael@0 426 namedColors: function () {
michael@0 427 return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
michael@0 428 }
michael@0 429 });
michael@0 430
michael@0 431
michael@0 432 // Module level functions
michael@0 433
michael@0 434 MochiKit.Base.update(MochiKit.Color, {
michael@0 435 /** @id MochiKit.Color.clampColorComponent */
michael@0 436 clampColorComponent: function (v, scale) {
michael@0 437 v *= scale;
michael@0 438 if (v < 0) {
michael@0 439 return 0;
michael@0 440 } else if (v > scale) {
michael@0 441 return scale;
michael@0 442 } else {
michael@0 443 return v;
michael@0 444 }
michael@0 445 },
michael@0 446
michael@0 447 _hslValue: function (n1, n2, hue) {
michael@0 448 if (hue > 6.0) {
michael@0 449 hue -= 6.0;
michael@0 450 } else if (hue < 0.0) {
michael@0 451 hue += 6.0;
michael@0 452 }
michael@0 453 var val;
michael@0 454 if (hue < 1.0) {
michael@0 455 val = n1 + (n2 - n1) * hue;
michael@0 456 } else if (hue < 3.0) {
michael@0 457 val = n2;
michael@0 458 } else if (hue < 4.0) {
michael@0 459 val = n1 + (n2 - n1) * (4.0 - hue);
michael@0 460 } else {
michael@0 461 val = n1;
michael@0 462 }
michael@0 463 return val;
michael@0 464 },
michael@0 465
michael@0 466 /** @id MochiKit.Color.hsvToRGB */
michael@0 467 hsvToRGB: function (hue, saturation, value, alpha) {
michael@0 468 if (arguments.length == 1) {
michael@0 469 var hsv = hue;
michael@0 470 hue = hsv.h;
michael@0 471 saturation = hsv.s;
michael@0 472 value = hsv.v;
michael@0 473 alpha = hsv.a;
michael@0 474 }
michael@0 475 var red;
michael@0 476 var green;
michael@0 477 var blue;
michael@0 478 if (saturation === 0) {
michael@0 479 red = 0;
michael@0 480 green = 0;
michael@0 481 blue = 0;
michael@0 482 } else {
michael@0 483 var i = Math.floor(hue * 6);
michael@0 484 var f = (hue * 6) - i;
michael@0 485 var p = value * (1 - saturation);
michael@0 486 var q = value * (1 - (saturation * f));
michael@0 487 var t = value * (1 - (saturation * (1 - f)));
michael@0 488 switch (i) {
michael@0 489 case 1: red = q; green = value; blue = p; break;
michael@0 490 case 2: red = p; green = value; blue = t; break;
michael@0 491 case 3: red = p; green = q; blue = value; break;
michael@0 492 case 4: red = t; green = p; blue = value; break;
michael@0 493 case 5: red = value; green = p; blue = q; break;
michael@0 494 case 6: // fall through
michael@0 495 case 0: red = value; green = t; blue = p; break;
michael@0 496 }
michael@0 497 }
michael@0 498 return {
michael@0 499 r: red,
michael@0 500 g: green,
michael@0 501 b: blue,
michael@0 502 a: alpha
michael@0 503 };
michael@0 504 },
michael@0 505
michael@0 506 /** @id MochiKit.Color.hslToRGB */
michael@0 507 hslToRGB: function (hue, saturation, lightness, alpha) {
michael@0 508 if (arguments.length == 1) {
michael@0 509 var hsl = hue;
michael@0 510 hue = hsl.h;
michael@0 511 saturation = hsl.s;
michael@0 512 lightness = hsl.l;
michael@0 513 alpha = hsl.a;
michael@0 514 }
michael@0 515 var red;
michael@0 516 var green;
michael@0 517 var blue;
michael@0 518 if (saturation === 0) {
michael@0 519 red = lightness;
michael@0 520 green = lightness;
michael@0 521 blue = lightness;
michael@0 522 } else {
michael@0 523 var m2;
michael@0 524 if (lightness <= 0.5) {
michael@0 525 m2 = lightness * (1.0 + saturation);
michael@0 526 } else {
michael@0 527 m2 = lightness + saturation - (lightness * saturation);
michael@0 528 }
michael@0 529 var m1 = (2.0 * lightness) - m2;
michael@0 530 var f = MochiKit.Color._hslValue;
michael@0 531 var h6 = hue * 6.0;
michael@0 532 red = f(m1, m2, h6 + 2);
michael@0 533 green = f(m1, m2, h6);
michael@0 534 blue = f(m1, m2, h6 - 2);
michael@0 535 }
michael@0 536 return {
michael@0 537 r: red,
michael@0 538 g: green,
michael@0 539 b: blue,
michael@0 540 a: alpha
michael@0 541 };
michael@0 542 },
michael@0 543
michael@0 544 /** @id MochiKit.Color.rgbToHSV */
michael@0 545 rgbToHSV: function (red, green, blue, alpha) {
michael@0 546 if (arguments.length == 1) {
michael@0 547 var rgb = red;
michael@0 548 red = rgb.r;
michael@0 549 green = rgb.g;
michael@0 550 blue = rgb.b;
michael@0 551 alpha = rgb.a;
michael@0 552 }
michael@0 553 var max = Math.max(Math.max(red, green), blue);
michael@0 554 var min = Math.min(Math.min(red, green), blue);
michael@0 555 var hue;
michael@0 556 var saturation;
michael@0 557 var value = max;
michael@0 558 if (min == max) {
michael@0 559 hue = 0;
michael@0 560 saturation = 0;
michael@0 561 } else {
michael@0 562 var delta = (max - min);
michael@0 563 saturation = delta / max;
michael@0 564
michael@0 565 if (red == max) {
michael@0 566 hue = (green - blue) / delta;
michael@0 567 } else if (green == max) {
michael@0 568 hue = 2 + ((blue - red) / delta);
michael@0 569 } else {
michael@0 570 hue = 4 + ((red - green) / delta);
michael@0 571 }
michael@0 572 hue /= 6;
michael@0 573 if (hue < 0) {
michael@0 574 hue += 1;
michael@0 575 }
michael@0 576 if (hue > 1) {
michael@0 577 hue -= 1;
michael@0 578 }
michael@0 579 }
michael@0 580 return {
michael@0 581 h: hue,
michael@0 582 s: saturation,
michael@0 583 v: value,
michael@0 584 a: alpha
michael@0 585 };
michael@0 586 },
michael@0 587
michael@0 588 /** @id MochiKit.Color.rgbToHSL */
michael@0 589 rgbToHSL: function (red, green, blue, alpha) {
michael@0 590 if (arguments.length == 1) {
michael@0 591 var rgb = red;
michael@0 592 red = rgb.r;
michael@0 593 green = rgb.g;
michael@0 594 blue = rgb.b;
michael@0 595 alpha = rgb.a;
michael@0 596 }
michael@0 597 var max = Math.max(red, Math.max(green, blue));
michael@0 598 var min = Math.min(red, Math.min(green, blue));
michael@0 599 var hue;
michael@0 600 var saturation;
michael@0 601 var lightness = (max + min) / 2.0;
michael@0 602 var delta = max - min;
michael@0 603 if (delta === 0) {
michael@0 604 hue = 0;
michael@0 605 saturation = 0;
michael@0 606 } else {
michael@0 607 if (lightness <= 0.5) {
michael@0 608 saturation = delta / (max + min);
michael@0 609 } else {
michael@0 610 saturation = delta / (2 - max - min);
michael@0 611 }
michael@0 612 if (red == max) {
michael@0 613 hue = (green - blue) / delta;
michael@0 614 } else if (green == max) {
michael@0 615 hue = 2 + ((blue - red) / delta);
michael@0 616 } else {
michael@0 617 hue = 4 + ((red - green) / delta);
michael@0 618 }
michael@0 619 hue /= 6;
michael@0 620 if (hue < 0) {
michael@0 621 hue += 1;
michael@0 622 }
michael@0 623 if (hue > 1) {
michael@0 624 hue -= 1;
michael@0 625 }
michael@0 626
michael@0 627 }
michael@0 628 return {
michael@0 629 h: hue,
michael@0 630 s: saturation,
michael@0 631 l: lightness,
michael@0 632 a: alpha
michael@0 633 };
michael@0 634 },
michael@0 635
michael@0 636 /** @id MochiKit.Color.toColorPart */
michael@0 637 toColorPart: function (num) {
michael@0 638 num = Math.round(num);
michael@0 639 var digits = num.toString(16);
michael@0 640 if (num < 16) {
michael@0 641 return '0' + digits;
michael@0 642 }
michael@0 643 return digits;
michael@0 644 },
michael@0 645
michael@0 646 __new__: function () {
michael@0 647 var m = MochiKit.Base;
michael@0 648 /** @id MochiKit.Color.fromRGBString */
michael@0 649 this.Color.fromRGBString = m.bind(
michael@0 650 this.Color._fromColorString, this.Color, "rgb", "fromRGB",
michael@0 651 [1.0/255.0, 1.0/255.0, 1.0/255.0, 1]
michael@0 652 );
michael@0 653 /** @id MochiKit.Color.fromHSLString */
michael@0 654 this.Color.fromHSLString = m.bind(
michael@0 655 this.Color._fromColorString, this.Color, "hsl", "fromHSL",
michael@0 656 [1.0/360.0, 0.01, 0.01, 1]
michael@0 657 );
michael@0 658
michael@0 659 var third = 1.0 / 3.0;
michael@0 660 /** @id MochiKit.Color.colors */
michael@0 661 var colors = {
michael@0 662 // NSColor colors plus transparent
michael@0 663 /** @id MochiKit.Color.blackColor */
michael@0 664 black: [0, 0, 0],
michael@0 665 /** @id MochiKit.Color.blueColor */
michael@0 666 blue: [0, 0, 1],
michael@0 667 /** @id MochiKit.Color.brownColor */
michael@0 668 brown: [0.6, 0.4, 0.2],
michael@0 669 /** @id MochiKit.Color.cyanColor */
michael@0 670 cyan: [0, 1, 1],
michael@0 671 /** @id MochiKit.Color.darkGrayColor */
michael@0 672 darkGray: [third, third, third],
michael@0 673 /** @id MochiKit.Color.grayColor */
michael@0 674 gray: [0.5, 0.5, 0.5],
michael@0 675 /** @id MochiKit.Color.greenColor */
michael@0 676 green: [0, 1, 0],
michael@0 677 /** @id MochiKit.Color.lightGrayColor */
michael@0 678 lightGray: [2 * third, 2 * third, 2 * third],
michael@0 679 /** @id MochiKit.Color.magentaColor */
michael@0 680 magenta: [1, 0, 1],
michael@0 681 /** @id MochiKit.Color.orangeColor */
michael@0 682 orange: [1, 0.5, 0],
michael@0 683 /** @id MochiKit.Color.purpleColor */
michael@0 684 purple: [0.5, 0, 0.5],
michael@0 685 /** @id MochiKit.Color.redColor */
michael@0 686 red: [1, 0, 0],
michael@0 687 /** @id MochiKit.Color.transparentColor */
michael@0 688 transparent: [0, 0, 0, 0],
michael@0 689 /** @id MochiKit.Color.whiteColor */
michael@0 690 white: [1, 1, 1],
michael@0 691 /** @id MochiKit.Color.yellowColor */
michael@0 692 yellow: [1, 1, 0]
michael@0 693 };
michael@0 694
michael@0 695 var makeColor = function (name, r, g, b, a) {
michael@0 696 var rval = this.fromRGB(r, g, b, a);
michael@0 697 this[name] = function () { return rval; };
michael@0 698 return rval;
michael@0 699 };
michael@0 700
michael@0 701 for (var k in colors) {
michael@0 702 var name = k + "Color";
michael@0 703 var bindArgs = m.concat(
michael@0 704 [makeColor, this.Color, name],
michael@0 705 colors[k]
michael@0 706 );
michael@0 707 this.Color[name] = m.bind.apply(null, bindArgs);
michael@0 708 }
michael@0 709
michael@0 710 var isColor = function () {
michael@0 711 for (var i = 0; i < arguments.length; i++) {
michael@0 712 if (!(arguments[i] instanceof Color)) {
michael@0 713 return false;
michael@0 714 }
michael@0 715 }
michael@0 716 return true;
michael@0 717 };
michael@0 718
michael@0 719 var compareColor = function (a, b) {
michael@0 720 return a.compareRGB(b);
michael@0 721 };
michael@0 722
michael@0 723 m.nameFunctions(this);
michael@0 724
michael@0 725 m.registerComparator(this.Color.NAME, isColor, compareColor);
michael@0 726
michael@0 727 this.EXPORT_TAGS = {
michael@0 728 ":common": this.EXPORT,
michael@0 729 ":all": m.concat(this.EXPORT, this.EXPORT_OK)
michael@0 730 };
michael@0 731
michael@0 732 }
michael@0 733 });
michael@0 734
michael@0 735 MochiKit.Color.EXPORT = [
michael@0 736 "Color"
michael@0 737 ];
michael@0 738
michael@0 739 MochiKit.Color.EXPORT_OK = [
michael@0 740 "clampColorComponent",
michael@0 741 "rgbToHSL",
michael@0 742 "hslToRGB",
michael@0 743 "rgbToHSV",
michael@0 744 "hsvToRGB",
michael@0 745 "toColorPart"
michael@0 746 ];
michael@0 747
michael@0 748 MochiKit.Color.__new__();
michael@0 749
michael@0 750 MochiKit.Base._exportSymbols(this, MochiKit.Color);
michael@0 751
michael@0 752 // Full table of css3 X11 colors <http://www.w3.org/TR/css3-color/#X11COLORS>
michael@0 753
michael@0 754 MochiKit.Color.Color._namedColors = {
michael@0 755 aliceblue: "#f0f8ff",
michael@0 756 antiquewhite: "#faebd7",
michael@0 757 aqua: "#00ffff",
michael@0 758 aquamarine: "#7fffd4",
michael@0 759 azure: "#f0ffff",
michael@0 760 beige: "#f5f5dc",
michael@0 761 bisque: "#ffe4c4",
michael@0 762 black: "#000000",
michael@0 763 blanchedalmond: "#ffebcd",
michael@0 764 blue: "#0000ff",
michael@0 765 blueviolet: "#8a2be2",
michael@0 766 brown: "#a52a2a",
michael@0 767 burlywood: "#deb887",
michael@0 768 cadetblue: "#5f9ea0",
michael@0 769 chartreuse: "#7fff00",
michael@0 770 chocolate: "#d2691e",
michael@0 771 coral: "#ff7f50",
michael@0 772 cornflowerblue: "#6495ed",
michael@0 773 cornsilk: "#fff8dc",
michael@0 774 crimson: "#dc143c",
michael@0 775 cyan: "#00ffff",
michael@0 776 darkblue: "#00008b",
michael@0 777 darkcyan: "#008b8b",
michael@0 778 darkgoldenrod: "#b8860b",
michael@0 779 darkgray: "#a9a9a9",
michael@0 780 darkgreen: "#006400",
michael@0 781 darkgrey: "#a9a9a9",
michael@0 782 darkkhaki: "#bdb76b",
michael@0 783 darkmagenta: "#8b008b",
michael@0 784 darkolivegreen: "#556b2f",
michael@0 785 darkorange: "#ff8c00",
michael@0 786 darkorchid: "#9932cc",
michael@0 787 darkred: "#8b0000",
michael@0 788 darksalmon: "#e9967a",
michael@0 789 darkseagreen: "#8fbc8f",
michael@0 790 darkslateblue: "#483d8b",
michael@0 791 darkslategray: "#2f4f4f",
michael@0 792 darkslategrey: "#2f4f4f",
michael@0 793 darkturquoise: "#00ced1",
michael@0 794 darkviolet: "#9400d3",
michael@0 795 deeppink: "#ff1493",
michael@0 796 deepskyblue: "#00bfff",
michael@0 797 dimgray: "#696969",
michael@0 798 dimgrey: "#696969",
michael@0 799 dodgerblue: "#1e90ff",
michael@0 800 firebrick: "#b22222",
michael@0 801 floralwhite: "#fffaf0",
michael@0 802 forestgreen: "#228b22",
michael@0 803 fuchsia: "#ff00ff",
michael@0 804 gainsboro: "#dcdcdc",
michael@0 805 ghostwhite: "#f8f8ff",
michael@0 806 gold: "#ffd700",
michael@0 807 goldenrod: "#daa520",
michael@0 808 gray: "#808080",
michael@0 809 green: "#008000",
michael@0 810 greenyellow: "#adff2f",
michael@0 811 grey: "#808080",
michael@0 812 honeydew: "#f0fff0",
michael@0 813 hotpink: "#ff69b4",
michael@0 814 indianred: "#cd5c5c",
michael@0 815 indigo: "#4b0082",
michael@0 816 ivory: "#fffff0",
michael@0 817 khaki: "#f0e68c",
michael@0 818 lavender: "#e6e6fa",
michael@0 819 lavenderblush: "#fff0f5",
michael@0 820 lawngreen: "#7cfc00",
michael@0 821 lemonchiffon: "#fffacd",
michael@0 822 lightblue: "#add8e6",
michael@0 823 lightcoral: "#f08080",
michael@0 824 lightcyan: "#e0ffff",
michael@0 825 lightgoldenrodyellow: "#fafad2",
michael@0 826 lightgray: "#d3d3d3",
michael@0 827 lightgreen: "#90ee90",
michael@0 828 lightgrey: "#d3d3d3",
michael@0 829 lightpink: "#ffb6c1",
michael@0 830 lightsalmon: "#ffa07a",
michael@0 831 lightseagreen: "#20b2aa",
michael@0 832 lightskyblue: "#87cefa",
michael@0 833 lightslategray: "#778899",
michael@0 834 lightslategrey: "#778899",
michael@0 835 lightsteelblue: "#b0c4de",
michael@0 836 lightyellow: "#ffffe0",
michael@0 837 lime: "#00ff00",
michael@0 838 limegreen: "#32cd32",
michael@0 839 linen: "#faf0e6",
michael@0 840 magenta: "#ff00ff",
michael@0 841 maroon: "#800000",
michael@0 842 mediumaquamarine: "#66cdaa",
michael@0 843 mediumblue: "#0000cd",
michael@0 844 mediumorchid: "#ba55d3",
michael@0 845 mediumpurple: "#9370db",
michael@0 846 mediumseagreen: "#3cb371",
michael@0 847 mediumslateblue: "#7b68ee",
michael@0 848 mediumspringgreen: "#00fa9a",
michael@0 849 mediumturquoise: "#48d1cc",
michael@0 850 mediumvioletred: "#c71585",
michael@0 851 midnightblue: "#191970",
michael@0 852 mintcream: "#f5fffa",
michael@0 853 mistyrose: "#ffe4e1",
michael@0 854 moccasin: "#ffe4b5",
michael@0 855 navajowhite: "#ffdead",
michael@0 856 navy: "#000080",
michael@0 857 oldlace: "#fdf5e6",
michael@0 858 olive: "#808000",
michael@0 859 olivedrab: "#6b8e23",
michael@0 860 orange: "#ffa500",
michael@0 861 orangered: "#ff4500",
michael@0 862 orchid: "#da70d6",
michael@0 863 palegoldenrod: "#eee8aa",
michael@0 864 palegreen: "#98fb98",
michael@0 865 paleturquoise: "#afeeee",
michael@0 866 palevioletred: "#db7093",
michael@0 867 papayawhip: "#ffefd5",
michael@0 868 peachpuff: "#ffdab9",
michael@0 869 peru: "#cd853f",
michael@0 870 pink: "#ffc0cb",
michael@0 871 plum: "#dda0dd",
michael@0 872 powderblue: "#b0e0e6",
michael@0 873 purple: "#800080",
michael@0 874 red: "#ff0000",
michael@0 875 rosybrown: "#bc8f8f",
michael@0 876 royalblue: "#4169e1",
michael@0 877 saddlebrown: "#8b4513",
michael@0 878 salmon: "#fa8072",
michael@0 879 sandybrown: "#f4a460",
michael@0 880 seagreen: "#2e8b57",
michael@0 881 seashell: "#fff5ee",
michael@0 882 sienna: "#a0522d",
michael@0 883 silver: "#c0c0c0",
michael@0 884 skyblue: "#87ceeb",
michael@0 885 slateblue: "#6a5acd",
michael@0 886 slategray: "#708090",
michael@0 887 slategrey: "#708090",
michael@0 888 snow: "#fffafa",
michael@0 889 springgreen: "#00ff7f",
michael@0 890 steelblue: "#4682b4",
michael@0 891 tan: "#d2b48c",
michael@0 892 teal: "#008080",
michael@0 893 thistle: "#d8bfd8",
michael@0 894 tomato: "#ff6347",
michael@0 895 turquoise: "#40e0d0",
michael@0 896 violet: "#ee82ee",
michael@0 897 wheat: "#f5deb3",
michael@0 898 white: "#ffffff",
michael@0 899 whitesmoke: "#f5f5f5",
michael@0 900 yellow: "#ffff00",
michael@0 901 yellowgreen: "#9acd32"
michael@0 902 };

mercurial