UNPKG

@sanity/ui

Version:

The Sanity UI components.

151 lines (127 loc) 3 kB
import {clamp, round} from '../utils' import {HSL, RGB, RGBA} from './types' /** * @internal */ export function hexToRgb(hex: string): RGB { if (hex.length === 4) { const hexR = hex.slice(1, 2) const hexG = hex.slice(2, 3) const hexB = hex.slice(3, 4) return { r: parseInt(hexR + hexR, 16), g: parseInt(hexG + hexG, 16), b: parseInt(hexB + hexB, 16), } } return { r: parseInt(hex.slice(1, 3), 16), g: parseInt(hex.slice(3, 5), 16), b: parseInt(hex.slice(5, 7), 16), } } /** * @internal */ export function rgbaToRGBA(rgba: string): RGBA { const values = rgba.replace(/rgba\(|\)/g, '').split(',') return { r: parseInt(values[0]), g: parseInt(values[1]), b: parseInt(values[2]), a: parseFloat(values[3]), } } /** * @internal */ export function rgbToHex(color: RGB | RGBA): string { const r = round(clamp(Math.round(color.r), 0, 255)) const g = round(clamp(Math.round(color.g), 0, 255)) const b = round(clamp(Math.round(color.b), 0, 255)) if ('a' in color) { return `rgba(${r},${g},${b},${color.a})` } return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1) } /** * @internal * @see https://css-tricks.com/converting-color-spaces-in-javascript/ */ export function rgbToHsl({r, g, b}: RGB): HSL { // Make r, g, and b fractions of 1 r /= 255 g /= 255 b /= 255 // Find greatest and smallest channel values const cmin = Math.min(r, g, b) const cmax = Math.max(r, g, b) const delta = cmax - cmin let h = 0 let s = 0 let l = 0 // Calculate hue // No difference if (delta == 0) h = 0 // Red is max else if (cmax == r) h = ((g - b) / delta) % 6 // Green is max else if (cmax == g) h = (b - r) / delta + 2 // Blue is max else h = (r - g) / delta + 4 h = Math.round(h * 60) // Make negative hues positive behind 360° if (h < 0) h += 360 // Calculate lightness l = (cmax + cmin) / 2 // Calculate saturation s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)) // Multiply l and s by 100 s = +(s * 100).toFixed(1) l = +(l * 100).toFixed(1) return {h, s, l} } /** * @internal */ export function hslToRgb(hsl: HSL): RGB { // Must be fractions of 1 const s = hsl.s / 100 const l = hsl.l / 100 const c = (1 - Math.abs(2 * l - 1)) * s const x = c * (1 - Math.abs(((hsl.h / 60) % 2) - 1)) const m = l - c / 2 let r = 0 let g = 0 let b = 0 if (0 <= hsl.h && hsl.h < 60) { r = c g = x b = 0 } else if (60 <= hsl.h && hsl.h < 120) { r = x g = c b = 0 } else if (120 <= hsl.h && hsl.h < 180) { r = 0 g = c b = x } else if (180 <= hsl.h && hsl.h < 240) { r = 0 g = x b = c } else if (240 <= hsl.h && hsl.h < 300) { r = x g = 0 b = c } else if (300 <= hsl.h && hsl.h < 360) { r = c g = 0 b = x } return { r: Math.round((r + m) * 255), g: Math.round((g + m) * 255), b: Math.round((b + m) * 255), } }