UNPKG

@leafer-in/color

Version:
323 lines (297 loc) 8.11 kB
import { isUndefined, isString, isObject, Plugin, ColorConvert } from "@leafer-ui/draw"; const colorNames = { transparent: "FFF0", aliceblue: "F0F8FF", antiquewhite: "FAEBD7", aqua: "0FF", aquamarine: "7FFFD4", azure: "F0FFFF", beige: "F5F5DC", bisque: "FFE4C4", black: "0", blanchedalmond: "FFEBCD", blue: "00F", blueviolet: "8A2BE2", brown: "A52A2A", burlywood: "DEB887", cadetblue: "5F9EA0", chartreuse: "7FFF00", chocolate: "D2691E", coral: "FF7F50", cornflowerblue: "6495ED", cornsilk: "FFF8DC", crimson: "DC143C", cyan: "0FF", darkblue: "00008B", darkcyan: "008B8B", darkgoldenrod: "B8860B", darkgray: "A9", darkgreen: "006400", darkgrey: "A9", 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: "69", dimgrey: "69", dodgerblue: "1E90FF", firebrick: "B22222", floralwhite: "FFFAF0", forestgreen: "228B22", fuchsia: "F0F", gainsboro: "DC", ghostwhite: "F8F8FF", gold: "FFD700", goldenrod: "DAA520", gray: "80", green: "008000", greenyellow: "ADFF2F", grey: "80", 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: "D3", lightgreen: "90EE90", lightgrey: "D3", lightpink: "FFB6C1", lightsalmon: "FFA07A", lightseagreen: "20B2AA", lightskyblue: "87CEFA", lightslategray: "789", lightslategrey: "789", 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: "D87093", papayawhip: "FFEFD5", peachpuff: "FFDAB9", peru: "CD853F", pink: "FFC0CB", plum: "DDA0DD", powderblue: "B0E0E6", purple: "800080", rebeccapurple: "639", red: "F00", rosybrown: "BC8F8F", royalblue: "4169E1", saddlebrown: "8B4513", salmon: "FA8072", sandybrown: "F4A460", seagreen: "2E8B57", seashell: "FFF5EE", sienna: "A0522D", silver: "C0", skyblue: "87CEEB", slateblue: "6A5ACD", slategray: "708090", slategrey: "708090", snow: "FFFAFA", springgreen: "00FF7F", steelblue: "4682B4", tan: "D2B48C", teal: "008080", thistle: "D8BFD8", tomato: "FF6347", turquoise: "40E0D0", violet: "EE82EE", wheat: "F5DEB3", white: "F", whitesmoke: "F5", yellow: "FF0", yellowgreen: "9ACD32" }; const rgbMatch = /^rgb\((\d+),\s*(\d+),\s*(\d+)/i; const rgbaMatch = /^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d*\.?\d+)/i; const hslMatch = /^hsl\((\d+),\s*(\d+)%\s*,\s*(\d+)%/i; const hslaMatch = /^hsla\((\d+),\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d*\.?\d+)/i; const int = parseInt, float = parseFloat, {round: round} = Math; let cache = {}, totalCache = 0; function colorToRGBA(color, opacity) { let RGBA; let useOpacity = !isUndefined(opacity) && opacity < 1; if (isString(color)) { const cacheColor = cache[color]; if (cacheColor) { RGBA = Object.assign({}, cacheColor); } else { switch (color[0]) { case "#": RGBA = hexToRGBA(color); break; case "R": case "r": if (color[4] === "(" && rgbaMatch.test(color)) RGBA = rgbaToRGBA(color); else if (color[3] === "(" && rgbMatch.test(color)) RGBA = rgbToRGBA(color); break; case "H": case "h": if (color[4] === "(" && hslaMatch.test(color)) RGBA = hslaToRGBA(color); else if (color[3] === "(" && hslMatch.test(color)) RGBA = hslToRGBA(color); break; } if (!RGBA) { const value = colorNames[color.toLowerCase()]; if (value) RGBA = hexToRGBA("#" + value); } if (RGBA) { totalCache++; if (totalCache > 1e4) cache = {}, totalCache = 0; cache[color] = Object.assign({}, RGBA); } } } else if (isObject(color)) { if (isUndefined(color.a)) color.a = 1; if (useOpacity) color = Object.assign({}, color); RGBA = color; } if (!RGBA) RGBA = { r: 255, g: 255, b: 255, a: 1 }; if (useOpacity) RGBA.a *= opacity; return RGBA; } function hexToRGBA(color) { let r, g, b, a = 1; switch (color.length) { case 9: r = int(color.slice(1, 3), 16); g = int(color.slice(3, 5), 16); b = int(color.slice(5, 7), 16); a = int(color.slice(7, 9), 16) / 255; break; case 7: r = int(color.slice(1, 3), 16); g = int(color.slice(3, 5), 16); b = int(color.slice(5, 7), 16); break; case 5: r = int(color[1] + color[1], 16); g = int(color[2] + color[2], 16); b = int(color[3] + color[3], 16); a = int(color[4] + color[4], 16) / 255; break; case 4: r = int(color[1] + color[1], 16); g = int(color[2] + color[2], 16); b = int(color[3] + color[3], 16); break; case 3: r = g = b = int(color[1] + color[2], 16); break; case 2: r = g = b = int(color[1] + color[1], 16); break; } return { r: r, g: g, b: b, a: a }; } function rgbToRGBA(color) { const match = rgbMatch.exec(color); return { r: int(match[1]), g: int(match[2]), b: int(match[3]), a: 1 }; } function rgbaToRGBA(color) { const match = rgbaMatch.exec(color); return { r: int(match[1]), g: int(match[2]), b: int(match[3]), a: float(match[4]) }; } function hslToRGBA(color) { const match = hslMatch.exec(color); return hsla(float(match[1]), float(match[2]), float(match[3]), 1); } function hslaToRGBA(color) { const match = hslaMatch.exec(color); return hsla(float(match[1]), float(match[2]), float(match[3]), float(match[4])); } const n1 = 1 / 6, n2 = .5, n3 = 2 / 3, n4 = 1 / 3; function hue(p, q, t) { if (t < 0) t++; else if (t > 1) t--; if (t < n1) return p + (q - p) * 6 * t; if (t < n2) return q; if (t < n3) return p + (q - p) * (n3 - t) * 6; return p; } function hsla(h, s, l, a = 1) { let r, g, b; h /= 360, s /= 100, l /= 100; if (s === 0) { r = g = b = l; } else { let q = l < .5 ? l * (1 + s) : l + s - l * s; let p = 2 * l - q; r = hue(p, q, h + n4); g = hue(p, q, h); b = hue(p, q, h - n4); } return { r: round(r * 255), g: round(g * 255), b: round(b * 255), a: a }; } Plugin.add("color"); ColorConvert.object = colorToRGBA;