@tbela99/css-parser
Version:
CSS parser, minifier and validator for node and the browser
219 lines (216 loc) • 7.39 kB
JavaScript
import { getColorComponents } from './utils/components.js';
import { multiplyMatrices } from './utils/matrix.js';
import { srgb2lsrgbvalues, lch2srgbvalues, lab2srgbvalues, cmyk2srgbvalues, hwb2srgbvalues, hsl2srgb, rgb2srgb, hex2srgbvalues, lsrgb2srgbvalues } from './srgb.js';
import { color2srgbvalues, toPrecisionValue, getNumber } from './color.js';
import { EnumToken, ColorType } from '../../ast/types.js';
import { getOKLCHComponents } from './oklch.js';
import { lchvalues2labvalues } from './lab.js';
function hex2oklabToken(token) {
const values = hex2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function rgb2oklabToken(token) {
const values = rgb2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function hsl2oklabToken(token) {
const values = hsl2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function hwb2oklabToken(token) {
const values = hwb2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function cmyk2oklabToken(token) {
const values = cmyk2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function lab2oklabToken(token) {
const values = lab2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function lch2oklabToken(token) {
const values = lch2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function oklch2oklabToken(token) {
const values = oklch2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function color2oklabToken(token) {
const values = color2oklabvalues(token);
if (values == null) {
return null;
}
return oklabToken(values);
}
function oklabToken(values) {
const chi = [
{ typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
{ typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
{ typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[2]) },
];
if (values.length == 4) {
chi.push({ typ: EnumToken.LiteralTokenType, val: "/" }, {
typ: EnumToken.PercentageTokenType,
val: toPrecisionValue(values[3], 2) * 100,
});
}
return {
typ: EnumToken.ColorTokenType,
val: "oklab",
chi,
kin: ColorType.OKLAB,
};
}
function hex2oklabvalues(token) {
const values = hex2srgbvalues(token);
if (values == null) {
return null;
}
// @ts-ignore
return srgb2oklab(...values);
}
function rgb2oklabvalues(token) {
const values = rgb2srgb(token);
if (values == null) {
return null;
}
// @ts-ignore
return srgb2oklab(...values);
}
function hsl2oklabvalues(token) {
const values = hsl2srgb(token);
if (values == null) {
return null;
}
// @ts-ignore
return srgb2oklab(...values);
}
function hwb2oklabvalues(token) {
// @ts-ignore
return srgb2oklab(...hwb2srgbvalues(token));
}
function cmyk2oklabvalues(token) {
const values = cmyk2srgbvalues(token);
// @ts-ignore
return values == null ? null : srgb2oklab(...values);
}
function lab2oklabvalues(token) {
const values = lab2srgbvalues(token);
if (values == null) {
return null;
}
// @ts-ignore
return srgb2oklab(...values);
}
function lch2oklabvalues(token) {
const values = lch2srgbvalues(token);
// @ts-ignore
return values == null ? null : srgb2oklab(...values);
}
function oklch2oklabvalues(token) {
const values = getOKLCHComponents(token);
// @ts-ignore
return values == null ? null : lchvalues2labvalues(...values);
}
function color2oklabvalues(token) {
const values = color2srgbvalues(token);
// @ts-ignore
return values == null ? null : srgb2oklab(...values);
}
function srgb2oklab(r, g, blue, alpha) {
[r, g, blue] = srgb2lsrgbvalues(r, g, blue);
let L = Math.cbrt(0.41222147079999993 * r + 0.5363325363 * g + 0.0514459929 * blue);
let M = Math.cbrt(0.2119034981999999 * r + 0.6806995450999999 * g + 0.1073969566 * blue);
let S = Math.cbrt(0.08830246189999998 * r + 0.2817188376 * g + 0.6299787005000002 * blue);
const l = 0.2104542553 * L + 0.793617785 * M - 0.0040720468 * S;
const a = r == g && g == blue ? 0 : 1.9779984951 * L - 2.428592205 * M + 0.4505937099 * S;
const b = r == g && g == blue ? 0 : 0.0259040371 * L + 0.7827717662 * M - 0.808675766 * S;
return alpha == null || alpha == 1 ? [l, a, b] : [l, a, b, alpha];
}
function getOKLABComponents(token) {
const components = getColorComponents(token);
if (components == null || components.length < 3) {
return null;
}
// @ts-ignore
let t = components[0];
// @ts-ignore
const l = getNumber(t);
// @ts-ignore
t = components[1];
// @ts-ignore
const a = getNumber(t) * (t.typ == EnumToken.PercentageTokenType ? 0.4 : 1);
// @ts-ignore
t = components[2];
// @ts-ignore
const b = getNumber(t) * (t.typ == EnumToken.PercentageTokenType ? 0.4 : 1);
// @ts-ignore
let alpha = null;
if (components.length > 3) {
alpha = getNumber(components[3]);
}
const rgb = [l, a, b];
if (alpha != 1 && alpha != null) {
rgb.push(alpha);
}
return rgb;
}
function OKLab_to_XYZ(l, a, b, alpha = null) {
// Given OKLab, convert to XYZ relative to D65
const LMStoXYZ = [
[1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
[-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
[-0.0763729366746601, -0.4214933324022432, 1.5869240198367816],
];
const OKLabtoLMS = [
[1.0, 0.3963377773761749, 0.2158037573099136],
[1.0, -0.1055613458156586, -0.0638541728258133],
[1.0, -0.0894841775298119, -1.2914855480194092],
];
const LMSnl = multiplyMatrices(OKLabtoLMS, [l, a, b]);
const xyz = multiplyMatrices(LMStoXYZ, LMSnl.map((c) => c ** 3));
if (alpha != null) {
xyz.push(alpha);
}
return xyz;
}
// from https://www.w3.org/TR/css-color-4/#color-conversion-code
function OKLab_to_sRGB(l, a, b) {
let L = Math.pow(l * 0.99999999845051981432 + 0.39633779217376785678 * a + 0.21580375806075880339 * b, 3);
let M = Math.pow(l * 1.0000000088817607767 - 0.1055613423236563494 * a - 0.063854174771705903402 * b, 3);
let S = Math.pow(l * 1.0000000546724109177 - 0.089484182094965759684 * a - 1.2914855378640917399 * b, 3);
return lsrgb2srgbvalues(
/* r: */
4.076741661347994 * L - 3.307711590408193 * M + 0.230969928729428 * S,
/* g: */
-1.2684380040921763 * L + 2.6097574006633715 * M - 0.3413193963102197 * S,
/* b: */
-0.004196086541837188 * L - 0.7034186144594493 * M + 1.7076147009309444 * S);
}
export { OKLab_to_XYZ, OKLab_to_sRGB, cmyk2oklabToken, cmyk2oklabvalues, color2oklabToken, getOKLABComponents, hex2oklabToken, hex2oklabvalues, hsl2oklabToken, hsl2oklabvalues, hwb2oklabToken, hwb2oklabvalues, lab2oklabToken, lab2oklabvalues, lch2oklabToken, lch2oklabvalues, oklch2oklabToken, oklch2oklabvalues, rgb2oklabToken, rgb2oklabvalues, srgb2oklab };