Skip to content
This repository
Browse code

start to add color functions

  • Loading branch information...
commit ee77c602cedd16ed1204d1488c23aa714d0f92e2 1 parent 67b54b4
Andrew Peterson authored
3  README.markdown
Source Rendered
@@ -85,11 +85,14 @@ To "mix these in", use the "macro" key:
85 85
86 86 ## Todo
87 87
  88 +* Support "has"
88 89 * Support more than one Macro
89 90 * Some color math
  91 +* Fix license
90 92 * Better name
91 93
92 94
  95 +
93 96 ## Motivation
94 97
95 98 This project comes from my frustration of trying to build standalone Javascript widgets. Web
14 names
... ... @@ -0,0 +1,14 @@
  1 +names:
  2 +css
  3 +stylesheet
  4 +sheet
  5 +js
  6 +javascript
  7 +script
  8 +styling
  9 +sass
  10 +dynamic
  11 +csscript
  12 +css
  13 +sscijs
  14 +jssstylescript
5 spec/csster_spec.js
@@ -45,10 +45,11 @@ describe("Csster", function() {
45 45 it('should render raw number as "px" value', function() {
46 46 expect(Csster.formatProperty('height', 12)).toEqual("height: 12px;\r");
47 47 });
48   -
49   -
50 48 });
51 49
  50 + // :hover selectors (no space between pieces)
  51 + // > blah direct decendent
  52 +
