michael@0: /***
michael@0:
michael@0: MochiKit.Color 1.4
michael@0:
michael@0: See for documentation, downloads, license, etc.
michael@0:
michael@0: (c) 2005 Bob Ippolito and others. All rights Reserved.
michael@0:
michael@0: ***/
michael@0:
michael@0: if (typeof(dojo) != 'undefined') {
michael@0: dojo.provide('MochiKit.Color');
michael@0: dojo.require('MochiKit.Base');
michael@0: dojo.require('MochiKit.DOM');
michael@0: dojo.require('MochiKit.Style');
michael@0: }
michael@0:
michael@0: if (typeof(JSAN) != 'undefined') {
michael@0: JSAN.use("MochiKit.Base", []);
michael@0: JSAN.use("MochiKit.DOM", []);
michael@0: JSAN.use("MochiKit.Style", []);
michael@0: }
michael@0:
michael@0: try {
michael@0: if (typeof(MochiKit.Base) == 'undefined') {
michael@0: throw "";
michael@0: }
michael@0: } catch (e) {
michael@0: throw "MochiKit.Color depends on MochiKit.Base";
michael@0: }
michael@0:
michael@0: try {
michael@0: if (typeof(MochiKit.Base) == 'undefined') {
michael@0: throw "";
michael@0: }
michael@0: } catch (e) {
michael@0: throw "MochiKit.Color depends on MochiKit.DOM";
michael@0: }
michael@0:
michael@0: try {
michael@0: if (typeof(MochiKit.Base) == 'undefined') {
michael@0: throw "";
michael@0: }
michael@0: } catch (e) {
michael@0: throw "MochiKit.Color depends on MochiKit.Style";
michael@0: }
michael@0:
michael@0: if (typeof(MochiKit.Color) == "undefined") {
michael@0: MochiKit.Color = {};
michael@0: }
michael@0:
michael@0: MochiKit.Color.NAME = "MochiKit.Color";
michael@0: MochiKit.Color.VERSION = "1.4";
michael@0:
michael@0: MochiKit.Color.__repr__ = function () {
michael@0: return "[" + this.NAME + " " + this.VERSION + "]";
michael@0: };
michael@0:
michael@0: MochiKit.Color.toString = function () {
michael@0: return this.__repr__();
michael@0: };
michael@0:
michael@0:
michael@0: /** @id MochiKit.Color.Color */
michael@0: MochiKit.Color.Color = function (red, green, blue, alpha) {
michael@0: if (typeof(alpha) == 'undefined' || alpha === null) {
michael@0: alpha = 1.0;
michael@0: }
michael@0: this.rgb = {
michael@0: r: red,
michael@0: g: green,
michael@0: b: blue,
michael@0: a: alpha
michael@0: };
michael@0: };
michael@0:
michael@0:
michael@0: // Prototype methods
michael@0:
michael@0: MochiKit.Color.Color.prototype = {
michael@0:
michael@0: __class__: MochiKit.Color.Color,
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.colorWithAlpha */
michael@0: colorWithAlpha: function (alpha) {
michael@0: var rgb = this.rgb;
michael@0: var m = MochiKit.Color;
michael@0: return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.colorWithHue */
michael@0: colorWithHue: function (hue) {
michael@0: // get an HSL model, and set the new hue...
michael@0: var hsl = this.asHSL();
michael@0: hsl.h = hue;
michael@0: var m = MochiKit.Color;
michael@0: // convert back to RGB...
michael@0: return m.Color.fromHSL(hsl);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.colorWithSaturation */
michael@0: colorWithSaturation: function (saturation) {
michael@0: // get an HSL model, and set the new hue...
michael@0: var hsl = this.asHSL();
michael@0: hsl.s = saturation;
michael@0: var m = MochiKit.Color;
michael@0: // convert back to RGB...
michael@0: return m.Color.fromHSL(hsl);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.colorWithLightness */
michael@0: colorWithLightness: function (lightness) {
michael@0: // get an HSL model, and set the new hue...
michael@0: var hsl = this.asHSL();
michael@0: hsl.l = lightness;
michael@0: var m = MochiKit.Color;
michael@0: // convert back to RGB...
michael@0: return m.Color.fromHSL(hsl);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.darkerColorWithLevel */
michael@0: darkerColorWithLevel: function (level) {
michael@0: var hsl = this.asHSL();
michael@0: hsl.l = Math.max(hsl.l - level, 0);
michael@0: var m = MochiKit.Color;
michael@0: return m.Color.fromHSL(hsl);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.lighterColorWithLevel */
michael@0: lighterColorWithLevel: function (level) {
michael@0: var hsl = this.asHSL();
michael@0: hsl.l = Math.min(hsl.l + level, 1);
michael@0: var m = MochiKit.Color;
michael@0: return m.Color.fromHSL(hsl);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.blendedColor */
michael@0: blendedColor: function (other, /* optional */ fraction) {
michael@0: if (typeof(fraction) == 'undefined' || fraction === null) {
michael@0: fraction = 0.5;
michael@0: }
michael@0: var sf = 1.0 - fraction;
michael@0: var s = this.rgb;
michael@0: var d = other.rgb;
michael@0: var df = fraction;
michael@0: return MochiKit.Color.Color.fromRGB(
michael@0: (s.r * sf) + (d.r * df),
michael@0: (s.g * sf) + (d.g * df),
michael@0: (s.b * sf) + (d.b * df),
michael@0: (s.a * sf) + (d.a * df)
michael@0: );
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.compareRGB */
michael@0: compareRGB: function (other) {
michael@0: var a = this.asRGB();
michael@0: var b = other.asRGB();
michael@0: return MochiKit.Base.compare(
michael@0: [a.r, a.g, a.b, a.a],
michael@0: [b.r, b.g, b.b, b.a]
michael@0: );
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.isLight */
michael@0: isLight: function () {
michael@0: return this.asHSL().b > 0.5;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.isDark */
michael@0: isDark: function () {
michael@0: return (!this.isLight());
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.toHSLString */
michael@0: toHSLString: function () {
michael@0: var c = this.asHSL();
michael@0: var ccc = MochiKit.Color.clampColorComponent;
michael@0: var rval = this._hslString;
michael@0: if (!rval) {
michael@0: var mid = (
michael@0: ccc(c.h, 360).toFixed(0)
michael@0: + "," + ccc(c.s, 100).toPrecision(4) + "%"
michael@0: + "," + ccc(c.l, 100).toPrecision(4) + "%"
michael@0: );
michael@0: var a = c.a;
michael@0: if (a >= 1) {
michael@0: a = 1;
michael@0: rval = "hsl(" + mid + ")";
michael@0: } else {
michael@0: if (a <= 0) {
michael@0: a = 0;
michael@0: }
michael@0: rval = "hsla(" + mid + "," + a + ")";
michael@0: }
michael@0: this._hslString = rval;
michael@0: }
michael@0: return rval;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.toRGBString */
michael@0: toRGBString: function () {
michael@0: var c = this.rgb;
michael@0: var ccc = MochiKit.Color.clampColorComponent;
michael@0: var rval = this._rgbString;
michael@0: if (!rval) {
michael@0: var mid = (
michael@0: ccc(c.r, 255).toFixed(0)
michael@0: + "," + ccc(c.g, 255).toFixed(0)
michael@0: + "," + ccc(c.b, 255).toFixed(0)
michael@0: );
michael@0: if (c.a != 1) {
michael@0: rval = "rgba(" + mid + "," + c.a + ")";
michael@0: } else {
michael@0: rval = "rgb(" + mid + ")";
michael@0: }
michael@0: this._rgbString = rval;
michael@0: }
michael@0: return rval;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.asRGB */
michael@0: asRGB: function () {
michael@0: return MochiKit.Base.clone(this.rgb);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.toHexString */
michael@0: toHexString: function () {
michael@0: var m = MochiKit.Color;
michael@0: var c = this.rgb;
michael@0: var ccc = MochiKit.Color.clampColorComponent;
michael@0: var rval = this._hexString;
michael@0: if (!rval) {
michael@0: rval = ("#" +
michael@0: m.toColorPart(ccc(c.r, 255)) +
michael@0: m.toColorPart(ccc(c.g, 255)) +
michael@0: m.toColorPart(ccc(c.b, 255))
michael@0: );
michael@0: this._hexString = rval;
michael@0: }
michael@0: return rval;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.asHSV */
michael@0: asHSV: function () {
michael@0: var hsv = this.hsv;
michael@0: var c = this.rgb;
michael@0: if (typeof(hsv) == 'undefined' || hsv === null) {
michael@0: hsv = MochiKit.Color.rgbToHSV(this.rgb);
michael@0: this.hsv = hsv;
michael@0: }
michael@0: return MochiKit.Base.clone(hsv);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.asHSL */
michael@0: asHSL: function () {
michael@0: var hsl = this.hsl;
michael@0: var c = this.rgb;
michael@0: if (typeof(hsl) == 'undefined' || hsl === null) {
michael@0: hsl = MochiKit.Color.rgbToHSL(this.rgb);
michael@0: this.hsl = hsl;
michael@0: }
michael@0: return MochiKit.Base.clone(hsl);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.toString */
michael@0: toString: function () {
michael@0: return this.toRGBString();
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.prototype.repr */
michael@0: repr: function () {
michael@0: var c = this.rgb;
michael@0: var col = [c.r, c.g, c.b, c.a];
michael@0: return this.__class__.NAME + "(" + col.join(", ") + ")";
michael@0: }
michael@0:
michael@0: };
michael@0:
michael@0: // Constructor methods
michael@0:
michael@0: MochiKit.Base.update(MochiKit.Color.Color, {
michael@0: /** @id MochiKit.Color.Color.fromRGB */
michael@0: fromRGB: function (red, green, blue, alpha) {
michael@0: // designated initializer
michael@0: var Color = MochiKit.Color.Color;
michael@0: if (arguments.length == 1) {
michael@0: var rgb = red;
michael@0: red = rgb.r;
michael@0: green = rgb.g;
michael@0: blue = rgb.b;
michael@0: if (typeof(rgb.a) == 'undefined') {
michael@0: alpha = undefined;
michael@0: } else {
michael@0: alpha = rgb.a;
michael@0: }
michael@0: }
michael@0: return new Color(red, green, blue, alpha);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromHSL */
michael@0: fromHSL: function (hue, saturation, lightness, alpha) {
michael@0: var m = MochiKit.Color;
michael@0: return m.Color.fromRGB(m.hslToRGB.apply(m, arguments));
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromHSV */
michael@0: fromHSV: function (hue, saturation, value, alpha) {
michael@0: var m = MochiKit.Color;
michael@0: return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments));
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromName */
michael@0: fromName: function (name) {
michael@0: var Color = MochiKit.Color.Color;
michael@0: // Opera 9 seems to "quote" named colors(?!)
michael@0: if (name.charAt(0) == '"') {
michael@0: name = name.substr(1, name.length - 2);
michael@0: }
michael@0: var htmlColor = Color._namedColors[name.toLowerCase()];
michael@0: if (typeof(htmlColor) == 'string') {
michael@0: return Color.fromHexString(htmlColor);
michael@0: } else if (name == "transparent") {
michael@0: return Color.transparentColor();
michael@0: }
michael@0: return null;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromString */
michael@0: fromString: function (colorString) {
michael@0: var self = MochiKit.Color.Color;
michael@0: var three = colorString.substr(0, 3);
michael@0: if (three == "rgb") {
michael@0: return self.fromRGBString(colorString);
michael@0: } else if (three == "hsl") {
michael@0: return self.fromHSLString(colorString);
michael@0: } else if (colorString.charAt(0) == "#") {
michael@0: return self.fromHexString(colorString);
michael@0: }
michael@0: return self.fromName(colorString);
michael@0: },
michael@0:
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromHexString */
michael@0: fromHexString: function (hexCode) {
michael@0: if (hexCode.charAt(0) == '#') {
michael@0: hexCode = hexCode.substring(1);
michael@0: }
michael@0: var components = [];
michael@0: var i, hex;
michael@0: if (hexCode.length == 3) {
michael@0: for (i = 0; i < 3; i++) {
michael@0: hex = hexCode.substr(i, 1);
michael@0: components.push(parseInt(hex + hex, 16) / 255.0);
michael@0: }
michael@0: } else {
michael@0: for (i = 0; i < 6; i += 2) {
michael@0: hex = hexCode.substr(i, 2);
michael@0: components.push(parseInt(hex, 16) / 255.0);
michael@0: }
michael@0: }
michael@0: var Color = MochiKit.Color.Color;
michael@0: return Color.fromRGB.apply(Color, components);
michael@0: },
michael@0:
michael@0:
michael@0: _fromColorString: function (pre, method, scales, colorCode) {
michael@0: // parses either HSL or RGB
michael@0: if (colorCode.indexOf(pre) === 0) {
michael@0: colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1);
michael@0: }
michael@0: var colorChunks = colorCode.split(/\s*,\s*/);
michael@0: var colorFloats = [];
michael@0: for (var i = 0; i < colorChunks.length; i++) {
michael@0: var c = colorChunks[i];
michael@0: var val;
michael@0: var three = c.substring(c.length - 3);
michael@0: if (c.charAt(c.length - 1) == '%') {
michael@0: val = 0.01 * parseFloat(c.substring(0, c.length - 1));
michael@0: } else if (three == "deg") {
michael@0: val = parseFloat(c) / 360.0;
michael@0: } else if (three == "rad") {
michael@0: val = parseFloat(c) / (Math.PI * 2);
michael@0: } else {
michael@0: val = scales[i] * parseFloat(c);
michael@0: }
michael@0: colorFloats.push(val);
michael@0: }
michael@0: return this[method].apply(this, colorFloats);
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromComputedStyle */
michael@0: fromComputedStyle: function (elem, style) {
michael@0: var d = MochiKit.DOM;
michael@0: var cls = MochiKit.Color.Color;
michael@0: for (elem = d.getElement(elem); elem; elem = elem.parentNode) {
michael@0: var actualColor = MochiKit.Style.computedStyle.apply(d, arguments);
michael@0: if (!actualColor) {
michael@0: continue;
michael@0: }
michael@0: var color = cls.fromString(actualColor);
michael@0: if (!color) {
michael@0: break;
michael@0: }
michael@0: if (color.asRGB().a > 0) {
michael@0: return color;
michael@0: }
michael@0: }
michael@0: return null;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromBackground */
michael@0: fromBackground: function (elem) {
michael@0: var cls = MochiKit.Color.Color;
michael@0: return cls.fromComputedStyle(
michael@0: elem, "backgroundColor", "background-color") || cls.whiteColor();
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.fromText */
michael@0: fromText: function (elem) {
michael@0: var cls = MochiKit.Color.Color;
michael@0: return cls.fromComputedStyle(
michael@0: elem, "color", "color") || cls.blackColor();
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.Color.namedColors */
michael@0: namedColors: function () {
michael@0: return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
michael@0: }
michael@0: });
michael@0:
michael@0:
michael@0: // Module level functions
michael@0:
michael@0: MochiKit.Base.update(MochiKit.Color, {
michael@0: /** @id MochiKit.Color.clampColorComponent */
michael@0: clampColorComponent: function (v, scale) {
michael@0: v *= scale;
michael@0: if (v < 0) {
michael@0: return 0;
michael@0: } else if (v > scale) {
michael@0: return scale;
michael@0: } else {
michael@0: return v;
michael@0: }
michael@0: },
michael@0:
michael@0: _hslValue: function (n1, n2, hue) {
michael@0: if (hue > 6.0) {
michael@0: hue -= 6.0;
michael@0: } else if (hue < 0.0) {
michael@0: hue += 6.0;
michael@0: }
michael@0: var val;
michael@0: if (hue < 1.0) {
michael@0: val = n1 + (n2 - n1) * hue;
michael@0: } else if (hue < 3.0) {
michael@0: val = n2;
michael@0: } else if (hue < 4.0) {
michael@0: val = n1 + (n2 - n1) * (4.0 - hue);
michael@0: } else {
michael@0: val = n1;
michael@0: }
michael@0: return val;
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.hsvToRGB */
michael@0: hsvToRGB: function (hue, saturation, value, alpha) {
michael@0: if (arguments.length == 1) {
michael@0: var hsv = hue;
michael@0: hue = hsv.h;
michael@0: saturation = hsv.s;
michael@0: value = hsv.v;
michael@0: alpha = hsv.a;
michael@0: }
michael@0: var red;
michael@0: var green;
michael@0: var blue;
michael@0: if (saturation === 0) {
michael@0: red = 0;
michael@0: green = 0;
michael@0: blue = 0;
michael@0: } else {
michael@0: var i = Math.floor(hue * 6);
michael@0: var f = (hue * 6) - i;
michael@0: var p = value * (1 - saturation);
michael@0: var q = value * (1 - (saturation * f));
michael@0: var t = value * (1 - (saturation * (1 - f)));
michael@0: switch (i) {
michael@0: case 1: red = q; green = value; blue = p; break;
michael@0: case 2: red = p; green = value; blue = t; break;
michael@0: case 3: red = p; green = q; blue = value; break;
michael@0: case 4: red = t; green = p; blue = value; break;
michael@0: case 5: red = value; green = p; blue = q; break;
michael@0: case 6: // fall through
michael@0: case 0: red = value; green = t; blue = p; break;
michael@0: }
michael@0: }
michael@0: return {
michael@0: r: red,
michael@0: g: green,
michael@0: b: blue,
michael@0: a: alpha
michael@0: };
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.hslToRGB */
michael@0: hslToRGB: function (hue, saturation, lightness, alpha) {
michael@0: if (arguments.length == 1) {
michael@0: var hsl = hue;
michael@0: hue = hsl.h;
michael@0: saturation = hsl.s;
michael@0: lightness = hsl.l;
michael@0: alpha = hsl.a;
michael@0: }
michael@0: var red;
michael@0: var green;
michael@0: var blue;
michael@0: if (saturation === 0) {
michael@0: red = lightness;
michael@0: green = lightness;
michael@0: blue = lightness;
michael@0: } else {
michael@0: var m2;
michael@0: if (lightness <= 0.5) {
michael@0: m2 = lightness * (1.0 + saturation);
michael@0: } else {
michael@0: m2 = lightness + saturation - (lightness * saturation);
michael@0: }
michael@0: var m1 = (2.0 * lightness) - m2;
michael@0: var f = MochiKit.Color._hslValue;
michael@0: var h6 = hue * 6.0;
michael@0: red = f(m1, m2, h6 + 2);
michael@0: green = f(m1, m2, h6);
michael@0: blue = f(m1, m2, h6 - 2);
michael@0: }
michael@0: return {
michael@0: r: red,
michael@0: g: green,
michael@0: b: blue,
michael@0: a: alpha
michael@0: };
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.rgbToHSV */
michael@0: rgbToHSV: function (red, green, blue, alpha) {
michael@0: if (arguments.length == 1) {
michael@0: var rgb = red;
michael@0: red = rgb.r;
michael@0: green = rgb.g;
michael@0: blue = rgb.b;
michael@0: alpha = rgb.a;
michael@0: }
michael@0: var max = Math.max(Math.max(red, green), blue);
michael@0: var min = Math.min(Math.min(red, green), blue);
michael@0: var hue;
michael@0: var saturation;
michael@0: var value = max;
michael@0: if (min == max) {
michael@0: hue = 0;
michael@0: saturation = 0;
michael@0: } else {
michael@0: var delta = (max - min);
michael@0: saturation = delta / max;
michael@0:
michael@0: if (red == max) {
michael@0: hue = (green - blue) / delta;
michael@0: } else if (green == max) {
michael@0: hue = 2 + ((blue - red) / delta);
michael@0: } else {
michael@0: hue = 4 + ((red - green) / delta);
michael@0: }
michael@0: hue /= 6;
michael@0: if (hue < 0) {
michael@0: hue += 1;
michael@0: }
michael@0: if (hue > 1) {
michael@0: hue -= 1;
michael@0: }
michael@0: }
michael@0: return {
michael@0: h: hue,
michael@0: s: saturation,
michael@0: v: value,
michael@0: a: alpha
michael@0: };
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.rgbToHSL */
michael@0: rgbToHSL: function (red, green, blue, alpha) {
michael@0: if (arguments.length == 1) {
michael@0: var rgb = red;
michael@0: red = rgb.r;
michael@0: green = rgb.g;
michael@0: blue = rgb.b;
michael@0: alpha = rgb.a;
michael@0: }
michael@0: var max = Math.max(red, Math.max(green, blue));
michael@0: var min = Math.min(red, Math.min(green, blue));
michael@0: var hue;
michael@0: var saturation;
michael@0: var lightness = (max + min) / 2.0;
michael@0: var delta = max - min;
michael@0: if (delta === 0) {
michael@0: hue = 0;
michael@0: saturation = 0;
michael@0: } else {
michael@0: if (lightness <= 0.5) {
michael@0: saturation = delta / (max + min);
michael@0: } else {
michael@0: saturation = delta / (2 - max - min);
michael@0: }
michael@0: if (red == max) {
michael@0: hue = (green - blue) / delta;
michael@0: } else if (green == max) {
michael@0: hue = 2 + ((blue - red) / delta);
michael@0: } else {
michael@0: hue = 4 + ((red - green) / delta);
michael@0: }
michael@0: hue /= 6;
michael@0: if (hue < 0) {
michael@0: hue += 1;
michael@0: }
michael@0: if (hue > 1) {
michael@0: hue -= 1;
michael@0: }
michael@0:
michael@0: }
michael@0: return {
michael@0: h: hue,
michael@0: s: saturation,
michael@0: l: lightness,
michael@0: a: alpha
michael@0: };
michael@0: },
michael@0:
michael@0: /** @id MochiKit.Color.toColorPart */
michael@0: toColorPart: function (num) {
michael@0: num = Math.round(num);
michael@0: var digits = num.toString(16);
michael@0: if (num < 16) {
michael@0: return '0' + digits;
michael@0: }
michael@0: return digits;
michael@0: },
michael@0:
michael@0: __new__: function () {
michael@0: var m = MochiKit.Base;
michael@0: /** @id MochiKit.Color.fromRGBString */
michael@0: this.Color.fromRGBString = m.bind(
michael@0: this.Color._fromColorString, this.Color, "rgb", "fromRGB",
michael@0: [1.0/255.0, 1.0/255.0, 1.0/255.0, 1]
michael@0: );
michael@0: /** @id MochiKit.Color.fromHSLString */
michael@0: this.Color.fromHSLString = m.bind(
michael@0: this.Color._fromColorString, this.Color, "hsl", "fromHSL",
michael@0: [1.0/360.0, 0.01, 0.01, 1]
michael@0: );
michael@0:
michael@0: var third = 1.0 / 3.0;
michael@0: /** @id MochiKit.Color.colors */
michael@0: var colors = {
michael@0: // NSColor colors plus transparent
michael@0: /** @id MochiKit.Color.blackColor */
michael@0: black: [0, 0, 0],
michael@0: /** @id MochiKit.Color.blueColor */
michael@0: blue: [0, 0, 1],
michael@0: /** @id MochiKit.Color.brownColor */
michael@0: brown: [0.6, 0.4, 0.2],
michael@0: /** @id MochiKit.Color.cyanColor */
michael@0: cyan: [0, 1, 1],
michael@0: /** @id MochiKit.Color.darkGrayColor */
michael@0: darkGray: [third, third, third],
michael@0: /** @id MochiKit.Color.grayColor */
michael@0: gray: [0.5, 0.5, 0.5],
michael@0: /** @id MochiKit.Color.greenColor */
michael@0: green: [0, 1, 0],
michael@0: /** @id MochiKit.Color.lightGrayColor */
michael@0: lightGray: [2 * third, 2 * third, 2 * third],
michael@0: /** @id MochiKit.Color.magentaColor */
michael@0: magenta: [1, 0, 1],
michael@0: /** @id MochiKit.Color.orangeColor */
michael@0: orange: [1, 0.5, 0],
michael@0: /** @id MochiKit.Color.purpleColor */
michael@0: purple: [0.5, 0, 0.5],
michael@0: /** @id MochiKit.Color.redColor */
michael@0: red: [1, 0, 0],
michael@0: /** @id MochiKit.Color.transparentColor */
michael@0: transparent: [0, 0, 0, 0],
michael@0: /** @id MochiKit.Color.whiteColor */
michael@0: white: [1, 1, 1],
michael@0: /** @id MochiKit.Color.yellowColor */
michael@0: yellow: [1, 1, 0]
michael@0: };
michael@0:
michael@0: var makeColor = function (name, r, g, b, a) {
michael@0: var rval = this.fromRGB(r, g, b, a);
michael@0: this[name] = function () { return rval; };
michael@0: return rval;
michael@0: };
michael@0:
michael@0: for (var k in colors) {
michael@0: var name = k + "Color";
michael@0: var bindArgs = m.concat(
michael@0: [makeColor, this.Color, name],
michael@0: colors[k]
michael@0: );
michael@0: this.Color[name] = m.bind.apply(null, bindArgs);
michael@0: }
michael@0:
michael@0: var isColor = function () {
michael@0: for (var i = 0; i < arguments.length; i++) {
michael@0: if (!(arguments[i] instanceof Color)) {
michael@0: return false;
michael@0: }
michael@0: }
michael@0: return true;
michael@0: };
michael@0:
michael@0: var compareColor = function (a, b) {
michael@0: return a.compareRGB(b);
michael@0: };
michael@0:
michael@0: m.nameFunctions(this);
michael@0:
michael@0: m.registerComparator(this.Color.NAME, isColor, compareColor);
michael@0:
michael@0: this.EXPORT_TAGS = {
michael@0: ":common": this.EXPORT,
michael@0: ":all": m.concat(this.EXPORT, this.EXPORT_OK)
michael@0: };
michael@0:
michael@0: }
michael@0: });
michael@0:
michael@0: MochiKit.Color.EXPORT = [
michael@0: "Color"
michael@0: ];
michael@0:
michael@0: MochiKit.Color.EXPORT_OK = [
michael@0: "clampColorComponent",
michael@0: "rgbToHSL",
michael@0: "hslToRGB",
michael@0: "rgbToHSV",
michael@0: "hsvToRGB",
michael@0: "toColorPart"
michael@0: ];
michael@0:
michael@0: MochiKit.Color.__new__();
michael@0:
michael@0: MochiKit.Base._exportSymbols(this, MochiKit.Color);
michael@0:
michael@0: // Full table of css3 X11 colors
michael@0:
michael@0: MochiKit.Color.Color._namedColors = {
michael@0: aliceblue: "#f0f8ff",
michael@0: antiquewhite: "#faebd7",
michael@0: aqua: "#00ffff",
michael@0: aquamarine: "#7fffd4",
michael@0: azure: "#f0ffff",
michael@0: beige: "#f5f5dc",
michael@0: bisque: "#ffe4c4",
michael@0: black: "#000000",
michael@0: blanchedalmond: "#ffebcd",
michael@0: blue: "#0000ff",
michael@0: blueviolet: "#8a2be2",
michael@0: brown: "#a52a2a",
michael@0: burlywood: "#deb887",
michael@0: cadetblue: "#5f9ea0",
michael@0: chartreuse: "#7fff00",
michael@0: chocolate: "#d2691e",
michael@0: coral: "#ff7f50",
michael@0: cornflowerblue: "#6495ed",
michael@0: cornsilk: "#fff8dc",
michael@0: crimson: "#dc143c",
michael@0: cyan: "#00ffff",
michael@0: darkblue: "#00008b",
michael@0: darkcyan: "#008b8b",
michael@0: darkgoldenrod: "#b8860b",
michael@0: darkgray: "#a9a9a9",
michael@0: darkgreen: "#006400",
michael@0: darkgrey: "#a9a9a9",
michael@0: darkkhaki: "#bdb76b",
michael@0: darkmagenta: "#8b008b",
michael@0: darkolivegreen: "#556b2f",
michael@0: darkorange: "#ff8c00",
michael@0: darkorchid: "#9932cc",
michael@0: darkred: "#8b0000",
michael@0: darksalmon: "#e9967a",
michael@0: darkseagreen: "#8fbc8f",
michael@0: darkslateblue: "#483d8b",
michael@0: darkslategray: "#2f4f4f",
michael@0: darkslategrey: "#2f4f4f",
michael@0: darkturquoise: "#00ced1",
michael@0: darkviolet: "#9400d3",
michael@0: deeppink: "#ff1493",
michael@0: deepskyblue: "#00bfff",
michael@0: dimgray: "#696969",
michael@0: dimgrey: "#696969",
michael@0: dodgerblue: "#1e90ff",
michael@0: firebrick: "#b22222",
michael@0: floralwhite: "#fffaf0",
michael@0: forestgreen: "#228b22",
michael@0: fuchsia: "#ff00ff",
michael@0: gainsboro: "#dcdcdc",
michael@0: ghostwhite: "#f8f8ff",
michael@0: gold: "#ffd700",
michael@0: goldenrod: "#daa520",
michael@0: gray: "#808080",
michael@0: green: "#008000",
michael@0: greenyellow: "#adff2f",
michael@0: grey: "#808080",
michael@0: honeydew: "#f0fff0",
michael@0: hotpink: "#ff69b4",
michael@0: indianred: "#cd5c5c",
michael@0: indigo: "#4b0082",
michael@0: ivory: "#fffff0",
michael@0: khaki: "#f0e68c",
michael@0: lavender: "#e6e6fa",
michael@0: lavenderblush: "#fff0f5",
michael@0: lawngreen: "#7cfc00",
michael@0: lemonchiffon: "#fffacd",
michael@0: lightblue: "#add8e6",
michael@0: lightcoral: "#f08080",
michael@0: lightcyan: "#e0ffff",
michael@0: lightgoldenrodyellow: "#fafad2",
michael@0: lightgray: "#d3d3d3",
michael@0: lightgreen: "#90ee90",
michael@0: lightgrey: "#d3d3d3",
michael@0: lightpink: "#ffb6c1",
michael@0: lightsalmon: "#ffa07a",
michael@0: lightseagreen: "#20b2aa",
michael@0: lightskyblue: "#87cefa",
michael@0: lightslategray: "#778899",
michael@0: lightslategrey: "#778899",
michael@0: lightsteelblue: "#b0c4de",
michael@0: lightyellow: "#ffffe0",
michael@0: lime: "#00ff00",
michael@0: limegreen: "#32cd32",
michael@0: linen: "#faf0e6",
michael@0: magenta: "#ff00ff",
michael@0: maroon: "#800000",
michael@0: mediumaquamarine: "#66cdaa",
michael@0: mediumblue: "#0000cd",
michael@0: mediumorchid: "#ba55d3",
michael@0: mediumpurple: "#9370db",
michael@0: mediumseagreen: "#3cb371",
michael@0: mediumslateblue: "#7b68ee",
michael@0: mediumspringgreen: "#00fa9a",
michael@0: mediumturquoise: "#48d1cc",
michael@0: mediumvioletred: "#c71585",
michael@0: midnightblue: "#191970",
michael@0: mintcream: "#f5fffa",
michael@0: mistyrose: "#ffe4e1",
michael@0: moccasin: "#ffe4b5",
michael@0: navajowhite: "#ffdead",
michael@0: navy: "#000080",
michael@0: oldlace: "#fdf5e6",
michael@0: olive: "#808000",
michael@0: olivedrab: "#6b8e23",
michael@0: orange: "#ffa500",
michael@0: orangered: "#ff4500",
michael@0: orchid: "#da70d6",
michael@0: palegoldenrod: "#eee8aa",
michael@0: palegreen: "#98fb98",
michael@0: paleturquoise: "#afeeee",
michael@0: palevioletred: "#db7093",
michael@0: papayawhip: "#ffefd5",
michael@0: peachpuff: "#ffdab9",
michael@0: peru: "#cd853f",
michael@0: pink: "#ffc0cb",
michael@0: plum: "#dda0dd",
michael@0: powderblue: "#b0e0e6",
michael@0: purple: "#800080",
michael@0: red: "#ff0000",
michael@0: rosybrown: "#bc8f8f",
michael@0: royalblue: "#4169e1",
michael@0: saddlebrown: "#8b4513",
michael@0: salmon: "#fa8072",
michael@0: sandybrown: "#f4a460",
michael@0: seagreen: "#2e8b57",
michael@0: seashell: "#fff5ee",
michael@0: sienna: "#a0522d",
michael@0: silver: "#c0c0c0",
michael@0: skyblue: "#87ceeb",
michael@0: slateblue: "#6a5acd",
michael@0: slategray: "#708090",
michael@0: slategrey: "#708090",
michael@0: snow: "#fffafa",
michael@0: springgreen: "#00ff7f",
michael@0: steelblue: "#4682b4",
michael@0: tan: "#d2b48c",
michael@0: teal: "#008080",
michael@0: thistle: "#d8bfd8",
michael@0: tomato: "#ff6347",
michael@0: turquoise: "#40e0d0",
michael@0: violet: "#ee82ee",
michael@0: wheat: "#f5deb3",
michael@0: white: "#ffffff",
michael@0: whitesmoke: "#f5f5f5",
michael@0: yellow: "#ffff00",
michael@0: yellowgreen: "#9acd32"
michael@0: };