@aotearoan/neon
Version:
Neon is a lightweight design library of Vue 3 components with minimal dependencies.
254 lines (253 loc) • 8.91 kB
JavaScript
var y = Object.defineProperty;
var z = (i, e, a) => e in i ? y(i, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : i[e] = a;
var T = (i, e, a) => (z(i, typeof e != "symbol" ? e + "" : e, a), a);
const t = class t {
/**
* Calculate luminance from RGB color Array.
*
* @param r Red value 0-255.
* @param g Green value 0-255.
* @param b Blue value 0-255.
*
* @returns The luminance.
*/
static luminance([e, a, r]) {
const n = [e, a, r].map((c) => (c /= 255, c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, t.gamma)));
return n[0] * t.red + n[1] * t.green + n[2] * t.blue;
}
/**
* Hex color string to RGB Array.
*
* @param hexString Hex color string to transform.
*
* @returns RGB color array.
*/
static toRgb(e) {
return [
Number.parseInt(e.substring(1, 3), 16),
Number.parseInt(e.substring(3, 5), 16),
Number.parseInt(e.substring(5, 7), 16)
];
}
/**
* Convert RGB color array to xyz color space.
*
* @param r Red value 0-255.
* @param g Green value 0-255.
* @param b Blue value 0-255.
*
* @returns xyz color value.
*/
static rgbToXyz(e) {
const [a, r, n] = e, c = t.rgbValueToXyz(a), b = t.rgbValueToXyz(r), o = t.rgbValueToXyz(n), u = t.xyzToLab((0.4124564 * c + 0.3575761 * b + 0.1804375 * o) / t.labXn), h = t.xyzToLab((0.2126729 * c + 0.7151522 * b + 0.072175 * o) / t.labYn), s = t.xyzToLab((0.0193339 * c + 0.119192 * b + 0.9503041 * o) / t.labZn);
return [u, h, s];
}
/**
* Convert RGB color array to Lab color space.
*
* @param r Red value 0-255.
* @param g Green value 0-255.
* @param b Blue value 0-255.
*
* @returns Lab color value.
*/
static rgbToLab(e) {
const [a, r, n] = t.rgbToXyz(e), c = 116 * r - 16;
return [Math.max(c, 0), 500 * (a - r), 200 * (r - n)];
}
/**
* Convert RGB color array to Hcl color space.
*
* @param r Red value 0-255.
* @param g Green value 0-255.
* @param b Blue value 0-255.
*
* @returns Hcl color value.
*/
static rgbToHcl(e) {
const a = t.rgbToLab(e);
return t.labToHcl(a);
}
/**
* Check two hex colors for their contrast accessibility.
*
* @param hex1 Hex color 1.
* @param hex2 Hex color 2.
*
* @returns {NeonContrastAccessibility} Accessibility data.
*/
static isAccessible(e, a) {
const r = t.contrast(t.toRgb(e), t.toRgb(a)), n = {
largeAA: !1,
largeAAA: !1,
normalAA: !1,
normalAAA: !1,
ratio: Math.round(100 * r) / 100
};
return r >= 3 && (n.largeAA = !0, r >= 4.5 && (n.normalAA = !0, n.largeAAA = !0, r >= 7 && (n.normalAAA = !0))), n;
}
/**
* Calculate the contrast ratio between two colors.
*
* @param rgb1 First color.
* @param rgb2 Second color.
*
* @returns The contrast ratio (x:1).
*/
static contrast(e, a) {
const r = t.luminance(e), n = t.luminance(a), c = Math.max(r, n), b = Math.min(r, n);
return (c + 0.05) / (b + 0.05);
}
/**
* Convert RGB color array to hex color string.
*
* @param r Red value 0-255.
* @param g Green value 0-255.
* @param b Blue value 0-255.
*
* @returns hex color string.
*/
static rgbToHex(e) {
const [a, r, n] = e, c = a.toString(16), b = r.toString(16), o = n.toString(16);
return `#${c.length === 1 ? `0${c}` : c}${b.length === 1 ? `0${b}` : b}${o.length === 1 ? `0${o}` : o}`;
}
/**
* Generate a Neon color palette with 5 light & 5 dark steps (l1-l5 & d1-d5) from a reference color. For both L1 & D1
* steps this will search for the closest match to the reference color that meets at least AA contrast requirements.
* The L2-L5 & D2-D5 steps are then generated based on a Hcl curve.
*
* @param referenceColor Hex string of the reference color from which to generate the palette.
* @param darkTextHex The dark text color hex string for calculating the contrast ratio for L1-L5 steps.
* @param lightTextHex The light text color hex string for calculating the contrast ratio for D1-D5 steps.
*
* @returns A map of the palette's color steps to hex values.
*/
static generatePalette(e, a, r) {
const n = t.toRgb(e), [c, b, o] = n, u = t.toRgb(a), h = t.toRgb(r), [s, R] = t.rgbToHcl(n), [x, m, M] = t.lightReferenceColor(n, u), [A, f, d] = t.darkReferenceColor(n, h), l = t.generateChromaCurve(m), g = t.generateLuminanceCurve(M, d);
return o > 2 * b && o > 2 * c ? {
l5: t.rgbToHex(t.hclToRgb(s - 30, l[0], g[0])),
l4: t.rgbToHex(t.hclToRgb(s - 25, l[1], g[1])),
l3: t.rgbToHex(t.hclToRgb(s - 20, l[2], g[2])),
l2: t.rgbToHex(t.hclToRgb(s - 15, l[3], g[3])),
l1: t.rgbToHex(t.hclToRgb(s - 10, l[4], g[4])),
d1: t.rgbToHex(t.hclToRgb(s - 10, l[5], g[5])),
d2: t.rgbToHex(t.hclToRgb(s - 10, l[6], g[6])),
d3: t.rgbToHex(t.hclToRgb(s - 10, l[7], g[7])),
d4: t.rgbToHex(t.hclToRgb(s - 10, l[8], g[8])),
d5: t.rgbToHex(t.hclToRgb(s - 10, l[9], g[9]))
} : {
l5: t.rgbToHex(t.hclToRgb(s, l[0], g[0])),
l4: t.rgbToHex(t.hclToRgb(s, l[1], g[1])),
l3: t.rgbToHex(t.hclToRgb(s, l[2], g[2])),
l2: t.rgbToHex(t.hclToRgb(s, l[3], g[3])),
l1: t.rgbToHex(t.hclToRgb(s, l[4], g[4])),
d1: t.rgbToHex(t.hclToRgb(s, l[5], g[5])),
d2: t.rgbToHex(t.hclToRgb(s, l[6], g[6])),
d3: t.rgbToHex(t.hclToRgb(s, l[7], g[7])),
d4: t.rgbToHex(t.hclToRgb(s, l[8], g[8])),
d5: t.rgbToHex(t.hclToRgb(s, l[9], g[9]))
};
}
static generateChromaCurve(e) {
const a = 0.25 * Math.abs(e - 10), r = 0.25 * Math.abs(e - 10);
return [
e - 4 * a,
e - 3 * a + 4,
e - 2 * a + 6,
e - a + 4,
e,
e,
e - r + 4,
e - 2 * r + 6,
e - 3 * r + 4,
e - 4 * r
];
}
static generateLuminanceCurve(e, a) {
const r = 0.25 * (96 - e), n = 0.25 * (a - 10);
return [
e + 4 * r,
e + 3 * r,
e + 2 * r,
e + r,
e,
a,
a - n + 2,
a - 2 * n + 1,
a - 3 * n - 1,
a - 4 * n
];
}
static xyzToLab(e) {
return e > t.labT3 ? Math.pow(e, 1 / 3) : e / t.labT2 + t.labT0;
}
static rgbValueToXyz(e) {
const a = e / 255;
return a <= 0.04045 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4);
}
static labToHcl(e) {
const [a, r, n] = e, c = Math.sqrt(r * r + n * n), b = (Math.atan2(n, r) * t.radiansToDegrees + 360) % 360;
return [Math.round(b), c, a];
}
static luminanceByChannel(e) {
return e <= 0.03928 ? e / 12.92 : Math.pow((e + 0.055) / 1.055, 2.4);
}
static relativeLuminance(e) {
const [a, r, n] = e, c = t.luminanceByChannel(a / 255), b = t.luminanceByChannel(r / 255), o = t.luminanceByChannel(n / 255);
return 0.2126 * c + 0.7152 * b + 0.0722 * o;
}
static contrastRatio(e, a) {
const r = t.relativeLuminance(e), n = t.relativeLuminance(a), c = Math.max(r, n), b = Math.min(r, n), o = (c + 0.05) / (b + 0.05);
return Math.floor(o * 100) / 100;
}
static labToXyz(e) {
return e > t.labT1 ? e * e * e : t.labT2 * (e - t.labT0);
}
static xyzToRgb(e) {
return e <= 304e-5 ? 255 * 12.92 * e : 255 * (1.055 * Math.pow(e, 1 / 2.4) - 0.055);
}
static labToRgb(e, a, r) {
const n = (e + 16) / 116, c = n + a / 500, b = n - r / 200, o = t.labXn * t.labToXyz(c), u = t.labYn * t.labToXyz(n), h = t.labZn * t.labToXyz(b), s = Math.round(
Math.min(255, Math.max(0, t.xyzToRgb(3.2404542 * o - 1.5371385 * u - 0.4985314 * h)))
), R = Math.round(
Math.min(255, Math.max(0, t.xyzToRgb(-0.969266 * o + 1.8760108 * u + 0.041556 * h)))
), x = Math.round(
Math.min(255, Math.max(0, t.xyzToRgb(0.0556434 * o - 0.2040259 * u + 1.0572252 * h)))
);
return [s, R, x];
}
static hclToLab(e, a, r) {
const n = e * t.degreesToRadians;
return [r, Math.cos(n) * a, Math.sin(n) * a];
}
static hclToRgb(e, a, r) {
const [n, c, b] = t.hclToLab(e, a, r);
return t.labToRgb(n, c, b);
}
static lightReferenceColor(e, a) {
let r = e;
const [n, c, b] = t.rgbToHcl(r);
let o = b;
for (; t.contrastRatio(r, a) < 4.5; )
o = o + 1, r = t.hclToRgb(n, c, o);
return [n, c, o];
}
static darkReferenceColor(e, a) {
let r = e;
const [n, c, b] = t.rgbToHcl(r);
let o = b;
for (; t.contrastRatio(r, a) < 4.5; )
o = o - 1, r = t.hclToRgb(n, c, o);
return [n, c, o];
}
};
T(t, "red", 0.2126), T(t, "green", 0.7152), T(t, "blue", 0.0722), T(t, "labXn", 0.95047), T(t, "labYn", 1), T(t, "labZn", 1.08883), T(t, "labT0", 0.137931034), // 4 / 29
T(t, "labT1", 0.206896552), // 6 / 29
T(t, "labT2", 0.12841855), // 3 * t1 * t1
T(t, "labT3", 8856452e-9), // t1 * t1 * t1
T(t, "degreesToRadians", Math.PI / 180), T(t, "radiansToDegrees", 180 / Math.PI), T(t, "gamma", 2.4);
let H = t;
export {
H as NeonColorUtils
};
//# sourceMappingURL=NeonColorUtils.es.js.map