// https://en.wikipedia.org/wiki/HSL_and_HSV import {ColorHSB, ColorRGB} from './common' export function rgbToHsb(color: ColorRGB) { const {r, g, b} = color if ([r, g, b].some(v => v < 0 || v > 255)) { throw new TypeError('r, g, b ∈ [0, 255]') } const max = Math.max(r, g, b) const min = Math.min(r, g, b) let h = 0 if (max === min) { h = 0 } else if (max === r) { h = 60 * ((g - b) / (max - min)) } else if (max === g) { h = 60 * ((b - r) / (max - min)) + 120 } // else if (max === b) { else { h = 60 * ((r - g) / (max - min)) + 240 } return { h: h < 0 ? h + 360 : h, s: max === 0 ? 0 : ((max - min) / max) * 100, b: (max / 255) * 100, } } export function hsbToRgb(color: ColorHSB) { const {h, s, b} = color if (h < 0 || h > 360) { throw new TypeError('hue: s ∈ [0°, 360°]') } if (s < 0 || s > 100) { throw new TypeError('saturation: s ∈ [0, 100]') } if (b < 0 || b > 100) { throw new TypeError('brightness: b ∈ [0, 100]') } const c = (b / 100) * (s / 100) const x = c * (1 - Math.abs((h / 60) % 2 - 1)) const m = b / 100 - c let rRGB = 0 let gRGB = 0 let bRGB = 0 if (0 <= h && h <= 60) { rRGB = c gRGB = x bRGB = 0 } else if (60 < h && h <= 120) { rRGB = x gRGB = c bRGB = 0 } else if (120 < h && h <= 180) { rRGB = 0 gRGB = c bRGB = x } else if (180 < h && h <= 240) { rRGB = 0 gRGB = x bRGB = c } else if (240 < h && h <= 300) { rRGB = x gRGB = 0 bRGB = c // } else if (300 < h && h <= 360) { } else { rRGB = c gRGB = 0 bRGB = x } return { r: Math.round((rRGB + m) * 255), g: Math.round((gRGB + m) * 255), b: Math.round((bRGB + m) * 255), } }