Published
Edited
Dec 25, 2020
1 fork
4 stars
Insert cell
Insert cell
Insert cell
TestColors = [{ r: 0, g: 0, b: 0 }, { r: 255, g: 0, b: 0 }]
Insert cell
scale = {
// Make an array of colors that interpolate between the two test
// colors in Oklab space.
let c0 = linear_srgb_to_oklab(srgb_to_linear_srgb(TestColors[0]));
let c1 = linear_srgb_to_oklab(srgb_to_linear_srgb(TestColors[1]));
let N = 10;
let colors = [];
for (let i = 0; i < N; i++) {
let v = i / (N - 1);
let c = {
L: (1 - v) * c0.L + v * c1.L,
a: (1 - v) * c0.a + v * c1.a,
b: (1 - v) * c0.b + v * c1.b
};
colors.push(linear_srgb_to_srgb(oklab_to_linear_srgb(c)));
}
return colors;
}
Insert cell
linear_srgb_to_oklab = function(c) {
let l = 0.4121656120 * c.r + 0.5362752080 * c.g + 0.0514575653 * c.b;
let m = 0.2118591070 * c.r + 0.6807189584 * c.g + 0.1074065790 * c.b;
let s = 0.0883097947 * c.r + 0.2818474174 * c.g + 0.6302613616 * c.b;

let l_ = Math.cbrt(l);
let m_ = Math.cbrt(m);
let s_ = Math.cbrt(s);

return {
L: 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
a: 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
};
}
Insert cell
oklab_to_linear_srgb = function(lab) {
let l_ = lab.L + 0.3963377774 * lab.a + 0.2158037573 * lab.b;
let m_ = lab.L - 0.1055613458 * lab.a - 0.0638541728 * lab.b;
let s_ = lab.L - 0.0894841775 * lab.a - 1.2914855480 * lab.b;

let l = l_ * l_ * l_;
let m = m_ * m_ * m_;
let s = s_ * s_ * s_;

return {
r: +4.0767245293 * l - 3.3072168827 * m + 0.2307590544 * s,
g: -1.2681437731 * l + 2.6093323231 * m - 0.3411344290 * s,
b: -0.0041119885 * l - 0.7034763098 * m + 1.7068625689 * s
};
}
Insert cell
srgb_to_linear_srgb = function(rgb) {
function f(x) {
if (x >= 0.04045) return ((x + 0.055) / (1 + 0.055)) ** 2.4;
else return x / 12.92;
}
return {
r: f(rgb.r / 255) * 255,
g: f(rgb.g / 255) * 255,
b: f(rgb.b / 255) * 255
};
}
Insert cell
linear_srgb_to_srgb = function(rgb) {
function f(x) {
if (x >= 0.0031308) return (1.055 * x) ** (1.0 / 2.4 - 0.055);
else return 12.92 * x;
}
return {
r: f(rgb.r / 255) * 255,
g: f(rgb.g / 255) * 255,
b: f(rgb.b / 255) * 255
};
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more