Files
colour-tools/docs/COLOUR-MATH.md
T

95 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Colour mathematics and terminology
This document records the choices that materially change a result. It is not a
replacement for CSS Color, Compositing and Blending, or WCAG.
## Parsing and conversion
The parser accepts CSS colour syntax supported by the installed Color.js
version, including hex and named colours; `rgb()`, `hsl()`, `hwb()`, Lab/LCH
and OKLab/OKLCH functions; and registered `color()` spaces. Conversion keeps
finite coordinates outside a target gamut. Hex and ordinary browser sRGB
previews require mapping; the UI labels when this happened.
The converter exposes device-oriented and mathematical representations, but a
numeric tuple is meaningful only with its named colour space, white point,
transfer curve and alpha convention. CMYK output is a convenient mathematical
conversion, not a printer ICC separation or proof.
## Alpha compositing
For a source colour over a backdrop, with straight alpha `αs` and `αb`, output
alpha is:
```text
αo = αs + αb × (1 αs)
```
For each premultiplied channel under normal source-over:
```text
Co = Cs × αs + Cb × αb × (1 αs)
co = Co / αo when αo > 0
```
Layers are accumulated from the bottom upward even though the editor displays
the top layer first. Layer opacity multiplies the colour's own alpha. Blend
modes are applied before source-over using the model in CSS Compositing and
Blending.
“Encoded sRGB” applies the operation directly to sRGB-encoded channel values,
matching many quick web calculators. “Linear-light sRGB” first removes the
sRGB transfer curve and is generally the physically meaningful choice for
mixing emitted light. The two results are expected to differ.
## Interpolation
A ramp samples its first and last stop and distributes missing positions like a
CSS gradient. Each segment is interpolated in the selected space with the
chosen easing. Cylindrical spaces need an explicit hue route: shorter, longer,
increasing, decreasing or raw. The default premultiplies colour components by
alpha before mixing and unpremultiplies afterwards, preventing hidden channels
inside a transparent endpoint from tinting the ramp. A straight-alpha toggle
is available for intentionally reproducing that model. OKLCH is the UI default
because equal numeric progress tends to look more even than encoded RGB; it
does not guarantee that every intermediate colour lies in a display gamut.
## Gamut mapping
An in-gamut check does not modify the colour. Display mapping uses an OKLCH
chroma-reduction method by default; channel clipping is available at the engine
boundary where explicitly selected. The result includes Delta E OK from the
source so callers can quantify the change. A browser preview is always mapped
to sRGB because CSS support and physical displays differ.
## Contrast and transparency
Relative luminance and WCAG 2 contrast are evaluated after translucent
foreground/background colours are composited over the stated canvas (white by
default). The ratio is:
```text
(Llighter + 0.05) / (Ldarker + 0.05)
```
The UI reports 3:1, 4.5:1 and 7:1 thresholds and searches for a nearby lighter
or darker passing foreground. A mathematical pass is only one part of an
accessibility review; font size/weight, focus states, disabled controls,
non-colour cues and actual display conditions remain relevant.
## Perceptual difference and simulations
Delta E 76, CMC, CIEDE2000, Delta E OK, ITP and Jz answer different historical
or application needs; values from different formulas are not interchangeable.
The colour-vision previews apply bounded matrices in linear sRGB and expose a
severity control. They are approximations for interface review, not a model of
every observer and not medical advice.
## Palette extraction
The raster extractor ignores sufficiently transparent pixels, converts bounded
samples to OKLab and clusters them deterministically. Reported coverage is the
share of accepted samples assigned to a cluster, not an exact segmentation of
every source pixel. Small antialiased regions and colour-managed decoding can
therefore influence the result.