Color Space Exploration
What constitutes a "vivid" color?
by austegard
HTML
<h1 id="header">
Color Space Exploration
</h1>
<p>
What constitutes a vivid color? <br>
Suggest Saturation must be > 15% and Perceived Brightness between 0.18 and 0.95
</p>
<table>
<td valign="top">
<input type="color" id="col" style="width:237px"><br>
Click above and select a color
</td>
<td>
RGB: <span id='rgb'></span><br>
Hue: <span id='hue'></span><br>
Hue Band: <span id='hb'></span><br>
Saturation: <span id='s'></span><br>
Perceived Brightness: <span id='pb'></span><br>
Relative Lumninance: <span id="y"></span><br>
Lightness: <span id="l"></span><br>
s * l = <span id="p"></span><br>
Vividness: <span id="v"></span>
</td>
</table>
CSS
body {font-family: Arial; }
td {padding: 5px;}
JavaScript
const $ = id => document.getElementById(id);
$("col").addEventListener("input", updateValues);
function updateValues(e) {
let c = e.target.value;
$("header").style.color = c;
let rgb = convertHexToRGB(c);
let r = rgb[0] / 255,
g = rgb[1] / 255,
b = rgb[2] / 255;
let hue = getHue(r, g, b);
let hueBand = ((hue + 30) % 360) / 30 | 0; //shifts purplish red to beginning of band
let s = getSaturation(r, g, b);
let pb = getPerceivedBrightness(r, g, b);
let y = getRelativeLuminance(r, g, b);
let l = getLightness(r, g, b);
let v = getVividness(r, g, b)
$("rgb").innerText = rgb;
$("hue").innerText = hue
$("hb").innerText = hueBand;
$("s").innerText = roundToDecimal(s * 100, 1) + '%';
$("pb").innerText = pb;
$("y").innerText = y;
$("l").innerText = l;
$("v").innerText = v;
$("p").innerText = roundToDecimal(s * l, 3);
}
function roundToDecimal(num, dec) {
return Math.round((num + Number.EPSILON) * 10 ** dec) / 10 ** dec
}
function convertHexToRGB(hex) {
if (hex[0] == "#") hex = hex.substring(1)
var aRgbHex = hex.match(/.{1,2}/g);
var aRgb = [
parseInt(aRgbHex[0], 16),
parseInt(aRgbHex[1], 16),
parseInt(aRgbHex[2], 16)
];
return aRgb;
}
function getHue(r, g, b) {
let maxc = Math.max(r, g, b);
let minc = Math.min(r, g, b);
let h = 0.0;
if (minc != maxc) {
let rangec = (maxc - minc);
let rc = (maxc - r) / rangec;
let gc = (maxc - g) / rangec;
let bc = (maxc - b) / rangec;
if (r == maxc) {
h = bc - gc;
} else if (g == maxc) {
h = 2.0 + rc - bc;
} else {
h = 4.0 + gc - rc;
}
h = 60 * (h < 0 ? h + 6 : h)
}
return Math.round(h);
}
function getSaturation(r, g, b) {
let maxc = Math.max(r, g, b);
let minc = Math.min(r, g, b);
let s = 0.0;
if (minc != maxc) {
let sumc = (maxc + minc);
let rangec = (maxc - minc);
let l = sumc / 2.0;
if (l <= 0.5)
s = rangec / sumc;
else
s = rangec / (2.0 - sumc);
}
...