| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 | /* MIT license */var colorNames = require('color-name');var swizzle = require('simple-swizzle');var hasOwnProperty = Object.hasOwnProperty;var reverseNames = Object.create(null);// create a list of reverse color namesfor (var name in colorNames) {	if (hasOwnProperty.call(colorNames, name)) {		reverseNames[colorNames[name]] = name;	}}var cs = module.exports = {	to: {},	get: {}};cs.get = function (string) {	var prefix = string.substring(0, 3).toLowerCase();	var val;	var model;	switch (prefix) {		case 'hsl':			val = cs.get.hsl(string);			model = 'hsl';			break;		case 'hwb':			val = cs.get.hwb(string);			model = 'hwb';			break;		default:			val = cs.get.rgb(string);			model = 'rgb';			break;	}	if (!val) {		return null;	}	return {model: model, value: val};};cs.get.rgb = function (string) {	if (!string) {		return null;	}	var abbr = /^#([a-f0-9]{3,4})$/i;	var hex = /^#([a-f0-9]{6})([a-f0-9]{2})?$/i;	var rgba = /^rgba?\(\s*([+-]?\d+)(?=[\s,])\s*(?:,\s*)?([+-]?\d+)(?=[\s,])\s*(?:,\s*)?([+-]?\d+)\s*(?:[,|\/]\s*([+-]?[\d\.]+)(%?)\s*)?\)$/;	var per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,?\s*([+-]?[\d\.]+)\%\s*,?\s*([+-]?[\d\.]+)\%\s*(?:[,|\/]\s*([+-]?[\d\.]+)(%?)\s*)?\)$/;	var keyword = /^(\w+)$/;	var rgb = [0, 0, 0, 1];	var match;	var i;	var hexAlpha;	if (match = string.match(hex)) {		hexAlpha = match[2];		match = match[1];		for (i = 0; i < 3; i++) {			// https://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/19			var i2 = i * 2;			rgb[i] = parseInt(match.slice(i2, i2 + 2), 16);		}		if (hexAlpha) {			rgb[3] = parseInt(hexAlpha, 16) / 255;		}	} else if (match = string.match(abbr)) {		match = match[1];		hexAlpha = match[3];		for (i = 0; i < 3; i++) {			rgb[i] = parseInt(match[i] + match[i], 16);		}		if (hexAlpha) {			rgb[3] = parseInt(hexAlpha + hexAlpha, 16) / 255;		}	} else if (match = string.match(rgba)) {		for (i = 0; i < 3; i++) {			rgb[i] = parseInt(match[i + 1], 0);		}		if (match[4]) {			if (match[5]) {				rgb[3] = parseFloat(match[4]) * 0.01;			} else {				rgb[3] = parseFloat(match[4]);			}		}	} else if (match = string.match(per)) {		for (i = 0; i < 3; i++) {			rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);		}		if (match[4]) {			if (match[5]) {				rgb[3] = parseFloat(match[4]) * 0.01;			} else {				rgb[3] = parseFloat(match[4]);			}		}	} else if (match = string.match(keyword)) {		if (match[1] === 'transparent') {			return [0, 0, 0, 0];		}		if (!hasOwnProperty.call(colorNames, match[1])) {			return null;		}		rgb = colorNames[match[1]];		rgb[3] = 1;		return rgb;	} else {		return null;	}	for (i = 0; i < 3; i++) {		rgb[i] = clamp(rgb[i], 0, 255);	}	rgb[3] = clamp(rgb[3], 0, 1);	return rgb;};cs.get.hsl = function (string) {	if (!string) {		return null;	}	var hsl = /^hsla?\(\s*([+-]?(?:\d{0,3}\.)?\d+)(?:deg)?\s*,?\s*([+-]?[\d\.]+)%\s*,?\s*([+-]?[\d\.]+)%\s*(?:[,|\/]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/;	var match = string.match(hsl);	if (match) {		var alpha = parseFloat(match[4]);		var h = ((parseFloat(match[1]) % 360) + 360) % 360;		var s = clamp(parseFloat(match[2]), 0, 100);		var l = clamp(parseFloat(match[3]), 0, 100);		var a = clamp(isNaN(alpha) ? 1 : alpha, 0, 1);		return [h, s, l, a];	}	return null;};cs.get.hwb = function (string) {	if (!string) {		return null;	}	var hwb = /^hwb\(\s*([+-]?\d{0,3}(?:\.\d+)?)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/;	var match = string.match(hwb);	if (match) {		var alpha = parseFloat(match[4]);		var h = ((parseFloat(match[1]) % 360) + 360) % 360;		var w = clamp(parseFloat(match[2]), 0, 100);		var b = clamp(parseFloat(match[3]), 0, 100);		var a = clamp(isNaN(alpha) ? 1 : alpha, 0, 1);		return [h, w, b, a];	}	return null;};cs.to.hex = function () {	var rgba = swizzle(arguments);	return (		'#' +		hexDouble(rgba[0]) +		hexDouble(rgba[1]) +		hexDouble(rgba[2]) +		(rgba[3] < 1			? (hexDouble(Math.round(rgba[3] * 255)))			: '')	);};cs.to.rgb = function () {	var rgba = swizzle(arguments);	return rgba.length < 4 || rgba[3] === 1		? 'rgb(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ')'		: 'rgba(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ', ' + rgba[3] + ')';};cs.to.rgb.percent = function () {	var rgba = swizzle(arguments);	var r = Math.round(rgba[0] / 255 * 100);	var g = Math.round(rgba[1] / 255 * 100);	var b = Math.round(rgba[2] / 255 * 100);	return rgba.length < 4 || rgba[3] === 1		? 'rgb(' + r + '%, ' + g + '%, ' + b + '%)'		: 'rgba(' + r + '%, ' + g + '%, ' + b + '%, ' + rgba[3] + ')';};cs.to.hsl = function () {	var hsla = swizzle(arguments);	return hsla.length < 4 || hsla[3] === 1		? 'hsl(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%)'		: 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')';};// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax// (hwb have alpha optional & 1 is default value)cs.to.hwb = function () {	var hwba = swizzle(arguments);	var a = '';	if (hwba.length >= 4 && hwba[3] !== 1) {		a = ', ' + hwba[3];	}	return 'hwb(' + hwba[0] + ', ' + hwba[1] + '%, ' + hwba[2] + '%' + a + ')';};cs.to.keyword = function (rgb) {	return reverseNames[rgb.slice(0, 3)];};// helpersfunction clamp(num, min, max) {	return Math.min(Math.max(min, num), max);}function hexDouble(num) {	var str = Math.round(num).toString(16).toUpperCase();	return (str.length < 2) ? '0' + str : str;}
 |