a tool for shared writing and social publishing
1// X = <negative/positive number with/without decimal places> 2// before/after a comma, 0 or more whitespaces are allowed 3// - hsb(X, X%, X%) 4// - hsba(X, X%, X%, X) 5const HSB_REGEX = 6 /hsb\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%)\)|hsba\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d(.\d+)?)\)/; 7 8export function parseHSBToRGB(color: string) { 9 let m: RegExpMatchArray | null; 10 if ((m = color.match(HSB_REGEX))) { 11 const [h, s, b, a] = (m[1] ?? m[2]) 12 .split(",") 13 .map((n) => Number(n.trim().replace("%", ""))); 14 let hue = normalizeHue(h); 15 let saturation = s / 100; 16 let brightness = b / 100; 17 let fn = (n: number, k = (n + hue / 60) % 6) => 18 brightness - saturation * brightness * Math.max(Math.min(k, 4 - k, 1), 0); 19 let [red, green, blue] = [ 20 Math.round(fn(5) * 255), 21 Math.round(fn(3) * 255), 22 Math.round(fn(1) * 255), 23 a, 24 ]; 25 return `rgb(${red}, ${green}, ${blue})`; 26 } 27} 28 29export function normalizeHue(hue: number) { 30 if (hue === 360) { 31 return hue; 32 } 33 34 return ((hue % 360) + 360) % 360; 35}