spectra
Advanced tools
Comparing version 0.1.0 to 0.2.0
{ | ||
"name": "spectra", | ||
"description": "Javascript color manipulation library.", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"author": "Aakash Patel <aakpat6@gmail.com>", | ||
@@ -19,20 +19,16 @@ "main": "spectra.js", | ||
"devDependencies": { | ||
"grunt-contrib-jasmine": "~0.4.0", | ||
"grunt-contrib-watch": "~0.5.1", | ||
"grunt": "~0.4.1", | ||
"grunt-contrib-uglify": "~0.2.7", | ||
"grunt-contrib-jshint": "~0.7.2", | ||
"grunt-karma-coveralls": "~2.1.1", | ||
"grunt": "~0.4.2", | ||
"grunt-contrib-uglify": "~0.3.1", | ||
"grunt-contrib-jshint": "~0.8.0", | ||
"grunt-karma": "~0.6.2", | ||
"grunt-karma-coveralls": "~2.3.0", | ||
"karma": "~0.10.9", | ||
"karma-script-launcher": "~0.1.0", | ||
"karma-chrome-launcher": "~0.1.1", | ||
"karma-html2js-preprocessor": "~0.1.0", | ||
"karma-firefox-launcher": "~0.1.2", | ||
"karma-jasmine": "~0.1.3", | ||
"karma-coffee-preprocessor": "~0.1.1", | ||
"requirejs": "~2.1.9", | ||
"karma-requirejs": "~0.2.0", | ||
"karma-jasmine": "~0.1.5", | ||
"karma-coffee-preprocessor": "~0.1.2", | ||
"karma-requirejs": "~0.2.1", | ||
"karma-phantomjs-launcher": "~0.1.1", | ||
"karma": "~0.10.8", | ||
"grunt-karma": "~0.6.2", | ||
"karma-coverage": "~0.1.4" | ||
"karma-coverage": "~0.1.5", | ||
"requirejs": "~2.1.10" | ||
}, | ||
@@ -39,0 +35,0 @@ "files": [ |
@@ -5,5 +5,12 @@ Spectra | ||
[![Coverage Status](https://coveralls.io/repos/aakpat6/spectra/badge.png?branch=master)](https://coveralls.io/r/aakpat6/spectra?branch=master) | ||
[![Dependency Status](https://gemnasium.com/aakpat6/spectra.png)](https://gemnasium.com/aakpat6/spectra) | ||
[![NPM version](https://badge.fury.io/js/spectra.png)](http://badge.fury.io/js/spectra) | ||
[![Stories in Ready](https://badge.waffle.io/aakpat6/spectra.png?label=ready)](https://waffle.io/aakpat6/spectra) | ||
![GA Beacon](https://ga-beacon.appspot.com/UA-46742689-1/aakpat6/spectra?pixel) | ||
Spectra is a Javascript library for quickly manipulating and converting colors. | ||
A small Javascript library for quickly manipulating and converting colors. | ||
[![NPM](https://nodei.co/npm/spectra.png?downloads=true&stars=true)](https://npmjs.org/package/spectra) | ||
Example | ||
@@ -27,4 +34,10 @@ ------- | ||
Simply download [spectra.min.js](https://github.com/aakpat6/spectra/releases/download/v0.1.0-beta.1/spectra.min.js) and include it before your source files. | ||
Simply download [spectra.min.js](https://github.com/aakpat6/spectra/releases/) and include it before your source files. | ||
### Bower | ||
The bower package is at `spectra-color`. | ||
bower install spectra-color | ||
### Node | ||
@@ -44,2 +57,6 @@ | ||
### Coverage | ||
Test coverage information can be generated by running `grunt karma`. Coverage information will be located in `test/coverage` after generation. | ||
Building | ||
@@ -57,2 +74,6 @@ -------- | ||
Take care to maintain the existing code style. Make sure to add tests in the `test/tester.js` file for any new features that you add. Make sure to run `grunt test` before submitting. Any code that doesn't pass all unit tests will not be accepted. | ||
Take care to maintain the existing code style. Make sure to add tests in the `test/tester.js` file for any new features that you add. Make sure to run `grunt test` before submitting. | ||
**Any code that doesn't pass the build will not be accepted.** | ||
Files should all have a newline at the end of them, for consistency. |
321
spectra.js
@@ -21,3 +21,3 @@ /**! | ||
// Store the old value of Spectra to reassign in case of noConflict. | ||
// Store the old value of Spectra to reassign in case of a call to noConflict. | ||
var oldSpectra = root.Spectra; | ||
@@ -28,4 +28,25 @@ | ||
// All official predefined css colors. | ||
var predefinedColors = { | ||
"white": "#ffffff", | ||
"silver": "#c0c0c0", | ||
"gray": "#808080", | ||
"black": "#000000", | ||
"red": "#ff0000", | ||
"maroon": "#800000", | ||
"yellow": "#ffff00", | ||
"olive": "#808000", | ||
"lime": "#00ff00", | ||
"green": "#008000", | ||
"aqua": "#00ffff", | ||
"teal": "#008080", | ||
"blue": "#0000ff", | ||
"navy": "#000080", | ||
"fuschia": "#ff00ff", | ||
"purple": "#800080", | ||
"orange": "#ffa500" | ||
}; | ||
/** | ||
* Clamps x to be between lower and upper. | ||
* Clamps x to be between lower and upper, inclusive. | ||
* If not specified, lower and upper are 0 and 1 respectively. | ||
@@ -88,5 +109,5 @@ * If x is outside the range lower to upper, the closest of lower or upper is used. | ||
var h = Util.clamp(Number(hsv.h || 0), 0, 360); | ||
var s = Util.clamp(Number(hsv.s || 0)); | ||
var v = Util.clamp(Number(hsv.v || 0)); | ||
var h = Util.clamp(hsv.h, 0, 360); | ||
var s = Util.clamp(hsv.s); | ||
var v = Util.clamp(hsv.v); | ||
var chroma = s * v; | ||
@@ -96,3 +117,3 @@ var sector = h / 60; // Sector of the color wheel. | ||
if(sector < 1.0) { | ||
if(sector < 1) { | ||
rgb.r = chroma; | ||
@@ -112,3 +133,3 @@ rgb.g = x; | ||
rgb.b = chroma; | ||
} else if (sector <= 6) { | ||
} else { | ||
rgb.r = chroma; | ||
@@ -153,5 +174,5 @@ rgb.b = x; | ||
Util.hslToRgb = function(hsl) { | ||
var h = Util.clamp(hsl.h, 0, 360); | ||
var s = Util.clamp(hsl.s); | ||
var l = Util.clamp(hsl.l); | ||
var h = Util.clamp((hsl.h || hsl.hue), 0, 360); | ||
var s = Util.clamp(hsl.s || hsl.saturation); | ||
var l = Util.clamp(hsl.l || hsl.lightness); | ||
var hsv = {}; | ||
@@ -166,2 +187,125 @@ hsv.h = h; | ||
/** | ||
* Turns an rgb color into a LAB color. | ||
*/ | ||
Util.rgbToLab = function(rgb) { | ||
// RGB to XYZ | ||
var tc = ""; | ||
rgb = { | ||
r: rgb.r / 255, | ||
g: rgb.g / 255, | ||
b: rgb.b / 255 | ||
}; | ||
var xyz = {}; | ||
for (tc in rgb) { | ||
if (rgb[tc] > 0.04045) { | ||
rgb[tc] = Math.pow(((rgb[tc] + 0.055) / 1.055), 2.4); | ||
} else { | ||
rgb[tc] /= 12.92; | ||
} | ||
rgb[tc] = rgb[tc] * 100; | ||
} | ||
xyz = { | ||
x: rgb.r * 0.4124 + rgb.g * 0.3576 + rgb.b * 0.1805, | ||
y: rgb.r * 0.2126 + rgb.g * 0.7152 + rgb.b * 0.0722, | ||
z: rgb.r * 0.0193 + rgb.g * 0.1192 + rgb.b * 0.9505 | ||
}; | ||
// XYZ to LAB | ||
tc = ''; | ||
var xyz2 = {}; | ||
var white = { | ||
x: 95.047, | ||
y: 100.000, | ||
z: 108.883 | ||
}; | ||
for (tc in xyz) { | ||
xyz2[tc] = xyz[tc] / white[tc]; | ||
if (xyz2[tc] > 0.008856) { | ||
xyz2[tc] = Math.pow(xyz2[tc], (1 / 3)); | ||
} else { | ||
xyz2[tc] = (7.787 * xyz2[tc]) + (16 / 116); | ||
} | ||
} | ||
var lab = { | ||
l: 116 * xyz2.y - 16, | ||
a: 500 * (xyz2.x - xyz2.y), | ||
b: 200 * (xyz2.y - xyz2.z) | ||
}; | ||
return lab; | ||
}; | ||
/** | ||
* Converts an lab color to rgb. | ||
*/ | ||
Util.labToRgb = function(lab) { | ||
var xyz = {}; | ||
var rgb = {}; | ||
// LAB to XYZ | ||
xyz.y = ((lab.l || lab.L) + 16) / 116; | ||
xyz.x = lab.a / 500 + xyz.y; | ||
xyz.z = xyz.y - lab.b / 200; | ||
if (Math.pow(xyz.y,3) > 0.008856) { | ||
xyz.y = Math.pow(xyz.y,3); | ||
} else { | ||
xyz.y = (xyz.y - 16 / 116) / 7.787; | ||
} | ||
if (Math.pow(xyz.x,3) > 0.008856) { | ||
xyz.x = Math.pow(xyz.x,3); | ||
} else { | ||
xyz.x = (xyz.x - 16 / 116) / 7.787; | ||
} | ||
if (Math.pow(xyz.z,3) > 0.008856) { | ||
xyz.z = Math.pow(xyz.z,3); | ||
} else { | ||
xyz.z = (xyz.z - 16 / 116) / 7.787; | ||
} | ||
// Observer= 2degree, Illuminant= D65 | ||
xyz.x *= 95.047 / 100; | ||
xyz.y *= 100.000 / 100; | ||
xyz.z *= 108.883 / 100; | ||
// XYZ to RGB | ||
rgb.r = xyz.x * 3.2406 + xyz.y * -1.5372 + xyz.z * -0.4986; | ||
rgb.g = xyz.x * -0.9689 + xyz.y * 1.8758 + xyz.z * 0.0415; | ||
rgb.b = xyz.x * 0.0557 + xyz.y * -0.2040 + xyz.z * 1.0570; | ||
if (rgb.r > 0.0031308) { | ||
rgb.r = 1.055 * Math.pow(rgb.r, (1 / 2.4)) - 0.055; | ||
} else { | ||
rgb.r *= 12.92; | ||
} | ||
if (rgb.g > 0.0031308) { | ||
rgb.g = 1.055 * Math.pow(rgb.g, (1 / 2.4)) - 0.055; | ||
} else { | ||
rgb.g *= 12.92; | ||
} | ||
if (rgb.b > 0.0031308) { | ||
rgb.b = 1.055 * Math.pow(rgb.b, (1 / 2.4)) - 0.055; | ||
} else { | ||
rgb.b *= 12.92; | ||
} | ||
rgb.r = Util.clamp(rgb.r * 255, 0, 255); | ||
rgb.g = Util.clamp(rgb.g * 255, 0, 255); | ||
rgb.b = Util.clamp(rgb.b * 255, 0, 255); | ||
return rgb; | ||
}; | ||
/** | ||
* Converts from CSS to RGB. | ||
@@ -218,2 +362,10 @@ */ | ||
/** | ||
* Converts a predefined color string to a Spectra object | ||
* Eg Util.parsePredefinedColor('white') === Spectra('#ffffff') === Spectra('{r: 255, g: 255, b: 255}'); | ||
*/ | ||
Util.parsePredefinedColor = function (string) { | ||
return new Spectra.fn(predefinedColors[string]); | ||
}; | ||
/** | ||
* Performs any conversions necessary to turn the arg into a Spectra object. | ||
@@ -229,8 +381,11 @@ */ | ||
color = Util.hsvToRgb(color.hsv); | ||
color.a = arg.a || 1; | ||
color.a = arg.a; | ||
} else if (color.hsl !== undefined) { | ||
color = Util.hslToRgb(color.hsl); | ||
color.a = arg.a || 1; | ||
color.a = arg.a; | ||
} else if (color.css !== undefined) { | ||
color = Util.parseCss(color.css); | ||
} else if (color.lab !== undefined) { | ||
color = Util.labToRgb(color.lab); | ||
color.a = arg.a; | ||
} | ||
@@ -265,13 +420,22 @@ | ||
} | ||
if (arg instanceof Spectra.fn) { | ||
return arg; | ||
} | ||
if (typeof arg === 'object') { | ||
if (arg.r !== undefined || arg.red !== undefined) { | ||
this.color = Util.normalize({r: arg.r, g: arg.g, b: arg.b, a: arg.a}); | ||
} | ||
if (arg.v !== undefined || arg.value !== undefined) { | ||
} else if (arg.v !== undefined || arg.value !== undefined) { | ||
this.color = Util.normalize({hsv: arg, a: arg.a}); | ||
} else if ((arg.l !== undefined || arg.lightness !== undefined) && | ||
(arg.s !== undefined || arg.saturation !== undefined)) { | ||
this.color = Util.normalize({hsl: arg, a: (arg.a || arg.alpha)}); | ||
} else if ((arg.l !== undefined || arg.L !== undefined) && (arg.a !== undefined)) { | ||
this.color = Util.normalize({lab: arg, a: (arg.a || arg.alpha)}); | ||
} else { | ||
throw new TypeError('Spectra argument ' + arg + ' is invalid.'); | ||
} | ||
if (arg.l !== undefined || arg.lightness !== undefined) { | ||
this.color = Util.normalize({hsl: arg, a: arg.a}); | ||
} else if (typeof arg === 'string') { | ||
if (arg.toLowerCase() in predefinedColors) { | ||
return Util.parsePredefinedColor(arg); | ||
} | ||
} else if (typeof arg === 'string') { | ||
this.color = Util.normalize({css: arg}); | ||
@@ -382,5 +546,5 @@ } else { | ||
// Pad the strings so that they are all 2 digits long, and concatenate. | ||
var rString = ('00' + this.red().toString(16)).slice(-2); | ||
var gString = ('00' + this.green().toString(16)).slice(-2); | ||
var bString = ('00' + this.blue().toString(16)).slice(-2); | ||
var rString = ('0' + this.red().toString(16)).slice(-2); | ||
var gString = ('0' + this.green().toString(16)).slice(-2); | ||
var bString = ('0' + this.blue().toString(16)).slice(-2); | ||
return '#' + rString + gString + bString; | ||
@@ -408,3 +572,13 @@ }; | ||
Spectra.fn.prototype.labObject = function() { | ||
return Util.rgbToLab(this.color); | ||
}; | ||
/** | ||
* Use hex string function for toString() operations | ||
* to allow direct assignment to CSS properties | ||
*/ | ||
Spectra.fn.prototype.toString = Spectra.fn.prototype.hex; | ||
/** | ||
* API Functions | ||
@@ -446,2 +620,14 @@ * ============= | ||
/** | ||
* Negates this color. | ||
* For a color {R, G, B}, returns a new color {R', G', B'}, where R' = 255 - R and so on. | ||
*/ | ||
Spectra.fn.prototype.negate = function() { | ||
var newColor = new Spectra(this.color); | ||
newColor.red(255 - newColor.red()); | ||
newColor.green(255 - newColor.green()); | ||
newColor.blue(255 - newColor.blue()); | ||
return newColor; | ||
}; | ||
/** | ||
* Lightens or darkens a color based on a percentage value. | ||
@@ -471,2 +657,13 @@ * Percentage should be passed in as an integer, so 40 would lighten the color 40%. | ||
/** | ||
* Lightens or darkens a color based on a random value in the specified range. | ||
* Percentage should be passed in as an integer, so 40 would lighten or darken up to 40%. | ||
*/ | ||
Spectra.fn.prototype.randomColorRange = function(percentage) { | ||
var adjustment = ((Math.random() * 2) - 1) * percentage; | ||
var newColor = new Spectra(this.color); | ||
newColor = newColor.shade_(adjustment); | ||
return newColor; | ||
}; | ||
/** | ||
* Adds saturation to the color based on a percentage value. | ||
@@ -526,5 +723,22 @@ */ | ||
/** | ||
* If a color is dark then it's best to have white text on it. | ||
* http://24ways.org/2010/calculating-color-contrast | ||
*/ | ||
Spectra.fn.prototype.isDark = function() { | ||
var yiq = ((this.red()*299)+(this.green()*587)+(this.blue()*144))/1000; | ||
return yiq < 131.5; | ||
}; | ||
/** | ||
* If a color is light then it's best to have black text on it. | ||
*/ | ||
Spectra.fn.prototype.isLight = function() { | ||
return !this.isDark(); | ||
}; | ||
/** | ||
* Returns the color that results from mixing percent of the other color into this color. | ||
*/ | ||
Spectra.fn.prototype.mix = function(other, percentage) { | ||
other = new Spectra(other); | ||
var p = arguments.length < 2 ? 0.5 : percentage / 100; | ||
@@ -540,5 +754,17 @@ return new Spectra({ | ||
/** | ||
* Returns a number from 0 to 1 representing the color contrast between the two colors. | ||
*/ | ||
Spectra.fn.prototype.contrast = function(other) { | ||
other = new Spectra(other); | ||
var diff = Math.max(this.red(), other.red()) - Math.min(this.red(), other.red()) + | ||
Math.max(this.green(), other.green()) - Math.min(this.green(), other.green()) + | ||
Math.max(this.blue(), other.blue()) - Math.min(this.blue(), other.blue()); | ||
return diff / 765; | ||
}; | ||
/** | ||
* Returns a gradient of colors approximately from this color to the other, consisting of n colors. | ||
*/ | ||
Spectra.fn.prototype.gradient = function(other, n) { | ||
other = new Spectra(other); | ||
var gradient = []; | ||
@@ -563,2 +789,57 @@ var r = this.red(); | ||
/** | ||
* Harmony | ||
* | ||
* @desc Returns an array of harmonious colors (goo.gl/R3FRlU). | ||
* @author Benjamin Fleming (benjamminf) | ||
* @since 2014-01-06 | ||
* @param type (string) - Type of harmony. | ||
* @param index (int) - At which point the original color exists on the set harmonies. Since | ||
* some types of color harmonies have inconsistent offsets (eg. rectangle) it's useful to | ||
* note where this original color lies on the set harmony hues. | ||
* @return Array of Spectra instances. | ||
*/ | ||
Spectra.fn.prototype.harmony = function(type, index) { | ||
index = typeof index === 'number' ? Math.abs(parseInt(index, 10)) : 0; | ||
var colors = []; | ||
var hsv = Util.rgbToHsv(this.color); | ||
var hues = [0, 180]; | ||
switch (type) { | ||
case 'analogous': | ||
hues = [0, 30, 60]; | ||
break; | ||
case 'triad': | ||
hues = [0, 120, 240]; | ||
break; | ||
case 'split-complementary': | ||
hues = [0, 150, 210]; | ||
break; | ||
case 'rectangle': | ||
hues = [0, 60, 180, 240]; | ||
break; | ||
case 'square': | ||
hues = [0, 90, 180, 270]; | ||
break; | ||
case 'complementary': | ||
hues = [0, 180]; | ||
break; | ||
} | ||
var n = hues.length; | ||
var offset = hues[index % n]; | ||
for (var i = 0; i < n; i++) { | ||
colors.push(new Spectra({ | ||
h: (hsv.h + hues[i] - offset) % 360, | ||
s: hsv.s, | ||
v: hsv.v, | ||
a: this.color.a | ||
})); | ||
} | ||
return colors; | ||
}; | ||
/** | ||
* Restores the old value of Spectra and returns the wrapper function. | ||
@@ -565,0 +846,0 @@ */ |
@@ -1,1 +0,1 @@ | ||
(function(){"use strict";var a=this,b=a.Spectra,c={};c.clamp=function(a,b,c){return b=void 0!==b?b:0,c=void 0!==c?c:1,Math.max(b,Math.min(c,a))},c.rgbToHsv=function(a){var b={},c=Number(a.r||0)/255,d=Number(a.g||0)/255,e=Number(a.b||0)/255,f=Math.max(c,d,e),g=Math.min(c,d,e),h=f-g;return b.v=f,0===b.v?(b.h=0,b.s=0):(b.s=(f-g)/f,0===b.s?b.h=0:(b.h=f===c?(d-e)/h:f===d?2+(e-c)/h:4+(c-d)/h,b.h*=60,b.h<0&&(b.h+=360))),b},c.hsvToRgb=function(a){var b={r:0,g:0,b:0},d=c.clamp(Number(a.h||0),0,360),e=c.clamp(Number(a.s||0)),f=c.clamp(Number(a.v||0)),g=e*f,h=d/60,i=g*(1-Math.abs(h%2-1));1>h?(b.r=g,b.g=i):2>h?(b.r=i,b.g=g):3>h?(b.g=g,b.b=i):4>h?(b.g=i,b.b=g):5>h?(b.r=i,b.b=g):6>=h&&(b.r=g,b.b=i);var j=f-g;return b.r+=j,b.g+=j,b.b+=j,b.r*=255,b.g*=255,b.b*=255,b},c.rgbToHsl=function(a){var b=c.rgbToHsv(a),d={};return d.h=b.h,d.l=(2-b.s)*b.v,d.s=b.s*b.v,d.s/=d.l<=1?d.l:2-d.l,d.l/=2,d},c.hslToRgb=function(a){var b=c.clamp(a.h,0,360),d=c.clamp(a.s),e=c.clamp(a.l),f={};return f.h=b,d*=.5>e?e:1-e,f.s=2*d/(e+d),f.v=e+d,c.hsvToRgb(f)},c.parseCss=function(a){var b={},d=/^#[0-9a-f]{3}$/i,e=a.match(d);if(e)return b={r:17*parseInt(a.charAt(1),16),g:17*parseInt(a.charAt(2),16),b:17*parseInt(a.charAt(3),16)},c.normalize(b);var f=/^#[0-9a-f]{6}$/i,g=a.match(f);if(g)return b={r:parseInt(a.slice(1,3),16),g:parseInt(a.slice(3,5),16),b:parseInt(a.slice(5,7),16)},c.normalize(b);var h=/^rgb\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+)\s*\)$/i,i=a.match(h);if(i)return b={r:parseInt(i[1],10),g:parseInt(i[2],10),b:parseInt(i[3],10)},c.normalize(b);var j=/^rgba\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+),\s*([0-9\.]+)\s*\)$/i,k=a.match(j);if(k)return b={r:parseInt(k[1],10),g:parseInt(k[2],10),b:parseInt(k[3],10),a:parseFloat(k[4],10)},c.normalize(b);throw new TypeError(a+" is not a valid CSS string for Spectra.")},c.normalize=function(a){a.a=a.a||1;var b=a;return void 0!==b.hsv?(b=c.hsvToRgb(b.hsv),b.a=a.a||1):void 0!==b.hsl?(b=c.hslToRgb(b.hsl),b.a=a.a||1):void 0!==b.css&&(b=c.parseCss(b.css)),b.r=b.red||b.r,b.g=b.green||b.g,b.b=b.blue||b.b,b.a=b.alpha||b.a,b.r=c.clamp(b.r,0,255),b.g=c.clamp(b.g,0,255),b.b=c.clamp(b.b,0,255),b.a=c.clamp(b.a,0,1),b};var Spectra=function(a){return new Spectra.fn(a)};Spectra.fn=function(a){if(null===a||void 0===a)throw new TypeError("Spectra argument must be defined.");if("object"==typeof a)(void 0!==a.r||void 0!==a.red)&&(this.color=c.normalize({r:a.r,g:a.g,b:a.b,a:a.a})),(void 0!==a.v||void 0!==a.value)&&(this.color=c.normalize({hsv:a,a:a.a})),(void 0!==a.l||void 0!==a.lightness)&&(this.color=c.normalize({hsl:a,a:a.a}));else{if("string"!=typeof a)throw new TypeError("Spectra argument "+a+" is invalid.");this.color=c.normalize({css:a})}return this},Spectra.fn.prototype.red=function(a){var b=this.color;return arguments.length?(b.r=a,this.color=c.normalize(b),this):Math.round(b.r)},Spectra.fn.prototype.green=function(a){var b=this.color;return arguments.length?(b.g=a,this.color=c.normalize(b),this):Math.round(b.g)},Spectra.fn.prototype.blue=function(a){var b=this.color;return arguments.length?(b.b=a,this.color=c.normalize(b),this):Math.round(b.b)},Spectra.fn.prototype.hue=function(a){var b=c.rgbToHsv(this.color);return arguments.length?(b.h=a,this.color=c.normalize({hsv:b,a:this.color.a}),this):Math.round(b.h)},Spectra.fn.prototype.saturationv=function(a){var b=c.rgbToHsv(this.color);return arguments.length?(b.s=a,this.color=c.normalize({hsv:b,a:this.color.a}),this):b.s},Spectra.fn.prototype.value=function(a){var b=c.rgbToHsv(this.color);return arguments.length?(b.v=a,this.color=c.normalize({hsv:b,a:this.color.a}),this):b.v},Spectra.fn.prototype.saturation=function(a){var b=c.rgbToHsl(this.color);return arguments.length?(b.s=a,this.color=c.normalize({hsl:b,a:this.color.a}),this):b.s},Spectra.fn.prototype.lightness=function(a){var b=c.rgbToHsl(this.color);return arguments.length?(b.l=a,this.color=c.normalize({hsl:b,a:this.color.a}),this):b.l},Spectra.fn.prototype.alpha=function(a){var b=this.color;return arguments.length?(b.a=a,this):b.a},Spectra.fn.prototype.hex=function(){var a=("00"+this.red().toString(16)).slice(-2),b=("00"+this.green().toString(16)).slice(-2),c=("00"+this.blue().toString(16)).slice(-2);return"#"+a+b+c},Spectra.fn.prototype.rgbaString=function(){return"rgba("+this.red()+","+this.green()+","+this.blue()+","+this.alpha()+")"},Spectra.fn.prototype.hslString=function(){return"hsl("+this.hue()+","+this.saturation()+","+Math.round(100*this.lightness())/100+")"},Spectra.fn.prototype.hslaString=function(){return"hsla("+this.hue()+","+this.saturation()+","+Math.round(100*this.lightness())/100+","+this.alpha()+")"},Spectra.fn.prototype.rgbNumber=function(){return this.red()<<16|this.green()<<8|this.blue()},Spectra.fn.prototype.equals=function(a){var b=this,c=a;return arguments.length<1?b===c:b.red()===c.red()&&b.green()===c.green()&&b.blue()===c.blue()&&b.alpha()===c.alpha()},Spectra.fn.prototype.complement=function(){var a=new Spectra(this.color);return a.hue((a.hue()+180)%360),a},Spectra.fn.prototype.shade_=function(a){var b=new Spectra(this.color);return b.lightness(b.lightness()+a/100),b},Spectra.fn.prototype.lighten=function(a){return this.shade_(a)},Spectra.fn.prototype.darken=function(a){return this.shade_(-a)},Spectra.fn.prototype.saturate=function(a){var b=a/100,c=new Spectra(this.color);return c.saturation(c.saturation()+b),c},Spectra.fn.prototype.desaturate=function(a){var b=a/100,c=new Spectra(this.color);return c.saturation(c.saturation()-b),c},Spectra.fn.prototype.fadeIn=function(a){var b=a/100,c=new Spectra(this.color);return c.alpha(c.alpha()+b),c},Spectra.fn.prototype.fadeOut=function(a){var b=a/100,c=new Spectra(this.color);return c.alpha(c.alpha()-b),c},Spectra.fn.prototype.luma=function(){return.2126*this.red()+.7152*this.green()+.0722*this.blue()},Spectra.fn.prototype.grayscale=function(){return this.desaturate(100)},Spectra.fn.prototype.mix=function(a,b){var c=arguments.length<2?.5:b/100;return new Spectra({r:this.red()*(1-c)+a.red()*c,g:this.green()*(1-c)+a.green()*c,b:this.blue()*(1-c)+a.blue()*c,a:this.alpha()*(1-c)+a.alpha()*c})},Spectra.fn.prototype.gradient=function(a,b){for(var c=[],d=this.red(),e=this.green(),f=this.blue(),g=(a.red()-this.red())/(b-1),h=(a.green()-this.green())/(b-1),i=(a.blue()-this.blue())/(b-1),j=0;b>j;j++)c.push(new Spectra({r:d,g:e,b:f})),d+=g,e+=h,f+=i;return c},Spectra.noConflict=function(){return a.Spectra=b,Spectra},Spectra.random=function(){return new Spectra({r:Math.floor(255*Math.random()),g:Math.floor(255*Math.random()),b:Math.floor(255*Math.random())})},"undefined"!=typeof exports?("undefined"!=typeof module&&(exports=module.exports=Spectra),exports.Spectra=Spectra):a.Spectra=Spectra}).call(this); | ||
(function(){"use strict";var a=this,b=a.Spectra,c={},d={white:"#ffffff",silver:"#c0c0c0",gray:"#808080",black:"#000000",red:"#ff0000",maroon:"#800000",yellow:"#ffff00",olive:"#808000",lime:"#00ff00",green:"#008000",aqua:"#00ffff",teal:"#008080",blue:"#0000ff",navy:"#000080",fuschia:"#ff00ff",purple:"#800080",orange:"#ffa500"};c.clamp=function(a,b,c){return b=void 0!==b?b:0,c=void 0!==c?c:1,Math.max(b,Math.min(c,a))},c.rgbToHsv=function(a){var b={},c=Number(a.r||0)/255,d=Number(a.g||0)/255,e=Number(a.b||0)/255,f=Math.max(c,d,e),g=Math.min(c,d,e),h=f-g;return b.v=f,0===b.v?(b.h=0,b.s=0):(b.s=(f-g)/f,0===b.s?b.h=0:(b.h=f===c?(d-e)/h:f===d?2+(e-c)/h:4+(c-d)/h,b.h*=60,b.h<0&&(b.h+=360))),b},c.hsvToRgb=function(a){var b={r:0,g:0,b:0},d=c.clamp(a.h,0,360),e=c.clamp(a.s),f=c.clamp(a.v),g=e*f,h=d/60,i=g*(1-Math.abs(h%2-1));1>h?(b.r=g,b.g=i):2>h?(b.r=i,b.g=g):3>h?(b.g=g,b.b=i):4>h?(b.g=i,b.b=g):5>h?(b.r=i,b.b=g):(b.r=g,b.b=i);var j=f-g;return b.r+=j,b.g+=j,b.b+=j,b.r*=255,b.g*=255,b.b*=255,b},c.rgbToHsl=function(a){var b=c.rgbToHsv(a),d={};return d.h=b.h,d.l=(2-b.s)*b.v,d.s=b.s*b.v,d.s/=d.l<=1?d.l:2-d.l,d.l/=2,d},c.hslToRgb=function(a){var b=c.clamp(a.h||a.hue,0,360),d=c.clamp(a.s||a.saturation),e=c.clamp(a.l||a.lightness),f={};return f.h=b,d*=.5>e?e:1-e,f.s=2*d/(e+d),f.v=e+d,c.hsvToRgb(f)},c.rgbToLab=function(a){var b="";a={r:a.r/255,g:a.g/255,b:a.b/255};var c={};for(b in a)a[b]>.04045?a[b]=Math.pow((a[b]+.055)/1.055,2.4):a[b]/=12.92,a[b]=100*a[b];c={x:.4124*a.r+.3576*a.g+.1805*a.b,y:.2126*a.r+.7152*a.g+.0722*a.b,z:.0193*a.r+.1192*a.g+.9505*a.b},b="";var d={},e={x:95.047,y:100,z:108.883};for(b in c)d[b]=c[b]/e[b],d[b]=d[b]>.008856?Math.pow(d[b],1/3):7.787*d[b]+16/116;var f={l:116*d.y-16,a:500*(d.x-d.y),b:200*(d.y-d.z)};return f},c.labToRgb=function(a){var b={},d={};return b.y=((a.l||a.L)+16)/116,b.x=a.a/500+b.y,b.z=b.y-a.b/200,b.y=Math.pow(b.y,3)>.008856?Math.pow(b.y,3):(b.y-16/116)/7.787,b.x=Math.pow(b.x,3)>.008856?Math.pow(b.x,3):(b.x-16/116)/7.787,b.z=Math.pow(b.z,3)>.008856?Math.pow(b.z,3):(b.z-16/116)/7.787,b.x*=95.047/100,b.y*=1,b.z*=1.08883,d.r=3.2406*b.x+-1.5372*b.y+b.z*-.4986,d.g=b.x*-.9689+1.8758*b.y+.0415*b.z,d.b=.0557*b.x+b.y*-.204+1.057*b.z,d.r>.0031308?d.r=1.055*Math.pow(d.r,1/2.4)-.055:d.r*=12.92,d.g>.0031308?d.g=1.055*Math.pow(d.g,1/2.4)-.055:d.g*=12.92,d.b>.0031308?d.b=1.055*Math.pow(d.b,1/2.4)-.055:d.b*=12.92,d.r=c.clamp(255*d.r,0,255),d.g=c.clamp(255*d.g,0,255),d.b=c.clamp(255*d.b,0,255),d},c.parseCss=function(a){var b={},d=/^#[0-9a-f]{3}$/i,e=a.match(d);if(e)return b={r:17*parseInt(a.charAt(1),16),g:17*parseInt(a.charAt(2),16),b:17*parseInt(a.charAt(3),16)},c.normalize(b);var f=/^#[0-9a-f]{6}$/i,g=a.match(f);if(g)return b={r:parseInt(a.slice(1,3),16),g:parseInt(a.slice(3,5),16),b:parseInt(a.slice(5,7),16)},c.normalize(b);var h=/^rgb\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+)\s*\)$/i,i=a.match(h);if(i)return b={r:parseInt(i[1],10),g:parseInt(i[2],10),b:parseInt(i[3],10)},c.normalize(b);var j=/^rgba\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+),\s*([0-9\.]+)\s*\)$/i,k=a.match(j);if(k)return b={r:parseInt(k[1],10),g:parseInt(k[2],10),b:parseInt(k[3],10),a:parseFloat(k[4],10)},c.normalize(b);throw new TypeError(a+" is not a valid CSS string for Spectra.")},c.parsePredefinedColor=function(a){return new Spectra.fn(d[a])},c.normalize=function(a){a.a=a.a||1;var b=a;return void 0!==b.hsv?(b=c.hsvToRgb(b.hsv),b.a=a.a):void 0!==b.hsl?(b=c.hslToRgb(b.hsl),b.a=a.a):void 0!==b.css?b=c.parseCss(b.css):void 0!==b.lab&&(b=c.labToRgb(b.lab),b.a=a.a),b.r=b.red||b.r,b.g=b.green||b.g,b.b=b.blue||b.b,b.a=b.alpha||b.a,b.r=c.clamp(b.r,0,255),b.g=c.clamp(b.g,0,255),b.b=c.clamp(b.b,0,255),b.a=c.clamp(b.a,0,1),b};var Spectra=function(a){return new Spectra.fn(a)};Spectra.fn=function(a){if(null===a||void 0===a)throw new TypeError("Spectra argument must be defined.");if(a instanceof Spectra.fn)return a;if("object"==typeof a)if(void 0!==a.r||void 0!==a.red)this.color=c.normalize({r:a.r,g:a.g,b:a.b,a:a.a});else if(void 0!==a.v||void 0!==a.value)this.color=c.normalize({hsv:a,a:a.a});else if(void 0===a.l&&void 0===a.lightness||void 0===a.s&&void 0===a.saturation){if(void 0===a.l&&void 0===a.L||void 0===a.a)throw new TypeError("Spectra argument "+a+" is invalid.");this.color=c.normalize({lab:a,a:a.a||a.alpha})}else this.color=c.normalize({hsl:a,a:a.a||a.alpha});else{if("string"!=typeof a)throw new TypeError("Spectra argument "+a+" is invalid.");if(a.toLowerCase()in d)return c.parsePredefinedColor(a);this.color=c.normalize({css:a})}return this},Spectra.fn.prototype.red=function(a){var b=this.color;return arguments.length?(b.r=a,this.color=c.normalize(b),this):Math.round(b.r)},Spectra.fn.prototype.green=function(a){var b=this.color;return arguments.length?(b.g=a,this.color=c.normalize(b),this):Math.round(b.g)},Spectra.fn.prototype.blue=function(a){var b=this.color;return arguments.length?(b.b=a,this.color=c.normalize(b),this):Math.round(b.b)},Spectra.fn.prototype.hue=function(a){var b=c.rgbToHsv(this.color);return arguments.length?(b.h=a,this.color=c.normalize({hsv:b,a:this.color.a}),this):Math.round(b.h)},Spectra.fn.prototype.saturationv=function(a){var b=c.rgbToHsv(this.color);return arguments.length?(b.s=a,this.color=c.normalize({hsv:b,a:this.color.a}),this):b.s},Spectra.fn.prototype.value=function(a){var b=c.rgbToHsv(this.color);return arguments.length?(b.v=a,this.color=c.normalize({hsv:b,a:this.color.a}),this):b.v},Spectra.fn.prototype.saturation=function(a){var b=c.rgbToHsl(this.color);return arguments.length?(b.s=a,this.color=c.normalize({hsl:b,a:this.color.a}),this):b.s},Spectra.fn.prototype.lightness=function(a){var b=c.rgbToHsl(this.color);return arguments.length?(b.l=a,this.color=c.normalize({hsl:b,a:this.color.a}),this):b.l},Spectra.fn.prototype.alpha=function(a){var b=this.color;return arguments.length?(b.a=a,this):b.a},Spectra.fn.prototype.hex=function(){var a=("0"+this.red().toString(16)).slice(-2),b=("0"+this.green().toString(16)).slice(-2),c=("0"+this.blue().toString(16)).slice(-2);return"#"+a+b+c},Spectra.fn.prototype.rgbaString=function(){return"rgba("+this.red()+","+this.green()+","+this.blue()+","+this.alpha()+")"},Spectra.fn.prototype.hslString=function(){return"hsl("+this.hue()+","+this.saturation()+","+Math.round(100*this.lightness())/100+")"},Spectra.fn.prototype.hslaString=function(){return"hsla("+this.hue()+","+this.saturation()+","+Math.round(100*this.lightness())/100+","+this.alpha()+")"},Spectra.fn.prototype.rgbNumber=function(){return this.red()<<16|this.green()<<8|this.blue()},Spectra.fn.prototype.labObject=function(){return c.rgbToLab(this.color)},Spectra.fn.prototype.toString=Spectra.fn.prototype.hex,Spectra.fn.prototype.equals=function(a){var b=this,c=a;return arguments.length<1?b===c:b.red()===c.red()&&b.green()===c.green()&&b.blue()===c.blue()&&b.alpha()===c.alpha()},Spectra.fn.prototype.complement=function(){var a=new Spectra(this.color);return a.hue((a.hue()+180)%360),a},Spectra.fn.prototype.negate=function(){var a=new Spectra(this.color);return a.red(255-a.red()),a.green(255-a.green()),a.blue(255-a.blue()),a},Spectra.fn.prototype.shade_=function(a){var b=new Spectra(this.color);return b.lightness(b.lightness()+a/100),b},Spectra.fn.prototype.lighten=function(a){return this.shade_(a)},Spectra.fn.prototype.darken=function(a){return this.shade_(-a)},Spectra.fn.prototype.randomColorRange=function(a){var b=(2*Math.random()-1)*a,c=new Spectra(this.color);return c=c.shade_(b)},Spectra.fn.prototype.saturate=function(a){var b=a/100,c=new Spectra(this.color);return c.saturation(c.saturation()+b),c},Spectra.fn.prototype.desaturate=function(a){var b=a/100,c=new Spectra(this.color);return c.saturation(c.saturation()-b),c},Spectra.fn.prototype.fadeIn=function(a){var b=a/100,c=new Spectra(this.color);return c.alpha(c.alpha()+b),c},Spectra.fn.prototype.fadeOut=function(a){var b=a/100,c=new Spectra(this.color);return c.alpha(c.alpha()-b),c},Spectra.fn.prototype.luma=function(){return.2126*this.red()+.7152*this.green()+.0722*this.blue()},Spectra.fn.prototype.grayscale=function(){return this.desaturate(100)},Spectra.fn.prototype.isDark=function(){var a=(299*this.red()+587*this.green()+144*this.blue())/1e3;return 131.5>a},Spectra.fn.prototype.isLight=function(){return!this.isDark()},Spectra.fn.prototype.mix=function(a,b){a=new Spectra(a);var c=arguments.length<2?.5:b/100;return new Spectra({r:this.red()*(1-c)+a.red()*c,g:this.green()*(1-c)+a.green()*c,b:this.blue()*(1-c)+a.blue()*c,a:this.alpha()*(1-c)+a.alpha()*c})},Spectra.fn.prototype.contrast=function(a){a=new Spectra(a);var b=Math.max(this.red(),a.red())-Math.min(this.red(),a.red())+Math.max(this.green(),a.green())-Math.min(this.green(),a.green())+Math.max(this.blue(),a.blue())-Math.min(this.blue(),a.blue());return b/765},Spectra.fn.prototype.gradient=function(a,b){a=new Spectra(a);for(var c=[],d=this.red(),e=this.green(),f=this.blue(),g=(a.red()-this.red())/(b-1),h=(a.green()-this.green())/(b-1),i=(a.blue()-this.blue())/(b-1),j=0;b>j;j++)c.push(new Spectra({r:d,g:e,b:f})),d+=g,e+=h,f+=i;return c},Spectra.fn.prototype.harmony=function(a,b){b="number"==typeof b?Math.abs(parseInt(b,10)):0;var d=[],e=c.rgbToHsv(this.color),f=[0,180];switch(a){case"analogous":f=[0,30,60];break;case"triad":f=[0,120,240];break;case"split-complementary":f=[0,150,210];break;case"rectangle":f=[0,60,180,240];break;case"square":f=[0,90,180,270];break;case"complementary":f=[0,180]}for(var g=f.length,h=f[b%g],i=0;g>i;i++)d.push(new Spectra({h:(e.h+f[i]-h)%360,s:e.s,v:e.v,a:this.color.a}));return d},Spectra.noConflict=function(){return a.Spectra=b,Spectra},Spectra.random=function(){return new Spectra({r:Math.floor(255*Math.random()),g:Math.floor(255*Math.random()),b:Math.floor(255*Math.random())})},"undefined"!=typeof exports?("undefined"!=typeof module&&(exports=module.exports=Spectra),exports.Spectra=Spectra):a.Spectra=Spectra}).call(this); |
37928
14
764
76