import {join} from '../../internal/string'; import {ALPHA_FULL_VALUE, DEFAULT_RGB, MAX_HEX, MAX_PERCENT} from '../constants'; import {getAlpha, getAlphaValue} from '../misc/alpha'; import {getHexValue} from '../misc/get'; import {isRgbLike} from '../misc/is'; import type {HSLAColor, HSLColor, RGBAColor, RGBColor} from '../models'; // #region Functions export function convertRgbToHex(rgb: RGBAColor | RGBColor, alpha: boolean): string { const hex = `${join( [rgb.red, rgb.green, rgb.blue].map(color => { const hexString = color.toString(16); return hexString.length === 1 ? `0${hexString}` : hexString; }), )}`; let a = ''; if (typeof alpha === 'boolean' && alpha) { a = getAlpha((rgb as RGBAColor).alpha).hex; } return `${hex}${a}`; } export function convertRgbToHsla(value: unknown): HSLAColor { const rgb = isRgbLike(value) ? getRgbValue(value) : {...DEFAULT_RGB}; const blue = rgb.blue / MAX_HEX; const green = rgb.green / MAX_HEX; const red = rgb.red / MAX_HEX; const maxHex = Math.max(blue, green, red); const minHex = Math.min(blue, green, red); const delta = maxHex - minHex; const lightness = (minHex + maxHex) / 2; let hue = 0; let saturation = 0; if (delta !== 0) { saturation = (maxHex - lightness) / Math.min(lightness, 1 - lightness); switch (maxHex) { case blue: hue = (red - green) / delta + 4; break; case green: hue = (blue - red) / delta + 2; break; case red: hue = (green - blue) / delta + (green < blue ? 6 : 0); break; } hue *= 60; } return { alpha: getAlphaValue((value as RGBAColor).alpha ?? ALPHA_FULL_VALUE), hue: +hue.toFixed(2), lightness: +(lightness * MAX_PERCENT).toFixed(2), saturation: +(saturation * MAX_PERCENT).toFixed(2), }; } export function getRgbValue(value: Record): RGBColor { return { blue: getHexValue((value as RGBColor).blue), green: getHexValue((value as RGBColor).green), red: getHexValue((value as RGBColor).red), }; } /** * Convert an _RGB(A)_ color to a hex color _(with optional alpha channel, i.e., opacity)_ * * _If the value is unable to be converted, a black hex color will be returned_ * * @param rgb _RGB(A)_ color * @param alpha Include alpha channel _(opacity)_? _(defaults to `false`)_ * @returns Hex color string */ export function rgbToHex(rgb: RGBAColor | RGBColor, alpha?: boolean): string { return convertRgbToHex(isRgbLike(rgb) ? getRgbValue(rgb) : {...DEFAULT_RGB}, alpha ?? false); } /** * Convert an _RGB(A)_ color to an _HSL_ color * * _If the value is unable to be converted, a black HSL color will be returned_ * * _Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L26_ * * @param rgb _RGB(A)_ color * @returns _HSL_ color */ export function rgbToHsl(rgb: RGBAColor | RGBColor): HSLColor { const {hue, lightness, saturation} = convertRgbToHsla(rgb); return { hue, lightness, saturation, }; } /** * Convert an _RGB(A)_ color to an _HSLA_ color * * _If the value is unable to be converted, a black _HSLA_ color with an alpha channel (opacity) of `0` will be returned_ * * _Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L26_ * * @param rgb _RGB(A)_ color * @returns _HSLA_ color */ export function rgbToHsla(rgb: RGBAColor | RGBColor): HSLAColor { return convertRgbToHsla(rgb); } // #endregion