Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 12x 12x 4x 4x 4x 4x 4x 4x 4x 8x 4x 4x 4x 4x 4x 4x 4x | function srgbToLinear(channel: number): number { const c = channel / 255; return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); } function rgbToLms( r: number, g: number, b: number ): { l: number; m: number; s: number } { return { l: 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b, m: 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b, s: 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b, }; } function lmsToCubeRoot(lms: { l: number; m: number; s: number }): { l_: number; m_: number; s_: number; } { return { l_: Math.cbrt(lms.l), m_: Math.cbrt(lms.m), s_: Math.cbrt(lms.s), }; } function cubeRootLmsToOklab(lms: { l_: number; m_: number; s_: number }): { L: number; A: number; B: number; } { return { L: 0.2104542553 * lms.l_ + 0.793617785 * lms.m_ - 0.0040720468 * lms.s_, A: 1.9779984951 * lms.l_ - 2.428592205 * lms.m_ + 0.4505937099 * lms.s_, B: 0.0259040371 * lms.l_ + 0.7827717662 * lms.m_ - 0.808675766 * lms.s_, }; } function oklabToOklch(lab: { L: number; A: number; B: number }): { l: number; c: number; h: number; } { const C = Math.sqrt(lab.A * lab.A + lab.B * lab.B); let H = Math.atan2(lab.B, lab.A) * (180 / Math.PI); Iif (H < 0) H += 360; return { l: lab.L, c: C, h: H }; } export function rgbToOklch( r: number, g: number, b: number ): { l: number; c: number; h: number } { const linearR = srgbToLinear(r); const linearG = srgbToLinear(g); const linearB = srgbToLinear(b); const lms = rgbToLms(linearR, linearG, linearB); const lmsCube = lmsToCubeRoot(lms); const oklab = cubeRootLmsToOklab(lmsCube); return oklabToOklch(oklab); } |