oklch.ts

OKLCH/OKLab ↔ sRGB conversions, gamut math, and oklch() strings.

The tuple-returning conversions allocate a fresh array per call, which is fine for most uses. Per-pixel or per-frame callers (a canvas gamut plane, a live chroma clamp) should use oklch_to_srgb_into, which writes into a caller-owned array. The gamut helpers allocate nothing.

Matrices and constants follow css-color-4 and Björn Ottosson's reference implementation.

view source

Declarations
#

18 declarations

Chroma
#

oklch.ts view source

Chroma

type number & Flavor<"Chroma">

import type {Chroma} from '@fuzdev/fuz_util/oklch.js';

OKLCH chroma, 0 or more and unbounded; sRGB colors stay below about 0.37.

external types

Flavored<number, 'Chroma'>

clamp_oklch
#

oklch.ts view source

([lightness, chroma, hue]: readonly [lightness: Lightness, chroma: Chroma, hue: Hue]): Oklch import {clamp_oklch} from '@fuzdev/fuz_util/oklch.js';

Clamps an OKLCH color the way the browser clamps a computed oklch(): lightness to [0, 1] and chroma to 0 or more. Derived values can overshoot an end, and the browser renders the clamped color, so anything measuring the rendered color has to clamp too.

__0

type readonly [lightness: Lightness, chroma: Chroma, hue: Hue]

returns

Oklch

linear_component_to_srgb
#

oklch.ts view source

(c: number): number import {linear_component_to_srgb} from '@fuzdev/fuz_util/oklch.js';

Converts a linear-light sRGB component to gamma-encoded in [0, 1].

c

type number

returns

number

Oklab
#

oklch.ts view source

Oklab

type [lightness: Lightness, a: number, b: number]

import type {Oklab} from '@fuzdev/fuz_util/oklch.js';

A color in OKLab: lightness in [0, 1], a/b roughly in [-0.4, 0.4].

oklab_to_oklch
#

oklch.ts view source

([lightness, a, b]: readonly [lightness: Lightness, a: number, b: number]): Oklch import {oklab_to_oklch} from '@fuzdev/fuz_util/oklch.js';

Converts OKLab to OKLCH. Hue is normalized to [0, 360); an achromatic color (chroma below the float noise of the conversion matrices) gets hue 0.

__0

type readonly [lightness: Lightness, a: number, b: number]

returns

Oklch

oklab_to_srgb
#

oklch.ts view source

([lightness, a, b]: readonly [lightness: Lightness, a: number, b: number]): RgbUnit import {oklab_to_srgb} from '@fuzdev/fuz_util/oklch.js';

Converts OKLab to gamma-encoded sRGB.

__0

type readonly [lightness: Lightness, a: number, b: number]

returns

RgbUnit

components that may fall outside [0, 1] when the color is out of gamut

Oklch
#

oklch.ts view source

Oklch

type [lightness: Lightness, chroma: Chroma, hue: Hue]

import type {Oklch} from '@fuzdev/fuz_util/oklch.js';

A color in OKLCH: lightness in [0, 1], chroma ≥ 0 (unbounded), hue in degrees.

oklch_in_srgb_gamut
#

oklch.ts view source

(lch: readonly [lightness: Lightness, chroma: Chroma, hue: Hue], epsilon?: number): boolean import {oklch_in_srgb_gamut} from '@fuzdev/fuz_util/oklch.js';

Checks whether an OKLCH color converts to sRGB with all components inside [0, 1]. Allocates nothing, so it's safe in hot loops.

lch

type readonly [lightness: Lightness, chroma: Chroma, hue: Hue]

epsilon

tolerance for float noise at the gamut boundary

type number
default GAMUT_EPSILON

returns

boolean

oklch_max_srgb_chroma
#

oklch.ts view source

(lightness: Lightness, hue: Hue, precision?: number): Chroma import {oklch_max_srgb_chroma} from '@fuzdev/fuz_util/oklch.js';

Finds the largest chroma at a given OKLCH lightness and hue such that every chroma below it is also inside the sRGB gamut. Returns 0 when the lightness itself is out of range. Allocates nothing.

