45 lines
846 B
TypeScript
45 lines
846 B
TypeScript
// Copyright 2024 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
// https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
|
|
export function rgbToHSL(
|
|
r: number,
|
|
g: number,
|
|
b: number
|
|
): {
|
|
h: number;
|
|
s: number;
|
|
l: number;
|
|
} {
|
|
// Normalize to [0, 1]
|
|
const rn = r / 255;
|
|
const gn = g / 255;
|
|
const bn = b / 255;
|
|
|
|
const xMax = Math.max(rn, gn, bn);
|
|
const xMin = Math.min(rn, gn, bn);
|
|
const v = xMax;
|
|
const c = xMax - xMin;
|
|
const l = v - c / 2;
|
|
let h: number;
|
|
|
|
if (c === 0) {
|
|
h = 0;
|
|
} else if (v === rn) {
|
|
h = 60 * (((gn - bn) / c) % 6);
|
|
} else if (v === gn) {
|
|
h = 60 * ((bn - rn) / c + 2);
|
|
} else {
|
|
// v === b
|
|
h = 60 * ((rn - gn) / c + 4);
|
|
}
|
|
|
|
let s: number;
|
|
if (l === 0 || l === 1) {
|
|
s = 0;
|
|
} else {
|
|
s = (v - l) / Math.min(l, 1 - l);
|
|
}
|
|
|
|
return { h, s, l };
|
|
}
|