Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display HWB/HSB/CMYK channels using RGB or HSL

I am trying to display each color channel for different color models, similar to this site.

That site displays HSB and CMYK but I would also like to show HWB.

For displaying RGB and HSL I obviously just used rgb() and hsl(). For example, to display the full range of s(aturation) in hsl I would do something like this:

hsl(hue, 0, luminosity);
hsl(hue, 50, luminosity);
hsl(hue, 100, luminosity);

Apply that to a linear gradient and then display on canvas. It seems addColorStop only supports keywords, hex, rgb/a and hsl/a. So how can I visually represent the other color models using the ones available?

I've looked everywhere and can't find anything, hopefully this isn't a duplicate question.

like image 460
EvilZebra Avatar asked Sep 05 '25 03:09

EvilZebra


1 Answers

Update 2023: Now HWB has full support. See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hwb#browser_compatibility

HWB is not supported in the browser or canvas at the moment. It's included in CSS module level 4, but not supported anywhere yet.

It's easy to convert to and from the color model though.

I converted these JavaScript functions to convert between RGB and HWB from this code (with some adjustments to normalize H and "de-normalize" RGB). They both return an object:

// RGB [0, 255]
// HWB [0, 1]
function rgb2hwb(r, g, b) {
  
  r /= 255;
  g /= 255;
  b /= 255;
  
  var f, i,
      w = Math.min(r, g, b);
      v = Math.max(r, g, b);
      black = 1 - v;
  
  if (v === w) return {h: 0, w: w, b: black};
  f = r === w ? g - b : (g === w ? b - r : r - g);
  i = r === w ? 3 : (g === w ? 5 : 1);

  return {h: (i - f / (v - w)) / 6, w: w, b: black}
}

// HWB [0, 1]
// RGB [0, 255]
function hwb2rgb(h, w, b) {
  
  h *= 6;
  
  var v = 1 - b, n, f, i;
  if (!h) return {r:v, g:v, b:v};
  i = h|0;
  f = h - i;
  if (i & 1) f = 1 - f;
  n = w + f * (v - w);
  v = (v * 255)|0;
  n = (n * 255)|0;
  w = (w * 255)|0;

  switch(i) {
    case 6:
    case 0: return {r:v, g:n, b: w};
    case 1: return {r:n, g:v, b: w};
    case 2: return {r:w, g:v, b: n};
    case 3: return {r:w, g:n, b: v};
    case 4: return {r:n, g:w, b: v};
    case 5: return {r:v, g:w, b: n};
  }
}

// ------ TEST -------
var hwb = rgb2hwb(250,100,10);
var rgb = hwb2rgb(hwb.h, hwb.w, hwb.b);
document.getElementById("hwb").innerHTML = hwb.h.toFixed(2) + "," + hwb.w.toFixed(2) + "," + hwb.w.toFixed(2);
document.getElementById("rgb").innerHTML = rgb.r + "," + rgb.g + "," + rgb.b;
Original RGB: <span>250,100,10</span><br>
rgb2hwb: <span id="hwb"></span><br>
hwb2rgb: <span id="rgb"></span><br>

To use it as a input for a color-stop etc., do something like this:

gr.addColorStop(n, fromHWB(360, 50, 50));
...

function fromHWB(H, W, B) {
    var c = hwb2rgb(H/360, W/100, B/100);
    return "rgb(" + c.r + "," + c.g + "," + c.b + ")"
}

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!