chroma-js
Version:
JavaScript library for color conversions
38 lines (33 loc) • 1.43 kB
JavaScript
import { unpack } from '../../utils/index.js';
import multiplyMatrices from '../../utils/multiply-matrices.js';
import { rgb2xyz } from '../lab/rgb2lab.js';
const rgb2oklab = (...args) => {
const [r, g, b, ...rest] = unpack(args, 'rgb');
const xyz = rgb2xyz(r, g, b);
const oklab = XYZ_to_OKLab(xyz);
return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
};
// from https://www.w3.org/TR/css-color-4/#color-conversion-code
function XYZ_to_OKLab(XYZ) {
// Given XYZ relative to D65, convert to OKLab
const XYZtoLMS = [
[0.819022437996703, 0.3619062600528904, -0.1288737815209879],
[0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
[0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
];
const LMStoOKLab = [
[0.210454268309314, 0.7936177747023054, -0.0040720430116193],
[1.9779985324311684, -2.4285922420485799, 0.450593709617411],
[0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
];
const LMS = multiplyMatrices(XYZtoLMS, XYZ);
// JavaScript Math.cbrt returns a sign-matched cube root
// beware if porting to other languages
// especially if tempted to use a general power function
return multiplyMatrices(
LMStoOKLab,
LMS.map((c) => Math.cbrt(c))
);
// L in range [0,1]. For use in CSS, multiply by 100 and add a percent
}
export default rgb2oklab;