zui
Version:
一个基于 Bootstrap 深度定制开源前端实践方案,帮助你快速构建现代跨屏应用。
507 lines (448 loc) • 15.1 kB
JavaScript
/* ========================================================================
* ZUI: color.js
* http://zui.sexy
* ========================================================================
* Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT
* ======================================================================== */
(function($, Math, window, undefined) {
'use strict';
var hexReg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/,
N255 = 255,
N360 = 360,
N100 = 100,
STR_STRING = 'string',
STR_OBJECT = 'object',
namedColors = {
aliceblue: '#f0f8ff',
antiquewhite: '#faebd7',
aqua: '#00ffff',
aquamarine: '#7fffd4',
azure: '#f0ffff',
beige: '#f5f5dc',
bisque: '#ffe4c4',
black: '#000000',
blanchedalmond: '#ffebcd',
blue: '#0000ff',
blueviolet: '#8a2be2',
brown: '#a52a2a',
burlywood: '#deb887',
cadetblue: '#5f9ea0',
chartreuse: '#7fff00',
chocolate: '#d2691e',
coral: '#ff7f50',
cornflowerblue: '#6495ed',
cornsilk: '#fff8dc',
crimson: '#dc143c',
cyan: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgoldenrod: '#b8860b',
darkgray: '#a9a9a9',
darkgreen: '#006400',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b',
darkslategray: '#2f4f4f',
darkturquoise: '#00ced1',
darkviolet: '#9400d3',
deeppink: '#ff1493',
deepskyblue: '#00bfff',
dimgray: '#696969',
dodgerblue: '#1e90ff',
firebrick: '#b22222',
floralwhite: '#fffaf0',
forestgreen: '#228b22',
fuchsia: '#ff00ff',
gainsboro: '#dcdcdc',
ghostwhite: '#f8f8ff',
gold: '#ffd700',
goldenrod: '#daa520',
gray: '#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',
lightgreen: '#90ee90',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#00ff00',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
maroon: '#800000',
mediumaquamarine: '#66cdaa',
mediumblue: '#0000cd',
mediumorchid: '#ba55d3',
mediumpurple: '#9370db',
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: '#db7093',
papayawhip: '#ffefd5',
peachpuff: '#ffdab9',
peru: '#cd853f',
pink: '#ffc0cb',
plum: '#dda0dd',
powderblue: '#b0e0e6',
purple: '#800080',
red: '#ff0000',
rosybrown: '#bc8f8f',
royalblue: '#4169e1',
saddlebrown: '#8b4513',
salmon: '#fa8072',
sandybrown: '#f4a460',
seagreen: '#2e8b57',
seashell: '#fff5ee',
sienna: '#a0522d',
silver: '#c0c0c0',
skyblue: '#87ceeb',
slateblue: '#6a5acd',
slategray: '#708090',
snow: '#fffafa',
springgreen: '#00ff7f',
steelblue: '#4682b4',
tan: '#d2b48c',
teal: '#008080',
thistle: '#d8bfd8',
tomato: '#ff6347',
turquoise: '#40e0d0',
violet: '#ee82ee',
wheat: '#f5deb3',
white: '#ffffff',
whitesmoke: '#f5f5f5',
yellow: '#ffff00',
yellowgreen: '#9acd32'
};
var isUndefined = function(x) {
return x === undefined;
};
var isNotUndefined = function(x) {
return !isUndefined(x);
};
var convertToInt = function(x) {
return parseInt(x);
};
var convertToRgbInt = function(x) {
return convertToInt(clamp(number(x), N255));
};
/* color */
var Color = function(r, g, b, a) {
var that = this;
that.r = that.g = that.b = 0;
that.a = 1;
if(isNotUndefined(a)) that.a = clamp(number(a), 1);
if(isNotUndefined(r) && isNotUndefined(g) && isNotUndefined(b)) {
that.r = convertToRgbInt(r);
that.g = convertToRgbInt(g);
that.b = convertToRgbInt(b);
} else if(isNotUndefined(r)) {
var type = typeof(r);
if(type == STR_STRING) {
r = r.toLowerCase();
if(r === 'transparent') {
that.a = 0;
} else if(namedColors[r]) {
this.rgb(hexToRgb(namedColors[r]));
} else if(r.indexOf('rgb') === 0) {
var rgbsArr = r.substring(r.indexOf('(') + 1, r.lastIndexOf(')')).split(',', 4);
that.rgb({
r: rgbsArr[0],
g: rgbsArr[1],
b: rgbsArr[2],
a: rgbsArr[3],
});
} else {
that.rgb(hexToRgb(r));
}
} else if(type == 'number' && isUndefined(g)) {
that.r = that.g = that.b = convertToRgbInt(r);
} else if(type == STR_OBJECT && isNotUndefined(r.r)) {
that.r = convertToRgbInt(r.r);
if(isNotUndefined(r.g)) that.g = convertToRgbInt(r.g);
if(isNotUndefined(r.b)) that.b = convertToRgbInt(r.b);
if(isNotUndefined(r.a)) that.a = clamp(number(r.a), 1);
} else if(type == STR_OBJECT && isNotUndefined(r.h)) {
var hsl = {
h: clamp(number(r.h), N360),
s: 1,
l: 1,
a: 1
};
if(isNotUndefined(r.s)) hsl.s = clamp(number(r.s), 1);
if(isNotUndefined(r.l)) hsl.l = clamp(number(r.l), 1);
if(isNotUndefined(r.a)) hsl.a = clamp(number(r.a), 1);
that.rgb(hslToRgb(hsl));
}
}
};
Color.prototype.rgb = function(rgb) {
var that = this;
if(isNotUndefined(rgb)) {
if(typeof(rgb) == STR_OBJECT) {
if(isNotUndefined(rgb.r)) that.r = convertToRgbInt(rgb.r);
if(isNotUndefined(rgb.g)) that.g = convertToRgbInt(rgb.g);
if(isNotUndefined(rgb.b)) that.b = convertToRgbInt(rgb.b);
if(isNotUndefined(rgb.a)) that.a = clamp(number(rgb.a), 1);
} else {
var v = convertToInt(number(rgb));
that.r = v;
that.g = v;
that.b = v;
}
return that;
} else return {
r: that.r,
g: that.g,
b: that.b,
a: that.a
};
};
Color.prototype.hue = function(hue) {
var that = this;
var hsl = that.toHsl();
if(isUndefined(hue)) return hsl.h;
else {
hsl.h = clamp(number(hue), N360);
that.rgb(hslToRgb(hsl));
return that;
}
};
Color.prototype.darken = function(amount) {
var that = this;
var hsl = that.toHsl();
hsl.l -= amount / N100;
hsl.l = clamp(hsl.l, 1);
that.rgb(hslToRgb(hsl));
return that;
};
Color.prototype.clone = function() {
var that = this;
return new Color(that.r, that.g, that.b, that.a);
};
Color.prototype.lighten = function(amount) {
return this.darken(-amount);
};
Color.prototype.fade = function(amount) {
this.a = clamp(amount / N100, 1);
return this;
};
Color.prototype.spin = function(amount) {
var hsl = this.toHsl();
var hue = (hsl.h + amount) % N360;
hsl.h = hue < 0 ? N360 + hue : hue;
return this.rgb(hslToRgb(hsl));
};
Color.prototype.toHsl = function() {
var that = this;
var r = that.r / N255,
g = that.g / N255,
b = that.b / N255,
a = that.a;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2,
d = max - min;
if(max === min) {
h = s = 0;
} else {
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return {
h: h * N360,
s: s,
l: l,
a: a
};
};
Color.prototype.luma = function() {
var r = this.r / N255,
g = this.g / N255,
b = this.b / N255;
r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
};
Color.prototype.saturate = function(amount) {
var hsl = this.toHsl();
hsl.s += amount / N100;
hsl.s = clamp(hsl.s);
return this.rgb(hslToRgb(hsl));
};
Color.prototype.desaturate = function(amount) {
return this.saturate(-amount);
};
Color.prototype.contrast = function(dark, light, threshold) {
if(isUndefined(light)) light = new Color(N255, N255, N255, 1);
else light = new Color(light);
if(isUndefined(dark)) dark = new Color(0, 0, 0, 1);
else dark = new Color(dark);
if(dark.luma() > light.luma()) {
var t = light;
light = dark;
dark = t;
}
if(this.a < 0.5) return dark;
if(isUndefined(threshold)) threshold = 0.43;
else threshold = number(threshold);
if(this.luma() < threshold) {
return light;
} else {
return dark;
}
};
Color.prototype.hexStr = function() {
var r = this.r.toString(16),
g = this.g.toString(16),
b = this.b.toString(16);
if(r.length == 1) r = '0' + r;
if(g.length == 1) g = '0' + g;
if(b.length == 1) b = '0' + b;
return '#' + r + g + b;
};
Color.prototype.toCssStr = function() {
var that = this;
if(that.a > 0) {
if(that.a < 1) {
return 'rgba(' + that.r + ',' + that.g + ',' + that.b + ',' + that.a + ')';
} else {
return that.hexStr();
}
} else {
return 'transparent';
}
};
Color.isColor = isColor;
Color.names = namedColors;
Color.get = function(colorName) {
return new Color(colorName);
};
/* helpers */
function hexToRgb(hex) {
hex = hex.toLowerCase();
if(hex && hexReg.test(hex)) {
var i;
if(hex.length === 4) {
var hexNew = '#';
for(i = 1; i < 4; i += 1) {
hexNew += hex.slice(i, i + 1).concat(hex.slice(i, i + 1));
}
hex = hexNew;
}
var hexChange = [];
for(i = 1; i < 7; i += 2) {
hexChange.push(convertToInt('0x' + hex.slice(i, i + 2)));
}
return {
r: hexChange[0],
g: hexChange[1],
b: hexChange[2],
a: 1
};
} else {
throw new Error('Wrong hex string! (hex: ' + hex + ')');
}
}
function isColor(hex) {
return typeof(hex) === STR_STRING && (hex.toLowerCase() === 'transparent' || namedColors[hex.toLowerCase()] || hexReg.test($.trim(hex.toLowerCase())));
}
function hslToRgb(hsl) {
var h = hsl.h,
s = hsl.s,
l = hsl.l,
a = hsl.a;
h = (number(h) % N360) / N360;
s = clamp(number(s));
l = clamp(number(l));
a = clamp(number(a));
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
var m1 = l * 2 - m2;
var r = {
r: hue(h + 1 / 3) * N255,
g: hue(h) * N255,
b: hue(h - 1 / 3) * N255,
a: a
};
return r;
function hue(h) {
h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
if(h * 6 < 1) {
return m1 + (m2 - m1) * h * 6;
} else if(h * 2 < 1) {
return m2;
} else if(h * 3 < 2) {
return m1 + (m2 - m1) * (2 / 3 - h) * 6;
} else {
return m1;
}
}
}
function fit(n, end, start) {
if(isUndefined(start)) start = 0;
if(isUndefined(end)) end = N255;
return Math.min(Math.max(n, start), end);
}
function clamp(v, max) {
return fit(v, max);
}
function number(n) {
if(typeof(n) == 'number') return n;
return parseFloat(n);
}
$.zui({
Color: Color
});
}(jQuery, Math, window, undefined));