Skip to content

Instantly share code, notes, and snippets.

@Dinir
Last active May 24, 2020 13:13
Show Gist options
  • Save Dinir/f15e9b075b917d440ff4f0f4ce08e322 to your computer and use it in GitHub Desktop.
Save Dinir/f15e9b075b917d440ff4f0f4ce08e322 to your computer and use it in GitHub Desktop.
Colour Party
function hexToRGBA (hex) {
if (typeof hex !== 'string') { return [0, 0, 0, 255] }
const string = hex.replace('#','').replace(/[^0-9a-f]/g, '0')
let formattedString = ''
switch (string.length) {
case 3:
for (let i = 0; i < 3; i++) { formattedString += string[i].repeat(2) }
formattedString += 'ff'
break
case 6:
formattedString = string + 'ff'
break
case 8:
formattedString = string
break
default:
formattedString = '000000ff'
break
}
const values = [0, 0, 0, 255]
for (let i = 0; i < 4; i++) {
values[i] =
parseInt(formattedString.slice( i * 2, ( i + 1 ) * 2 ), 16) || values[i]
}
return values
}
/**
* Convert HSV (0-360, 0-100, 0-100) to RGB (0-255 each)
* @param {number[]} hsv array containing hue, saturation, and value
* @returns {number[]} array containing value of each color
*
* @link https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB
* @link https://www.desmos.com/calculator/jhx7p5idov
*/
function HSVToRGB (hsv) {
// convert value range of saturation and value
// from [0-100] to [0-1]
const H = hsv[0]
const S = hsv[1] / 100
const V = hsv[2] / 100
// chroma
const C = V * S
// intermediate values for the second largest component of the color
const Hquantized = H / 60
const X = C * ( 1 - Math.abs( Hquantized % 2 - 1 ) )
let R = 0, G = 0, B = 0
// set base rgb value
if (Hquantized >= 0 && Hquantized <= 2) {
if (Hquantized <= 1) { R = C; G = X } else { R = X; G = C }
} else if (Hquantized > 2 && Hquantized <= 4) {
if (Hquantized <= 3) { G = C; B = X } else { G = X; B = C }
} else if (Hquantized > 4 && Hquantized <= 6) {
if (Hquantized <= 5) { B = C; R = X } else { B = X; R = C }
}
// value matching variable
const m = V - C;
// convert range from [0-1] to [0-255]
return [R,G,B].map(v => Math.round( 255 * (v + m) ))
}
/**
* Convert RGB (0-255 each) to HSV (0-360, 0-100, 0-100)
* @param {number[]} rgb array containing value of each color
* @returns {number[]} array containing hue, saturation, and value
*
* @link https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
* @link http://kourbatov.com/faq/rgb2hsv.htm
*/
function RGBToHSV (rgb) {
// convert value range from [0-255] to [0-1]
const [R,G,B] = rgb.map(v => v / 255)
// maximum component (value)
const Xmax = Math.max(R,G,B), V = Xmax
// minimum component
const Xmin = Math.min(R,G,B)
// range (chroma)
const C = Xmax - Xmin
// non-chromatic
if (C === 0) { return [0, 0, V] }
// mid-range (lightness)
const L = V - C / 2
// common hue
let H = 60
switch (V) {
case R: H *= (G-B)/C; break
case G: H *= 2 + (B-R)/C; break
case B: H *= 4 + (R-G)/C; break
}
if (H < 0) { H += 360 }
if (H > 360) { H %= 360 }
// saturation
const S = C / V
// convert range from [0-360, 0-1, 0-1] to [0-360, 0-100, 0-100] rounded
return [H, 100 * S, 100 * V].map(Math.round)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment