Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js"></script>  
</head>
<body>
<p>
  A quick experiment with different interpolation
  strategies in Lch. See JS for notes.
</p>
<div><span>Linear</span><div id="box0" class="box"></div></div>
<div><span>Corrected</span><div id="box1" class="box"></div></div>
</body>
</html>
 
.box > * {
  width: 1.1%;
  height: 100%;
  display: block;
  position: absolute;
  top: 0;
  background: currentColor;
}
.box {
  position: relative;
  height: 1em;
  border: 1px solid black;
  flex-grow: 1;
}
body > div {
  display: flex;
  margin: 1px 0;
  font-size:30px;
  line-height: 1;
}
span {
  width: 4.5em;
}
 
// Experimenting with different interpolation
// strategies in Lch
var lch0 = [50, 120, 0];
var lch1 = [50, 0, 180];
function interpolate(a, b, t, linear) {
  var l0 = a[0];
  var l1 = b[0];
  var c0 = a[1];
  var c1 = b[1];
  var h0 = a[2];
  var h1 = b[2];
  
  var ln = l0 + (l1 - l0)*t;
  var cn = c0 + (c1 - c0)*t;
  var hn;
  
  if (linear) {
    
    // Naive linear interpolation of hue
    // no good when chroma at either end is mismatched.
    hn = h0 + (h1 - h0)*t;
    
  } else {
  
    // Mike's awful maths below. We don't want "t" to linearly
    // interpolate from 0..1, we want a curve: t^p, where p!=1
    //
    // n = contribution of color c1 to the hue of the gradient:
    //     0 when chroma(c1) is 0
    //     0.5 when chroma(c0) == chroma(c1)
    //     1 when chrome(c0) is 0
    //
    // then p is exponent so when:
    //     n=0, p=∞
    //     n=0.5, p=1
    //     n=1, p=0
    //
    // This looks like a tangent to me!
    // Bang it in, see what happens.
    //
    var n = c1 + c0 === 0 ? 0 : c1 / (c1+c0);
    var p = Math.tan(Math.PI * (1 - n) / 2);
    hn = h0 + (h1 - h0) * Math.pow(t, p); 
  }
  return chroma.lch(ln, cn, hn);
}
function loader() {
  var box = document.getElementById("box0");
  var max = 99;
  for (var i=0;i<=max;i++) {
    var e = document.createElement("div");
    e.style.color = interpolate(lch0, lch1, i / max, true).hex();
    e.style.left = i + "%";
    box.appendChild(e);
  }
  
  var box = document.getElementById("box1");
  var max = 99;
  for (var i=0;i<=max;i++) {
    var e = document.createElement("div");
    e.style.color = interpolate(lch0, lch1, i / max, false).hex();
    e.style.left = i + "%";
    box.appendChild(e);
  }
}
window.addEventListener("DOMContentLoaded", loader);
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
faceless2pro
0viewers