Published
Edited
Sep 20, 2020
Importers
26 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
display_white_luminance = 200 // 200 nits ?
Insert cell
srgb_to_xyz_abs = (rgb) =>
srgb_to_xyz(rgb).map(X => display_white_luminance/100 * X)
Insert cell
viewof user_color = html`<input type=color value=#d7b7fb>`
Insert cell
user_xyz = srgb_to_xyz_abs(from_hex(user_color))
Insert cell
user_jab = Jzazbz(user_xyz)
Insert cell
Insert cell
Jzazbz = {
const PQ = function perceptual_quantizer(X) {
const XX = Math.pow(X*1e-4, 0.1593017578125);
return Math.pow(
(0.8359375 + 18.8515625*XX) / (1 + 18.6875*XX),
134.034375); };
return function Jzazbz([X, Y, Z]) {
const
Lp = PQ(0.674207838*X + 0.382799340*Y - 0.047570458*Z),
Mp = PQ(0.149284160*X + 0.739628340*Y + 0.083327300*Z),
Sp = PQ(0.070941080*X + 0.174768000*Y + 0.670970020*Z),
Iz = 0.5 * (Lp + Mp),
az = 3.524000*Lp - 4.066708*Mp + 0.542708*Sp,
bz = 0.199076*Lp + 1.096799*Mp - 1.295875*Sp,
Jz = (0.44 * Iz) / (1 - 0.56*Iz) - 1.6295499532821566e-11;
return [Jz, az, bz];
}
}
Insert cell
Insert cell
Jzazbz_inverse = {
const PQ_inv = function perceptual_quantizer_inverse(X) {
const XX = Math.pow(X, 7.460772656268214e-03);
return 1e4 * Math.pow(
(0.8359375 - XX) / (18.6875*XX - 18.8515625),
6.277394636015326); };
return function Jzazbz_inverse([Jz, az, bz]) {
Jz = Jz + 1.6295499532821566e-11;
const
Iz = Jz / (0.44 + 0.56*Jz),
L = PQ_inv(Iz + 1.386050432715393e-1*az + 5.804731615611869e-2*bz),
M = PQ_inv(Iz - 1.386050432715393e-1*az - 5.804731615611891e-2*bz),
S = PQ_inv(Iz - 9.601924202631895e-2*az - 8.118918960560390e-1*bz);
return [
+ 1.661373055774069e+00*L - 9.145230923250668e-01*M + 2.313620767186147e-01*S,
- 3.250758740427037e-01*L + 1.571847038366936e+00*M - 2.182538318672940e-01*S,
- 9.098281098284756e-02*L - 3.127282905230740e-01*M + 1.522766561305260e+00*S];
}
}
Insert cell
Insert cell
JzCzhz = function JzCzhz(XYZ) {
const [Jz, az, bz] = Jzazbz(XYZ);
return [
Jz,
Math.sqrt(az*az + bz*bz),
Math.atan2(bz, az)];
}
Insert cell
Insert cell
JzCzhz_inverse = function JzCzhz_inverse([Jz, Cz, hz]) {
return Jzazbz_inverse([Jz, Cz * Math.cos(hz), Cz * Math.sin(hz)]);
}
Insert cell
Insert cell
deltaEz = function deltaEz(XYZ1, XYZ2) {
const
[Jz1, Cz1, hz1] = JzCzhz(XYZ1),
[Jz2, Cz2, hz2] = JzCzhz(XYZ2),
dJz = Jz2 - Jz1, dCz = Cz2 - Cz1, dhz = hz2 - hz1,
dHz2 = 2*Cz1*Cz2*(1 - Math.cos(dhz));
return Math.sqrt(dJz*dJz + dCz*dCz + dHz2);
}
Insert cell
Insert cell
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