UNPKG

@spellix/magic-color-transformer

Version:

Magic color transform library

66 lines (49 loc) 2.01 kB
/* eslint-disable -- allow for magic-color */ import type { HexColor, HsbColor, HslColor, LabColor, RgbColor } from '../types'; import { rgbToHex, rgbToHsb, rgbToHsl } from './rgb'; const labRegex = /^lab\(\s*(100|[1-9]?\d(?:\.\d+)?)\s+(-?(?:1[01]\d|12[0-8]|\d?\d)(?:\.\d+)?)\s+(-?(?:1[01]\d|12[0-8]|\d?\d)(?:\.\d+)?)(?:\s*\/\s*(0|0?\.\d+|1(?:\.0)?))?\s*\)$/; export function isLab(color: string): boolean { return labRegex.test(color); } export function parseLab(color: string): { values: LabColor; alpha: number } { const match = labRegex.exec(color); if (!match) throw new Error('Invalid Lab color format.'); // @ts-expect-error - allow for magic-color const lab = [Number.parseFloat(match[1]), Number.parseFloat(match[2]), Number.parseFloat(match[3])] as LabColor; const alpha = match[4] ? Number.parseFloat(match[4]) : 1; return { values: lab, alpha }; } function xyz_rgb(r: number) { r = 255 * (r <= 0.003_04 ? 12.92 * r : 1.055 * r ** (1 / 2.4) - 0.055); return Math.min(Math.max(0, r), 255); // return 255 * (r <= 0.00304 ? 12.92 * r : 1.055 * r ** (1 / 2.4) - 0.055) } function lab_xyz(t: number) { return t > 0.206_896_552 ? t * t * t : 0.128_418_55 * (t - 0.137_931_034); } export function labToRgb(color: LabColor): RgbColor { const [l, a, b] = color; let x; let y; let z; y = (l + 16) / 116; x = y + a / 500; z = y - b / 200; y = Number(lab_xyz(y)); x = 0.950_47 * lab_xyz(x); z = 1.088_83 * lab_xyz(z); const r = xyz_rgb(3.240_454_2 * x - 1.537_138_5 * y - 0.498_531_4 * z); // D65 -> sRGB const g = xyz_rgb(-0.969_266 * x + 1.876_010_8 * y + 0.041_556 * z); const b_ = xyz_rgb(0.055_643_4 * x - 0.204_025_9 * y + 1.057_225_2 * z); return [r, g, b_]; } export function labToHex(color: LabColor): HexColor { return rgbToHex(labToRgb(color)); } export function labToHsl(color: LabColor): HslColor { return rgbToHsl(labToRgb(color)); } export function labToHsb(color: LabColor): HsbColor { return rgbToHsb(labToRgb(color)); }