diff --git a/bin/build.js b/bin/build.js deleted file mode 100755 index 2a22efd..0000000 --- a/bin/build.js +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env node - -var fs = require('fs'), - AssetGraph = require('assetgraph'), - commandLineOptions = require('optimist') - .demand(1) - .argv; - -new AssetGraph() - .loadAssets(commandLineOptions._) - .pullGlobalsIntoVariables({type: 'JavaScript'}, {wrapInFunction: true}) - .compressJavaScript() - .queue(function (assetGraph) { - var text = assetGraph.findAssets()[0].text + "\n"; - if (commandLineOptions.o) { - fs.writeFile(commandLineOptions.o, text, 'utf-8', function (err) { - if (err) { - throw err; - } - }); - } else { - console.log(text); - } - }) - .run(function (err) { - if (err) { - throw err; - } - }); diff --git a/index.js b/index.js new file mode 100644 index 0000000..4dc5bd0 --- /dev/null +++ b/index.js @@ -0,0 +1,20 @@ +module.exports = require('./lib/color') + .use(require('./lib/XYZ')) + .use(require('./lib/LAB')) + .use(require('./lib/HSV')) + .use(require('./lib/HSL')) + .use(require('./lib/CMYK')) + + // Convenience functions + .use(require('./lib/plugins/namedColors')) + .use(require('./lib/plugins/clearer.js')) + .use(require('./lib/plugins/darken.js')) + .use(require('./lib/plugins/desaturate.js')) + .use(require('./lib/plugins/greyscale.js')) + .use(require('./lib/plugins/lighten.js')) + .use(require('./lib/plugins/mix.js')) + .use(require('./lib/plugins/negate.js')) + .use(require('./lib/plugins/opaquer.js')) + .use(require('./lib/plugins/rotate.js')) + .use(require('./lib/plugins/saturate.js')) + .use(require('./lib/plugins/toAlpha.js')); diff --git a/lib/CMYK.js b/lib/CMYK.js new file mode 100644 index 0000000..8d97461 --- /dev/null +++ b/lib/CMYK.js @@ -0,0 +1,30 @@ +module.exports = function CMYK(color) { + color.installColorSpace('CMYK', ['cyan', 'magenta', 'yellow', 'black', 'alpha'], { + rgb: function () { + return new color.RGB((1 - this._cyan * (1 - this._black) - this._black), + (1 - this._magenta * (1 - this._black) - this._black), + (1 - this._yellow * (1 - this._black) - this._black), + this._alpha); + }, + + fromRgb: function () { // Becomes one.color.RGB.prototype.cmyk + // Adapted from http://www.javascripter.net/faq/rgb2cmyk.htm + var red = this._red, + green = this._green, + blue = this._blue, + cyan = 1 - red, + magenta = 1 - green, + yellow = 1 - blue, + black = 1; + if (red || green || blue) { + black = Math.min(cyan, Math.min(magenta, yellow)); + cyan = (cyan - black) / (1 - black); + magenta = (magenta - black) / (1 - black); + yellow = (yellow - black) / (1 - black); + } else { + black = 1; + } + return new color.CMYK(cyan, magenta, yellow, black, this._alpha); + } + }); +}; diff --git a/lib/HSL.js b/lib/HSL.js new file mode 100644 index 0000000..60f8d18 --- /dev/null +++ b/lib/HSL.js @@ -0,0 +1,29 @@ +module.exports = function HSL(color) { + color.use(require('./HSV')); + + color.installColorSpace('HSL', ['hue', 'saturation', 'lightness', 'alpha'], { + hsv: function () { + // Algorithm adapted from http://wiki.secondlife.com/wiki/Color_conversion_scripts + var l = this._lightness * 2, + s = this._saturation * ((l <= 1) ? l : 2 - l), + saturation; + + // Avoid division by zero when l + s is very small (approaching black): + if (l + s < 1e-9) { + saturation = 0; + } else { + saturation = (2 * s) / (l + s); + } + + return new color.HSV(this._hue, saturation, (l + s) / 2, this._alpha); + }, + + rgb: function () { + return this.hsv().rgb(); + }, + + fromRgb: function () { // Becomes one.color.RGB.prototype.hsv + return this.hsv().hsl(); + } + }); +}; diff --git a/lib/HSV.js b/lib/HSV.js new file mode 100644 index 0000000..246a498 --- /dev/null +++ b/lib/HSV.js @@ -0,0 +1,93 @@ +module.exports = function HSV(color) { + color.installColorSpace('HSV', ['hue', 'saturation', 'value', 'alpha'], { + rgb: function () { + var hue = this._hue, + saturation = this._saturation, + value = this._value, + i = Math.min(5, Math.floor(hue * 6)), + f = hue * 6 - i, + p = value * (1 - saturation), + q = value * (1 - f * saturation), + t = value * (1 - (1 - f) * saturation), + red, + green, + blue; + switch (i) { + case 0: + red = value; + green = t; + blue = p; + break; + case 1: + red = q; + green = value; + blue = p; + break; + case 2: + red = p; + green = value; + blue = t; + break; + case 3: + red = p; + green = q; + blue = value; + break; + case 4: + red = t; + green = p; + blue = value; + break; + case 5: + red = value; + green = p; + blue = q; + break; + } + return new color.RGB(red, green, blue, this._alpha); + }, + + hsl: function () { + var l = (2 - this._saturation) * this._value, + sv = this._saturation * this._value, + svDivisor = l <= 1 ? l : (2 - l), + saturation; + + // Avoid division by zero when lightness approaches zero: + if (svDivisor < 1e-9) { + saturation = 0; + } else { + saturation = sv / svDivisor; + } + return new color.HSL(this._hue, saturation, l / 2, this._alpha); + }, + + fromRgb: function () { // Becomes one.color.RGB.prototype.hsv + var red = this._red, + green = this._green, + blue = this._blue, + max = Math.max(red, green, blue), + min = Math.min(red, green, blue), + delta = max - min, + hue, + saturation = (max === 0) ? 0 : (delta / max), + value = max; + if (delta === 0) { + hue = 0; + } else { + switch (max) { + case red: + hue = (green - blue) / delta / 6 + (green < blue ? 1 : 0); + break; + case green: + hue = (blue - red) / delta / 6 + 1 / 3; + break; + case blue: + hue = (red - green) / delta / 6 + 2 / 3; + break; + } + } + return new color.HSV(hue, saturation, value, this._alpha); + } + }); +}; diff --git a/lib/LAB.js b/lib/LAB.js new file mode 100644 index 0000000..1b91813 --- /dev/null +++ b/lib/LAB.js @@ -0,0 +1,33 @@ +module.exports = function LAB(color) { + color.use(require('./XYZ.js')); + + color.installColorSpace('LAB', ['l', 'a', 'b', 'alpha'], { + fromRgb: function () { + return this.xyz().lab(); + }, + + rgb: function () { + return this.xyz().rgb(); + }, + + xyz: function () { + // http://www.easyrgb.com/index.php?X=MATH&H=08#text8 + var convert = function (channel) { + var pow = Math.pow(channel, 3); + return pow > 0.008856 ? + pow : + (channel - 16 / 116) / 7.87; + }, + y = (this._l + 16) / 116, + x = this._a / 500 + y, + z = y - this._b / 200; + + return new color.XYZ( + convert(x) * 95.047, + convert(y) * 100.000, + convert(z) * 108.883, + this._alpha + ); + } + }); +}; diff --git a/lib/XYZ.js b/lib/XYZ.js new file mode 100644 index 0000000..4657bc0 --- /dev/null +++ b/lib/XYZ.js @@ -0,0 +1,64 @@ +module.exports = function XYZ(color) { + color.installColorSpace('XYZ', ['x', 'y', 'z', 'alpha'], { + fromRgb: function () { + // http://www.easyrgb.com/index.php?X=MATH&H=02#text2 + var convert = function (channel) { + return channel > 0.04045 ? + Math.pow((channel + 0.055) / 1.055, 2.4) : + channel / 12.92; + }, + r = convert(this._red), + g = convert(this._green), + b = convert(this._blue); + + // Reference white point sRGB D65: + // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + return new color.XYZ( + r * 0.4124564 + g * 0.3575761 + b * 0.1804375, + r * 0.2126729 + g * 0.7151522 + b * 0.0721750, + r * 0.0193339 + g * 0.1191920 + b * 0.9503041, + this._alpha + ); + }, + + rgb: function () { + // http://www.easyrgb.com/index.php?X=MATH&H=01#text1 + var x = this._x, + y = this._y, + z = this._z, + convert = function (channel) { + return channel > 0.0031308 ? + 1.055 * Math.pow(channel, 1 / 2.4) - 0.055 : + 12.92 * channel; + }; + + // Reference white point sRGB D65: + // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + return new colorRGB( + convert(x * 3.2404542 + y * -1.5371385 + z * -0.4985314), + convert(x * -0.9692660 + y * 1.8760108 + z * 0.0415560), + convert(x * 0.0556434 + y * -0.2040259 + z * 1.0572252), + this._alpha + ); + }, + + lab: function () { + // http://www.easyrgb.com/index.php?X=MATH&H=07#text7 + var convert = function (channel) { + return channel > 0.008856 ? + Math.pow(channel, 1 / 3) : + 7.787037 * channel + 4 / 29; + }, + x = convert(this._x / 95.047), + y = convert(this._y / 100.000), + z = convert(this._z / 108.883); + + return new color.LAB( + (116 * y) - 16, + 500 * (x - y), + 200 * (y - z), + this._alpha + ); + } + }); +}; diff --git a/lib/color-namedColors.js b/lib/color-namedColors.js deleted file mode 100644 index ff80174..0000000 --- a/lib/color-namedColors.js +++ /dev/null @@ -1,151 +0,0 @@ -/*global namedColors*/ -namedColors = { - aliceblue: 'f0f8ff', - antiquewhite: 'faebd7', - aqua: '0ff', - aquamarine: '7fffd4', - azure: 'f0ffff', - beige: 'f5f5dc', - bisque: 'ffe4c4', - black: '000', - blanchedalmond: 'ffebcd', - blue: '00f', - blueviolet: '8a2be2', - brown: 'a52a2a', - burlywood: 'deb887', - cadetblue: '5f9ea0', - chartreuse: '7fff00', - chocolate: 'd2691e', - coral: 'ff7f50', - cornflowerblue: '6495ed', - cornsilk: 'fff8dc', - crimson: 'dc143c', - cyan: '0ff', - darkblue: '00008b', - darkcyan: '008b8b', - darkgoldenrod: 'b8860b', - darkgray: 'a9a9a9', - darkgrey: 'a9a9a9', - darkgreen: '006400', - darkkhaki: 'bdb76b', - darkmagenta: '8b008b', - darkolivegreen: '556b2f', - darkorange: 'ff8c00', - darkorchid: '9932cc', - darkred: '8b0000', - darksalmon: 'e9967a', - darkseagreen: '8fbc8f', - darkslateblue: '483d8b', - darkslategray: '2f4f4f', - darkslategrey: '2f4f4f', - darkturquoise: '00ced1', - darkviolet: '9400d3', - deeppink: 'ff1493', - deepskyblue: '00bfff', - dimgray: '696969', - dimgrey: '696969', - dodgerblue: '1e90ff', - firebrick: 'b22222', - floralwhite: 'fffaf0', - forestgreen: '228b22', - fuchsia: 'f0f', - gainsboro: 'dcdcdc', - ghostwhite: 'f8f8ff', - gold: 'ffd700', - goldenrod: 'daa520', - gray: '808080', - grey: '808080', - green: '008000', - greenyellow: 'adff2f', - honeydew: 'f0fff0', - hotpink: 'ff69b4', - indianred: 'cd5c5c', - indigo: '4b0082', - ivory: 'fffff0', - khaki: 'f0e68c', - lavender: 'e6e6fa', - lavenderblush: 'fff0f5', - lawngreen: '7cfc00', - lemonchiffon: 'fffacd', - lightblue: 'add8e6', - lightcoral: 'f08080', - lightcyan: 'e0ffff', - lightgoldenrodyellow: 'fafad2', - lightgray: 'd3d3d3', - lightgrey: 'd3d3d3', - lightgreen: '90ee90', - lightpink: 'ffb6c1', - lightsalmon: 'ffa07a', - lightseagreen: '20b2aa', - lightskyblue: '87cefa', - lightslategray: '789', - lightslategrey: '789', - lightsteelblue: 'b0c4de', - lightyellow: 'ffffe0', - lime: '0f0', - limegreen: '32cd32', - linen: 'faf0e6', - magenta: 'f0f', - maroon: '800000', - mediumaquamarine: '66cdaa', - mediumblue: '0000cd', - mediumorchid: 'ba55d3', - mediumpurple: '9370d8', - mediumseagreen: '3cb371', - mediumslateblue: '7b68ee', - mediumspringgreen: '00fa9a', - mediumturquoise: '48d1cc', - mediumvioletred: 'c71585', - midnightblue: '191970', - mintcream: 'f5fffa', - mistyrose: 'ffe4e1', - moccasin: 'ffe4b5', - navajowhite: 'ffdead', - navy: '000080', - oldlace: 'fdf5e6', - olive: '808000', - olivedrab: '6b8e23', - orange: 'ffa500', - orangered: 'ff4500', - orchid: 'da70d6', - palegoldenrod: 'eee8aa', - palegreen: '98fb98', - paleturquoise: 'afeeee', - palevioletred: 'd87093', - papayawhip: 'ffefd5', - peachpuff: 'ffdab9', - peru: 'cd853f', - pink: 'ffc0cb', - plum: 'dda0dd', - powderblue: 'b0e0e6', - purple: '800080', - rebeccapurple: '639', - red: 'f00', - rosybrown: 'bc8f8f', - royalblue: '4169e1', - saddlebrown: '8b4513', - salmon: 'fa8072', - sandybrown: 'f4a460', - seagreen: '2e8b57', - seashell: 'fff5ee', - sienna: 'a0522d', - silver: 'c0c0c0', - skyblue: '87ceeb', - slateblue: '6a5acd', - slategray: '708090', - slategrey: '708090', - snow: 'fffafa', - springgreen: '00ff7f', - steelblue: '4682b4', - tan: 'd2b48c', - teal: '008080', - thistle: 'd8bfd8', - tomato: 'ff6347', - turquoise: '40e0d0', - violet: 'ee82ee', - wheat: 'f5deb3', - white: 'fff', - whitesmoke: 'f5f5f5', - yellow: 'ff0', - yellowgreen: '9acd32' -}; diff --git a/lib/color.js b/lib/color.js index 27af486..726d376 100644 --- a/lib/color.js +++ b/lib/color.js @@ -1,7 +1,6 @@ -/*jshint evil:true, onevar:false*/ +/*jshint onevar:false*/ /*global define*/ var installedColorSpaces = [], - namedColors = {}, undef = function (obj) { return typeof obj === 'undefined'; }, @@ -17,19 +16,19 @@ var installedColorSpaces = [], "(?:," + alphaChannelRegExp.source + ")?" + "\\)$", "i"); -function ONECOLOR(obj) { - if (Object.prototype.toString.apply(obj) === '[object Array]') { - if (typeof obj[0] === 'string' && typeof ONECOLOR[obj[0]] === 'function') { +function color(obj) { + if (Array.isArray(obj)) { + if (typeof obj[0] === 'string' && typeof color[obj[0]] === 'function') { // Assumed array from .toJSON() - return new ONECOLOR[obj[0]](obj.slice(1, obj.length)); + return new color[obj[0]](obj.slice(1, obj.length)); } else if (obj.length === 4) { // Assumed 4 element int RGB array from canvas with all channels [0;255] - return new ONECOLOR.RGB(obj[0] / 255, obj[1] / 255, obj[2] / 255, obj[3] / 255); + return new color.RGB(obj[0] / 255, obj[1] / 255, obj[2] / 255, obj[3] / 255); } } else if (typeof obj === 'string') { var lowerCased = obj.toLowerCase(); - if (namedColors[lowerCased]) { - obj = '#' + namedColors[lowerCased]; + if (color.namedColors[lowerCased]) { + obj = '#' + color.namedColors[lowerCased]; } if (lowerCased === 'transparent') { obj = 'rgba(0,0,0,0)'; @@ -43,10 +42,10 @@ function ONECOLOR(obj) { firstChannelDivisor = matchCssSyntax[3] ? 100 : (hasHue ? 360 : 255), secondChannelDivisor = (matchCssSyntax[5] || hasHue) ? 100 : 255, thirdChannelDivisor = (matchCssSyntax[7] || hasHue) ? 100 : 255; - if (undef(ONECOLOR[colorSpaceName])) { - throw new Error("one.color." + colorSpaceName + " is not installed."); + if (undef(color[colorSpaceName])) { + throw new Error('color.' + colorSpaceName + ' is not installed.'); } - return new ONECOLOR[colorSpaceName]( + return new color[colorSpaceName]( parseFloat(matchCssSyntax[2]) / firstChannelDivisor, parseFloat(matchCssSyntax[4]) / secondChannelDivisor, parseFloat(matchCssSyntax[6]) / thirdChannelDivisor, @@ -61,7 +60,7 @@ function ONECOLOR(obj) { // Split obj into red, green, and blue components var hexMatch = obj.match(/^#?([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/i); if (hexMatch) { - return new ONECOLOR.RGB( + return new color.RGB( parseInt(hexMatch[1], 16) / 255, parseInt(hexMatch[2], 16) / 255, parseInt(hexMatch[3], 16) / 255 @@ -69,7 +68,7 @@ function ONECOLOR(obj) { } // No match so far. Lets try the less likely ones - if (ONECOLOR.CMYK) { + if (color.CMYK) { var cmykMatch = obj.match(new RegExp( "^cmyk" + "\\(" + @@ -79,7 +78,7 @@ function ONECOLOR(obj) { percentageChannelRegExp.source + "\\)$", "i")); if (cmykMatch) { - return new ONECOLOR.CMYK( + return new color.CMYK( parseFloat(cmykMatch[1]) / 100, parseFloat(cmykMatch[2]) / 100, parseFloat(cmykMatch[3]) / 100, @@ -93,35 +92,35 @@ function ONECOLOR(obj) { return false; } -function installColorSpace(colorSpaceName, propertyNames, config) { - ONECOLOR[colorSpaceName] = new Function(propertyNames.join(","), - // Allow passing an array to the constructor: - "if (Object.prototype.toString.apply(" + propertyNames[0] + ") === '[object Array]') {" + - propertyNames.map(function (propertyName, i) { - return propertyName + "=" + propertyNames[0] + "[" + i + "];"; - }).reverse().join("") + - "}" + - "if (" + propertyNames.filter(function (propertyName) { - return propertyName !== 'alpha'; - }).map(function (propertyName) { - return "isNaN(" + propertyName + ")"; - }).join("||") + "){" + "throw new Error(\"[" + colorSpaceName + "]: Invalid color: (\"+" + propertyNames.join("+\",\"+") + "+\")\");}" + - propertyNames.map(function (propertyName) { - if (propertyName === 'hue') { - return "this._hue=hue<0?hue-Math.floor(hue):hue%1"; // Wrap - } else if (propertyName === 'alpha') { - return "this._alpha=(isNaN(alpha)||alpha>1)?1:(alpha<0?0:alpha);"; +color.namedColors = {}; + +color.installColorSpace = function (colorSpaceName, propertyNames, config) { + color[colorSpaceName] = function (a1) { // ... + var args = Array.isArray(a1) ? a1 : arguments; + propertyNames.forEach(function (propertyName, i) { + var propertyValue = args[i]; + if (propertyName === 'alpha') { + this._alpha = (isNaN(propertyValue) || propertyValue > 1) ? 1 : (propertyValue < 0 ? 0 : propertyValue); } else { - return "this._" + propertyName + "=" + propertyName + "<0?0:(" + propertyName + ">1?1:" + propertyName + ")"; + if (isNaN(propertyValue)) { + throw new Error('[' + colorSpaceName + ']: Invalid color: (' + propertyNames.join(',') + ')'); + } + if (propertyName === 'hue') { + this._hue = propertyValue < 0 ? propertyValue - Math.floor(propertyValue) : propertyValue % 1; + } else { + this['_' + propertyName] = propertyValue < 0 ? 0 : (propertyValue > 1 ? 1 : propertyValue); + } } - }).join(";") + ";" - ); - ONECOLOR[colorSpaceName].propertyNames = propertyNames; + }, this); + }; + color[colorSpaceName].propertyNames = propertyNames; - var prototype = ONECOLOR[colorSpaceName].prototype; + var prototype = color[colorSpaceName].prototype; ['valueOf', 'hex', 'hexa', 'css', 'cssa'].forEach(function (methodName) { - prototype[methodName] = prototype[methodName] || (colorSpaceName === 'RGB' ? prototype.hex : new Function("return this.rgb()." + methodName + "();")); + prototype[methodName] = prototype[methodName] || (colorSpaceName === 'RGB' ? prototype.hex : function () { + return this.rgb()[methodName](); + }); }); prototype.isColor = true; @@ -142,19 +141,17 @@ function installColorSpace(colorSpaceName, propertyNames, config) { return true; }; - prototype.toJSON = new Function( - "return ['" + colorSpaceName + "', " + - propertyNames.map(function (propertyName) { - return "this._" + propertyName; - }, this).join(", ") + - "];" - ); + prototype.toJSON = function () { + return '[' + colorSpaceName + ' ' + propertyNames.map(function (propertyName) { + return this['_' + propertyName]; + }).join(', ') + ']'; + }; for (var propertyName in config) { if (config.hasOwnProperty(propertyName)) { var matchFromColorSpace = propertyName.match(/^from(.*)$/); if (matchFromColorSpace) { - ONECOLOR[matchFromColorSpace[1].toUpperCase()].prototype[colorSpaceName.toLowerCase()] = config[propertyName]; + color[matchFromColorSpace[1].toUpperCase()].prototype[colorSpaceName.toLowerCase()] = config[propertyName]; } else { prototype[propertyName] = config[propertyName]; } @@ -165,38 +162,47 @@ function installColorSpace(colorSpaceName, propertyNames, config) { prototype[colorSpaceName.toLowerCase()] = function () { return this; }; - prototype.toString = new Function("return \"[one.color." + colorSpaceName + ":\"+" + propertyNames.map(function (propertyName, i) { - return "\" " + propertyNames[i] + "=\"+this._" + propertyName; - }).join("+") + "+\"]\";"); + prototype.toString = function () { + return '[' + colorSpaceName + ' ' + propertyNames.map(function (propertyName) { + return this['_' + propertyName]; + }).join(', ') + ']'; + }; // Generate getters and setters propertyNames.forEach(function (propertyName, i) { - prototype[propertyName] = prototype[propertyName === 'black' ? 'k' : propertyName[0]] = new Function("value", "isDelta", + var shortName = propertyName === 'black' ? 'k' : propertyName.charAt(0); + prototype[propertyName] = prototype[shortName] = function (value, isDelta) { // Simple getter mode: color.red() - "if (typeof value === 'undefined') {" + - "return this._" + propertyName + ";" + - "}" + - // Adjuster: color.red(+.2, true) - "if (isDelta) {" + - "return new this.constructor(" + propertyNames.map(function (otherPropertyName, i) { - return "this._" + otherPropertyName + (propertyName === otherPropertyName ? "+value" : ""); - }).join(", ") + ");" + - "}" + - // Setter: color.red(.2); - "return new this.constructor(" + propertyNames.map(function (otherPropertyName, i) { - return propertyName === otherPropertyName ? "value" : "this._" + otherPropertyName; - }).join(", ") + ");"); + if (typeof value === 'undefined') { + return this['_' + propertyName]; + } else if (isDelta) { + // Adjuster: color.red(+.2, true) + return new this.constructor(propertyNames.map(function (otherPropertyName, i) { + return this['_' + otherPropertyName] + (propertyName === otherPropertyName ? value : 0); + }, this)); + } else { + // Setter: color.red(.2); + return new this.constructor(propertyNames.map(function (otherPropertyName, i) { + return (propertyName === otherPropertyName) ? value : this['_' + otherPropertyName]; + }, this)); + } + }; }); function installForeignMethods(targetColorSpaceName, sourceColorSpaceName) { var obj = {}; - obj[sourceColorSpaceName.toLowerCase()] = new Function("return this.rgb()." + sourceColorSpaceName.toLowerCase() + "();"); // Fallback - ONECOLOR[sourceColorSpaceName].propertyNames.forEach(function (propertyName, i) { - obj[propertyName] = obj[propertyName === 'black' ? 'k' : propertyName[0]] = new Function("value", "isDelta", "return this." + sourceColorSpaceName.toLowerCase() + "()." + propertyName + "(value, isDelta);"); + obj[sourceColorSpaceName.toLowerCase()] = function () { + return this.rgb()[sourceColorSpaceName.toLowerCase()](); + }; + color[sourceColorSpaceName].propertyNames.forEach(function (propertyName, i) { + var shortName = propertyName === 'black' ? 'k' : propertyName.charAt(0); + obj[propertyName] = obj[shortName] = function (value, isDelta) { + return this[sourceColorSpaceName.toLowerCase()]()[propertyName](value, isDelta); + }; }); for (var prop in obj) { - if (obj.hasOwnProperty(prop) && ONECOLOR[targetColorSpaceName].prototype[prop] === undefined) { - ONECOLOR[targetColorSpaceName].prototype[prop] = obj[prop]; + if (obj.hasOwnProperty(prop) && color[targetColorSpaceName].prototype[prop] === undefined) { + color[targetColorSpaceName].prototype[prop] = obj[prop]; } } } @@ -207,15 +213,27 @@ function installColorSpace(colorSpaceName, propertyNames, config) { }); installedColorSpaces.push(colorSpaceName); -} + return color; +}; + +color.pluginByName = {}; + +color.use = function (plugin) { + var pluginName = plugin.name; + if (typeof pluginName !== 'string' || !this.pluginByName[pluginName]) { + this.pluginByName[pluginName] = plugin; + plugin(color); + } + return color; +}; -ONECOLOR.installMethod = function (name, fn) { +color.installMethod = function (name, fn) { installedColorSpaces.forEach(function (colorSpace) { - ONECOLOR[colorSpace].prototype[name] = fn; + color[colorSpace].prototype[name] = fn; }); }; -installColorSpace('RGB', ['red', 'green', 'blue', 'alpha'], { +color.installColorSpace('RGB', ['red', 'green', 'blue', 'alpha'], { hex: function () { var hexString = (Math.round(255 * this._red) * 0x10000 + Math.round(255 * this._green) * 0x100 + Math.round(255 * this._blue)).toString(16); return '#' + ('00000'.substr(0, 6 - hexString.length)) + hexString; @@ -234,18 +252,5 @@ installColorSpace('RGB', ['red', 'green', 'blue', 'alpha'], { return "rgba(" + Math.round(255 * this._red) + "," + Math.round(255 * this._green) + "," + Math.round(255 * this._blue) + "," + this._alpha + ")"; } }); -if (typeof define === 'function' && !undef(define.amd)) { - define(function () { - return ONECOLOR; - }); -} else if (typeof exports === 'object') { - // Node module export - module.exports = ONECOLOR; -} else { - one = window.one || {}; - one.color = ONECOLOR; -} -if (typeof jQuery !== 'undefined' && undef(jQuery.color)) { - jQuery.color = ONECOLOR; -} +module.exports = color; diff --git a/lib/color/CMYK.js b/lib/color/CMYK.js deleted file mode 100644 index 7c8d4f5..0000000 --- a/lib/color/CMYK.js +++ /dev/null @@ -1,31 +0,0 @@ -/*global one*/ -INCLUDE('lib:color.js'); - -installColorSpace('CMYK', ['cyan', 'magenta', 'yellow', 'black', 'alpha'], { - rgb: function () { - return new ONECOLOR.RGB((1 - this._cyan * (1 - this._black) - this._black), - (1 - this._magenta * (1 - this._black) - this._black), - (1 - this._yellow * (1 - this._black) - this._black), - this._alpha); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.cmyk - // Adapted from http://www.javascripter.net/faq/rgb2cmyk.htm - var red = this._red, - green = this._green, - blue = this._blue, - cyan = 1 - red, - magenta = 1 - green, - yellow = 1 - blue, - black = 1; - if (red || green || blue) { - black = Math.min(cyan, Math.min(magenta, yellow)); - cyan = (cyan - black) / (1 - black); - magenta = (magenta - black) / (1 - black); - yellow = (yellow - black) / (1 - black); - } else { - black = 1; - } - return new ONECOLOR.CMYK(cyan, magenta, yellow, black, this._alpha); - } -}); diff --git a/lib/color/HSL.js b/lib/color/HSL.js deleted file mode 100644 index d51cebc..0000000 --- a/lib/color/HSL.js +++ /dev/null @@ -1,30 +0,0 @@ -/*global one*/ -INCLUDE('lib:color.js'); - -INCLUDE('lib:color/HSV.js'); - -installColorSpace('HSL', ['hue', 'saturation', 'lightness', 'alpha'], { - hsv: function () { - // Algorithm adapted from http://wiki.secondlife.com/wiki/Color_conversion_scripts - var l = this._lightness * 2, - s = this._saturation * ((l <= 1) ? l : 2 - l), - saturation; - - // Avoid division by zero when l + s is very small (approaching black): - if (l + s < 1e-9) { - saturation = 0; - } else { - saturation = (2 * s) / (l + s); - } - - return new ONECOLOR.HSV(this._hue, saturation, (l + s) / 2, this._alpha); - }, - - rgb: function () { - return this.hsv().rgb(); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.hsv - return this.hsv().hsl(); - } -}); diff --git a/lib/color/HSV.js b/lib/color/HSV.js deleted file mode 100644 index f2527d4..0000000 --- a/lib/color/HSV.js +++ /dev/null @@ -1,94 +0,0 @@ -/*global one*/ -INCLUDE('lib:color.js'); - -installColorSpace('HSV', ['hue', 'saturation', 'value', 'alpha'], { - rgb: function () { - var hue = this._hue, - saturation = this._saturation, - value = this._value, - i = Math.min(5, Math.floor(hue * 6)), - f = hue * 6 - i, - p = value * (1 - saturation), - q = value * (1 - f * saturation), - t = value * (1 - (1 - f) * saturation), - red, - green, - blue; - switch (i) { - case 0: - red = value; - green = t; - blue = p; - break; - case 1: - red = q; - green = value; - blue = p; - break; - case 2: - red = p; - green = value; - blue = t; - break; - case 3: - red = p; - green = q; - blue = value; - break; - case 4: - red = t; - green = p; - blue = value; - break; - case 5: - red = value; - green = p; - blue = q; - break; - } - return new ONECOLOR.RGB(red, green, blue, this._alpha); - }, - - hsl: function () { - var l = (2 - this._saturation) * this._value, - sv = this._saturation * this._value, - svDivisor = l <= 1 ? l : (2 - l), - saturation; - - // Avoid division by zero when lightness approaches zero: - if (svDivisor < 1e-9) { - saturation = 0; - } else { - saturation = sv / svDivisor; - } - return new ONECOLOR.HSL(this._hue, saturation, l / 2, this._alpha); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.hsv - var red = this._red, - green = this._green, - blue = this._blue, - max = Math.max(red, green, blue), - min = Math.min(red, green, blue), - delta = max - min, - hue, - saturation = (max === 0) ? 0 : (delta / max), - value = max; - if (delta === 0) { - hue = 0; - } else { - switch (max) { - case red: - hue = (green - blue) / delta / 6 + (green < blue ? 1 : 0); - break; - case green: - hue = (blue - red) / delta / 6 + 1 / 3; - break; - case blue: - hue = (red - green) / delta / 6 + 2 / 3; - break; - } - } - return new ONECOLOR.HSV(hue, saturation, value, this._alpha); - } -}); diff --git a/lib/color/LAB.js b/lib/color/LAB.js deleted file mode 100644 index a28d622..0000000 --- a/lib/color/LAB.js +++ /dev/null @@ -1,33 +0,0 @@ -/*global INCLUDE, installColorSpace, ONECOLOR*/ -INCLUDE('lib:color.js'); -INCLUDE('lib:color/XYZ.js'); - -installColorSpace('LAB', ['l', 'a', 'b', 'alpha'], { - fromRgb: function () { - return this.xyz().lab(); - }, - - rgb: function () { - return this.xyz().rgb(); - }, - - xyz: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=08#text8 - var convert = function (channel) { - var pow = Math.pow(channel, 3); - return pow > 0.008856 ? - pow : - (channel - 16 / 116) / 7.87; - }, - y = (this._l + 16) / 116, - x = this._a / 500 + y, - z = y - this._b / 200; - - return new ONECOLOR.XYZ( - convert(x) * 95.047, - convert(y) * 100.000, - convert(z) * 108.883, - this._alpha - ); - } -}); diff --git a/lib/color/XYZ.js b/lib/color/XYZ.js deleted file mode 100644 index 87104b1..0000000 --- a/lib/color/XYZ.js +++ /dev/null @@ -1,65 +0,0 @@ -/*global INCLUDE, installColorSpace, ONECOLOR*/ -INCLUDE('lib:color.js'); - -installColorSpace('XYZ', ['x', 'y', 'z', 'alpha'], { - fromRgb: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=02#text2 - var convert = function (channel) { - return channel > 0.04045 ? - Math.pow((channel + 0.055) / 1.055, 2.4) : - channel / 12.92; - }, - r = convert(this._red), - g = convert(this._green), - b = convert(this._blue); - - // Reference white point sRGB D65: - // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html - return new ONECOLOR.XYZ( - r * 0.4124564 + g * 0.3575761 + b * 0.1804375, - r * 0.2126729 + g * 0.7151522 + b * 0.0721750, - r * 0.0193339 + g * 0.1191920 + b * 0.9503041, - this._alpha - ); - }, - - rgb: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=01#text1 - var x = this._x, - y = this._y, - z = this._z, - convert = function (channel) { - return channel > 0.0031308 ? - 1.055 * Math.pow(channel, 1 / 2.4) - 0.055 : - 12.92 * channel; - }; - - // Reference white point sRGB D65: - // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html - return new ONECOLOR.RGB( - convert(x * 3.2404542 + y * -1.5371385 + z * -0.4985314), - convert(x * -0.9692660 + y * 1.8760108 + z * 0.0415560), - convert(x * 0.0556434 + y * -0.2040259 + z * 1.0572252), - this._alpha - ); - }, - - lab: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=07#text7 - var convert = function (channel) { - return channel > 0.008856 ? - Math.pow(channel, 1 / 3) : - 7.787037 * channel + 4 / 29; - }, - x = convert(this._x / 95.047), - y = convert(this._y / 100.000), - z = convert(this._z / 108.883); - - return new ONECOLOR.LAB( - (116 * y) - 16, - 500 * (x - y), - 200 * (y - z), - this._alpha - ); - } -}); diff --git a/lib/color/_all.js b/lib/color/_all.js deleted file mode 100644 index 072e519..0000000 --- a/lib/color/_all.js +++ /dev/null @@ -1,25 +0,0 @@ -/*global one*/ - -// This file is purely for the build system -INCLUDE('lib:color.js'); -INCLUDE('lib:color-namedColors.js'); - -// Order is important to prevent channel name clashes. Lab <-> hsL -INCLUDE('lib:color/XYZ.js'); -INCLUDE('lib:color/LAB.js'); -INCLUDE('lib:color/HSV.js'); -INCLUDE('lib:color/HSL.js'); -INCLUDE('lib:color/CMYK.js'); - -// Convenience functions -INCLUDE('lib:color/plugins/clearer.js'); -INCLUDE('lib:color/plugins/darken.js'); -INCLUDE('lib:color/plugins/desaturate.js'); -INCLUDE('lib:color/plugins/greyscale.js'); -INCLUDE('lib:color/plugins/lighten.js'); -INCLUDE('lib:color/plugins/mix.js'); -INCLUDE('lib:color/plugins/negate.js'); -INCLUDE('lib:color/plugins/opaquer.js'); -INCLUDE('lib:color/plugins/rotate.js'); -INCLUDE('lib:color/plugins/saturate.js'); -INCLUDE('lib:color/plugins/toAlpha.js'); diff --git a/lib/color/_base.js b/lib/color/_base.js deleted file mode 100644 index 48579e7..0000000 --- a/lib/color/_base.js +++ /dev/null @@ -1,6 +0,0 @@ -/*global one*/ - -// This file is purely for the build system -INCLUDE('lib:color.js'); -INCLUDE('lib:color/HSV.js'); -INCLUDE('lib:color/HSL.js'); diff --git a/lib/color/plugins/clearer.js b/lib/color/plugins/clearer.js deleted file mode 100644 index 73e6528..0000000 --- a/lib/color/plugins/clearer.js +++ /dev/null @@ -1,3 +0,0 @@ -ONECOLOR.installMethod('clearer', function (amount) { - return this.alpha(isNaN(amount) ? -0.1 : -amount, true); -}); diff --git a/lib/color/plugins/darken.js b/lib/color/plugins/darken.js deleted file mode 100644 index 04d7616..0000000 --- a/lib/color/plugins/darken.js +++ /dev/null @@ -1,5 +0,0 @@ -INCLUDE('../HSL.js'); - -ONECOLOR.installMethod('darken', function (amount) { - return this.lightness(isNaN(amount) ? -0.1 : -amount, true); -}); diff --git a/lib/color/plugins/desaturate.js b/lib/color/plugins/desaturate.js deleted file mode 100644 index 49f902e..0000000 --- a/lib/color/plugins/desaturate.js +++ /dev/null @@ -1,5 +0,0 @@ -INCLUDE('../HSL.js'); - -ONECOLOR.installMethod('desaturate', function (amount) { - return this.saturation(isNaN(amount) ? -0.1 : -amount, true); -}); diff --git a/lib/color/plugins/greyscale.js b/lib/color/plugins/greyscale.js deleted file mode 100644 index 5560443..0000000 --- a/lib/color/plugins/greyscale.js +++ /dev/null @@ -1,9 +0,0 @@ -function gs () { - var rgb = this.rgb(), - val = rgb._red * 0.3 + rgb._green * 0.59 + rgb._blue * 0.11; - - return new ONECOLOR.RGB(val, val, val, this._alpha); -}; - -ONECOLOR.installMethod('greyscale', gs); -ONECOLOR.installMethod('grayscale', gs); diff --git a/lib/color/plugins/lighten.js b/lib/color/plugins/lighten.js deleted file mode 100644 index 86667cf..0000000 --- a/lib/color/plugins/lighten.js +++ /dev/null @@ -1,5 +0,0 @@ -INCLUDE('../HSL.js'); - -ONECOLOR.installMethod('lighten', function (amount) { - return this.lightness(isNaN(amount) ? 0.1 : amount, true); -}); diff --git a/lib/color/plugins/mix.js b/lib/color/plugins/mix.js deleted file mode 100644 index 4e4fb26..0000000 --- a/lib/color/plugins/mix.js +++ /dev/null @@ -1,17 +0,0 @@ -ONECOLOR.installMethod('mix', function (otherColor, weight) { - otherColor = ONECOLOR(otherColor).rgb(); - weight = 1 - (isNaN(weight) ? 0.5 : weight); - - var w = weight * 2 - 1, - a = this._alpha - otherColor._alpha, - weight1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2, - weight2 = 1 - weight1, - rgb = this.rgb(); - - return new ONECOLOR.RGB( - rgb._red * weight1 + otherColor._red * weight2, - rgb._green * weight1 + otherColor._green * weight2, - rgb._blue * weight1 + otherColor._blue * weight2, - rgb._alpha * weight + otherColor._alpha * (1 - weight) - ); -}); diff --git a/lib/color/plugins/negate.js b/lib/color/plugins/negate.js deleted file mode 100644 index eb42b52..0000000 --- a/lib/color/plugins/negate.js +++ /dev/null @@ -1,4 +0,0 @@ -ONECOLOR.installMethod('negate', function () { - var rgb = this.rgb(); - return new ONECOLOR.RGB(1 - rgb._red, 1 - rgb._green, 1 - rgb._blue, this._alpha); -}); diff --git a/lib/color/plugins/opaquer.js b/lib/color/plugins/opaquer.js deleted file mode 100644 index dfba843..0000000 --- a/lib/color/plugins/opaquer.js +++ /dev/null @@ -1,3 +0,0 @@ -ONECOLOR.installMethod('opaquer', function (amount) { - return this.alpha(isNaN(amount) ? 0.1 : amount, true); -}); diff --git a/lib/color/plugins/rotate.js b/lib/color/plugins/rotate.js deleted file mode 100644 index cba5677..0000000 --- a/lib/color/plugins/rotate.js +++ /dev/null @@ -1,3 +0,0 @@ -ONECOLOR.installMethod('rotate', function (degrees) { - return this.hue((degrees || 0) / 360, true); -}); diff --git a/lib/color/plugins/saturate.js b/lib/color/plugins/saturate.js deleted file mode 100644 index 0aba5bb..0000000 --- a/lib/color/plugins/saturate.js +++ /dev/null @@ -1,5 +0,0 @@ -INCLUDE('../HSL.js'); - -ONECOLOR.installMethod('saturate', function (amount) { - return this.saturation(isNaN(amount) ? 0.1 : amount, true); -}); diff --git a/lib/color/plugins/toAlpha.js b/lib/color/plugins/toAlpha.js deleted file mode 100644 index 1ffa553..0000000 --- a/lib/color/plugins/toAlpha.js +++ /dev/null @@ -1,46 +0,0 @@ -// Adapted from http://gimp.sourcearchive.com/documentation/2.6.6-1ubuntu1/color-to-alpha_8c-source.html -/* - toAlpha returns a color where the values of the argument have been converted to alpha -*/ -ONECOLOR.installMethod('toAlpha', function (color) { - var me = this.rgb(), - other = ONECOLOR(color).rgb(), - epsilon = 1e-10, - a = new ONECOLOR.RGB(0, 0, 0, me._alpha), - channels = ['_red', '_green', '_blue']; - - channels.forEach(function (channel) { - if (me[channel] < epsilon) { - a[channel] = me[channel]; - } else if (me[channel] > other[channel]) { - a[channel] = (me[channel] - other[channel]) / (1 - other[channel]); - } else if (me[channel] > other[channel]) { - a[channel] = (other[channel] - me[channel]) / other[channel]; - } else { - a[channel] = 0; - } - }); - - if (a._red > a._green) { - if (a._red > a._blue) { - me._alpha = a._red; - } else { - me._alpha = a._blue; - } - } else if (a._green > a._blue) { - me._alpha = a._green; - } else { - me._alpha = a._blue; - } - - if (me._alpha < epsilon) { - return me; - } - - channels.forEach(function (channel) { - me[channel] = (me[channel] - other[channel]) / me._alpha + other[channel]; - }); - me._alpha *= a._alpha; - - return me; -}); diff --git a/lib/ender.js b/lib/ender.js deleted file mode 100644 index 5008d49..0000000 --- a/lib/ender.js +++ /dev/null @@ -1,5 +0,0 @@ -!function ($) { - $.ender({ - color: one.color - }); -}(ender); diff --git a/lib/es5-shim.js b/lib/es5-shim.js deleted file mode 100644 index 740ce82..0000000 --- a/lib/es5-shim.js +++ /dev/null @@ -1,97 +0,0 @@ -// This is copied from es5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js -(function () { - var prepareString = "a"[0] !== "a", - // ES5 9.9 - // http://es5.github.com/#x9.9 - toObject = function (o) { - if (o === null) { // this matches both null and undefined - throw new TypeError("can't convert " + o + " to object"); - } - // If the implementation doesn't support by-index access of - // string characters (ex. IE < 9), split the string - if (prepareString && typeof o === "string" && o) { - return o.split(""); - } - return new Object(o); - }; - - - // ES5 15.4.4.18 - // http://es5.github.com/#x15.4.4.18 - // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach - if (!Array.prototype.forEach) { - Array.prototype.forEach = function forEach(fun /*, thisp*/) { - var self = toObject(this), - thisp = arguments[1], - i = -1, - length = self.length >>> 0; - - // If no callback function or if callback is not a callable function - if (typeof fun !== "function") { - throw new TypeError(); // TODO message - } - - while (++i < length) { - if (i in self) { - // Invoke the callback function with call, passing arguments: - // context, property value, property key, thisArg object context - fun.call(thisp, self[i], i, self); - } - } - }; - } - - // ES5 15.4.4.19 - // http://es5.github.com/#x15.4.4.19 - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map - if (!Array.prototype.map) { - Array.prototype.map = function map(fun /*, thisp*/) { - var self = toObject(this), - length = self.length >>> 0, - result = new Array(length), - thisp = arguments[1], - i; - - // If no callback function or if callback is not a callable function - if (typeof fun !== "function") { - throw new TypeError(fun + " is not a function"); - } - - for (i = 0; i < length; i += 1) { - if (i in self) { - result[i] = fun.call(thisp, self[i], i, self); - } - } - return result; - }; - } - - // ES5 15.4.4.20 - // http://es5.github.com/#x15.4.4.20 - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter - if (!Array.prototype.filter) { - Array.prototype.filter = function filter(fun /*, thisp */) { - var self = toObject(this), - length = self.length >>> 0, - result = [], - value, - thisp = arguments[1], - i; - - // If no callback function or if callback is not a callable function - if (typeof fun !== "function") { - throw new TypeError(fun + " is not a function"); - } - - for (i = 0; i < length; i += 1) { - if (i in self) { - value = self[i]; - if (fun.call(thisp, value, i, self)) { - result.push(value); - } - } - } - return result; - }; - } -}()); diff --git a/lib/plugins/clearer.js b/lib/plugins/clearer.js new file mode 100644 index 0000000..e2b571a --- /dev/null +++ b/lib/plugins/clearer.js @@ -0,0 +1,5 @@ +module.exports = function clearer(color) { + color.installMethod('clearer', function (amount) { + return this.alpha(isNaN(amount) ? -0.1 : -amount, true); + }); +}; diff --git a/lib/plugins/darken.js b/lib/plugins/darken.js new file mode 100644 index 0000000..f0acfd3 --- /dev/null +++ b/lib/plugins/darken.js @@ -0,0 +1,7 @@ +module.exports = function darken(color) { + color.use(require('../HSL')); + + color.installMethod('darken', function (amount) { + return this.lightness(isNaN(amount) ? -0.1 : -amount, true); + }); +}; diff --git a/lib/plugins/desaturate.js b/lib/plugins/desaturate.js new file mode 100644 index 0000000..80ac649 --- /dev/null +++ b/lib/plugins/desaturate.js @@ -0,0 +1,7 @@ +module.exports = function desaturate(color) { + color.use(require('../HSL')); + + color.installMethod('desaturate', function (amount) { + return this.saturation(isNaN(amount) ? -0.1 : -amount, true); + }); +}; diff --git a/lib/plugins/greyscale.js b/lib/plugins/greyscale.js new file mode 100644 index 0000000..3b59de7 --- /dev/null +++ b/lib/plugins/greyscale.js @@ -0,0 +1,11 @@ +module.exports = function grayscale(color) { + function gs () { + var rgb = this.rgb(), + val = rgb._red * 0.3 + rgb._green * 0.59 + rgb._blue * 0.11; + + return new color.RGB(val, val, val, this._alpha); + } + + color.installMethod('greyscale', gs); + color.installMethod('grayscale', gs); +}; diff --git a/lib/plugins/lighten.js b/lib/plugins/lighten.js new file mode 100644 index 0000000..cddcab4 --- /dev/null +++ b/lib/plugins/lighten.js @@ -0,0 +1,7 @@ +module.exports = function lighten(color) { + color.use(require('../HSL')); + + color.installMethod('lighten', function (amount) { + return this.lightness(isNaN(amount) ? 0.1 : amount, true); + }); +}; diff --git a/lib/plugins/mix.js b/lib/plugins/mix.js new file mode 100644 index 0000000..ec02197 --- /dev/null +++ b/lib/plugins/mix.js @@ -0,0 +1,19 @@ +module.exports = function mix(color) { + color.installMethod('mix', function (otherColor, weight) { + otherColor = color(otherColor).rgb(); + weight = 1 - (isNaN(weight) ? 0.5 : weight); + + var w = weight * 2 - 1, + a = this._alpha - othercolor._alpha, + weight1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2, + weight2 = 1 - weight1, + rgb = this.rgb(); + + return new color.RGB( + rgb._red * weight1 + othercolor._red * weight2, + rgb._green * weight1 + othercolor._green * weight2, + rgb._blue * weight1 + othercolor._blue * weight2, + rgb._alpha * weight + othercolor._alpha * (1 - weight) + ); + }); +}; diff --git a/lib/plugins/namedColors.js b/lib/plugins/namedColors.js new file mode 100644 index 0000000..95e1734 --- /dev/null +++ b/lib/plugins/namedColors.js @@ -0,0 +1,152 @@ +module.exports = function namedColors(color) { + color.namedColors = { + aliceblue: 'f0f8ff', + antiquewhite: 'faebd7', + aqua: '0ff', + aquamarine: '7fffd4', + azure: 'f0ffff', + beige: 'f5f5dc', + bisque: 'ffe4c4', + black: '000', + blanchedalmond: 'ffebcd', + blue: '00f', + blueviolet: '8a2be2', + brown: 'a52a2a', + burlywood: 'deb887', + cadetblue: '5f9ea0', + chartreuse: '7fff00', + chocolate: 'd2691e', + coral: 'ff7f50', + cornflowerblue: '6495ed', + cornsilk: 'fff8dc', + crimson: 'dc143c', + cyan: '0ff', + darkblue: '00008b', + darkcyan: '008b8b', + darkgoldenrod: 'b8860b', + darkgray: 'a9a9a9', + darkgrey: 'a9a9a9', + darkgreen: '006400', + darkkhaki: 'bdb76b', + darkmagenta: '8b008b', + darkolivegreen: '556b2f', + darkorange: 'ff8c00', + darkorchid: '9932cc', + darkred: '8b0000', + darksalmon: 'e9967a', + darkseagreen: '8fbc8f', + darkslateblue: '483d8b', + darkslategray: '2f4f4f', + darkslategrey: '2f4f4f', + darkturquoise: '00ced1', + darkviolet: '9400d3', + deeppink: 'ff1493', + deepskyblue: '00bfff', + dimgray: '696969', + dimgrey: '696969', + dodgerblue: '1e90ff', + firebrick: 'b22222', + floralwhite: 'fffaf0', + forestgreen: '228b22', + fuchsia: 'f0f', + gainsboro: 'dcdcdc', + ghostwhite: 'f8f8ff', + gold: 'ffd700', + goldenrod: 'daa520', + gray: '808080', + grey: '808080', + green: '008000', + greenyellow: 'adff2f', + honeydew: 'f0fff0', + hotpink: 'ff69b4', + indianred: 'cd5c5c', + indigo: '4b0082', + ivory: 'fffff0', + khaki: 'f0e68c', + lavender: 'e6e6fa', + lavenderblush: 'fff0f5', + lawngreen: '7cfc00', + lemonchiffon: 'fffacd', + lightblue: 'add8e6', + lightcoral: 'f08080', + lightcyan: 'e0ffff', + lightgoldenrodyellow: 'fafad2', + lightgray: 'd3d3d3', + lightgrey: 'd3d3d3', + lightgreen: '90ee90', + lightpink: 'ffb6c1', + lightsalmon: 'ffa07a', + lightseagreen: '20b2aa', + lightskyblue: '87cefa', + lightslategray: '789', + lightslategrey: '789', + lightsteelblue: 'b0c4de', + lightyellow: 'ffffe0', + lime: '0f0', + limegreen: '32cd32', + linen: 'faf0e6', + magenta: 'f0f', + maroon: '800000', + mediumaquamarine: '66cdaa', + mediumblue: '0000cd', + mediumorchid: 'ba55d3', + mediumpurple: '9370d8', + mediumseagreen: '3cb371', + mediumslateblue: '7b68ee', + mediumspringgreen: '00fa9a', + mediumturquoise: '48d1cc', + mediumvioletred: 'c71585', + midnightblue: '191970', + mintcream: 'f5fffa', + mistyrose: 'ffe4e1', + moccasin: 'ffe4b5', + navajowhite: 'ffdead', + navy: '000080', + oldlace: 'fdf5e6', + olive: '808000', + olivedrab: '6b8e23', + orange: 'ffa500', + orangered: 'ff4500', + orchid: 'da70d6', + palegoldenrod: 'eee8aa', + palegreen: '98fb98', + paleturquoise: 'afeeee', + palevioletred: 'd87093', + papayawhip: 'ffefd5', + peachpuff: 'ffdab9', + peru: 'cd853f', + pink: 'ffc0cb', + plum: 'dda0dd', + powderblue: 'b0e0e6', + purple: '800080', + rebeccapurple: '639', + red: 'f00', + rosybrown: 'bc8f8f', + royalblue: '4169e1', + saddlebrown: '8b4513', + salmon: 'fa8072', + sandybrown: 'f4a460', + seagreen: '2e8b57', + seashell: 'fff5ee', + sienna: 'a0522d', + silver: 'c0c0c0', + skyblue: '87ceeb', + slateblue: '6a5acd', + slategray: '708090', + slategrey: '708090', + snow: 'fffafa', + springgreen: '00ff7f', + steelblue: '4682b4', + tan: 'd2b48c', + teal: '008080', + thistle: 'd8bfd8', + tomato: 'ff6347', + turquoise: '40e0d0', + violet: 'ee82ee', + wheat: 'f5deb3', + white: 'fff', + whitesmoke: 'f5f5f5', + yellow: 'ff0', + yellowgreen: '9acd32' + }; +}; diff --git a/lib/plugins/negate.js b/lib/plugins/negate.js new file mode 100644 index 0000000..8c3eef4 --- /dev/null +++ b/lib/plugins/negate.js @@ -0,0 +1,6 @@ +module.exports = function negate(color) { + color.installMethod('negate', function () { + var rgb = this.rgb(); + return new color.RGB(1 - rgb._red, 1 - rgb._green, 1 - rgb._blue, this._alpha); + }); +}; diff --git a/lib/plugins/opaquer.js b/lib/plugins/opaquer.js new file mode 100644 index 0000000..1caa8db --- /dev/null +++ b/lib/plugins/opaquer.js @@ -0,0 +1,5 @@ +module.exports = function opaquer(color) { + color.installMethod('opaquer', function (amount) { + return this.alpha(isNaN(amount) ? 0.1 : amount, true); + }); +}; diff --git a/lib/plugins/rotate.js b/lib/plugins/rotate.js new file mode 100644 index 0000000..2c74a99 --- /dev/null +++ b/lib/plugins/rotate.js @@ -0,0 +1,7 @@ +module.exports = function rotate(color) { + color.use(require('../HSL')); + + color.installMethod('rotate', function (degrees) { + return this.hue((degrees || 0) / 360, true); + }); +}; diff --git a/lib/plugins/saturate.js b/lib/plugins/saturate.js new file mode 100644 index 0000000..a9ad5c6 --- /dev/null +++ b/lib/plugins/saturate.js @@ -0,0 +1,7 @@ +module.exports = function saturate(color) { + color.use(require('../HSL')); + + color.installMethod('saturate', function (amount) { + return this.saturation(isNaN(amount) ? 0.1 : amount, true); + }); +}; diff --git a/lib/plugins/toAlpha.js b/lib/plugins/toAlpha.js new file mode 100644 index 0000000..e52047c --- /dev/null +++ b/lib/plugins/toAlpha.js @@ -0,0 +1,46 @@ +// Adapted from http://gimp.sourcearchive.com/documentation/2.6.6-1ubuntu1/color-to-alpha_8c-source.html +// toAlpha returns a color where the values of the argument have been converted to alpha +module.exports = function toAlpha(color) { + color.installMethod('toAlpha', function (color) { + var me = this.rgb(), + other = color(color).rgb(), + epsilon = 1e-10, + a = new color.RGB(0, 0, 0, me._alpha), + channels = ['_red', '_green', '_blue']; + + channels.forEach(function (channel) { + if (me[channel] < epsilon) { + a[channel] = me[channel]; + } else if (me[channel] > other[channel]) { + a[channel] = (me[channel] - other[channel]) / (1 - other[channel]); + } else if (me[channel] > other[channel]) { + a[channel] = (other[channel] - me[channel]) / other[channel]; + } else { + a[channel] = 0; + } + }); + + if (a._red > a._green) { + if (a._red > a._blue) { + me._alpha = a._red; + } else { + me._alpha = a._blue; + } + } else if (a._green > a._blue) { + me._alpha = a._green; + } else { + me._alpha = a._blue; + } + + if (me._alpha < epsilon) { + return me; + } + + channels.forEach(function (channel) { + me[channel] = (me[channel] - other[channel]) / me._alpha + other[channel]; + }); + me._alpha *= a._alpha; + + return me; + }); +}; diff --git a/minimal.js b/minimal.js new file mode 100644 index 0000000..dfd8b7a --- /dev/null +++ b/minimal.js @@ -0,0 +1,3 @@ +module.exports = require('./lib/color') + .use(require('./lib/HSV')) + .use(require('./lib/HSL')); diff --git a/one-color-all-debug.js b/one-color-all-debug.js deleted file mode 100644 index 2fefe05..0000000 --- a/one-color-all-debug.js +++ /dev/null @@ -1,775 +0,0 @@ -/*jshint evil:true, onevar:false*/ -/*global define*/ -var installedColorSpaces = [], - namedColors = {}, - undef = function (obj) { - return typeof obj === 'undefined'; - }, - channelRegExp = /\s*(\.\d+|\d+(?:\.\d+)?)(%)?\s*/, - percentageChannelRegExp = /\s*(\.\d+|100|\d?\d(?:\.\d+)?)%\s*/, - alphaChannelRegExp = /\s*(\.\d+|\d+(?:\.\d+)?)\s*/, - cssColorRegExp = new RegExp( - "^(rgb|hsl|hsv)a?" + - "\\(" + - channelRegExp.source + "," + - channelRegExp.source + "," + - channelRegExp.source + - "(?:," + alphaChannelRegExp.source + ")?" + - "\\)$", "i"); - -function ONECOLOR(obj) { - if (Object.prototype.toString.apply(obj) === '[object Array]') { - if (typeof obj[0] === 'string' && typeof ONECOLOR[obj[0]] === 'function') { - // Assumed array from .toJSON() - return new ONECOLOR[obj[0]](obj.slice(1, obj.length)); - } else if (obj.length === 4) { - // Assumed 4 element int RGB array from canvas with all channels [0;255] - return new ONECOLOR.RGB(obj[0] / 255, obj[1] / 255, obj[2] / 255, obj[3] / 255); - } - } else if (typeof obj === 'string') { - var lowerCased = obj.toLowerCase(); - if (namedColors[lowerCased]) { - obj = '#' + namedColors[lowerCased]; - } - if (lowerCased === 'transparent') { - obj = 'rgba(0,0,0,0)'; - } - // Test for CSS rgb(....) string - var matchCssSyntax = obj.match(cssColorRegExp); - if (matchCssSyntax) { - var colorSpaceName = matchCssSyntax[1].toUpperCase(), - alpha = undef(matchCssSyntax[8]) ? matchCssSyntax[8] : parseFloat(matchCssSyntax[8]), - hasHue = colorSpaceName[0] === 'H', - firstChannelDivisor = matchCssSyntax[3] ? 100 : (hasHue ? 360 : 255), - secondChannelDivisor = (matchCssSyntax[5] || hasHue) ? 100 : 255, - thirdChannelDivisor = (matchCssSyntax[7] || hasHue) ? 100 : 255; - if (undef(ONECOLOR[colorSpaceName])) { - throw new Error("one.color." + colorSpaceName + " is not installed."); - } - return new ONECOLOR[colorSpaceName]( - parseFloat(matchCssSyntax[2]) / firstChannelDivisor, - parseFloat(matchCssSyntax[4]) / secondChannelDivisor, - parseFloat(matchCssSyntax[6]) / thirdChannelDivisor, - alpha - ); - } - // Assume hex syntax - if (obj.length < 6) { - // Allow CSS shorthand - obj = obj.replace(/^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i, '$1$1$2$2$3$3'); - } - // Split obj into red, green, and blue components - var hexMatch = obj.match(/^#?([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/i); - if (hexMatch) { - return new ONECOLOR.RGB( - parseInt(hexMatch[1], 16) / 255, - parseInt(hexMatch[2], 16) / 255, - parseInt(hexMatch[3], 16) / 255 - ); - } - - // No match so far. Lets try the less likely ones - if (ONECOLOR.CMYK) { - var cmykMatch = obj.match(new RegExp( - "^cmyk" + - "\\(" + - percentageChannelRegExp.source + "," + - percentageChannelRegExp.source + "," + - percentageChannelRegExp.source + "," + - percentageChannelRegExp.source + - "\\)$", "i")); - if (cmykMatch) { - return new ONECOLOR.CMYK( - parseFloat(cmykMatch[1]) / 100, - parseFloat(cmykMatch[2]) / 100, - parseFloat(cmykMatch[3]) / 100, - parseFloat(cmykMatch[4]) / 100 - ); - } - } - } else if (typeof obj === 'object' && obj.isColor) { - return obj; - } - return false; -} - -function installColorSpace(colorSpaceName, propertyNames, config) { - ONECOLOR[colorSpaceName] = new Function(propertyNames.join(","), - // Allow passing an array to the constructor: - "if (Object.prototype.toString.apply(" + propertyNames[0] + ") === '[object Array]') {" + - propertyNames.map(function (propertyName, i) { - return propertyName + "=" + propertyNames[0] + "[" + i + "];"; - }).reverse().join("") + - "}" + - "if (" + propertyNames.filter(function (propertyName) { - return propertyName !== 'alpha'; - }).map(function (propertyName) { - return "isNaN(" + propertyName + ")"; - }).join("||") + "){" + "throw new Error(\"[" + colorSpaceName + "]: Invalid color: (\"+" + propertyNames.join("+\",\"+") + "+\")\");}" + - propertyNames.map(function (propertyName) { - if (propertyName === 'hue') { - return "this._hue=hue<0?hue-Math.floor(hue):hue%1"; // Wrap - } else if (propertyName === 'alpha') { - return "this._alpha=(isNaN(alpha)||alpha>1)?1:(alpha<0?0:alpha);"; - } else { - return "this._" + propertyName + "=" + propertyName + "<0?0:(" + propertyName + ">1?1:" + propertyName + ")"; - } - }).join(";") + ";" - ); - ONECOLOR[colorSpaceName].propertyNames = propertyNames; - - var prototype = ONECOLOR[colorSpaceName].prototype; - - ['valueOf', 'hex', 'hexa', 'css', 'cssa'].forEach(function (methodName) { - prototype[methodName] = prototype[methodName] || (colorSpaceName === 'RGB' ? prototype.hex : new Function("return this.rgb()." + methodName + "();")); - }); - - prototype.isColor = true; - - prototype.equals = function (otherColor, epsilon) { - if (undef(epsilon)) { - epsilon = 1e-10; - } - - otherColor = otherColor[colorSpaceName.toLowerCase()](); - - for (var i = 0; i < propertyNames.length; i = i + 1) { - if (Math.abs(this['_' + propertyNames[i]] - otherColor['_' + propertyNames[i]]) > epsilon) { - return false; - } - } - - return true; - }; - - prototype.toJSON = new Function( - "return ['" + colorSpaceName + "', " + - propertyNames.map(function (propertyName) { - return "this._" + propertyName; - }, this).join(", ") + - "];" - ); - - for (var propertyName in config) { - if (config.hasOwnProperty(propertyName)) { - var matchFromColorSpace = propertyName.match(/^from(.*)$/); - if (matchFromColorSpace) { - ONECOLOR[matchFromColorSpace[1].toUpperCase()].prototype[colorSpaceName.toLowerCase()] = config[propertyName]; - } else { - prototype[propertyName] = config[propertyName]; - } - } - } - - // It is pretty easy to implement the conversion to the same color space: - prototype[colorSpaceName.toLowerCase()] = function () { - return this; - }; - prototype.toString = new Function("return \"[one.color." + colorSpaceName + ":\"+" + propertyNames.map(function (propertyName, i) { - return "\" " + propertyNames[i] + "=\"+this._" + propertyName; - }).join("+") + "+\"]\";"); - - // Generate getters and setters - propertyNames.forEach(function (propertyName, i) { - prototype[propertyName] = prototype[propertyName === 'black' ? 'k' : propertyName[0]] = new Function("value", "isDelta", - // Simple getter mode: color.red() - "if (typeof value === 'undefined') {" + - "return this._" + propertyName + ";" + - "}" + - // Adjuster: color.red(+.2, true) - "if (isDelta) {" + - "return new this.constructor(" + propertyNames.map(function (otherPropertyName, i) { - return "this._" + otherPropertyName + (propertyName === otherPropertyName ? "+value" : ""); - }).join(", ") + ");" + - "}" + - // Setter: color.red(.2); - "return new this.constructor(" + propertyNames.map(function (otherPropertyName, i) { - return propertyName === otherPropertyName ? "value" : "this._" + otherPropertyName; - }).join(", ") + ");"); - }); - - function installForeignMethods(targetColorSpaceName, sourceColorSpaceName) { - var obj = {}; - obj[sourceColorSpaceName.toLowerCase()] = new Function("return this.rgb()." + sourceColorSpaceName.toLowerCase() + "();"); // Fallback - ONECOLOR[sourceColorSpaceName].propertyNames.forEach(function (propertyName, i) { - obj[propertyName] = obj[propertyName === 'black' ? 'k' : propertyName[0]] = new Function("value", "isDelta", "return this." + sourceColorSpaceName.toLowerCase() + "()." + propertyName + "(value, isDelta);"); - }); - for (var prop in obj) { - if (obj.hasOwnProperty(prop) && ONECOLOR[targetColorSpaceName].prototype[prop] === undefined) { - ONECOLOR[targetColorSpaceName].prototype[prop] = obj[prop]; - } - } - } - - installedColorSpaces.forEach(function (otherColorSpaceName) { - installForeignMethods(colorSpaceName, otherColorSpaceName); - installForeignMethods(otherColorSpaceName, colorSpaceName); - }); - - installedColorSpaces.push(colorSpaceName); -} - -ONECOLOR.installMethod = function (name, fn) { - installedColorSpaces.forEach(function (colorSpace) { - ONECOLOR[colorSpace].prototype[name] = fn; - }); -}; - -installColorSpace('RGB', ['red', 'green', 'blue', 'alpha'], { - hex: function () { - var hexString = (Math.round(255 * this._red) * 0x10000 + Math.round(255 * this._green) * 0x100 + Math.round(255 * this._blue)).toString(16); - return '#' + ('00000'.substr(0, 6 - hexString.length)) + hexString; - }, - - hexa: function () { - var alphaString = Math.round(this._alpha * 255).toString(16); - return '#' + '00'.substr(0, 2 - alphaString.length) + alphaString + this.hex().substr(1, 6); - }, - - css: function () { - return "rgb(" + Math.round(255 * this._red) + "," + Math.round(255 * this._green) + "," + Math.round(255 * this._blue) + ")"; - }, - - cssa: function () { - return "rgba(" + Math.round(255 * this._red) + "," + Math.round(255 * this._green) + "," + Math.round(255 * this._blue) + "," + this._alpha + ")"; - } -}); -if (typeof define === 'function' && !undef(define.amd)) { - define(function () { - return ONECOLOR; - }); -} else if (typeof exports === 'object') { - // Node module export - module.exports = ONECOLOR; -} else { - one = window.one || {}; - one.color = ONECOLOR; -} - -if (typeof jQuery !== 'undefined' && undef(jQuery.color)) { - jQuery.color = ONECOLOR; -} - -/*global namedColors*/ -namedColors = { - aliceblue: 'f0f8ff', - antiquewhite: 'faebd7', - aqua: '0ff', - aquamarine: '7fffd4', - azure: 'f0ffff', - beige: 'f5f5dc', - bisque: 'ffe4c4', - black: '000', - blanchedalmond: 'ffebcd', - blue: '00f', - blueviolet: '8a2be2', - brown: 'a52a2a', - burlywood: 'deb887', - cadetblue: '5f9ea0', - chartreuse: '7fff00', - chocolate: 'd2691e', - coral: 'ff7f50', - cornflowerblue: '6495ed', - cornsilk: 'fff8dc', - crimson: 'dc143c', - cyan: '0ff', - darkblue: '00008b', - darkcyan: '008b8b', - darkgoldenrod: 'b8860b', - darkgray: 'a9a9a9', - darkgrey: 'a9a9a9', - darkgreen: '006400', - darkkhaki: 'bdb76b', - darkmagenta: '8b008b', - darkolivegreen: '556b2f', - darkorange: 'ff8c00', - darkorchid: '9932cc', - darkred: '8b0000', - darksalmon: 'e9967a', - darkseagreen: '8fbc8f', - darkslateblue: '483d8b', - darkslategray: '2f4f4f', - darkslategrey: '2f4f4f', - darkturquoise: '00ced1', - darkviolet: '9400d3', - deeppink: 'ff1493', - deepskyblue: '00bfff', - dimgray: '696969', - dimgrey: '696969', - dodgerblue: '1e90ff', - firebrick: 'b22222', - floralwhite: 'fffaf0', - forestgreen: '228b22', - fuchsia: 'f0f', - gainsboro: 'dcdcdc', - ghostwhite: 'f8f8ff', - gold: 'ffd700', - goldenrod: 'daa520', - gray: '808080', - grey: '808080', - green: '008000', - greenyellow: 'adff2f', - honeydew: 'f0fff0', - hotpink: 'ff69b4', - indianred: 'cd5c5c', - indigo: '4b0082', - ivory: 'fffff0', - khaki: 'f0e68c', - lavender: 'e6e6fa', - lavenderblush: 'fff0f5', - lawngreen: '7cfc00', - lemonchiffon: 'fffacd', - lightblue: 'add8e6', - lightcoral: 'f08080', - lightcyan: 'e0ffff', - lightgoldenrodyellow: 'fafad2', - lightgray: 'd3d3d3', - lightgrey: 'd3d3d3', - lightgreen: '90ee90', - lightpink: 'ffb6c1', - lightsalmon: 'ffa07a', - lightseagreen: '20b2aa', - lightskyblue: '87cefa', - lightslategray: '789', - lightslategrey: '789', - lightsteelblue: 'b0c4de', - lightyellow: 'ffffe0', - lime: '0f0', - limegreen: '32cd32', - linen: 'faf0e6', - magenta: 'f0f', - maroon: '800000', - mediumaquamarine: '66cdaa', - mediumblue: '0000cd', - mediumorchid: 'ba55d3', - mediumpurple: '9370d8', - mediumseagreen: '3cb371', - mediumslateblue: '7b68ee', - mediumspringgreen: '00fa9a', - mediumturquoise: '48d1cc', - mediumvioletred: 'c71585', - midnightblue: '191970', - mintcream: 'f5fffa', - mistyrose: 'ffe4e1', - moccasin: 'ffe4b5', - navajowhite: 'ffdead', - navy: '000080', - oldlace: 'fdf5e6', - olive: '808000', - olivedrab: '6b8e23', - orange: 'ffa500', - orangered: 'ff4500', - orchid: 'da70d6', - palegoldenrod: 'eee8aa', - palegreen: '98fb98', - paleturquoise: 'afeeee', - palevioletred: 'd87093', - papayawhip: 'ffefd5', - peachpuff: 'ffdab9', - peru: 'cd853f', - pink: 'ffc0cb', - plum: 'dda0dd', - powderblue: 'b0e0e6', - purple: '800080', - rebeccapurple: '639', - red: 'f00', - rosybrown: 'bc8f8f', - royalblue: '4169e1', - saddlebrown: '8b4513', - salmon: 'fa8072', - sandybrown: 'f4a460', - seagreen: '2e8b57', - seashell: 'fff5ee', - sienna: 'a0522d', - silver: 'c0c0c0', - skyblue: '87ceeb', - slateblue: '6a5acd', - slategray: '708090', - slategrey: '708090', - snow: 'fffafa', - springgreen: '00ff7f', - steelblue: '4682b4', - tan: 'd2b48c', - teal: '008080', - thistle: 'd8bfd8', - tomato: 'ff6347', - turquoise: '40e0d0', - violet: 'ee82ee', - wheat: 'f5deb3', - white: 'fff', - whitesmoke: 'f5f5f5', - yellow: 'ff0', - yellowgreen: '9acd32' -}; - -/*global INCLUDE, installColorSpace, ONECOLOR*/ - -installColorSpace('XYZ', ['x', 'y', 'z', 'alpha'], { - fromRgb: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=02#text2 - var convert = function (channel) { - return channel > 0.04045 ? - Math.pow((channel + 0.055) / 1.055, 2.4) : - channel / 12.92; - }, - r = convert(this._red), - g = convert(this._green), - b = convert(this._blue); - - // Reference white point sRGB D65: - // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html - return new ONECOLOR.XYZ( - r * 0.4124564 + g * 0.3575761 + b * 0.1804375, - r * 0.2126729 + g * 0.7151522 + b * 0.0721750, - r * 0.0193339 + g * 0.1191920 + b * 0.9503041, - this._alpha - ); - }, - - rgb: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=01#text1 - var x = this._x, - y = this._y, - z = this._z, - convert = function (channel) { - return channel > 0.0031308 ? - 1.055 * Math.pow(channel, 1 / 2.4) - 0.055 : - 12.92 * channel; - }; - - // Reference white point sRGB D65: - // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html - return new ONECOLOR.RGB( - convert(x * 3.2404542 + y * -1.5371385 + z * -0.4985314), - convert(x * -0.9692660 + y * 1.8760108 + z * 0.0415560), - convert(x * 0.0556434 + y * -0.2040259 + z * 1.0572252), - this._alpha - ); - }, - - lab: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=07#text7 - var convert = function (channel) { - return channel > 0.008856 ? - Math.pow(channel, 1 / 3) : - 7.787037 * channel + 4 / 29; - }, - x = convert(this._x / 95.047), - y = convert(this._y / 100.000), - z = convert(this._z / 108.883); - - return new ONECOLOR.LAB( - (116 * y) - 16, - 500 * (x - y), - 200 * (y - z), - this._alpha - ); - } -}); - -/*global INCLUDE, installColorSpace, ONECOLOR*/ - -installColorSpace('LAB', ['l', 'a', 'b', 'alpha'], { - fromRgb: function () { - return this.xyz().lab(); - }, - - rgb: function () { - return this.xyz().rgb(); - }, - - xyz: function () { - // http://www.easyrgb.com/index.php?X=MATH&H=08#text8 - var convert = function (channel) { - var pow = Math.pow(channel, 3); - return pow > 0.008856 ? - pow : - (channel - 16 / 116) / 7.87; - }, - y = (this._l + 16) / 116, - x = this._a / 500 + y, - z = y - this._b / 200; - - return new ONECOLOR.XYZ( - convert(x) * 95.047, - convert(y) * 100.000, - convert(z) * 108.883, - this._alpha - ); - } -}); - -/*global one*/ - -installColorSpace('HSV', ['hue', 'saturation', 'value', 'alpha'], { - rgb: function () { - var hue = this._hue, - saturation = this._saturation, - value = this._value, - i = Math.min(5, Math.floor(hue * 6)), - f = hue * 6 - i, - p = value * (1 - saturation), - q = value * (1 - f * saturation), - t = value * (1 - (1 - f) * saturation), - red, - green, - blue; - switch (i) { - case 0: - red = value; - green = t; - blue = p; - break; - case 1: - red = q; - green = value; - blue = p; - break; - case 2: - red = p; - green = value; - blue = t; - break; - case 3: - red = p; - green = q; - blue = value; - break; - case 4: - red = t; - green = p; - blue = value; - break; - case 5: - red = value; - green = p; - blue = q; - break; - } - return new ONECOLOR.RGB(red, green, blue, this._alpha); - }, - - hsl: function () { - var l = (2 - this._saturation) * this._value, - sv = this._saturation * this._value, - svDivisor = l <= 1 ? l : (2 - l), - saturation; - - // Avoid division by zero when lightness approaches zero: - if (svDivisor < 1e-9) { - saturation = 0; - } else { - saturation = sv / svDivisor; - } - return new ONECOLOR.HSL(this._hue, saturation, l / 2, this._alpha); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.hsv - var red = this._red, - green = this._green, - blue = this._blue, - max = Math.max(red, green, blue), - min = Math.min(red, green, blue), - delta = max - min, - hue, - saturation = (max === 0) ? 0 : (delta / max), - value = max; - if (delta === 0) { - hue = 0; - } else { - switch (max) { - case red: - hue = (green - blue) / delta / 6 + (green < blue ? 1 : 0); - break; - case green: - hue = (blue - red) / delta / 6 + 1 / 3; - break; - case blue: - hue = (red - green) / delta / 6 + 2 / 3; - break; - } - } - return new ONECOLOR.HSV(hue, saturation, value, this._alpha); - } -}); - -/*global one*/ - - -installColorSpace('HSL', ['hue', 'saturation', 'lightness', 'alpha'], { - hsv: function () { - // Algorithm adapted from http://wiki.secondlife.com/wiki/Color_conversion_scripts - var l = this._lightness * 2, - s = this._saturation * ((l <= 1) ? l : 2 - l), - saturation; - - // Avoid division by zero when l + s is very small (approaching black): - if (l + s < 1e-9) { - saturation = 0; - } else { - saturation = (2 * s) / (l + s); - } - - return new ONECOLOR.HSV(this._hue, saturation, (l + s) / 2, this._alpha); - }, - - rgb: function () { - return this.hsv().rgb(); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.hsv - return this.hsv().hsl(); - } -}); - -/*global one*/ - -installColorSpace('CMYK', ['cyan', 'magenta', 'yellow', 'black', 'alpha'], { - rgb: function () { - return new ONECOLOR.RGB((1 - this._cyan * (1 - this._black) - this._black), - (1 - this._magenta * (1 - this._black) - this._black), - (1 - this._yellow * (1 - this._black) - this._black), - this._alpha); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.cmyk - // Adapted from http://www.javascripter.net/faq/rgb2cmyk.htm - var red = this._red, - green = this._green, - blue = this._blue, - cyan = 1 - red, - magenta = 1 - green, - yellow = 1 - blue, - black = 1; - if (red || green || blue) { - black = Math.min(cyan, Math.min(magenta, yellow)); - cyan = (cyan - black) / (1 - black); - magenta = (magenta - black) / (1 - black); - yellow = (yellow - black) / (1 - black); - } else { - black = 1; - } - return new ONECOLOR.CMYK(cyan, magenta, yellow, black, this._alpha); - } -}); - -ONECOLOR.installMethod('clearer', function (amount) { - return this.alpha(isNaN(amount) ? -0.1 : -amount, true); -}); - - -ONECOLOR.installMethod('darken', function (amount) { - return this.lightness(isNaN(amount) ? -0.1 : -amount, true); -}); - - -ONECOLOR.installMethod('desaturate', function (amount) { - return this.saturation(isNaN(amount) ? -0.1 : -amount, true); -}); - -function gs () { - var rgb = this.rgb(), - val = rgb._red * 0.3 + rgb._green * 0.59 + rgb._blue * 0.11; - - return new ONECOLOR.RGB(val, val, val, this._alpha); -}; - -ONECOLOR.installMethod('greyscale', gs); -ONECOLOR.installMethod('grayscale', gs); - - -ONECOLOR.installMethod('lighten', function (amount) { - return this.lightness(isNaN(amount) ? 0.1 : amount, true); -}); - -ONECOLOR.installMethod('mix', function (otherColor, weight) { - otherColor = ONECOLOR(otherColor).rgb(); - weight = 1 - (isNaN(weight) ? 0.5 : weight); - - var w = weight * 2 - 1, - a = this._alpha - otherColor._alpha, - weight1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2, - weight2 = 1 - weight1, - rgb = this.rgb(); - - return new ONECOLOR.RGB( - rgb._red * weight1 + otherColor._red * weight2, - rgb._green * weight1 + otherColor._green * weight2, - rgb._blue * weight1 + otherColor._blue * weight2, - rgb._alpha * weight + otherColor._alpha * (1 - weight) - ); -}); - -ONECOLOR.installMethod('negate', function () { - var rgb = this.rgb(); - return new ONECOLOR.RGB(1 - rgb._red, 1 - rgb._green, 1 - rgb._blue, this._alpha); -}); - -ONECOLOR.installMethod('opaquer', function (amount) { - return this.alpha(isNaN(amount) ? 0.1 : amount, true); -}); - -ONECOLOR.installMethod('rotate', function (degrees) { - return this.hue((degrees || 0) / 360, true); -}); - - -ONECOLOR.installMethod('saturate', function (amount) { - return this.saturation(isNaN(amount) ? 0.1 : amount, true); -}); - -// Adapted from http://gimp.sourcearchive.com/documentation/2.6.6-1ubuntu1/color-to-alpha_8c-source.html -/* - toAlpha returns a color where the values of the argument have been converted to alpha -*/ -ONECOLOR.installMethod('toAlpha', function (color) { - var me = this.rgb(), - other = ONECOLOR(color).rgb(), - epsilon = 1e-10, - a = new ONECOLOR.RGB(0, 0, 0, me._alpha), - channels = ['_red', '_green', '_blue']; - - channels.forEach(function (channel) { - if (me[channel] < epsilon) { - a[channel] = me[channel]; - } else if (me[channel] > other[channel]) { - a[channel] = (me[channel] - other[channel]) / (1 - other[channel]); - } else if (me[channel] > other[channel]) { - a[channel] = (other[channel] - me[channel]) / other[channel]; - } else { - a[channel] = 0; - } - }); - - if (a._red > a._green) { - if (a._red > a._blue) { - me._alpha = a._red; - } else { - me._alpha = a._blue; - } - } else if (a._green > a._blue) { - me._alpha = a._green; - } else { - me._alpha = a._blue; - } - - if (me._alpha < epsilon) { - return me; - } - - channels.forEach(function (channel) { - me[channel] = (me[channel] - other[channel]) / me._alpha + other[channel]; - }); - me._alpha *= a._alpha; - - return me; -}); - -/*global one*/ - -// This file is purely for the build system - -// Order is important to prevent channel name clashes. Lab <-> hsL - -// Convenience functions - diff --git a/one-color-debug.js b/one-color-debug.js deleted file mode 100644 index d45b117..0000000 --- a/one-color-debug.js +++ /dev/null @@ -1,379 +0,0 @@ -/*jshint evil:true, onevar:false*/ -/*global define*/ -var installedColorSpaces = [], - namedColors = {}, - undef = function (obj) { - return typeof obj === 'undefined'; - }, - channelRegExp = /\s*(\.\d+|\d+(?:\.\d+)?)(%)?\s*/, - percentageChannelRegExp = /\s*(\.\d+|100|\d?\d(?:\.\d+)?)%\s*/, - alphaChannelRegExp = /\s*(\.\d+|\d+(?:\.\d+)?)\s*/, - cssColorRegExp = new RegExp( - "^(rgb|hsl|hsv)a?" + - "\\(" + - channelRegExp.source + "," + - channelRegExp.source + "," + - channelRegExp.source + - "(?:," + alphaChannelRegExp.source + ")?" + - "\\)$", "i"); - -function ONECOLOR(obj) { - if (Object.prototype.toString.apply(obj) === '[object Array]') { - if (typeof obj[0] === 'string' && typeof ONECOLOR[obj[0]] === 'function') { - // Assumed array from .toJSON() - return new ONECOLOR[obj[0]](obj.slice(1, obj.length)); - } else if (obj.length === 4) { - // Assumed 4 element int RGB array from canvas with all channels [0;255] - return new ONECOLOR.RGB(obj[0] / 255, obj[1] / 255, obj[2] / 255, obj[3] / 255); - } - } else if (typeof obj === 'string') { - var lowerCased = obj.toLowerCase(); - if (namedColors[lowerCased]) { - obj = '#' + namedColors[lowerCased]; - } - if (lowerCased === 'transparent') { - obj = 'rgba(0,0,0,0)'; - } - // Test for CSS rgb(....) string - var matchCssSyntax = obj.match(cssColorRegExp); - if (matchCssSyntax) { - var colorSpaceName = matchCssSyntax[1].toUpperCase(), - alpha = undef(matchCssSyntax[8]) ? matchCssSyntax[8] : parseFloat(matchCssSyntax[8]), - hasHue = colorSpaceName[0] === 'H', - firstChannelDivisor = matchCssSyntax[3] ? 100 : (hasHue ? 360 : 255), - secondChannelDivisor = (matchCssSyntax[5] || hasHue) ? 100 : 255, - thirdChannelDivisor = (matchCssSyntax[7] || hasHue) ? 100 : 255; - if (undef(ONECOLOR[colorSpaceName])) { - throw new Error("one.color." + colorSpaceName + " is not installed."); - } - return new ONECOLOR[colorSpaceName]( - parseFloat(matchCssSyntax[2]) / firstChannelDivisor, - parseFloat(matchCssSyntax[4]) / secondChannelDivisor, - parseFloat(matchCssSyntax[6]) / thirdChannelDivisor, - alpha - ); - } - // Assume hex syntax - if (obj.length < 6) { - // Allow CSS shorthand - obj = obj.replace(/^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i, '$1$1$2$2$3$3'); - } - // Split obj into red, green, and blue components - var hexMatch = obj.match(/^#?([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/i); - if (hexMatch) { - return new ONECOLOR.RGB( - parseInt(hexMatch[1], 16) / 255, - parseInt(hexMatch[2], 16) / 255, - parseInt(hexMatch[3], 16) / 255 - ); - } - - // No match so far. Lets try the less likely ones - if (ONECOLOR.CMYK) { - var cmykMatch = obj.match(new RegExp( - "^cmyk" + - "\\(" + - percentageChannelRegExp.source + "," + - percentageChannelRegExp.source + "," + - percentageChannelRegExp.source + "," + - percentageChannelRegExp.source + - "\\)$", "i")); - if (cmykMatch) { - return new ONECOLOR.CMYK( - parseFloat(cmykMatch[1]) / 100, - parseFloat(cmykMatch[2]) / 100, - parseFloat(cmykMatch[3]) / 100, - parseFloat(cmykMatch[4]) / 100 - ); - } - } - } else if (typeof obj === 'object' && obj.isColor) { - return obj; - } - return false; -} - -function installColorSpace(colorSpaceName, propertyNames, config) { - ONECOLOR[colorSpaceName] = new Function(propertyNames.join(","), - // Allow passing an array to the constructor: - "if (Object.prototype.toString.apply(" + propertyNames[0] + ") === '[object Array]') {" + - propertyNames.map(function (propertyName, i) { - return propertyName + "=" + propertyNames[0] + "[" + i + "];"; - }).reverse().join("") + - "}" + - "if (" + propertyNames.filter(function (propertyName) { - return propertyName !== 'alpha'; - }).map(function (propertyName) { - return "isNaN(" + propertyName + ")"; - }).join("||") + "){" + "throw new Error(\"[" + colorSpaceName + "]: Invalid color: (\"+" + propertyNames.join("+\",\"+") + "+\")\");}" + - propertyNames.map(function (propertyName) { - if (propertyName === 'hue') { - return "this._hue=hue<0?hue-Math.floor(hue):hue%1"; // Wrap - } else if (propertyName === 'alpha') { - return "this._alpha=(isNaN(alpha)||alpha>1)?1:(alpha<0?0:alpha);"; - } else { - return "this._" + propertyName + "=" + propertyName + "<0?0:(" + propertyName + ">1?1:" + propertyName + ")"; - } - }).join(";") + ";" - ); - ONECOLOR[colorSpaceName].propertyNames = propertyNames; - - var prototype = ONECOLOR[colorSpaceName].prototype; - - ['valueOf', 'hex', 'hexa', 'css', 'cssa'].forEach(function (methodName) { - prototype[methodName] = prototype[methodName] || (colorSpaceName === 'RGB' ? prototype.hex : new Function("return this.rgb()." + methodName + "();")); - }); - - prototype.isColor = true; - - prototype.equals = function (otherColor, epsilon) { - if (undef(epsilon)) { - epsilon = 1e-10; - } - - otherColor = otherColor[colorSpaceName.toLowerCase()](); - - for (var i = 0; i < propertyNames.length; i = i + 1) { - if (Math.abs(this['_' + propertyNames[i]] - otherColor['_' + propertyNames[i]]) > epsilon) { - return false; - } - } - - return true; - }; - - prototype.toJSON = new Function( - "return ['" + colorSpaceName + "', " + - propertyNames.map(function (propertyName) { - return "this._" + propertyName; - }, this).join(", ") + - "];" - ); - - for (var propertyName in config) { - if (config.hasOwnProperty(propertyName)) { - var matchFromColorSpace = propertyName.match(/^from(.*)$/); - if (matchFromColorSpace) { - ONECOLOR[matchFromColorSpace[1].toUpperCase()].prototype[colorSpaceName.toLowerCase()] = config[propertyName]; - } else { - prototype[propertyName] = config[propertyName]; - } - } - } - - // It is pretty easy to implement the conversion to the same color space: - prototype[colorSpaceName.toLowerCase()] = function () { - return this; - }; - prototype.toString = new Function("return \"[one.color." + colorSpaceName + ":\"+" + propertyNames.map(function (propertyName, i) { - return "\" " + propertyNames[i] + "=\"+this._" + propertyName; - }).join("+") + "+\"]\";"); - - // Generate getters and setters - propertyNames.forEach(function (propertyName, i) { - prototype[propertyName] = prototype[propertyName === 'black' ? 'k' : propertyName[0]] = new Function("value", "isDelta", - // Simple getter mode: color.red() - "if (typeof value === 'undefined') {" + - "return this._" + propertyName + ";" + - "}" + - // Adjuster: color.red(+.2, true) - "if (isDelta) {" + - "return new this.constructor(" + propertyNames.map(function (otherPropertyName, i) { - return "this._" + otherPropertyName + (propertyName === otherPropertyName ? "+value" : ""); - }).join(", ") + ");" + - "}" + - // Setter: color.red(.2); - "return new this.constructor(" + propertyNames.map(function (otherPropertyName, i) { - return propertyName === otherPropertyName ? "value" : "this._" + otherPropertyName; - }).join(", ") + ");"); - }); - - function installForeignMethods(targetColorSpaceName, sourceColorSpaceName) { - var obj = {}; - obj[sourceColorSpaceName.toLowerCase()] = new Function("return this.rgb()." + sourceColorSpaceName.toLowerCase() + "();"); // Fallback - ONECOLOR[sourceColorSpaceName].propertyNames.forEach(function (propertyName, i) { - obj[propertyName] = obj[propertyName === 'black' ? 'k' : propertyName[0]] = new Function("value", "isDelta", "return this." + sourceColorSpaceName.toLowerCase() + "()." + propertyName + "(value, isDelta);"); - }); - for (var prop in obj) { - if (obj.hasOwnProperty(prop) && ONECOLOR[targetColorSpaceName].prototype[prop] === undefined) { - ONECOLOR[targetColorSpaceName].prototype[prop] = obj[prop]; - } - } - } - - installedColorSpaces.forEach(function (otherColorSpaceName) { - installForeignMethods(colorSpaceName, otherColorSpaceName); - installForeignMethods(otherColorSpaceName, colorSpaceName); - }); - - installedColorSpaces.push(colorSpaceName); -} - -ONECOLOR.installMethod = function (name, fn) { - installedColorSpaces.forEach(function (colorSpace) { - ONECOLOR[colorSpace].prototype[name] = fn; - }); -}; - -installColorSpace('RGB', ['red', 'green', 'blue', 'alpha'], { - hex: function () { - var hexString = (Math.round(255 * this._red) * 0x10000 + Math.round(255 * this._green) * 0x100 + Math.round(255 * this._blue)).toString(16); - return '#' + ('00000'.substr(0, 6 - hexString.length)) + hexString; - }, - - hexa: function () { - var alphaString = Math.round(this._alpha * 255).toString(16); - return '#' + '00'.substr(0, 2 - alphaString.length) + alphaString + this.hex().substr(1, 6); - }, - - css: function () { - return "rgb(" + Math.round(255 * this._red) + "," + Math.round(255 * this._green) + "," + Math.round(255 * this._blue) + ")"; - }, - - cssa: function () { - return "rgba(" + Math.round(255 * this._red) + "," + Math.round(255 * this._green) + "," + Math.round(255 * this._blue) + "," + this._alpha + ")"; - } -}); -if (typeof define === 'function' && !undef(define.amd)) { - define(function () { - return ONECOLOR; - }); -} else if (typeof exports === 'object') { - // Node module export - module.exports = ONECOLOR; -} else { - one = window.one || {}; - one.color = ONECOLOR; -} - -if (typeof jQuery !== 'undefined' && undef(jQuery.color)) { - jQuery.color = ONECOLOR; -} - -/*global one*/ - -installColorSpace('HSV', ['hue', 'saturation', 'value', 'alpha'], { - rgb: function () { - var hue = this._hue, - saturation = this._saturation, - value = this._value, - i = Math.min(5, Math.floor(hue * 6)), - f = hue * 6 - i, - p = value * (1 - saturation), - q = value * (1 - f * saturation), - t = value * (1 - (1 - f) * saturation), - red, - green, - blue; - switch (i) { - case 0: - red = value; - green = t; - blue = p; - break; - case 1: - red = q; - green = value; - blue = p; - break; - case 2: - red = p; - green = value; - blue = t; - break; - case 3: - red = p; - green = q; - blue = value; - break; - case 4: - red = t; - green = p; - blue = value; - break; - case 5: - red = value; - green = p; - blue = q; - break; - } - return new ONECOLOR.RGB(red, green, blue, this._alpha); - }, - - hsl: function () { - var l = (2 - this._saturation) * this._value, - sv = this._saturation * this._value, - svDivisor = l <= 1 ? l : (2 - l), - saturation; - - // Avoid division by zero when lightness approaches zero: - if (svDivisor < 1e-9) { - saturation = 0; - } else { - saturation = sv / svDivisor; - } - return new ONECOLOR.HSL(this._hue, saturation, l / 2, this._alpha); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.hsv - var red = this._red, - green = this._green, - blue = this._blue, - max = Math.max(red, green, blue), - min = Math.min(red, green, blue), - delta = max - min, - hue, - saturation = (max === 0) ? 0 : (delta / max), - value = max; - if (delta === 0) { - hue = 0; - } else { - switch (max) { - case red: - hue = (green - blue) / delta / 6 + (green < blue ? 1 : 0); - break; - case green: - hue = (blue - red) / delta / 6 + 1 / 3; - break; - case blue: - hue = (red - green) / delta / 6 + 2 / 3; - break; - } - } - return new ONECOLOR.HSV(hue, saturation, value, this._alpha); - } -}); - -/*global one*/ - - -installColorSpace('HSL', ['hue', 'saturation', 'lightness', 'alpha'], { - hsv: function () { - // Algorithm adapted from http://wiki.secondlife.com/wiki/Color_conversion_scripts - var l = this._lightness * 2, - s = this._saturation * ((l <= 1) ? l : 2 - l), - saturation; - - // Avoid division by zero when l + s is very small (approaching black): - if (l + s < 1e-9) { - saturation = 0; - } else { - saturation = (2 * s) / (l + s); - } - - return new ONECOLOR.HSV(this._hue, saturation, (l + s) / 2, this._alpha); - }, - - rgb: function () { - return this.hsv().rgb(); - }, - - fromRgb: function () { // Becomes one.color.RGB.prototype.hsv - return this.hsv().hsl(); - } -}); - -/*global one*/ - -// This file is purely for the build system - diff --git a/one-color-ieshim.js b/one-color-ieshim.js deleted file mode 100644 index 443756b..0000000 --- a/one-color-ieshim.js +++ /dev/null @@ -1 +0,0 @@ -!function(){var prepareString="a"!=="a"[0],toObject=function(o){if(null===o)throw new TypeError("can't convert "+o+" to object");return prepareString&&"string"==typeof o&&o?o.split(""):new Object(o)};Array.prototype.forEach||(Array.prototype.forEach=function(fun){var self=toObject(this),thisp=arguments[1],i=-1,length=self.length>>>0;if("function"!=typeof fun)throw new TypeError;for(;++i>>0,result=new Array(length),thisp=arguments[1];if("function"!=typeof fun)throw new TypeError(fun+" is not a function");for(i=0;length>i;i+=1)i in self&&(result[i]=fun.call(thisp,self[i],i,self));return result}),Array.prototype.filter||(Array.prototype.filter=function(fun){var value,i,self=toObject(this),length=self.length>>>0,result=[],thisp=arguments[1];if("function"!=typeof fun)throw new TypeError(fun+" is not a function");for(i=0;length>i;i+=1)i in self&&(value=self[i],fun.call(thisp,value,i,self)&&result.push(value));return result})}(); \ No newline at end of file diff --git a/package.json b/package.json index 884a0b0..54b6a7c 100644 --- a/package.json +++ b/package.json @@ -16,27 +16,22 @@ "email": "munter@fumle.dk" }, { - "name": "Andreas Lind Petersen", + "name": "Andreas Lind", "email": "andreas@one.com" } ], "devDependencies": { - "assetgraph": "=1.0.1", - "assetgraph-builder": "=1.0.3", - "jamjs": "=0.2.17", + "browserify": "13.0.0", + "exorcist": "0.4.0", "optimist": "=0.3.1", - "uglify-js": "=2.4.15", - "vows": "=0.7.0" + "uglifyify": "3.0.1" }, "engines": { "node": ">=0.4.8" }, "files": [ - "one-color-all-debug.js", "one-color-all.js", - "one-color-debug.js", - "one-color.js", - "one-color-ieshim.js" + "one-color.js" ], "publishConfig": { "registry": "http://registry.npmjs.org/" @@ -44,7 +39,8 @@ "main": "one-color-all-debug.js", "ender": "lib/ender.js", "scripts": { - "postpublish": "jam publish", + "build": "browserify -p bundle-collapser/plugin -t uglifyify --debug -e index -s one.color | exorcist one-color-all.map > one-color-all.js && browserify -p bundle-collapser/plugin -t uglifyify --debug -e minimal -s one.color | exorcist one-color.map > one-color.js", + "preversion": "npm run build && npm test", "test": "vows" }, "jam": { @@ -56,5 +52,9 @@ "README.md", "LICENSE" ] + }, + "dependencies": { + "browserify": "13.0.0", + "bundle-collapser": "1.2.1" } }