var colorlib = require('./color-lib');
var colorNames = require('./color-names');
function isColor(c) {
return c instanceof Color;
}
/** @class Color
* Color class accepts a CSS color string, rgb, hsl data as the input, manipulate the color, and returns a CSS-compatible color string.
* @constructor
*
* @example
* new Color('red') // named CSS colors
*
* @example
* new Color('#f00') // hex 3 characters
*
* @example
* new Color('#e2b644') // hex 6 characters
*
* @example
* new Color('rgb(255, 0, 100)') // rgb()
*
* @example
* new Color('rgba(255, 0, 100, 0.5)') // rgba()
*
* @example
* new Color([255,0,0]) // rgb array
*
* @example
* new Color([255,0,0, 0.5]) // rgba array (alpha channel)
*
* @example
* new Color({ // hsl object
* h: 0.2,
* s: 0.5,
* l: 1
* })
*
* @example
* new Color({ // hsla object
* h: 0.5,
* s: 1,
* l: 1,
* a: 0.5
* })
*/
var Color = function () {
var a = arguments[0];
if (isColor(a)) {
/**
* The the array containing red, green, blue color values, and the alpha channel value
*
* @property rgb
*
* @example
* console.log( new Color('red').rgb ); // outputs [255,0,0]
*
*/
this.rgb = a.rgb.slice();
}
else if (typeof a === 'object' && 'h' in a && 's' in a && 'l' in a) {
this.rgb = colorlib.hsl2rgb([a.h, a.s, a.l]);
if ('a' in a && a.a >= 0 && a.a < 1) {
this.rgb[3] = a.a;
}
}
else if (arguments.length === 1) {
this.rgb = colorlib.getRGB(a);
}
else {
this.rgb = colorlib.getRGB(Array.from(arguments));
}
};
Color.prototype = {
toString: function () {
return colorlib.rgb2css(this.rgb);
},
// setters
/**
* Sets the transparency of a color
*
* @method alpha
* @memberof Color
* @param {Number} alpha transparency level between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#f00').alpha(0.5).toString(); // returns "rgba(255,0,0,0.5)"
*
*/
alpha: function (v) {
return new Color(colorlib.alpha(this.rgb, v));
},
/**
* Increases the "lightness" of a color value
*
* @method lighten
* @memberof Color
* @param {Number} lightenBy amount to lighten between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#f00').lighten(0.5).toString(); // returns "#FF8080"
*
*/
lighten: function (v) {
return new Color(colorlib.lighten(this.rgb, v));
},
/**
* Decreases the "lightness" of a color value
*
* @method darken
* @memberof Color
* @param {Number} darkenBy amount to darken between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#f00').darken(0.5).toString(); // returns "#800000"
*
*/
darken: function (v) {
return new Color(colorlib.darken(this.rgb, v));
},
/**
* Increases the "saturation" of a color value
*
* @method saturate
* @memberof Color
* @param {Number} saturateBy amount to saturate between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('rgb(125,0,0)').saturate(0.2).toString(); // returns "#7D0000"
*
*/
saturate: function (v) {
return new Color(colorlib.saturate(this.rgb, v));
},
/**
* Decreases the "saturation" of a color value
*
* @method desaturate
* @memberof Color
* @param {Number} desaturateBy amount to desaturate between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color(125,0,0).desaturate(0.2).toString(); // returns "#710C0C"
*
*/
desaturate: function (v) {
return new Color(colorlib.desaturate(this.rgb, v));
},
/**
* Shifts the "hue" of a color value by a given percentage
*
* @method shiftHue
* @memberof Color
* @param {Number} hueShift amount to modify the hue by between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color(255,255,0).shiftHue(0.25).toString(); // returns "#00FF7F"
*
*/
shiftHue: function (v) {
return new Color(colorlib.shiftHue(this.rgb, v));
},
/**
* Shifts the hue of a color closer to another color by a given percentage
*
* @method combine
* @memberof Color
* @param {Object} targetColor color string, array, or object
* @param {Number} [amount=0.5] how close to the target color between 0 and 1 (0.5 is half-way between)
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color(0).combine('#fff').toString(); // returns "#808080"
* new Color(255,0,0).combine('#00f',0.7).toString(); // returns "#4D00B3"
*
*/
combine: function (t, v) {
var combineColor = new Color(t);
var c = colorlib.combine(this.rgb, combineColor.rgb, v);
return new Color(c);
},
/**
* Shifts only the hue of a color closer to another color by a given percentage
*
* @method tint
* @memberof Color
* @param {String} targetColor color string or array
* @param {Number} amount amount to shift the hue toward the target color between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('rgb(255,0,0)').tint('#00f',0.5).toString(); // returns "#F0F"
* new Color('rgb(0,0,100)').tint('rgb(100,0,0)',0.1).toString(); // returns "#140064"
*
*/
tint: function (t, v) {
var tintColor = new Color(t);
return new Color(colorlib.tint(this.rgb, tintColor.rgb, v));
},
/**
* Set the "hue" of a color
*
* @method hue
* @memberof Color
* @param {Number} hue hue value between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#f00').hue(2/3).toString(); // returns "#00F"
* new Color('#0f0').hue(1).toString(); // returns "#F00"
* new Color('#00f').hue(1/3).toString(); // returns "#0F0"
*
*/
hue: function (v) {
return new Color(colorlib.hue(this.rgb, v));
},
/**
* Set the "saturation" of a color
*
* @method saturation
* @memberof Color
* @param {Number} saturation saturation value between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('rgb(100,50,50)').saturation(0).toString(); // returns "#4B4B4B"
* new Color('rgb(50,0,0)').saturation(0.5).toString(); // returns "#260C0C"
* new Color('rgb(50,50,100)').saturation(1).toString(); // returns "#000096"
*
*/
saturation: function (v) {
return new Color(colorlib.saturation(this.rgb, v));
},
/**
* Set the lightness of a color, how close to white or black the color will be
*
* @method lightness
* @memberof Color
* @param {Number} lightness lightness value between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('rgb(255,0,0)').lightness(0).toString(); // returns "#000"
* new Color('rgb(255,0,0)').lightness(0.5).toString(); // returns "#F00"
* new Color('rgb(255,0,0)').lightness(1).toString(); // returns "#FFF"
*
*/
lightness: function (v) {
return new Color(colorlib.lightness(this.rgb, v));
},
/**
* Inverts the color
*
* @method invert
* @memberof Color
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#f00').invert(1).toString(); // returns "#0FF"
* new Color('#fff').invert().toString(); // returns "#000"
*
*/
invert: function () {
return new Color(colorlib.invert(this.rgb));
},
/**
* Set the hue, saturation, or lightness of a color and return the new color
*
* @method hsl
* @memberof Color
* @param {Number} hue hue value between 0 and 1
* @param {Number} saturation saturation value between 0 and 1
* @param {Number} lightness lightness value between 0 and 1
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#f00').hsl(null,0.5,0.5).toString(); // returns "#BF4040"
*
*/
hsl: function () {
var a = Array.from(arguments);
a.unshift(this.rgb);
return new Color(colorlib.setHSL.apply(null, a));
},
/**
* Set the red component of a color
*
* @method red
* @memberof Color
* @param {Number} red red component 0-255
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('rgb(0,0,255)').red(255).toString(); // returns "#F0F"
*
*/
red: function (r) {
return new Color(colorlib.setRGB(this.rgb, [r]));
},
/**
* Set the green component of a color
*
* @method green
* @memberof Color
* @param {Number} green green component 0-255
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('rgb(255,0,0)').green(255).toString(); // returns "#FF0"
*
*/
green: function (g) {
return new Color(colorlib.setRGB(this.rgb, [null, g]));
},
/**
* Set the blue component of a color
*
* @method blue
* @memberof Color
* @param {Number} blue blue component 0-255
* @return {Color} new Color() instance
* @instance
*
* @example
* new Color('#FF0').blue(255).toString(); // returns "#FFF"
*
*/
blue: function (b) {
return new Color(colorlib.setRGB(this.rgb, [null, null, b]));
},
// getters
/**
* Returns the transparency of a color
*
* @method getAlpha
* @memberof Color
* @return {Number} alpha transparency level between 0 and 1
* @instance
*
* @example
* new Color('#F00').getAlpha(); // returns 0
* new Color('rgba(255,0,0,0.5)').getAlpha(); // returns 0.5
*
*/
getAlpha: function () {
return (this.rgb.length === 4) ? this.rgb[3] : 1;
},
/**
* Returns the hexidecimal value of the color
*
* @method getHex
* @memberof Color
* @return {String} hex color value
* @instance
*
* @example
* new Color('rgba(255,0,0,0.5)').getHex(); // returns "#f00"
*
*/
getHex: function () {
return colorlib.rgb2hex(this.rgb);
},
/**
* Returns the red component of a color string
*
* @method getRed
* @memberof Color
* @return {Number} red component 0-255
* @instance
*
* @example
* new Color('#fff').getRed(); // returns 255
*
*/
getRed: function () {
return this.rgb[0];
},
/**
* Returns the green component of a color string
*
* @method getGreen
* @memberof Color
* @return {Number} green component 0-255
* @instance
*
* @example
* new Color('#fff').getGreen(); // returns 255
*
*/
getGreen: function () {
return this.rgb[1];
},
/**
* Returns the blue component of a color string
*
* @method getBlue
* @memberof Color
* @return {Number} blue component 0-255
* @instance
*
* @example
* new Color('#fff').getBlue(); // returns 255
*
*/
getBlue: function () {
return this.rgb[2];
},
/**
* Returns an [h,s,l] array from color string
*
* @method getHSL
* @memberof Color
* @return {Number[]} hsl array of [hue,saturation,lightness]
* @instance
*
* @example
* new Color('#f00').getHSL(); // returns [0,1,0.5]
*
*/
getHSL: function () {
return colorlib.getHSL(this.rgb);
},
/**
* Return the "hue" of a color
*
* @method getHue
* @memberof Color
* @return {Number} hue hue value between 0 and 1
* @instance
*
* @example
* new Color('#a1b2c1').getHue(); // returns "0.578125"}
* new Color('#f00').getHue(); // returns 0
* new Color('#0f0').getHue(); // returns 0.3333333333333333
* new Color('#00f').getHue(); // returns 0.6666666666666666
*
*/
getHue: function () {
return this.getHSL()[0];
},
/**
* Return the "saturation" of a color
*
* @method getSaturation
* @memberof Color
* @return {Number} saturation saturation value between 0 and 1
* @instance
v
* @example
* new Color('rgb(100,100,100)').getSaturation(); // returns 0
* new Color('rgb(100,50,100)').getSaturation(); // returns 0.8333333333333334
* new Color('rgb(100,0,100)').getSaturation(); // returns 1
*
*/
getSaturation: function () {
return this.getHSL()[1];
},
/**
* Return the lightness of a color (how close to white or black the color is)
*
* @method getLightness
* @memberof Color
* @return {Number} lightness lightness value between 0 and 1
* @instance
*
* @example
* new Color('rgb(0,0,0)').getLightness(); // returns 0
* new Color('rgb(100,50,100)').getLightness(); // returns 0.29411764705882354
* new Color('rgb(255,255,255)').getLightness(); // returns 1
*
*/
getLightness: function () {
return this.getHSL()[2];
}
};
module.exports = Color;
/**
* Color.names is n object literal containing the list of named color values and their RGB value array
*
* @property names
* @memberof Color
*
* @example
* console.log( Color.names.red ); // outputs [255,0,0]
*/
Color.names = colorNames;