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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more