Last active
April 24, 2020 16:11
-
-
Save jonobr1/5166698 to your computer and use it in GitHub Desktop.
Interpret any valid css string and return an r, g, b, (a) object with normalized values.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Interpret any valid css string as an r, g, b, (a) object. | |
* If nothing found then it returns an object that is black with | |
* no alpha. | |
* | |
* Usage: interpret('red'); // { r: 1, g: 0, b: 0 }; | |
* interpret('#f00'); // { r: 1, g: 0, b: 0 }; | |
* interpret('#ff000'); // { r: 1, g: 0, b: 0 }; | |
* interpret('rgb(255, 0, 0)'); // { r: 1, g: 0, b: 0 }; | |
* interpret('rgba(255, 0, 0, 1)'); // { r: 1, g: 0, b: 0, a: 1 }; | |
* interpret('hsl()'); | |
* interpret('hsla()'); | |
* | |
* @author jonobr1 / http://jonobr1.com/ | |
*/ | |
(function() { | |
var root = this; | |
var previousInterpret = root.interpret || {}; | |
var interpret = root.interpret = function(v) { | |
for (var i = 0, l = stringParsers.length; i < l; i++) { | |
var color = stringParsers[i](v); | |
if (color) { | |
return color; | |
} | |
} | |
/** | |
* Default to invisible black if can't find a color. | |
*/ | |
return { | |
r: 0, g: 0, b: 0, a: 0 | |
}; | |
}; | |
interpret.noConflict = function() { | |
root.interpret = previousInterpret; | |
return this; | |
}; | |
/** | |
* CSS Color interpretation from | |
* https://github.com/brehaut/color-js/blob/master/color.js | |
* Copyright (c) 2008-2010, Andrew Brehaut, Tim Baumann, Matt Wilson | |
* All rights reserved. | |
*/ | |
// css_colors maps color names onto their hex values | |
// these names are defined by W3C | |
var css_colors = {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',darkgrey:'#A9A9A9',darkgreen:'#006400',darkkhaki:'#BDB76B',darkmagenta:'#8B008B',darkolivegreen:'#556B2F',darkorange:'#FF8C00',darkorchid:'#9932CC',darkred:'#8B0000',darksalmon:'#E9967A',darkseagreen:'#8FBC8F',darkslateblue:'#483D8B',darkslategray:'#2F4F4F',darkslategrey:'#2F4F4F',darkturquoise:'#00CED1',darkviolet:'#9400D3',deeppink:'#FF1493',deepskyblue:'#00BFFF',dimgray:'#696969',dimgrey:'#696969',dodgerblue:'#1E90FF',firebrick:'#B22222',floralwhite:'#FFFAF0',forestgreen:'#228B22',fuchsia:'#FF00FF',gainsboro:'#DCDCDC',ghostwhite:'#F8F8FF',gold:'#FFD700',goldenrod:'#DAA520',gray:'#808080',grey:'#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',lightgrey:'#D3D3D3',lightgreen:'#90EE90',lightpink:'#FFB6C1',lightsalmon:'#FFA07A',lightseagreen:'#20B2AA',lightskyblue:'#87CEFA',lightslategray:'#778899',lightslategrey:'#778899',lightsteelblue:'#B0C4DE',lightyellow:'#FFFFE0',lime:'#00FF00',limegreen:'#32CD32',linen:'#FAF0E6',magenta:'#FF00FF',maroon:'#800000',mediumaquamarine:'#66CDAA',mediumblue:'#0000CD',mediumorchid:'#BA55D3',mediumpurple:'#9370D8',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:'#D87093',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',slategrey:'#708090',snow:'#FFFAFA',springgreen:'#00FF7F',transparent:'#000',steelblue:'#4682B4',tan:'#D2B48C',teal:'#008080',thistle:'#D8BFD8',tomato:'#FF6347',turquoise:'#40E0D0',violet:'#EE82EE',wheat:'#F5DEB3',white:'#FFFFFF',whitesmoke:'#F5F5F5',yellow:'#FFFF00',yellowgreen:'#9ACD32'}; | |
// CSS value regexes, according to http://www.w3.org/TR/css3-values/ | |
var css_integer = '(?:\\+|-)?\\d+'; | |
var css_float = '(?:\\+|-)?\\d*\\.\\d+'; | |
var css_number = '(?:' + css_integer + ')|(?:' + css_float + ')'; | |
css_integer = '(' + css_integer + ')'; | |
css_float = '(' + css_float + ')'; | |
css_number = '(' + css_number + ')'; | |
var css_percentage = css_number + '%'; | |
var css_whitespace = '\\s*?'; | |
// http://www.w3.org/TR/2003/CR-css3-color-20030514/ | |
var hsl_hsla_regex = new RegExp([ | |
'^hsl(a?)\\(', css_number, ',', css_percentage, ',', css_percentage, '(,', css_number, ')?\\)$' | |
].join(css_whitespace) ); | |
var rgb_rgba_integer_regex = new RegExp([ | |
'^rgb(a?)\\(', css_integer, ',', css_integer, ',', css_integer, '(,', css_number, ')?\\)$' | |
].join(css_whitespace) ); | |
var rgb_rgba_percentage_regex = new RegExp([ | |
'^rgb(a?)\\(', css_percentage, ',', css_percentage, ',', css_percentage, '(,', css_number, ')?\\)$' | |
].join(css_whitespace) ); | |
var remove_comma_regex = /^,\s*/; | |
var hslToRgb = function(h, s, l, a) { | |
var r, g, b; | |
if (s == 0) { | |
r = g = b = l; // achromatic | |
} else { | |
function hue2rgb(p, q, t){ | |
if(t < 0) t += 1; | |
if(t > 1) t -= 1; | |
if(t < 1 / 6) return p + (q - p) * 6 * t; | |
if(t < 1 / 2) return q; | |
if(t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; | |
return p; | |
} | |
var q = l < 0.5 ? l * (1 + s) : l + s - l * s; | |
var p = 2 * l - q; | |
} | |
var alpha = _.isUndefined(a) || _.isNull(a) ? 1.0 : a.replace(remove_comma_regex, ''); | |
return { | |
r: hue2rgb(p, q, h + 1 / 3), | |
g: hue2rgb(p, q, h), | |
b: hue2rgb(p, q, h - 1 / 3), | |
a: alpha | |
}; | |
} | |
var stringParsers = [ | |
// CSS RGB(A) literal | |
function(css) { | |
css = trim(css); | |
var withInteger = match(rgb_rgba_integer_regex, 255); | |
if (withInteger) { | |
return withInteger; | |
} | |
return match(rgb_rgba_percentage_regex, 100); | |
function match(regex, max_value) { | |
var colorGroups = css.match(regex); | |
if (!colorGroups || (!!colorGroups[1] + !!colorGroups[5] === 1)) { | |
return; | |
} | |
var alpha = _.isUndefined(colorGroups[5]) ? 1.0 : colorGroups[5].replace(remove_comma_regex, ''); | |
return { | |
r: Math.min(1, Math.max(0, colorGroups[2] / max_value)), | |
g: Math.min(1, Math.max(0, colorGroups[3] / max_value)), | |
b: Math.min(1, Math.max(0, colorGroups[4] / max_value)), | |
a: Math.min(1, Math.max(alpha, 0)) | |
}; | |
} | |
}, | |
function(css) { | |
var lower = css.toLowerCase(); | |
if (lower in css_colors) { | |
css = css_colors[lower]; | |
} | |
if (!css.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/)) { | |
return; | |
} | |
css = css.replace(/^#/, ''); | |
var bytes = css.length / 3; | |
var max = Math.pow(16, bytes) - 1; | |
return { | |
r: parseInt(css.slice(0, bytes), 16) / max, | |
g: parseInt(css.slice(bytes * 1,bytes * 2), 16) / max, | |
b: parseInt(css.slice(bytes * 2), 16) / max, | |
a: 1.0 | |
}; | |
}, | |
// css HSL(A) literal | |
function(css) { | |
var colorGroups = trim(css).match(hsl_hsla_regex); | |
// if there is an "a" after "hsl", there must be a fourth parameter and the other way round | |
if (!colorGroups || (!!colorGroups[1] + !!colorGroups[5] === 1)) { | |
return null; | |
} | |
var h = ((colorGroups[2] % 360 + 360) % 360) / 360; | |
var s = Math.max(0, Math.min(parseInt(colorGroups[3], 10) / 100, 1)); | |
var l = Math.max(0, Math.min(parseInt(colorGroups[4], 10) / 100, 1)); | |
return hslToRgb(h, s, l, colorGroups[5]); | |
} | |
]; | |
function trim(str) { | |
return str.replace(/^\s+|\s+$/g, ''); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment