@leafer-in/color
Version:
323 lines (297 loc) • 8.11 kB
JavaScript
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;