<p><em><a href="https://codepen.io/TabAtkins/pen/xepaqm">Original demo</a> and basically all JS by <a href="https://codepen.io/TabAtkins/">Tab Atkins</a></em></p>

<p>
<code>linear-gradient(90deg, blue, 66.6%, white)</code> vs. simulated <code>linear-gradient(90deg, blue, ease-in, white)</code>
</p>
<article>
<div id="d01"></div>
<canvas id="c01" width=200 height=200></canvas>
</article>

<p>
<code>linear-gradient(90deg, blue, 23%, #AFAFFF 50%, 68%, white 93%)</code> vs. simulated <code>linear-gradient(90deg, blue, ease-out, white)</code>
</p>
<article>
<div id="d02"></div>
<canvas id="c02" width=200 height=200></canvas>
</article>

<p>
<code>linear-gradient(90deg, blue, 5.5%, #AFAFFF 22%, #E4E4FF 48%, 66%, white 88%)</code> vs. simulated <code>linear-gradient(90deg, blue, ease, white)</code> 
</p>
<article>
<div id="d03"></div>
<canvas id="c03" width=200 height=200></canvas>
</article>

<hr>

<p>
<code>linear-gradient(90deg, blue, 33.3%, white)</code> vs. <code>linear-gradient(90deg, blue, ease-out, white)</code>
</p>
<article>
<div id="d04"></div>
<canvas id="c04" width=200 height=200></canvas>
</article>
article, div, canvas {
  display: block;
  width: 1000px;
  height: 50px;
  margin: 0;
}
article {
  height: auto;
  padding: 10px 1px 1px;
  margin-bottom: 1em;
  background: 
    linear-gradient(90deg, #0008 1px, 1px, transparent) top left / 10% 100% repeat-x,
    linear-gradient(90deg, #0003 1px, 1px, transparent) top left / 1% 100% repeat-x,
    #EEE;
}
p {
  margin-bottom: 0.25em;
}
code {
  color: maroon;
  background: #FED;
}

/* ------------------------------ 
  easing comparisons start here
------------------------------ */

#d01 {
  background: linear-gradient(90deg, blue, 66.6%, white);
}

#d02 {
  background: linear-gradient(90deg, blue, 23%, #AFAFFF 50%, 68%, white 93%);
}

#d03 {
  background: linear-gradient(90deg, blue, 5.5%, #AFAFFF 22%, #E4E4FF 48%, 66%, white 88%);
}

#d04 {
  background: linear-gradient(90deg, blue, 33.3%, white);
}
const ease_in = [[.42, 0], [1, 1]]; // ease-in
const ease_out = [[0, 0], [.58, 1]]; // ease-out
const ease = [[0, .25], [.1, 1]]; // ease

class BezierMap {
  constructor(p1, p2) {
    this.points = [];
    for(var i = 0; i <= 1000; i++ ) {
      this.points.push(bezierPoint(i/1000, p1, p2));
    }
  }
  get(x) {
    if(x < 0 || x > 1) throw "In .get(x), x must be in [0,1]";
    let prevPoint = null;
    let nextPoint = this.points[0];
    for(const p of this.points.slice(1)) {
      [prevPoint, nextPoint] = [nextPoint, p];
      if(p[0] > x) break;
    }
    const prog = (x-prevPoint[0]) / (nextPoint[0]/prevPoint[0]);
    return linearNumber(prog, prevPoint[1], nextPoint[1]);
  }
}
function bezierPoint(prog, p1, p2) {
  const m1 = linearArray(prog, [0,0], p1);
  const m2 = linearArray(prog, p1, p2);
  const m3 = linearArray(prog, p2, [1,1]);
  const n1 = linearArray(prog, m1, m2);
  const n2 = linearArray(prog, m2, m3);
  return linearArray(prog, n1, n2);
}
function linearArray(p, a1, a2) {
  if(a1.length != a2.length) throw "In linearArray(x,y), x and y must be same length.";
  return a1.map((e,i)=>linearNumber(p, e, a2[i]));
}
function linearNumber(p, a, b) {
  const p_ = 1-p;
  return p_*a + p*b;
}

function drawEasing(canvas, easing) {
  const ctx = canvas.getContext("2d");
  for(var i = 0; i < 200; i++) {
      var prog = i/200;
      var map = new BezierMap(...easing);
      var start = [0, 0, 1];
      var end = [1, 1, 1];
    var colorProg = map.get(prog);
    const color = linearArray(colorProg, start, end);
    ctx.fillStyle = `rgb(${color.map(x=>x*100+"%").join(",")})`;
    ctx.fillRect(i, 0, 1, 200);
  }
}

drawEasing(document.querySelector("#c01"), ease_in);
drawEasing(document.querySelector("#c02"), ease_out);
drawEasing(document.querySelector("#c03"), ease);
// --
drawEasing(document.querySelector("#c04"), ease_out);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.