colorizr
Version:
Manipulate colors like a boss
318 lines (281 loc) • 7.52 kB
text/typescript
import brightnessDifference from '~/brightness-difference';
import chroma from '~/chroma';
import colorDifference from '~/color-difference';
import compare from '~/compare';
import contrast from '~/contrast';
import darken from '~/darken';
import deltaE from '~/delta-e';
import desaturate from '~/desaturate';
import formatCSS from '~/format-css';
import grayscale from '~/grayscale';
import invert from '~/invert';
import lighten from '~/lighten';
import luminance from '~/luminance';
import mix, { MixOptions } from '~/mix';
import { MESSAGES } from '~/modules/constants';
import { invariant } from '~/modules/invariant';
import { resolveColor } from '~/modules/parsed-color';
import opacify from '~/opacify';
import opacity from '~/opacity';
import readableColor from '~/readable-color';
import rotate from '~/rotate';
import saturate from '~/saturate';
import toGamut from '~/to-gamut';
import transparentize from '~/transparentize';
import { Analysis, ColorModel, ColorType, HEX, HSL, LAB, LCH, RGB } from '~/types';
export interface ColorizrOptions {
/**
* Output color format.
*
* If not specified, the output will use the same format as the input color.
*/
format?: ColorType;
}
export default class Colorizr {
/** The alpha/opacity value (0-1). */
public alpha: number;
public hex: HEX;
public hsl: HSL;
public oklab: LAB;
public oklch: LCH;
public rgb: RGB;
public type: ColorType;
constructor(color: string | ColorModel, options: ColorizrOptions = {}) {
invariant(!!color, MESSAGES.colorRequired);
const parsed = resolveColor(color);
this.hex = parsed.hex;
this.hsl = parsed.hsl;
this.oklab = parsed.oklab;
this.oklch = parsed.oklch;
this.rgb = parsed.rgb;
this.alpha = parsed.alpha;
this.type = options.format ?? parsed.type;
}
/**
* Get CSS string
*/
get css(): string {
return this.currentColor;
}
/**
* Get the red value
*/
get red(): number {
return this.rgb.r;
}
/**
* Get the green value
*/
get green(): number {
return this.rgb.g;
}
/**
* Get the blue value
*/
get blue(): number {
return this.rgb.b;
}
/**
* Get the hue value
*/
get hue(): number {
return this.hsl.h;
}
/**
* Get the saturation value
*/
get saturation(): number {
return this.hsl.s;
}
/**
* Get the lightness value
*/
get lightness(): number {
return this.hsl.l;
}
/**
* Get the luminance value
*/
get luminance(): number {
return luminance(this.currentColor);
}
/**
* Get the chroma value
*/
get chroma(): number {
return chroma(this.currentColor);
}
/**
* Get the opacity value.
*/
get opacity(): number {
return opacity(this.currentColor);
}
/**
* Get the most readable color (light or dark) for this color as a background.
*/
get readableColor(): string {
return readableColor(this.currentColor);
}
private get currentColor(): string {
return formatCSS(this[this.type], { format: this.type, alpha: this.alpha });
}
/**
* Get the brightness difference between this color and another.
*
* @param input - The color to compare against.
* @returns The brightness difference value.
*/
public brightnessDifference(input: string): number {
return brightnessDifference(this.currentColor, input);
}
/**
* Get the color difference between this color and another.
*
* @param input - The color to compare against.
* @returns The color difference value.
*/
public colorDifference(input: string): number {
return colorDifference(this.currentColor, input);
}
/**
* Test 2 colors for WCAG compliance.
*
* @param input - The color to compare against.
* @returns Analysis object with compliance information.
*/
public compare(input: string): Analysis {
return compare(this.currentColor, input);
}
/**
* Get the contrast ratio between this color and another.
*
* @param input - The color to compare against.
* @returns The contrast ratio.
*/
public contrast(input: string): number {
return contrast(this.currentColor, input);
}
/**
* Get the perceptual color difference (Delta E OK) between this color and another.
*
* @param input - The color to compare against.
* @returns The Delta E OK value.
*/
public deltaE(input: string): number {
return deltaE(this.currentColor, input);
}
/**
* Format the color to a specific type.
*
* @param type - The color format to convert to.
* @param precision - The decimal precision for the output.
* @returns The formatted color string.
*/
public format(type: ColorType, precision?: number): string {
return formatCSS(this.rgb, {
alpha: this.alpha,
format: type,
precision,
});
}
/**
* Increase lightness.
*
* @param amount - A number between 0 and 100.
* @returns The lightened color string.
*/
public lighten(amount: number): string {
return lighten(this.currentColor, amount);
}
/**
* Decrease lightness.
*
* @param amount - A number between 0 and 100.
* @returns The darkened color string.
*/
public darken(amount: number): string {
return darken(this.currentColor, amount);
}
/**
* Increase saturation.
*
* @param amount - A number between 0 and 100.
* @returns The saturated color string.
*/
public saturate(amount: number): string {
return saturate(this.currentColor, amount);
}
/**
* Decrease saturation.
*
* @param amount - A number between 0 and 100.
* @returns The desaturated color string.
*/
public desaturate(amount: number): string {
return desaturate(this.currentColor, amount);
}
/**
* Convert to grayscale.
*
* @returns The grayscale color string.
*/
public grayscale(): string {
return grayscale(this.currentColor);
}
/**
* Invert color.
*
* @returns The inverted color string.
*/
public invert(): string {
return invert(this.currentColor);
}
/**
* Mix with another color.
*
* @param color - The color to mix with.
* @param ratio - A number between 0 and 1 (0 = this color, 1 = input color).
* @param options - Mix options: format, hue mode, interpolation space.
* @returns The mixed color string.
*/
public mix(color: string, ratio?: number, options?: MixOptions): string {
return mix(this.currentColor, color, ratio, options);
}
/**
* Add opacity to the color.
*
* @param alpha - A number between 0 and 1.
* @returns The opacified color string.
*/
public opacify(alpha: number = 0.9): string {
return opacify(this.currentColor, alpha, this.type);
}
/**
* Rotate color hue.
*
* @param degrees - A number between -360 and 360.
* @returns The rotated color string.
*/
public rotate(degrees: number): string {
return rotate(this.currentColor, degrees);
}
/**
* Map this color into the sRGB gamut by reducing chroma.
*
* @param format - Optional output color format.
* @returns The gamut-mapped color string.
*/
public toGamut(format?: ColorType): string {
return toGamut(this.currentColor, format);
}
/**
* Make the color more transparent.
*
* @param alpha - A number between -1 and 1.
* @returns The transparentized color string.
*/
public transparentize(alpha: number = 0.1): string {
return transparentize(this.currentColor, alpha, this.type);
}
}