Calculate color Hue Saturation Lightness from XY coordinates

I'm working on a color picker and I came to the point I can't get a color lightness formula right, let me show you what I mean:

function getHSL(e){
  const 
  // correct formula is -> Math.floor( (offsetY for hueEl) / ( hueEl height ) * 360 ),
  // we use a given value from context
  // no problem here
  hue = 320,
  // no problem here
  saturation = Math.floor( ( e.offsetX / width  ) * 100 ),
  // I need a correct formula for lightness
  lightness = Math.floor( ( 1 - e.offsetY / height ) * 50 );

  // apply changes to test 
  demo.innerHTML += `hue: ${hue}, saturation: ${saturation}, lightness: ${lightness}<br>`;
  demo.style.backgroundColor = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
  demo.style.color = lightness > 20 ? 'black' : 'white';
}

var color = 'rgb(200,50,150)';
var width = 150;
var height = 150;
var pickerEl = document.querySelector('.picker');
var hueEl = document.querySelector('.hue');
var ctx1 = pickerEl.getContext('2d');
var ctx2 = hueEl.getContext('2d');
var demo = document.querySelector('.demo');

// fill canvas
ctx1.rect(0, 0, width, height);
ctx2.rect(0, 0, 15, height);

ctx1.fillStyle = color;
ctx1.fillRect(0, 0, width, height);

const grdWhite = ctx2.createLinearGradient(0, 0, width, 0);
grdWhite.addColorStop(0, 'rgba(255,255,255,1)');
grdWhite.addColorStop(1, 'rgba(255,255,255,0)');
ctx1.fillStyle = grdWhite;
ctx1.fillRect(0, 0, width, height);

const grdBlack = ctx2.createLinearGradient(0, 0, 0, height);
grdBlack.addColorStop(0, 'rgba(0,0,0,0)');
grdBlack.addColorStop(1, 'rgba(0,0,0,1)');
ctx1.fillStyle = grdBlack;
ctx1.fillRect(0, 0, width, height);

const grd1 = ctx2.createLinearGradient(0, 0, 0, height);
grd1.addColorStop(0, 'rgba(255, 0, 0, 1)');
grd1.addColorStop(0.17, 'rgba(255, 255, 0, 1)');
grd1.addColorStop(0.34, 'rgba(0, 255, 0, 1)');
grd1.addColorStop(0.51, 'rgba(0, 255, 255, 1)');
grd1.addColorStop(0.68, 'rgba(0, 0, 255, 1)');
grd1.addColorStop(0.85, 'rgba(255, 0, 255, 1)');
grd1.addColorStop(1, 'rgba(255, 0, 0, 1)');
ctx2.fillStyle = grd1;
ctx2.fill();
// fill canvas

// run here
document.addEventListener('click', getHSL)
div {float: left; } .demo { padding:1.5rem; margin-left: 1.5rem}
<div>
 <canvas class="picker" height="150" width="150" tabindex="1"></canvas>
 <canvas class="hue" height="150" width="15" tabindex="1"></canvas>
</div>
<div class="demo"></div>

Explain:

  • you click on bottom-left, bottom-right or top-right corners, you get "appropriate" or acceptable lightness value
  • you click on top-left you get probably half the lightness

I figured I need to also take into account the offsetX or a relation between offsetX and offsetY but I'm out of combinations left to try, I have no idea where to look for a correct formula.

Appreciate any reply, and thanks in advance.



Read more here: https://stackoverflow.com/questions/66305511/calculate-color-hue-saturation-lightness-from-xy-coordinates

Content Attribution

This content was originally published by thednp at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: