generated from tpl/obsidian-sample-plugin
Switch color class to use chroma color as underlying data storage
This commit is contained in:
parent
86ffa3753f
commit
b5b9a3fd31
|
@ -2,6 +2,8 @@ import chroma from "chroma-js";
|
||||||
|
|
||||||
const style = getComputedStyle(document.body);
|
const style = getComputedStyle(document.body);
|
||||||
|
|
||||||
|
export const WCAG_TEXT_CONTRAST_RATIO = 4.5;
|
||||||
|
export const WCAG_NON_TEXT_CONTRAST_RATIO = 3.5;
|
||||||
export const COLOR_NAMES = [
|
export const COLOR_NAMES = [
|
||||||
"red",
|
"red",
|
||||||
"orange",
|
"orange",
|
||||||
|
@ -12,86 +14,59 @@ export const COLOR_NAMES = [
|
||||||
"purple",
|
"purple",
|
||||||
"pink",
|
"pink",
|
||||||
] as const;
|
] as const;
|
||||||
|
export type ColorName = (typeof COLOR_NAMES)[number];
|
||||||
|
|
||||||
export function isColorName(color: string): color is ColorName {
|
export function isColorName(color: string): color is ColorName {
|
||||||
return COLOR_NAMES.includes(color as ColorName);
|
return COLOR_NAMES.includes(color as ColorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ColorName = (typeof COLOR_NAMES)[number];
|
|
||||||
export type RGB = [number, number, number];
|
|
||||||
|
|
||||||
export class Color {
|
export class Color {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly r: number,
|
private readonly _chroma: chroma.Color,
|
||||||
private readonly g: number,
|
private readonly _alpha: number = 1
|
||||||
private readonly b: number,
|
|
||||||
private readonly a: number = 1
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
get hex(): string {
|
get hex(): string {
|
||||||
const rHex = this.r.toString(16).padStart(2, "0");
|
return this.chroma.hex();
|
||||||
const gHex = this.g.toString(16).padStart(2, "0");
|
|
||||||
const bHex = this.b.toString(16).padStart(2, "0");
|
|
||||||
|
|
||||||
return `#${rHex}${gHex}${bHex}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get rgb(): string {
|
get rgb(): string {
|
||||||
return `rgb(${this.r}, ${this.g}, ${this.b})`;
|
return this.chroma.css();
|
||||||
}
|
}
|
||||||
|
|
||||||
get rgba(): string {
|
get rgba(): string {
|
||||||
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`;
|
return this.chroma.alpha(this._alpha).css();
|
||||||
|
}
|
||||||
|
|
||||||
|
get chroma(): chroma.Color {
|
||||||
|
return this._chroma;
|
||||||
}
|
}
|
||||||
|
|
||||||
get contrastColor(): Color {
|
get contrastColor(): Color {
|
||||||
return this.r * 0.299 +
|
return chroma.contrast(this.chroma, "white") < WCAG_TEXT_CONTRAST_RATIO
|
||||||
this.g * 0.587 +
|
? new Color(chroma("black"))
|
||||||
this.b * 0.114 +
|
: new Color(chroma("white"));
|
||||||
(1 - this.a) * 255 >
|
|
||||||
186
|
|
||||||
? new Color(0, 0, 0)
|
|
||||||
: new Color(255, 255, 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha(alpha: number): Color {
|
alpha(alpha: number): Color {
|
||||||
return new Color(this.r, this.g, this.b, alpha);
|
alpha = Math.max(0, Math.min(1, alpha));
|
||||||
|
return new Color(this.chroma, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
darken(amount?: number): Color {
|
darken(amount?: number): Color {
|
||||||
return new Color(
|
return new Color(this.chroma.darken(amount));
|
||||||
...chroma([this.r, this.g, this.b]).darken(amount).rgb()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lighten(amount?: number): Color {
|
lighten(amount?: number): Color {
|
||||||
return new Color(
|
return new Color(this.chroma.brighten(amount));
|
||||||
...chroma([this.r, this.g, this.b]).brighten(amount).rgb()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromName(color: ColorName): Color {
|
static fromName(color: ColorName): Color {
|
||||||
const rawRgb = style
|
return new Color(chroma(style.getPropertyValue(`--color-${color}`)));
|
||||||
.getPropertyValue(`--color-${color}-rgb`)
|
|
||||||
.split(", ");
|
|
||||||
|
|
||||||
return new Color(
|
|
||||||
parseInt(rawRgb[0], 10),
|
|
||||||
parseInt(rawRgb[1], 10),
|
|
||||||
parseInt(rawRgb[2], 10)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCSSColor(color: string): Color {
|
static fromCSSColor(color: string): Color {
|
||||||
const ctx = document.createElement("canvas").getContext("2d")!;
|
return new Color(chroma(color));
|
||||||
ctx.fillStyle = color;
|
|
||||||
const hexColor = ctx.fillStyle;
|
|
||||||
|
|
||||||
return new Color(
|
|
||||||
parseInt(hexColor.slice(1, 3), 16),
|
|
||||||
parseInt(hexColor.slice(3, 5), 16),
|
|
||||||
parseInt(hexColor.slice(5, 7), 16)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static getAll(): Color[] {
|
static getAll(): Color[] {
|
||||||
|
@ -106,7 +81,7 @@ export class Color {
|
||||||
return chroma
|
return chroma
|
||||||
.scale(colors)
|
.scale(colors)
|
||||||
.mode("lch")
|
.mode("lch")
|
||||||
.colors(n, "rgb")
|
.colors(n, null)
|
||||||
.map(([r, g, b]) => new Color(r, g, b));
|
.map((color) => new Color(color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue