<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);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.