This is deliberately the *safe* maximum for ramps, not the outermost gamut intersection: the sRGB gamut is non-convex in OKLab (most visibly near the blue primary), so the constant-(L, H) chroma ray can exit and re-enter the gamut. A ramp needs the whole [0, C] segment representable, so the scan stops at the first exit.

lightness

hue

type Hue

precision

terminate when the refinement interval is smaller than this

type number
default 1e-5

returns

Chroma

oklch_to_oklab
#

oklch.ts view source

([lightness, chroma, hue]: readonly [lightness: Lightness, chroma: Chroma, hue: Hue]): Oklab import {oklch_to_oklab} from '@fuzdev/fuz_util/oklch.js';

Converts OKLCH to OKLab.

__0

type readonly [lightness: Lightness, chroma: Chroma, hue: Hue]

returns

Oklab

oklch_to_srgb
#

oklch.ts view source

(lch: readonly [lightness: Lightness, chroma: Chroma, hue: Hue]): RgbUnit import {oklch_to_srgb} from '@fuzdev/fuz_util/oklch.js';

Converts OKLCH to gamma-encoded sRGB.

lch

type readonly [lightness: Lightness, chroma: Chroma, hue: Hue]

returns

RgbUnit

components that may fall outside [0, 1] when the color is out of gamut

oklch_to_srgb_into
#

oklch.ts view source

(lch: readonly [lightness: Lightness, chroma: Chroma, hue: Hue], out: RgbUnit): RgbUnit import {oklch_to_srgb_into} from '@fuzdev/fuz_util/oklch.js';

Converts OKLCH to gamma-encoded sRGB, writing into out instead of allocating. For hot loops like per-pixel canvas fills; out may be reused across calls.

lch

the color to convert

type readonly [lightness: Lightness, chroma: Chroma, hue: Hue]

out

the array to write the sRGB components into

type RgbUnit

returns

RgbUnit

out, with components that may fall outside [0, 1] when the color is out of gamut

mutates

  • out — overwrites all three components

oklch_to_string
#

oklch.ts view source

(lightness: Lightness, chroma: Chroma, hue: Hue): string import {oklch_to_string} from '@fuzdev/fuz_util/oklch.js';

Renders an OKLCH color as a CSS oklch() string, rounding lightness and chroma to 4 decimals and hue to 2.

lightness

chroma

type Chroma

hue

type Hue

returns

string

parse_oklch_string
#

oklch.ts view source

(value: string): Oklch import {parse_oklch_string} from '@fuzdev/fuz_util/oklch.js';

Parses a CSS oklch() string, with or without the oklch( wrapper. Accepts percentages, a deg hue unit, none components (as 0), and exponents. The alpha channel is accepted and ignored.

value

type string

returns

Oklch

throws

  • Error - if the string isn't an `oklch()` color

RgbUnit
#

oklch.ts view source

RgbUnit

type [r: number, g: number, b: number]

import type {RgbUnit} from '@fuzdev/fuz_util/oklch.js';

An RGB color with components in the unit interval [0, 1]. Values are gamma-encoded sRGB unless a function documents linear-light. Out-of-gamut results are not clamped, so components may fall outside [0, 1].

srgb_component_to_linear
#

oklch.ts view source

(c: number): number import {srgb_component_to_linear} from '@fuzdev/fuz_util/oklch.js';

Converts a gamma-encoded sRGB component in [0, 1] to linear-light.

c

type number

returns

number

srgb_to_oklab
#

oklch.ts view source

([r, g, b]: readonly [r: number, g: number, b: number]): Oklab import {srgb_to_oklab} from '@fuzdev/fuz_util/oklch.js';

Converts gamma-encoded sRGB to OKLab.

__0

type readonly [r: number, g: number, b: number]

returns

Oklab

srgb_to_oklch
#

oklch.ts view source

(rgb: readonly [r: number, g: number, b: number]): Oklch import {srgb_to_oklch} from '@fuzdev/fuz_util/oklch.js';

Converts gamma-encoded sRGB to OKLCH.

rgb

type readonly [r: number, g: number, b: number]

returns

Oklch

Depends on
#