mirror of
https://github.com/nunocoracao/blowfish.git
synced 2026-01-30 15:31:52 +00:00
config redirect
This commit is contained in:
+485
@@ -0,0 +1,485 @@
|
||||
/* MIT license */
|
||||
var convert = require('color-convert');
|
||||
var string = require('chartjs-color-string');
|
||||
|
||||
var Color = function (obj) {
|
||||
if (obj instanceof Color) {
|
||||
return obj;
|
||||
}
|
||||
if (!(this instanceof Color)) {
|
||||
return new Color(obj);
|
||||
}
|
||||
|
||||
this.valid = false;
|
||||
this.values = {
|
||||
rgb: [0, 0, 0],
|
||||
hsl: [0, 0, 0],
|
||||
hsv: [0, 0, 0],
|
||||
hwb: [0, 0, 0],
|
||||
cmyk: [0, 0, 0, 0],
|
||||
alpha: 1
|
||||
};
|
||||
|
||||
// parse Color() argument
|
||||
var vals;
|
||||
if (typeof obj === 'string') {
|
||||
vals = string.getRgba(obj);
|
||||
if (vals) {
|
||||
this.setValues('rgb', vals);
|
||||
} else if (vals = string.getHsla(obj)) {
|
||||
this.setValues('hsl', vals);
|
||||
} else if (vals = string.getHwb(obj)) {
|
||||
this.setValues('hwb', vals);
|
||||
}
|
||||
} else if (typeof obj === 'object') {
|
||||
vals = obj;
|
||||
if (vals.r !== undefined || vals.red !== undefined) {
|
||||
this.setValues('rgb', vals);
|
||||
} else if (vals.l !== undefined || vals.lightness !== undefined) {
|
||||
this.setValues('hsl', vals);
|
||||
} else if (vals.v !== undefined || vals.value !== undefined) {
|
||||
this.setValues('hsv', vals);
|
||||
} else if (vals.w !== undefined || vals.whiteness !== undefined) {
|
||||
this.setValues('hwb', vals);
|
||||
} else if (vals.c !== undefined || vals.cyan !== undefined) {
|
||||
this.setValues('cmyk', vals);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Color.prototype = {
|
||||
isValid: function () {
|
||||
return this.valid;
|
||||
},
|
||||
rgb: function () {
|
||||
return this.setSpace('rgb', arguments);
|
||||
},
|
||||
hsl: function () {
|
||||
return this.setSpace('hsl', arguments);
|
||||
},
|
||||
hsv: function () {
|
||||
return this.setSpace('hsv', arguments);
|
||||
},
|
||||
hwb: function () {
|
||||
return this.setSpace('hwb', arguments);
|
||||
},
|
||||
cmyk: function () {
|
||||
return this.setSpace('cmyk', arguments);
|
||||
},
|
||||
|
||||
rgbArray: function () {
|
||||
return this.values.rgb;
|
||||
},
|
||||
hslArray: function () {
|
||||
return this.values.hsl;
|
||||
},
|
||||
hsvArray: function () {
|
||||
return this.values.hsv;
|
||||
},
|
||||
hwbArray: function () {
|
||||
var values = this.values;
|
||||
if (values.alpha !== 1) {
|
||||
return values.hwb.concat([values.alpha]);
|
||||
}
|
||||
return values.hwb;
|
||||
},
|
||||
cmykArray: function () {
|
||||
return this.values.cmyk;
|
||||
},
|
||||
rgbaArray: function () {
|
||||
var values = this.values;
|
||||
return values.rgb.concat([values.alpha]);
|
||||
},
|
||||
hslaArray: function () {
|
||||
var values = this.values;
|
||||
return values.hsl.concat([values.alpha]);
|
||||
},
|
||||
alpha: function (val) {
|
||||
if (val === undefined) {
|
||||
return this.values.alpha;
|
||||
}
|
||||
this.setValues('alpha', val);
|
||||
return this;
|
||||
},
|
||||
|
||||
red: function (val) {
|
||||
return this.setChannel('rgb', 0, val);
|
||||
},
|
||||
green: function (val) {
|
||||
return this.setChannel('rgb', 1, val);
|
||||
},
|
||||
blue: function (val) {
|
||||
return this.setChannel('rgb', 2, val);
|
||||
},
|
||||
hue: function (val) {
|
||||
if (val) {
|
||||
val %= 360;
|
||||
val = val < 0 ? 360 + val : val;
|
||||
}
|
||||
return this.setChannel('hsl', 0, val);
|
||||
},
|
||||
saturation: function (val) {
|
||||
return this.setChannel('hsl', 1, val);
|
||||
},
|
||||
lightness: function (val) {
|
||||
return this.setChannel('hsl', 2, val);
|
||||
},
|
||||
saturationv: function (val) {
|
||||
return this.setChannel('hsv', 1, val);
|
||||
},
|
||||
whiteness: function (val) {
|
||||
return this.setChannel('hwb', 1, val);
|
||||
},
|
||||
blackness: function (val) {
|
||||
return this.setChannel('hwb', 2, val);
|
||||
},
|
||||
value: function (val) {
|
||||
return this.setChannel('hsv', 2, val);
|
||||
},
|
||||
cyan: function (val) {
|
||||
return this.setChannel('cmyk', 0, val);
|
||||
},
|
||||
magenta: function (val) {
|
||||
return this.setChannel('cmyk', 1, val);
|
||||
},
|
||||
yellow: function (val) {
|
||||
return this.setChannel('cmyk', 2, val);
|
||||
},
|
||||
black: function (val) {
|
||||
return this.setChannel('cmyk', 3, val);
|
||||
},
|
||||
|
||||
hexString: function () {
|
||||
return string.hexString(this.values.rgb);
|
||||
},
|
||||
rgbString: function () {
|
||||
return string.rgbString(this.values.rgb, this.values.alpha);
|
||||
},
|
||||
rgbaString: function () {
|
||||
return string.rgbaString(this.values.rgb, this.values.alpha);
|
||||
},
|
||||
percentString: function () {
|
||||
return string.percentString(this.values.rgb, this.values.alpha);
|
||||
},
|
||||
hslString: function () {
|
||||
return string.hslString(this.values.hsl, this.values.alpha);
|
||||
},
|
||||
hslaString: function () {
|
||||
return string.hslaString(this.values.hsl, this.values.alpha);
|
||||
},
|
||||
hwbString: function () {
|
||||
return string.hwbString(this.values.hwb, this.values.alpha);
|
||||
},
|
||||
keyword: function () {
|
||||
return string.keyword(this.values.rgb, this.values.alpha);
|
||||
},
|
||||
|
||||
rgbNumber: function () {
|
||||
var rgb = this.values.rgb;
|
||||
return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
||||
},
|
||||
|
||||
luminosity: function () {
|
||||
// http://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||
var rgb = this.values.rgb;
|
||||
var lum = [];
|
||||
for (var i = 0; i < rgb.length; i++) {
|
||||
var chan = rgb[i] / 255;
|
||||
lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);
|
||||
}
|
||||
return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
|
||||
},
|
||||
|
||||
contrast: function (color2) {
|
||||
// http://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
||||
var lum1 = this.luminosity();
|
||||
var lum2 = color2.luminosity();
|
||||
if (lum1 > lum2) {
|
||||
return (lum1 + 0.05) / (lum2 + 0.05);
|
||||
}
|
||||
return (lum2 + 0.05) / (lum1 + 0.05);
|
||||
},
|
||||
|
||||
level: function (color2) {
|
||||
var contrastRatio = this.contrast(color2);
|
||||
if (contrastRatio >= 7.1) {
|
||||
return 'AAA';
|
||||
}
|
||||
|
||||
return (contrastRatio >= 4.5) ? 'AA' : '';
|
||||
},
|
||||
|
||||
dark: function () {
|
||||
// YIQ equation from http://24ways.org/2010/calculating-color-contrast
|
||||
var rgb = this.values.rgb;
|
||||
var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
|
||||
return yiq < 128;
|
||||
},
|
||||
|
||||
light: function () {
|
||||
return !this.dark();
|
||||
},
|
||||
|
||||
negate: function () {
|
||||
var rgb = [];
|
||||
for (var i = 0; i < 3; i++) {
|
||||
rgb[i] = 255 - this.values.rgb[i];
|
||||
}
|
||||
this.setValues('rgb', rgb);
|
||||
return this;
|
||||
},
|
||||
|
||||
lighten: function (ratio) {
|
||||
var hsl = this.values.hsl;
|
||||
hsl[2] += hsl[2] * ratio;
|
||||
this.setValues('hsl', hsl);
|
||||
return this;
|
||||
},
|
||||
|
||||
darken: function (ratio) {
|
||||
var hsl = this.values.hsl;
|
||||
hsl[2] -= hsl[2] * ratio;
|
||||
this.setValues('hsl', hsl);
|
||||
return this;
|
||||
},
|
||||
|
||||
saturate: function (ratio) {
|
||||
var hsl = this.values.hsl;
|
||||
hsl[1] += hsl[1] * ratio;
|
||||
this.setValues('hsl', hsl);
|
||||
return this;
|
||||
},
|
||||
|
||||
desaturate: function (ratio) {
|
||||
var hsl = this.values.hsl;
|
||||
hsl[1] -= hsl[1] * ratio;
|
||||
this.setValues('hsl', hsl);
|
||||
return this;
|
||||
},
|
||||
|
||||
whiten: function (ratio) {
|
||||
var hwb = this.values.hwb;
|
||||
hwb[1] += hwb[1] * ratio;
|
||||
this.setValues('hwb', hwb);
|
||||
return this;
|
||||
},
|
||||
|
||||
blacken: function (ratio) {
|
||||
var hwb = this.values.hwb;
|
||||
hwb[2] += hwb[2] * ratio;
|
||||
this.setValues('hwb', hwb);
|
||||
return this;
|
||||
},
|
||||
|
||||
greyscale: function () {
|
||||
var rgb = this.values.rgb;
|
||||
// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
|
||||
var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
|
||||
this.setValues('rgb', [val, val, val]);
|
||||
return this;
|
||||
},
|
||||
|
||||
clearer: function (ratio) {
|
||||
var alpha = this.values.alpha;
|
||||
this.setValues('alpha', alpha - (alpha * ratio));
|
||||
return this;
|
||||
},
|
||||
|
||||
opaquer: function (ratio) {
|
||||
var alpha = this.values.alpha;
|
||||
this.setValues('alpha', alpha + (alpha * ratio));
|
||||
return this;
|
||||
},
|
||||
|
||||
rotate: function (degrees) {
|
||||
var hsl = this.values.hsl;
|
||||
var hue = (hsl[0] + degrees) % 360;
|
||||
hsl[0] = hue < 0 ? 360 + hue : hue;
|
||||
this.setValues('hsl', hsl);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Ported from sass implementation in C
|
||||
* https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
|
||||
*/
|
||||
mix: function (mixinColor, weight) {
|
||||
var color1 = this;
|
||||
var color2 = mixinColor;
|
||||
var p = weight === undefined ? 0.5 : weight;
|
||||
|
||||
var w = 2 * p - 1;
|
||||
var a = color1.alpha() - color2.alpha();
|
||||
|
||||
var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
|
||||
var w2 = 1 - w1;
|
||||
|
||||
return this
|
||||
.rgb(
|
||||
w1 * color1.red() + w2 * color2.red(),
|
||||
w1 * color1.green() + w2 * color2.green(),
|
||||
w1 * color1.blue() + w2 * color2.blue()
|
||||
)
|
||||
.alpha(color1.alpha() * p + color2.alpha() * (1 - p));
|
||||
},
|
||||
|
||||
toJSON: function () {
|
||||
return this.rgb();
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
|
||||
// making the final build way to big to embed in Chart.js. So let's do it manually,
|
||||
// assuming that values to clone are 1 dimension arrays containing only numbers,
|
||||
// except 'alpha' which is a number.
|
||||
var result = new Color();
|
||||
var source = this.values;
|
||||
var target = result.values;
|
||||
var value, type;
|
||||
|
||||
for (var prop in source) {
|
||||
if (source.hasOwnProperty(prop)) {
|
||||
value = source[prop];
|
||||
type = ({}).toString.call(value);
|
||||
if (type === '[object Array]') {
|
||||
target[prop] = value.slice(0);
|
||||
} else if (type === '[object Number]') {
|
||||
target[prop] = value;
|
||||
} else {
|
||||
console.error('unexpected color value:', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
Color.prototype.spaces = {
|
||||
rgb: ['red', 'green', 'blue'],
|
||||
hsl: ['hue', 'saturation', 'lightness'],
|
||||
hsv: ['hue', 'saturation', 'value'],
|
||||
hwb: ['hue', 'whiteness', 'blackness'],
|
||||
cmyk: ['cyan', 'magenta', 'yellow', 'black']
|
||||
};
|
||||
|
||||
Color.prototype.maxes = {
|
||||
rgb: [255, 255, 255],
|
||||
hsl: [360, 100, 100],
|
||||
hsv: [360, 100, 100],
|
||||
hwb: [360, 100, 100],
|
||||
cmyk: [100, 100, 100, 100]
|
||||
};
|
||||
|
||||
Color.prototype.getValues = function (space) {
|
||||
var values = this.values;
|
||||
var vals = {};
|
||||
|
||||
for (var i = 0; i < space.length; i++) {
|
||||
vals[space.charAt(i)] = values[space][i];
|
||||
}
|
||||
|
||||
if (values.alpha !== 1) {
|
||||
vals.a = values.alpha;
|
||||
}
|
||||
|
||||
// {r: 255, g: 255, b: 255, a: 0.4}
|
||||
return vals;
|
||||
};
|
||||
|
||||
Color.prototype.setValues = function (space, vals) {
|
||||
var values = this.values;
|
||||
var spaces = this.spaces;
|
||||
var maxes = this.maxes;
|
||||
var alpha = 1;
|
||||
var i;
|
||||
|
||||
this.valid = true;
|
||||
|
||||
if (space === 'alpha') {
|
||||
alpha = vals;
|
||||
} else if (vals.length) {
|
||||
// [10, 10, 10]
|
||||
values[space] = vals.slice(0, space.length);
|
||||
alpha = vals[space.length];
|
||||
} else if (vals[space.charAt(0)] !== undefined) {
|
||||
// {r: 10, g: 10, b: 10}
|
||||
for (i = 0; i < space.length; i++) {
|
||||
values[space][i] = vals[space.charAt(i)];
|
||||
}
|
||||
|
||||
alpha = vals.a;
|
||||
} else if (vals[spaces[space][0]] !== undefined) {
|
||||
// {red: 10, green: 10, blue: 10}
|
||||
var chans = spaces[space];
|
||||
|
||||
for (i = 0; i < space.length; i++) {
|
||||
values[space][i] = vals[chans[i]];
|
||||
}
|
||||
|
||||
alpha = vals.alpha;
|
||||
}
|
||||
|
||||
values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
|
||||
|
||||
if (space === 'alpha') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var capped;
|
||||
|
||||
// cap values of the space prior converting all values
|
||||
for (i = 0; i < space.length; i++) {
|
||||
capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
|
||||
values[space][i] = Math.round(capped);
|
||||
}
|
||||
|
||||
// convert to all the other color spaces
|
||||
for (var sname in spaces) {
|
||||
if (sname !== space) {
|
||||
values[sname] = convert[space][sname](values[space]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
Color.prototype.setSpace = function (space, args) {
|
||||
var vals = args[0];
|
||||
|
||||
if (vals === undefined) {
|
||||
// color.rgb()
|
||||
return this.getValues(space);
|
||||
}
|
||||
|
||||
// color.rgb(10, 10, 10)
|
||||
if (typeof vals === 'number') {
|
||||
vals = Array.prototype.slice.call(args);
|
||||
}
|
||||
|
||||
this.setValues(space, vals);
|
||||
return this;
|
||||
};
|
||||
|
||||
Color.prototype.setChannel = function (space, index, val) {
|
||||
var svalues = this.values[space];
|
||||
if (val === undefined) {
|
||||
// color.red()
|
||||
return svalues[index];
|
||||
} else if (val === svalues[index]) {
|
||||
// color.red(color.red())
|
||||
return this;
|
||||
}
|
||||
|
||||
// color.red(100)
|
||||
svalues[index] = val;
|
||||
this.setValues(space, svalues);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.Color = Color;
|
||||
}
|
||||
|
||||
module.exports = Color;
|
||||
Reference in New Issue
Block a user