39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
export type RgbTuple = readonly [number, number, number];
|
|
|
|
export interface AccentVariables {
|
|
"--nodedc-accent-rgb": string;
|
|
"--nodedc-on-accent-rgb": string;
|
|
}
|
|
|
|
function clampChannel(value: number): number {
|
|
return Math.max(0, Math.min(255, Math.round(value)));
|
|
}
|
|
|
|
function linearChannel(channel: number): number {
|
|
const normalized = clampChannel(channel) / 255;
|
|
return normalized <= 0.04045
|
|
? normalized / 12.92
|
|
: ((normalized + 0.055) / 1.055) ** 2.4;
|
|
}
|
|
|
|
export function relativeLuminance(rgb: RgbTuple): number {
|
|
const [red, green, blue] = rgb.map(linearChannel) as [number, number, number];
|
|
return red * 0.2126 + green * 0.7152 + blue * 0.0722;
|
|
}
|
|
|
|
export function readableTextRgb(rgb: RgbTuple): RgbTuple {
|
|
return relativeLuminance(rgb) > 0.46 ? [11, 17, 23] : [247, 248, 244];
|
|
}
|
|
|
|
export function rgbTuple(value: RgbTuple): string {
|
|
return value.map(clampChannel).join(" ");
|
|
}
|
|
|
|
export function createAccentVariables(accent: RgbTuple): AccentVariables {
|
|
return {
|
|
"--nodedc-accent-rgb": rgbTuple(accent),
|
|
"--nodedc-on-accent-rgb": rgbTuple(readableTextRgb(accent)),
|
|
};
|
|
}
|
|
|