function parseHex(hex){
return parseInt(hex.padEnd(2, hex), 16) / 255;
}
function clamp(n, min, max){
return Math.min(Math.max(min, n), max);
}
function parseAlpha(a, asPercentage) {
return clamp(asPercentage ? (a / 100) : a, 0, 1);
}
function validateNumbers(array){
return !array.some(Number.isNaN);
}
function constrainAngle(angle) {
angle = angle % 360;
if (angle < 0) {
angle += 360;
}
return angle;
}
function hslToRgb([h, s, l, alpha]) {
h = constrainAngle(h);
s /= 100;
l /= 100;
function f(n) {
const k = (n + h / 30) % 12;
const a = s * Math.min(l, 1 - l);
return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
}
return [f(0), f(8), f(4), alpha];
}const input = "#ff00ccf1";
let result;
const hexRegexp = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/;
if (hexRegexp.test(input)) {
const step = input.length < 6 ? 1 : 2;
let i = 1;
result = [
parseHex(input.slice(i, i += step)),
parseHex(input.slice(i, i += step)),
parseHex(input.slice(i, i += step)),
parseHex(input.slice(i, i + step) || 'ff'),
];
}const input = "rgb(128, 0, 0)";
let result;
const rgbRegExp = /^rgba?\(\s*([\de.+-]+)(%)?(?:\s+|\s*(,)\s*)([\de.+-]+)(%)?(?:\s+|\s*(,)\s*)([\de.+-]+)(%)?(?:\s*([,\/])\s*([\de.+-]+)(%)?)?\s*\)$/;
const rgbMatch = input.match(rgbRegExp);
if (rgbMatch) {
const [
_, // eslint-disable-line @typescript-eslint/no-unused-vars
r, // <numeric>
rp, // % (optional)
f1, // , (optional)
g, // <numeric>
gp, // % (optional)
f2, // , (optional)
b, // <numeric>
bp, // % (optional)
f3, // ,|/ (optional)
a, // <numeric> (optional)
ap, // % (optional)
] = rgbMatch;
const argFormat = [f1 || ' ', f2 || ' ', f3].join('');
if (
argFormat === ' ' ||
argFormat === ' /' ||
argFormat === ',,' ||
argFormat === ',,,'
) {
const valFormat = [rp, gp, bp].join('');
const maxValue =
(valFormat === '%%%') ? 100 :
(valFormat === '') ? 255 : 0;
if (maxValue) {
const rgba = [
clamp(+r / maxValue, 0, 1),
clamp(+g / maxValue, 0, 1),
clamp(+b / maxValue, 0, 1),
a ? parseAlpha(+a, ap) : 1,
];
if (validateNumbers(rgba)) {
result = rgba;
}
}
}
}const input = "rgba(128, 0, 0, 1)";
let result;
const rgbRegExp = /^rgba?\(\s*([\de.+-]+)(%)?(?:\s+|\s*(,)\s*)([\de.+-]+)(%)?(?:\s+|\s*(,)\s*)([\de.+-]+)(%)?(?:\s*([,\/])\s*([\de.+-]+)(%)?)?\s*\)$/;
const rgbMatch = input.match(rgbRegExp);
if (rgbMatch) {
const [
_, // eslint-disable-line @typescript-eslint/no-unused-vars
r, // <numeric>
rp, // % (optional)
f1, // , (optional)
g, // <numeric>
gp, // % (optional)
f2, // , (optional)
b, // <numeric>
bp, // % (optional)
f3, // ,|/ (optional)
a, // <numeric> (optional)
ap, // % (optional)
] = rgbMatch;
const argFormat = [f1 || ' ', f2 || ' ', f3].join('');
if (
argFormat === ' ' ||
argFormat === ' /' ||
argFormat === ',,' ||
argFormat === ',,,'
) {
const valFormat = [rp, gp, bp].join('');
const maxValue =
(valFormat === '%%%') ? 100 :
(valFormat === '') ? 255 : 0;
if (maxValue) {
const rgba = [
clamp(+r / maxValue, 0, 1),
clamp(+g / maxValue, 0, 1),
clamp(+b / maxValue, 0, 1),
a ? parseAlpha(+a, ap) : 1,
];
if (validateNumbers(rgba)) {
result = rgba;
}
}
}
}const input = "hsl(120 50% 80%)";
let result;
const hslRegExp = /^hsla?\(\s*([\de.+-]+)(?:deg)?(?:\s+|\s*(,)\s*)([\de.+-]+)%(?:\s+|\s*(,)\s*)([\de.+-]+)%(?:\s*([,\/])\s*([\de.+-]+)(%)?)?\s*\)$/;
const hslMatch = input.match(hslRegExp);
if (hslMatch) {
const [
_, // eslint-disable-line @typescript-eslint/no-unused-vars
h, // <numeric>
f1, // , (optional)
s, // <numeric>
f2, // , (optional)
l, // <numeric>
f3, // ,|/ (optional)
a, // <numeric> (optional)
ap, // % (optional)
] = hslMatch;
const argFormat = [f1 || ' ', f2 || ' ', f3].join('');
if (
argFormat === ' ' ||
argFormat === ' /' ||
argFormat === ',,' ||
argFormat === ',,,'
) {
const hsla = [
+h,
clamp(+s, 0, 100),
clamp(+l, 0, 100),
a ? parseAlpha(+a, ap) : 1,
];
if (validateNumbers(hsla)) {
result = hslToRgb(hsla);
}
// invalid numbers
}
// comma optional syntax requires no commas at all
}const input = "[128, 0, 0, 1]";
try {
const [r, g, b, a] = JSON.parse(input);
if (!isNaN(r + g + b)) {
return [
clamp(+r / 255, 0, 1),
clamp(+g / 255, 0, 1),
clamp(+b / 255, 0, 1),
clamp(isNaN(a) ? 1 : +a, 0, 1)];
}
} catch(ex) {
// Invalid JSON
}