neft
Version:
Universal Platform
272 lines (250 loc) • 7.96 kB
text/coffeescript
'use strict'
assert = require 'src/assert'
###
Parse 3-digit hex, 6-digit hex, rgb, rgba, hsl, hsla, or named color into RGBA hex.
###
exports.toRGBAHex = do ->
NAMED_COLORS =
'': 0x00000000
transparent: 0x00000000
black: 0x000000ff
silver: 0xc0c0c0ff
gray: 0x808080ff
white: 0xffffffff
maroon: 0x800000ff
red: 0xff0000ff
purple: 0x800080ff
fuchsia: 0xff00ffff
green: 0x008000ff
lime: 0x00ff00ff
olive: 0x808000ff
yellow: 0xffff00ff
navy: 0x000080ff
blue: 0x0000ffff
teal: 0x008080ff
aqua: 0x00ffffff
orange: 0xffa500ff
aliceblue: 0xf0f8ffff
antiquewhite: 0xfaebd7ff
aquamarine: 0x7fffd4ff
azure: 0xf0ffffff
beige: 0xf5f5dcff
bisque: 0xffe4c4ff
blanchedalmond: 0xffe4c4ff
blueviolet: 0x8a2be2ff
brown: 0xa52a2aff
burlywood: 0xdeb887ff
cadetblue: 0x5f9ea0ff
chartreuse: 0x7fff00ff
chocolate: 0xd2691eff
coral: 0xff7f50ff
cornflowerblue: 0x6495edff
cornsilk: 0xfff8dcff
crimson: 0xdc143cff
darkblue: 0x00008bff
darkcyan: 0x008b8bff
darkgoldenrod: 0xb8860bff
darkgray: 0xa9a9a9ff
darkgreen: 0x006400ff
darkgrey: 0xa9a9a9ff
darkkhaki: 0xbdb76bff
darkmagenta: 0x8b008bff
darkolivegreen: 0x556b2fff
darkorange: 0xff8c00ff
darkorchid: 0x9932ccff
darkred: 0x8b0000ff
darksalmon: 0xe9967aff
darkseagreen: 0x8fbc8fff
darkslateblue: 0x483d8bff
darkslategray: 0x2f4f4fff
darkslategrey: 0x2f4f4fff
darkturquoise: 0x00ced1ff
darkviolet: 0x9400d3ff
deeppink: 0xff1493ff
deepskyblue: 0x00bfffff
dimgray: 0x696969ff
dimgrey: 0x696969ff
dodgerblue: 0x1e90ffff
firebrick: 0xb22222ff
floralwhite: 0xfffaf0ff
forestgreen: 0x228b22ff
gainsboro: 0xdcdcdcff
ghostwhite: 0xf8f8ffff
gold: 0xffd700ff
goldenrod: 0xdaa520ff
greenyellow: 0xadff2fff
grey: 0x808080ff
honeydew: 0xf0fff0ff
hotpink: 0xff69b4ff
indianred: 0xcd5c5cff
indigo: 0x4b0082ff
ivory: 0xfffff0ff
khaki: 0xf0e68cff
lavender: 0xe6e6faff
lavenderblush: 0xfff0f5ff
lawngreen: 0x7cfc00ff
lemonchiffon: 0xfffacdff
lightblue: 0xadd8e6ff
lightcoral: 0xf08080ff
lightcyan: 0xe0ffffff
lightgoldenrodyellow: 0xfafad2ff
lightgray: 0xd3d3d3ff
lightgreen: 0x90ee90ff
lightgrey: 0xd3d3d3ff
lightpink: 0xffb6c1ff
lightsalmon: 0xffa07aff
lightseagreen: 0x20b2aaff
lightskyblue: 0x87cefaff
lightslategray: 0x778899ff
lightslategrey: 0x778899ff
lightsteelblue: 0xb0c4deff
lightyellow: 0xffffe0ff
limegreen: 0x32cd32ff
linen: 0xfaf0e6ff
mediumaquamarine: 0x66cdaaff
mediumblue: 0x0000cdff
mediumorchid: 0xba55d3ff
mediumpurple: 0x9370dbff
mediumseagreen: 0x3cb371ff
mediumslateblue: 0x7b68eeff
mediumspringgreen: 0x00fa9aff
mediumturquoise: 0x48d1ccff
mediumvioletred: 0xc71585ff
midnightblue: 0x191970ff
mintcream: 0xf5fffaff
mistyrose: 0xffe4e1ff
moccasin: 0xffe4b5ff
navajowhite: 0xffdeadff
oldlace: 0xfdf5e6ff
olivedrab: 0x6b8e23ff
orangered: 0xff4500ff
orchid: 0xda70d6ff
palegoldenrod: 0xeee8aaff
palegreen: 0x98fb98ff
paleturquoise: 0xafeeeeff
palevioletred: 0xdb7093ff
papayawhip: 0xffefd5ff
peachpuff: 0xffdab9ff
peru: 0xcd853fff
pink: 0xffc0cbff
plum: 0xdda0ddff
powderblue: 0xb0e0e6ff
rosybrown: 0xbc8f8fff
royalblue: 0x4169e1ff
saddlebrown: 0x8b4513ff
salmon: 0xfa8072ff
sandybrown: 0xf4a460ff
seagreen: 0x2e8b57ff
seashell: 0xfff5eeff
sienna: 0xa0522dff
skyblue: 0x87ceebff
slateblue: 0x6a5acdff
slategray: 0x708090ff
slategrey: 0x708090ff
snow: 0xfffafaff
springgreen: 0x00ff7fff
steelblue: 0x4682b4ff
tan: 0xd2b48cff
thistle: 0xd8bfd8ff
tomato: 0xff6347ff
turquoise: 0x40e0d0ff
violet: 0xee82eeff
wheat: 0xf5deb3ff
whitesmoke: 0xf5f5f5ff
yellowgreen: 0x9acd32ff
rebeccapurple: 0x663399ff
DIGIT_3_RE = /^#[0-9a-fA-F]{3}$/
DIGIT_6_RE = /^#[0-9a-fA-F]{6}$/
RGB_RE = /^rgb\s*\(\s*([0-9.]+)\s*,\s*([0-9.]+)\s*,\s*([0-9.]+)\s*\)$/
RGBA_RE = /^rgba\s*\(\s*([0-9.]+)\s*,\s*([0-9.]+)\s*,\s*([0-9.]+)\s*,\s*([0-9.]+)\s*\)$/
HSL_RE = /^hsl\s*\(\s*([0-9.]+)\s*,\s*([0-9.]+)\s*%\s*,\s*([0-9.]+)\s*%\s*\)$/
HSLA_RE = /^hsla\s*\(\s*([0-9.]+)\s*,\s*([0-9.]+)\s*%\s*,\s*([0-9.]+)\s*%\s*,\s*([0-9.]+)\s*\)$/
numberToHex = (val) ->
val = parseFloat val
if val < 0
val = 0
else if val > 255
val = 255
hex = Math.round val
hex
alphaToHex = (val) ->
numberToHex Math.round(parseFloat(val) * 255)
# http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
hslToRgb = do ->
hueToRgb = (p, q, t) ->
if t < 0
t += 1
if t > 1
t -= 1
if t * 6 < 1
return p + (q - p) * t * 6
if t * 2 < 1
return q
if t * 3 < 2
return p + (q - p) * (2 / 3 - t) * 6
return p
(hStr, sStr, lStr) ->
p = q = h = s = l = 0.0
h = (parseFloat(hStr) % 360) / 360
s = parseFloat(sStr) / 100
l = parseFloat(lStr) / 100
if s is 0
red = green = blue = l
else
if l <= 0.5
q = l * (s + 1)
else
q = l + s - l * s
p = l * 2 - q
red = hueToRgb p, q, h + 1 / 3
green = hueToRgb p, q, h
blue = hueToRgb p, q, h - 1 / 3
return Math.round(red * 255) << 16 |
Math.round(green * 255) << 8 |
Math.round(blue * 255)
(color, defaultColor = 'transparent') ->
assert.isString color
r = g = b = a = 0
if (result = NAMED_COLORS[color]) isnt undefined
return result
# 3-digit hexadecimal
if DIGIT_3_RE.test(color)
r = parseInt color[1], 16
g = parseInt color[2], 16
b = parseInt color[3], 16
r = r<<4 | r
g = g<<4 | g
b = b<<4 | b
a = 0xFF
# 6-digit hexadecimal
else if DIGIT_6_RE.test(color)
r = parseInt color.substr(1, 2), 16
g = parseInt color.substr(3, 2), 16
b = parseInt color.substr(5, 2), 16
a = 0xFF
# rgb
else if match = RGB_RE.exec(color)
r = numberToHex match[1]
g = numberToHex match[2]
b = numberToHex match[3]
a = 0xFF
# rgba
else if match = RGBA_RE.exec(color)
r = numberToHex match[1]
g = numberToHex match[2]
b = numberToHex match[3]
a = alphaToHex match[4]
# hsl
else if match = HSL_RE.exec(color)
b = hslToRgb match[1], match[2], match[3]
a = 0xFF
# hsla
else if match = HSLA_RE.exec(color)
b = hslToRgb match[1], match[2], match[3]
a = alphaToHex match[4]
else
return exports.toRGBAHex(defaultColor)
return (r << 24 |
g << 16 |
b << 8 |
a) >>> 0