UNPKG

nhb-toolbox

Version:

A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.

197 lines (196 loc) 6.63 kB
import { isHex6, isHex8, isHSL, isHSLA, isRGB, isRGBA } from './guards.js'; import { _isValidAlpha } from './helpers.js'; import { extractAlphaColorValues, extractSolidColorValues, percentToHex } from './utils.js'; export const convertHslToRgb = (h, s, l) => { s /= 100; l /= 100; const c = (1 - Math.abs(2 * l - 1)) * s; const x = c * (1 - Math.abs(((h / 60) % 2) - 1)); const m = l - c / 2; let r = 0, g = 0, b = 0; if (h >= 0 && h < 60) [r, g] = [c, x]; else if (h >= 60 && h < 120) [r, g] = [x, c]; else if (h >= 120 && h < 180) [g, b] = [c, x]; else if (h >= 180 && h < 240) [g, b] = [x, c]; else if (h >= 240 && h < 300) [r, b] = [x, c]; else if (h >= 300 && h < 360) [r, b] = [c, x]; r = Math.round((r + m) * 255); g = Math.round((g + m) * 255); b = Math.round((b + m) * 255); return `rgb(${r}, ${g}, ${b})`; }; export const convertRgbToHsl = (r, g, b) => { r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let h = 0, s = 0; const l = (max + min) / 2; if (max !== min) { const diff = max - min; s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min); switch (max) { case r: h = (g - b) / diff + (g < b ? 6 : 0); break; case g: h = (b - r) / diff + 2; break; case b: h = (r - g) / diff + 4; break; } h *= 60; } return `hsl(${Math.round(h)}, ${Number((s * 100).toFixed(2))}%, ${Number((l * 100).toFixed(2))}%)`; }; export const convertHslToHex = (h, s, l) => { const rgb = convertHslToRgb(h, s, l).match(/\d+/g)?.map(Number) ?? [0, 0, 0]; return convertRgbToHex(rgb[0], rgb[1], rgb[2]); }; export const convertHexToHsl = (hex) => { let newHex = hex?.trim()?.replace('#', ''); if (newHex?.length === 3) { newHex = newHex ?.split('') ?.map((char) => char + char) ?.join(''); } const r = parseInt(newHex.slice(0, 2), 16); const g = parseInt(newHex.slice(2, 4), 16); const b = parseInt(newHex.slice(4, 6), 16); return convertRgbToHsl(r, g, b); }; export const convertRgbToHex = (r, g, b) => { const hex = [r, g, b] ?.map((v) => v.toString(16).padStart(2, '0')) ?.join('') ?.toUpperCase(); return `#${hex}`; }; export const convertHexToRgb = (hex) => { let newHex = hex?.trim()?.replace('#', ''); if (newHex?.length === 3) { newHex = newHex ?.split('') ?.map((char) => char + char) ?.join(''); } const r = parseInt(newHex.slice(0, 2), 16); const g = parseInt(newHex.slice(2, 4), 16); const b = parseInt(newHex.slice(4, 6), 16); return `rgb(${r}, ${g}, ${b})`; }; export const convertRgbToRgba = (r, g, b, a = 1) => { let newAlpha = a; if (!_isValidAlpha(a)) { newAlpha = 1; console.warn(`Alpha value must be between 0-1, ${a} converted to 1!`); } return `rgba(${r}, ${g}, ${b}, ${parseFloat(newAlpha.toFixed(1))})`; }; export const convertRgbaToHex8 = (r, g, b, a = 1) => { let newAlpha = a; if (!_isValidAlpha(a)) { newAlpha = 1; console.warn(`Alpha value must be between 0-1, ${a} converted to 1!`); } const alphaHex = percentToHex(Math.round(newAlpha * 100)); const hex = convertRgbToHex(r, g, b); return `${hex}${alphaHex}`; }; export const convertHslaToRgba = (h, s, l, a = 1) => { let newAlpha = a; if (!_isValidAlpha(a)) { newAlpha = 1; console.warn(`Alpha value must be between 0-1, ${a} converted to 1!`); } const rgb = convertHslToRgb(h, s, l); const [r, g, b] = extractSolidColorValues(rgb); return convertRgbToRgba(r, g, b, parseFloat(newAlpha.toFixed(1))); }; export const convertRgbaToHsla = (r, g, b, a = 1) => { let newAlpha = a; if (!_isValidAlpha(a)) { newAlpha = 1; console.warn(`Alpha value must be between 0-1, ${a} converted to 1!`); } const hsl = convertRgbToHsl(r, g, b); const [h, s, l] = extractSolidColorValues(hsl); return `hsla(${h}, ${s}%, ${l}%, ${parseFloat(newAlpha.toFixed(1))})`; }; export const convertHex8ToRgba = (hex8) => { const hex = hex8?.trim()?.replace('#', ''); const r = parseInt(hex.slice(0, 2), 16); const g = parseInt(hex.slice(2, 4), 16); const b = parseInt(hex.slice(4, 6), 16); const a = parseInt(hex.slice(6, 8), 16) / 255; return `rgba(${r}, ${g}, ${b}, ${parseFloat(a.toFixed(1))})`; }; export const convertHslaToHex8 = (h, s, l, a = 1) => { let newAlpha = a; if (!_isValidAlpha(a)) { newAlpha = 1; console.warn(`Alpha value must be between 0-1, ${a} converted to 1!`); } const alphaHex = percentToHex(Math.round(newAlpha * 100)); const hex = convertHslToHex(h, s, l); return `${hex}${alphaHex}`; }; export const convertHex8ToHsla = (hex8) => { const rgba = convertHex8ToRgba(hex8); return convertRgbaToHsla(...extractAlphaColorValues(rgba)); }; export function convertColorCode(color) { const trimmedColor = color?.trim(); if (isHex6(trimmedColor)) { return { rgb: convertHexToRgb(trimmedColor), hsl: convertHexToHsl(trimmedColor), }; } if (isRGB(trimmedColor)) { const rgbValues = extractSolidColorValues(trimmedColor); return { hex: convertRgbToHex(...rgbValues), hsl: convertRgbToHsl(...rgbValues), }; } if (isHSL(trimmedColor)) { const hslValues = extractSolidColorValues(trimmedColor); return { hex: convertHslToHex(...hslValues), rgb: convertHslToRgb(...hslValues), }; } if (isHex8(trimmedColor)) { return { rgba: convertHex8ToRgba(trimmedColor), hsla: convertHex8ToHsla(trimmedColor), }; } if (isRGBA(trimmedColor)) { const rgbaValues = extractAlphaColorValues(trimmedColor); return { hex8: convertRgbaToHex8(...rgbaValues), hsla: convertRgbaToHsla(...rgbaValues), }; } if (isHSLA(trimmedColor)) { const hslaValues = extractAlphaColorValues(trimmedColor); return { hex8: convertHslaToHex8(...hslaValues), rgba: convertHslaToRgba(...hslaValues), }; } throw new TypeError(`${color} is not a valid color!`, { cause: 'Unrecognized Color Format', }); }