3 // RGB Colors - #ff0014, #eee
5 tree.Color = function (rgb, a) {
7 // The end goal here, is to parse the arguments
8 // into an integer triplet, such as `128, 255, 0`
10 // This facilitates operations and conversions.
12 if (Array.isArray(rgb)) {
14 } else if (rgb.length == 6) {
15 this.rgb = rgb.match(/.{2}/g).map(function (c) {
16 return parseInt(c, 16);
19 this.rgb = rgb.split('').map(function (c) {
20 return parseInt(c + c, 16);
23 this.alpha = typeof(a) === 'number' ? a : 1;
25 tree.Color.prototype = {
26 eval: function () { return this },
29 // If we have some transparency, the only way to represent it
30 // is via `rgba`. Otherwise, we use the hex representation,
31 // which has better compatibility with older browsers.
32 // Values are capped between `0` and `255`, rounded and zero-padded.
35 if (this.alpha < 1.0) {
36 return "rgba(" + this.rgb.map(function (c) {
38 }).concat(this.alpha).join(', ') + ")";
40 return '#' + this.rgb.map(function (i) {
42 i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
43 return i.length === 1 ? '0' + i : i;
49 // Operations have to be done per-channel, if not,
50 // channels will spill onto each other. Once we have
51 // our result, in the form of an integer triplet,
52 // we create a new Color node to hold the result.
54 operate: function (op, other) {
57 if (! (other instanceof tree.Color)) {
58 other = other.toColor();
61 for (var c = 0; c < 3; c++) {
62 result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
64 return new(tree.Color)(result, this.alpha + other.alpha);
68 var r = this.rgb[0] / 255,
69 g = this.rgb[1] / 255,
70 b = this.rgb[2] / 255,
73 var max = Math.max(r, g, b), min = Math.min(r, g, b);
74 var h, s, l = (max + min) / 2, d = max - min;
79 s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
82 case r: h = (g - b) / d + (g < b ? 6 : 0); break;
83 case g: h = (b - r) / d + 2; break;
84 case b: h = (r - g) / d + 4; break;
88 return { h: h * 360, s: s, l: l, a: a };
91 var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
92 return '#' + argb.map(function (i) {
94 i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
95 return i.length === 1 ? '0' + i : i;
101 })(require('less/tree'));