52 53
53 54 describe('#formatRules', function() {
54 55 it("should output style rule from element name", function() {
244 spec/functions_spec.js
... ... @@ -0,0 +1,244 @@
  1 +describe('color functions', function() {
  2 +
  3 + describe('toHex string', function() {
  4 + beforeEach(function() { });
  5 +
  6 + it('should noop if hex passed in', function() {
  7 + expect("#123456".toHexColor()).toEqual('#123456');
  8 + });
  9 + it('should convert websafe color to hex', function() {
  10 + expect("#369".toHexColor()).toEqual('#336699');
  11 + });
  12 + it('should convert black to hex', function() {
  13 + expect("black".toHexColor()).toEqual('#000000');
  14 + });
  15 + it('should convert white to hex', function() {
  16 + expect("white".toHexColor()).toEqual('#ffffff');
  17 + });
  18 + it('should convert olive to hex', function() {
  19 + expect("olive".toHexColor()).toEqual('#808000');
  20 + });
  21 + });
  22 +
  23 + describe('parsing hex string', function() {
  24 +
  25 + var sample = "#123456";
  26 +
  27 + it('should set red', function() {
  28 + expect(sample.toRGB()[0]).toEqual(18);
  29 + });
  30 + it('should set green', function() {
  31 + expect(sample.toRGB()[1]).toEqual(52);
  32 + });
  33 + it('should set blue', function() {
  34 + expect(sample.toRGB()[2]).toEqual(86);
  35 + });
  36 + it('should return red', function() {
  37 + expect(sample.red()).toEqual(18);
  38 + });
  39 + it('should return red', function() {
  40 + expect(sample.green()).toEqual(52);
  41 + });
  42 + it('should return red', function() {
  43 + expect(sample.blue()).toEqual(86);
  44 + });
  45 + });
  46 +
  47 + describe('toHSL', function() {
  48 + it('should convert white to hsl', function() {
  49 + expect('#ffffff'.toHSL()).toEqual([0,0,100]);
  50 + });
  51 + it('should convert black to hsl', function() {
  52 + expect('#000000'.toHSL()).toEqual([0,0,0]);
  53 + });
  54 + it('should convert red to hsl', function() {
  55 + expect('#ff0000'.toHSL()).toEqual([0,100,50]);
  56 + });
  57 + it('should convert green to hsl', function() {
  58 + expect('#00ff00'.toHSL()).toEqual([120,100,50]);
  59 + });
  60 + it('should convert blue to hsl', function() {
  61 + expect('#0000ff'.toHSL()).toEqual([240,100,50]);
  62 + });
  63 + });
  64 +
  65 + describe('hslToHtmlColor', function() {
  66 + it('should convert white to hsl and back', function() {
  67 + var hsl = '#ffffff'.toHSL();
  68 + expect(hslToHtmlColor.apply(null,hsl)).toEqual('#ffffff');
  69 + });
  70 + it('should convert black to hsl and back', function() {
  71 + var hsl = '#000'.toHSL();
  72 + expect(hslToHtmlColor.apply(null,hsl).toHexColor()).toEqual('#000000');
  73 + });
  74 + it('should convert blue to hsl and back', function() {
  75 + var hsl = '#0000ff'.toHSL();
  76 + expect(hslToHtmlColor.apply(null,hsl).toHexColor()).toEqual('#0000ff');
  77 + });
  78 + });
  79 +
  80 + describe('lighten', function() {
  81 + it('should do nothing with zero', function() {
  82 + expect('#800'.lighten(0)).toEqual('#880000');
  83 + });
  84 + it('should set to white with 100', function() {
  85 + expect('#800'.lighten(100)).toEqual('#000000');
  86 + });
  87 + it('should do nothing if already white', function() {
  88 + expect('#fff'.lighten(20)).toEqual('#fff');
  89 + });
  90 + it('should lighten 20%', function() {
  91 + expect('#880000'.lighten(20)).toEqual('#ee0000');
  92 + });
  93 + });
  94 +
  95 +});
  96 +
  97 +
  98 +//
  99 +//it('should lighten_tests_bounds', function() {
  100 +// assert_error_message("Amount -0.001 must be between 0% and 100% for `lighten'",
  101 +// "lighten(#123, -0.001)")
  102 +// assert_error_message("Amount 100.001 must be between 0% and 100% for `lighten'",
  103 +// "lighten(#123, 100.001)")
  104 +//});
  105 +//
  106 +//it('should lighten_tests_types', function() {
  107 +// assert_error_message("\"foo\" is not a color for `lighten'", "lighten(\"foo\", 10%)")
  108 +// assert_error_message("\"foo\" is not a number for `lighten'", "lighten(#fff, \"foo\")")
  109 +//});
  110 +//
  111 +//it('should darken', function() {
  112 +// expect(evaluate("darken(hsl(25, 100, 80), 30%)")).toEqual('#ff6a00');
  113 +// expect(evaluate("darken(#800, 20%)")).toEqual('#220000');
  114 +// assert_equal("black", evaluate("darken(#000, 20%)"))
  115 +// assert_equal("black", evaluate("darken(#800, 100%)"))
  116 +// expect(evaluate("darken(#800, 0%)")).toEqual('#880000');
  117 +// assert_equal("rgba(34, 0, 0, 0.5)", evaluate("darken(rgba(136, 0, 0, 0.5), 20%)"))
  118 +//});
  119 +//
  120 +//it('should darken_tests_bounds', function() {
  121 +// assert_error_message("Amount -0.001 must be between 0% and 100% for `darken'",
  122 +// "darken(#123, -0.001)")
  123 +// assert_error_message("Amount 100.001 must be between 0% and 100% for `darken'",
  124 +// "darken(#123, 100.001)")
  125 +//});
  126 +//
  127 +//it('should darken_tests_types', function() {
  128 +// assert_error_message("\"foo\" is not a color for `darken'", "darken(\"foo\", 10%)")
  129 +// assert_error_message("\"foo\" is not a number for `darken'", "darken(#fff, \"foo\")")
  130 +//});
  131 +//
  132 +//it('should saturate', function() {
  133 +// expect(evaluate("saturate(hsl(120, 30, 90), 20%)")).toEqual('#d9f2d9');
  134 +// expect(evaluate("saturate(#855, 20%)")).toEqual('#9e3f3f');
  135 +// assert_equal("black", evaluate("saturate(#000, 20%)"))
  136 +// assert_equal("white", evaluate("saturate(#fff, 20%)"))
  137 +// expect(evaluate("saturate(#8a8, 100%)")).toEqual('#33ff33');
  138 +// expect(evaluate("saturate(#8a8, 0%)")).toEqual('#88aa88');
  139 +// assert_equal("rgba(158, 63, 63, 0.5)", evaluate("saturate(rgba(136, 85, 85, 0.5), 20%)"))
  140 +//});
  141 +//
  142 +//it('should saturate_tests_bounds', function() {
  143 +// assert_error_message("Amount -0.001 must be between 0% and 100% for `saturate'",
  144 +// "saturate(#123, -0.001)")
  145 +// assert_error_message("Amount 100.001 must be between 0% and 100% for `saturate'",
  146 +// "saturate(#123, 100.001)")
  147 +//});
  148 +//
  149 +//it('should saturate_tests_types', function() {
  150 +// assert_error_message("\"foo\" is not a color for `saturate'", "saturate(\"foo\", 10%)")
  151 +// assert_error_message("\"foo\" is not a number for `saturate'", "saturate(#fff, \"foo\")")
  152 +//});
  153 +//
  154 +//it('should desaturate', function() {
  155 +// expect(evaluate("desaturate(hsl(120, 30, 90), 20%)")).toEqual('#e3e8e3');
  156 +// expect(evaluate("desaturate(#855, 20%)")).toEqual('#726b6b');
  157 +// assert_equal("black", evaluate("desaturate(#000, 20%)"))
  158 +// assert_equal("white", evaluate("desaturate(#fff, 20%)"))
  159 +// expect(evaluate("desaturate(#8a8, 100%)")).toEqual('#999999');
  160 +// expect(evaluate("desaturate(#8a8, 0%)")).toEqual('#88aa88');
  161 +// assert_equal("rgba(114, 107, 107, 0.5)", evaluate("desaturate(rgba(136, 85, 85, 0.5), 20%)"))
  162 +//});
  163 +//
  164 +//it('should desaturate_tests_bounds', function() {
  165 +// assert_error_message("Amount -0.001 must be between 0% and 100% for `desaturate'",
  166 +// "desaturate(#123, -0.001)")
  167 +// assert_error_message("Amount 100.001 must be between 0% and 100% for `desaturate'",
  168 +// "desaturate(#123, 100.001)")
  169 +//});
  170 +//
  171 +//it('should desaturate_tests_types', function() {
  172 +// assert_error_message("\"foo\" is not a color for `desaturate'", "desaturate(\"foo\", 10%)")
  173 +// assert_error_message("\"foo\" is not a number for `desaturate'", "desaturate(#fff, \"foo\")")
  174 +//});
  175 +//
  176 +//it('should adjust_hue', function() {
  177 +// expect(evaluate("adjust-hue(hsl(120, 30, 90), 60deg)")).toEqual('#deeded');
  178 +// expect(evaluate("adjust-hue(hsl(120, 30, 90), -60deg)")).toEqual('#ededde');
  179 +// expect(evaluate("adjust-hue(#811, 45deg)")).toEqual('#886a11');
  180 +// assert_equal("black", evaluate("adjust-hue(#000, 45deg)"))
  181 +// assert_equal("white", evaluate("adjust-hue(#fff, 45deg)"))
  182 +// expect(evaluate("adjust-hue(#8a8, 360deg)")).toEqual('#88aa88');
  183 +// expect(evaluate("adjust-hue(#8a8, 0deg)")).toEqual('#88aa88');
  184 +// assert_equal("rgba(136, 106, 17, 0.5)", evaluate("adjust-hue(rgba(136, 17, 17, 0.5), 45deg)"))
  185 +//});
  186 +//
  187 +//it('should adjust_hue_tests_types', function() {
  188 +// assert_error_message("\"foo\" is not a color for `adjust-hue'", "adjust-hue(\"foo\", 10%)")
  189 +// assert_error_message("\"foo\" is not a number for `adjust-hue'", "adjust-hue(#fff, \"foo\")")
  190 +//});
  191 +//
  192 +//it('should mix', function() {
  193 +// expect(evaluate("mix(#f00, #00f)")).toEqual('#7f007f');
  194 +// expect(evaluate("mix(#f00, #0ff)")).toEqual('#7f7f7f');
  195 +// expect(evaluate("mix(#f70, #0aa)")).toEqual('#7f9055');
  196 +// expect(evaluate("mix(#f00, #00f, 25%)")).toEqual('#3f00bf');
  197 +// assert_equal("rgba(63, 0, 191, 0.75)", evaluate("mix(rgba(255, 0, 0, 0.5), #00f)"))
  198 +// assert_equal("red", evaluate("mix(#f00, #00f, 100%)"))
  199 +// assert_equal("blue", evaluate("mix(#f00, #00f, 0%)"))
  200 +// assert_equal("rgba(255, 0, 0, 0.5)", evaluate("mix(#f00, transparentize(#00f, 1))"))
  201 +// assert_equal("rgba(0, 0, 255, 0.5)", evaluate("mix(transparentize(#f00, 1), #00f)"))
  202 +// assert_equal("red", evaluate("mix(#f00, transparentize(#00f, 1), 100%)"))
  203 +// assert_equal("blue", evaluate("mix(transparentize(#f00, 1), #00f, 0%)"))
  204 +// assert_equal("rgba(0, 0, 255, 0)", evaluate("mix(#f00, transparentize(#00f, 1), 0%)"))
  205 +// assert_equal("rgba(255, 0, 0, 0)", evaluate("mix(transparentize(#f00, 1), #00f, 100%)"))
  206 +//});
  207 +//
  208 +//it('should mix_tests_types', function() {
  209 +// assert_error_message("\"foo\" is not a color for `mix'", "mix(\"foo\", #f00, 10%)")
  210 +// assert_error_message("\"foo\" is not a color for `mix'", "mix(#f00, \"foo\", 10%)")
  211 +// assert_error_message("\"foo\" is not a number for `mix'", "mix(#f00, #baf, \"foo\")")
  212 +//});
  213 +//
  214 +//it('should mix_tests_bounds', function() {
  215 +// assert_error_message("Weight -0.001 must be between 0% and 100% for `mix'",
  216 +// "mix(#123, #456, -0.001)")
  217 +// assert_error_message("Weight 100.001 must be between 0% and 100% for `mix'",
  218 +// "mix(#123, #456, 100.001)")
  219 +//});
  220 +//
  221 +//it('should grayscale', function() {
  222 +// expect(evaluate("grayscale(#abc)")).toEqual('#bbbbbb');
  223 +// assert_equal("gray", evaluate("grayscale(#f00)"))
  224 +// assert_equal("gray", evaluate("grayscale(#00f)"))
  225 +// assert_equal("white", evaluate("grayscale(white)"))
  226 +// assert_equal("black", evaluate("grayscale(black)"))
  227 +//});
  228 +//
  229 +//def tets_grayscale_tests_types
  230 +// assert_error_message("\"foo\" is not a color for `grayscale'", "grayscale(\"foo\")")
  231 +//});
  232 +//
  233 +//it('should complement', function() {
  234 +// expect(evaluate("complement(#abc)")).toEqual('#ccbbaa');
  235 +// assert_equal("aqua", evaluate("complement(red)"))
  236 +// assert_equal("red", evaluate("complement(aqua)"))
  237 +// assert_equal("white", evaluate("complement(white)"))
  238 +// assert_equal("black", evaluate("complement(black)"))
  239 +//});
  240 +//
  241 +//def tets_complement_tests_types
  242 +// assert_error_message("\"foo\" is not a color for `complement'", "complement(\"foo\")")
  243 +//});
  244 +//
2  spec_runner.html
@@ -9,10 +9,12 @@
9 9 <style type="text/css"></style>
10 10 <!-- include source files here... -->
11 11 <script type="text/javascript" src="src/csster.js"></script>
  12 + <script type="text/javascript" src="src/function/color.js"></script>
12 13
13 14 <!-- include spec files here... -->
14 15 <script type="text/javascript" src="spec/spec_helper.js"></script>
15 16 <script type="text/javascript" src="spec/csster_spec.js"></script>
  17 + <script type="text/javascript" src="spec/functions_spec.js"></script>
16 18
17 19 </head>
18 20 <body>
1  src/csster.js
@@ -57,6 +57,7 @@ var Csster = {
57 57 'border-left-color',
58 58 'border-left-style',
59 59 'border-left-width',
  60 + 'border-radius',
60 61 'border-right',
61 62 'border-right-color',
62 63 'border-right-style',
152 src/function/color.js
... ... @@ -0,0 +1,152 @@
  1 +/*
  2 + Use a singleton cache of all color strings we see.
  3 + Each key points to a structure, which can have hex, rgb, etc. values in it.
  4 + */
  5 +var ColorCache = {}; // used for storing values associated with a string
  6 +
  7 +var HTML4_COLORS = {
  8 + 'black' : '#000000',
  9 + 'silver' : '#c0c0c0',
  10 + 'gray' : '#808080',
  11 + 'white' : '#ffffff',
  12 + 'maroon' : '#800000',
  13 + 'red' : '#ff0000',
  14 + 'purple' : '#800080',
  15 + 'fuchsia': '#ff00ff',
  16 + 'green' : '#008000',
  17 + 'lime' : '#00ff00',
  18 + 'olive' : '#808000',
  19 + 'yellow' : '#ffff00',
  20 + 'navy' : '#000080',
  21 + 'blue' : '#0000ff',
  22 + 'teal' : '#008080',
  23 + 'aqua' : '#00ffff'
  24 +};
  25 +
  26 +
  27 +String.prototype.colorCache = function() {
  28 + if (!ColorCache[this]) ColorCache[this] = {};
  29 + return ColorCache[this];
  30 +};
  31 +String.prototype.toHexColor = function() {
  32 + if (this[0] == '#' && this.length == 7) {
  33 + this.colorCache()['hex'] = '' + this;
  34 + } else if (this[0] == '#' && this.length == 4) {
  35 + this.colorCache()['hex'] = '#' + this[1] + this[1] + this[2] + this[2] + this[3] + this[3];
  36 + } else {
  37 + this.colorCache()['hex'] = HTML4_COLORS[this];
  38 + }
  39 + return this.colorCache()['hex'];
  40 +};
  41 +
  42 +String.prototype.toRGB = function() {
  43 + var cache = this.colorCache();
  44 + if (cache.rgb) return cache.rgb;
  45 + var h = this.toHexColor();
  46 + cache.rgb = [parseInt(h.substr(1, 2), 16),parseInt(h.substr(3, 2), 16),parseInt(h.substr(5, 2), 16)];
  47 + return cache.rgb;
  48 +};
  49 +
  50 +String.prototype.red = function() {
  51 + return this.toRGB()[0];
  52 +};
  53 +String.prototype.green = function() {
  54 + return this.toRGB()[1];
  55 +};
  56 +String.prototype.blue = function() {
  57 + return this.toRGB()[2];
  58 +};
  59 +String.prototype.lighten = function(percent) {
  60 + var hsl = this.toHSL();
  61 + var newHSL = [hsl[0],hsl[1],Math.min(100, hsl[2] + percent)];
  62 + return hslToHtmlColor(newHSL);
  63 +};
  64 +
  65 +
  66 +// [0..360, 0..100, 0.100]
  67 +String.prototype.toHSL = function() {
  68 + var rgb = this.toRGB();
  69 + var r = this.red() / 255,g = this.green() / 255,b = this.blue() / 255;
  70 + var max = Math.max(r, g, b), min = Math.min(r, g, b);
  71 + var h, s, l = (max + min) / 2;
  72 +
  73 + if (max == min) {
  74 + h = s = 0; // achromatic
  75 + } else {
  76 + var d = max - min;
  77 + s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  78 + switch (max) {
  79 + case r: h = (g - b) / d + (g < b ? 6 : 0); break;
  80 + case g: h = (b - r) / d + 2; break;
  81 + case b: h = (r - g) / d + 4; break;
  82 + }
  83 + h /= 6;
  84 + }
  85 +
  86 + var cache = this.colorCache();
  87 + cache.hsl = [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)];
  88 + return cache.hsl;
  89 +};
  90 +
  91 +
  92 +function hslToHtmlColor(h, s, l) {
  93 +
  94 + var hsl2rgb = function(h, s, l) {
  95 + if (isArray(h)) {
  96 + l = h[2] || 0;
  97 + s = h[1] || 0;
  98 + h = h[0] || 0;
  99 + }
  100 + s = s / 100;
  101 + l = l / 100;
  102 + h = h % 360;
  103 +
  104 + var r,g,b;
  105 + if (h < 120) {
  106 + r = (120 - h) / 60;
  107 + g = h / 60;
  108 + b = 0;
  109 + } else {
  110 + if (h < 240) {
  111 + r = 0;
  112 + g = (240 - h) / 60;
  113 + b = (h - 120) / 60;
  114 + } else {
  115 + r = (h - 240) / 60;
  116 + g = 0;
  117 + b = (360 - h) / 60;
  118 + }
  119 + }
  120 + r = Math.min(r, 1);
  121 + g = Math.min(g, 1);
  122 + b = Math.min(b, 1);
  123 + r = 2 * s * r + (1 - s);
  124 + g = 2 * s * g + (1 - s);
  125 + b = 2 * s * b + (1 - s);
  126 + if (l < 0.5) {
  127 + r = l * r;
  128 + g = l * g;
  129 + b = l * b;
  130 + } else {
  131 + r = (1 - l) * r + 2 * l - 1;
  132 + g = (1 - l) * g + 2 * l - 1;
  133 + b = (1 - l) * b + 2 * l - 1;
  134 + }
  135 + r = Math.ceil(r * 255);
  136 + g = Math.ceil(g * 255);
  137 + b = Math.ceil(b * 255);
  138 + return [r,g,b];
  139 + };
  140 +
  141 +
  142 + var rgb = hsl2rgb(h, s, l);
  143 +
  144 + function hex2(n) {
  145 + var h = n.toString(16);
  146 + if (h.length == 1) h = '0' + h;
  147 + return h;
  148 + }
  149 +
  150 + return "#" + hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
  151 +}
  152 +
333 src/function/functions.js
... ... @@ -0,0 +1,333 @@
  1 +/**
  2 + Functions applied to property values.
  3 + #lighten
  4 + Makes a color lighter.
  5 + #darken
  6 + Makes a color darker.
  7 + #saturate
  8 + Makes a color more saturated.
  9 + #desaturate
  10 + Makes a color less saturated.
  11 + #grayscale
  12 + Converts a color to grayscale.
  13 + #complement
  14 + Returns the complement of a color.
  15 +
  16 +
  17 + def grayscale(color)
  18 + desaturate color, Number.new(100)
  19 + end
  20 +
  21 +
  22 + def desaturate(color, amount)
  23 + adjust(color, amount, :saturation, 0..100, :-, "%")
  24 + end
  25 + */
  26 +
  27 +function rgbToHsl(r, g, b) {
  28 + r /= 255,g /= 255,b /= 255;
  29 + var max = Math.max(r, g, b), min = Math.min(r, g, b);
  30 + var h, s, l = (max + min) / 2;
  31 +
  32 + if (max == min) {
  33 + h = s = 0; // achromatic
  34 + } else {
  35 + var d = max - min;
  36 + s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  37 + switch (max) {
  38 + case r: h = (g - b) / d + (g < b ? 6 : 0); break;
  39 + case g: h = (b - r) / d + 2; break;
  40 + case b: h = (r - g) / d + 4; break;
  41 + }
  42 + h /= 6;
  43 + }
  44 +
  45 + return [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)];
  46 +}
  47 +
  48 +
  49 +function rgbToHsv(r, g, b) {
  50 + var
  51 + min = Math.min(r, g, b),
  52 + max = Math.max(r, g, b),
  53 + delta = max - min,
  54 + h, s, v = max;
  55 +
  56 + v = Math.floor(max / 255 * 100);
  57 + if (max != 0)
  58 + s = Math.floor(delta / max * 100);
  59 + else {
  60 + // black
  61 + return [0, 0, 0];
  62 + }
  63 +
  64 + if (r == max)
  65 + h = ( g - b ) / delta; // between yellow & magenta
  66 + else if (g == max)
  67 + h = 2 + ( b - r ) / delta; // between cyan & yellow
  68 + else
  69 + h = 4 + ( r - g ) / delta; // between magenta & cyan
  70 +
  71 + h = Math.floor(h * 60); // degrees
  72 + if (h < 0) h += 360;
  73 +
  74 + return [h, s, v];
  75 +}
  76 +
  77 +
  78 +/*
  79 +
  80 + *
  81 + */
  82 +
  83 +
  84 +function hsl2rgb(h, s, l) {
  85 + var m1, m2, hue;
  86 + var r, g, b
  87 + s /= 100;
  88 + l /= 100;
  89 + if (s == 0)
  90 + r = g = b = (l * 255);
  91 + else {
  92 + if (l <= 0.5)
  93 + m2 = l * (s + 1);
  94 + else
  95 + m2 = l + s - l * s;
  96 + m1 = l * 2 - m2;
  97 + hue = h / 360;
  98 + r = HueToRgb(m1, m2, hue + 1 / 3);
  99 + g = HueToRgb(m1, m2, hue);
  100 + b = HueToRgb(m1, m2, hue - 1 / 3);
  101 + }
  102 + return {r: r, g: g, b: b};
  103 +}
  104 +
  105 +function HueToRgb(m1, m2, hue) {
  106 + var v;
  107 + if (hue < 0)
  108 + hue += 1;
  109 + else if (hue > 1)
  110 + hue -= 1;
  111 +
  112 + if (6 * hue < 1)
  113 + v = m1 + (m2 - m1) * hue * 6;
  114 + else if (2 * hue < 1)
  115 + v = m2;
  116 + else if (3 * hue < 2)
  117 + v = m1 + (m2 - m1) * (2 / 3 - hue) * 6;
  118 + else
  119 + v = m1;
  120 +
  121 + return 255 * v;
  122 +}
  123 +
  124 +
  125 +//calculate rgb component
  126 +function hToC(x, y, h) {
  127 + var c;
  128 + if (h < 0) {
  129 + h += 1;
  130 + }
  131 + if (h > 1) {
  132 + h -= 1;
  133 + }
  134 + if (h < 1 / 6) {
  135 + c = x + (y - x) * h * 6;
  136 + } else {
  137 + if (h < 1 / 2) {
  138 + c = y;
  139 + } else {
  140 + if (h < 2 / 3) {
  141 + c = x + (y - x) * (2 / 3 - h) * 6;
  142 + } else {
  143 + c = x;
  144 + }
  145 + }
  146 + }
  147 + return c;
  148 +}
  149 +
  150 +//convert hsl to rgb (all values 0..1)
  151 +function hslToRgb(h, s, l) {
  152 + var
  153 + y = (l > .5) ?
  154 + l + s - l * s :
  155 + l * (s + 1),
  156 + x = l * 2 - y,
  157 + r = hToC(x, y, h + 1 / 3),
  158 + g = hToC(x, y, h),
  159 + b = hToC(x, y, h - 1 / 3);
  160 + return [r, g, b];
  161 +}
  162 +
  163 +//convert hsl to an html color string
  164 +function hslToHtmlColor(h, s, l) {
  165 + var rgb = hslToRgb(h, s, l);
  166 + return "#" + toHex(rgb[0] * 255) + toHex(rgb[1] * 255) + toHex(rgb[2] * 255);
  167 +}
  168 +
  169 +//convert decimal to hex
  170 +function toHex(decimal, places) {
  171 + if (places == undefined || isNaN(places)) places = 2;
  172 + var hex = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");
  173 + var next = 0;
  174 + var hexidecimal = "";
  175 + decimal = Math.floor(decimal);
  176 + while (decimal > 0) {
  177 + next = decimal % 16;
  178 + decimal = Math.floor((decimal - next) / 16);
  179 + hexidecimal = hex[next] + hexidecimal;
  180 + }
  181 + while (hexidecimal.length < places) {
  182 + hexidecimal = "0" + hexidecimal;
  183 + }
  184 + return hexidecimal;
  185 +}
  186 +
  187 +
  188 +
  189 +
  190 +
  191 +
  192 +
  193 +
  194 +
  195 +
  196 +
  197 +
  198 +
  199 +
  200 +
  201 +
  202 +
  203 +
  204 +
  205 +
  206 +
  207 +
  208 +
  209 +
  210 +
  211 +
  212 +
  213 +
  214 +
  215 +
  216 +
  217 +
  218 +
  219 +
  220 +
  221 +
  222 +
  223 +// Makes a color lighter.
  224 +// Takes a color and an amount between 0% and 100%,
  225 +// and returns a color with the lightness increased by that value.
  226 +//
  227 +// For example:
  228 +//
  229 +// lighten(hsl(0, 0%, 0%), 30%) => hsl(0, 0, 30)
  230 +// lighten(#800, 20%) => #e00
  231 +//
  232 +// @param color [Color]
  233 +// @param amount [Number]
  234 +// @return [Color]
  235 +// @see #darken
  236 +// @raise [ArgumentError] If `color` isn't a color,
  237 +// or `number` isn't a number between 0% and 100%
  238 + function lighten(color, amount) {
  239 + adjust(color, amount, :lightness, 0..100, :+, "%")
  240 + }
  241 +// Makes a color darker.
  242 +// Takes a color and an amount between 0% and 100%,
  243 +// and returns a color with the lightness decreased by that value.
  244 +//
  245 +// For example:
  246 +//
  247 +// darken(hsl(25, 100%, 80%), 30%) => hsl(25, 100%, 50%)
  248 +// darken(#800, 20%) => #200
  249 +//
  250 +// @param color [Color]
  251 +// @param amount [Number]
  252 +// @return [Color]
  253 +// @see #lighten
  254 +// @raise [ArgumentError] If `color` isn't a color,
  255 +// or `number` isn't a number between 0% and 100%
  256 + function darken(color, amount) {
  257 + adjust(color, amount, :lightness, 0..100, :-, "%")
  258 + }
  259 +// Makes a color more saturated.
  260 +// Takes a color and an amount between 0% and 100%,
  261 +// and returns a color with the saturation increased by that value.
  262 +//
  263 +// For example:
  264 +//
  265 +// saturate(hsl(120, 30%, 90%), 20%) => hsl(120, 50%, 90%)
  266 +// saturate(#855, 20%) => #9e3f3f
  267 +//
  268 +// @param color [Color]
  269 +// @param amount [Number]
  270 +// @return [Color]
  271 +// @see #desaturate
  272 +// @raise [ArgumentError] If `color` isn't a color,
  273 +// or `number` isn't a number between 0% and 100%
  274 + function saturate(color, amount) {
  275 + adjust(color, amount, :saturation, 0..100, :+, "%")
  276 + }
  277 +// Makes a color less saturated.
  278 +// Takes a color and an amount between 0% and 100%,
  279 +// and returns a color with the saturation decreased by that value.
  280 +//
  281 +// For example:
  282 +//
  283 +// desaturate(hsl(120, 30%, 90%), 20%) => hsl(120, 10%, 90%)
  284 +// desaturate(#855, 20%) => #726b6b
  285 +//
  286 +// @param color [Color]
  287 +// @param amount [Number]
  288 +// @return [Color]
  289 +// @see #saturate
  290 +// @raise [ArgumentError] If `color` isn't a color,
  291 +// or `number` isn't a number between 0% and 100%
  292 + function desaturate(color, amount) {
  293 + adjust(color, amount, :saturation, 0..100, :-, "%")
  294 + }
  295 +// Changes the hue of a color while retaining the lightness and saturation.
  296 +// Takes a color and a number of degrees (usually between -360deg and 360deg),
  297 +// and returns a color with the hue rotated by that value.
  298 +//
  299 +// For example:
  300 +//
  301 +// adjust-hue(hsl(120, 30%, 90%), 60deg) => hsl(180, 30%, 90%)
  302 +// adjust-hue(hsl(120, 30%, 90%), 060deg) => hsl(60, 30%, 90%)
  303 +// adjust-hue(#811, 45deg) => #886a11
  304 +//
  305 +// @param color [Color]
  306 +// @param amount [Number]
  307 +// @return [Color]
  308 +// @raise [ArgumentError] If `color` isn't a color, or `number` isn't a number
  309 + function adjust_hue(color, degrees) {
  310 + color.with(:hue => color.hue + degrees.value)
  311 + }
  312 +
  313 +// Converts a color to grayscale.
  314 +// This is identical to `desaturate(color, 100%)`.
  315 +//
  316 +// @param color [Color]
  317 +// @return [Color]
  318 +// @raise [ArgumentError] if `color` isn't a color
  319 +// @see #desaturate
  320 + function grayscale(color) {
  321 + desaturate color, Number.new(100)
  322 + }
  323 +// Returns the complement of a color.
  324 +// This is identical to `adjust-hue(color, 180deg)`.
  325 +//
  326 +// @param color [Color]
  327 +// @return [Color]
  328 +// @raise [ArgumentError] if `color` isn't a color
  329 +// @see #adjust_hue #adjust-hue
  330 + function complement(color) {
  331 + adjust_hue color, Number.new(180)
  332 + }
  333 +
15 src/macro/macros.js
... ... @@ -0,0 +1,15 @@
  1 +/*
  2 + * Functions that return a set of properties and their values.
  3 + */
  4 +
  5 +/**
  6 + * CSS3 rounded corners
  7 + * @param radius
  8 + */
  9 +function roundedCorners(radius) {
  10 + return {
  11 + '-webkit-border-radius': radius,
  12 + '-moz-border-radius': radius,
  13 + 'border-radius': radius
  14 + }
  15 +}

0 comments on commit ee77c60

Please sign in to comment.
Something went wrong with that request. Please try again.