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);
  }
 ...