Color Mixing & Interpolation
Master blending colors with mix(), creating multi-stop gradients with interpolate(), and generating discrete color scale palettes.
Saturon provides a powerful, CSS-spec-compliant engine for blending and interpolating colors. Whether you need to mix two colors by exact percentages, create fluid multi-stop gradients, or generate discrete color palettes, the static methods on the Color class provide a highly accurate, developer-friendly API.
By default, all mixing and interpolation in Saturon happens in the OKLab color space, ensuring perceptually uniform transitions without the muddy "gray dead zones" common in standard RGB mixing.
Static Mixing with Color.mix()
The Color.mix() method accurately replicates the behavior of the W3C CSS color-mix() function. It statically mixes an array of colors together based on defined weights or percentages.
Signature
static mix(colors: MixItem[], options: MixOptions): ColorThe colors array expects objects containing a color (a Color instance) and an optional percentage (a number from 0 to 1). If percentages are omitted, Saturon distributes the remaining weight evenly, exactly like CSS.
Example
Live Color Mixer
#ae8fa1oklab(0.68438 0.0421 -0.01318)import { Color } from "saturon";const color1 = Color.from("#009dff");const color2 = Color.from("#ff6200");const mixed = Color.mix( [ { color: color1, percentage: 0.5 }, { color: color2, percentage: 0.5 } ], { in: "oklab", hue: "shorter" } // Leaving them undefined defaults to { in: "oklab", hue: "shorter" });console.log(mixed.to("hex-color"));Continuous Interpolation with Color.interpolate()
When you need to transition smoothly across a multi-stop color gradient, Color.interpolate() returns a highly optimized sampling function.
Signature
static interpolate(colors: Color[], options: MixOptions): (t: number) => ColorInstead of returning a single color, it returns a function that accepts a normalized progress value t (from 0 to 1). Saturon handles segment mapping internally, meaning you can pass as many color stops as you want.
Example
Live Interpolation Ramp
#ffee00oklab(0.93301 -0.0488 0.19118)import { Color } from "saturon";const color1 = Color.from("#ee00ff");const color2 = Color.from("#ffee00");const color3 = Color.from("#00ffee");const ramp = Color.interpolate( [color1, color2, color3], { in: "oklab", hue: "shorter" } // Leaving them undefined defaults to { in: "oklab", hue: "shorter" });// Sample the gradient at a normalized progress pointconst sample = ramp(0.50);console.log(sample.to("hex-color"));Palette Generation with Color.scale()
If you are building design systems, themes, or data visualizations, you often need a specific number of discrete colors extracted from a gradient. Color.scale() automates this by discretizing an interpolation into a fixed number of steps.
Signature
static scale(colors: Color[], options: ScaleOptions): Color[]This method shares the same options as interpolate(), but adds a steps property (defaulting to 5).
Example
Live Palette Generator
#ff00bboklab(0.66672 0.27384 -0.07388)#ea78aaoklab(0.71723 0.14908 -0.01549)#ccad94oklab(0.76774 0.02433 0.04291)#9bd877oklab(0.81825 -0.10043 0.10131)#00ff44oklab(0.86876 -0.22518 0.1597)import { Color } from "saturon";const color1 = Color.from("#ff00bb");const color2 = Color.from("#00ff44");const palette = Color.scale( [color1, color2], { steps: 5, in: "oklab", hue: "shorter" } // Leaving them undefined defaults to { steps: 5, in: "oklab", hue: "shorter" });palette.forEach((color) => console.log(color.to("hex-color")));Interpolation Spaces & Hue Strategies
The exact visual result of mixing or interpolating colors depends entirely on the color space you choose to mix them in, and how you handle hue angles.
The in Option
You can mix colors in any supported color space by changing the in property in your MixOptions.
| Space | Characteristics |
|---|---|
"oklab" (Default) | Perceptually uniform. Best for general-purpose mixing, preventing muddy midtones. |
"srgb" | Standard digital mixing. Can result in dark/gray bands between contrasting colors. |
"oklch", "lch", "hsl" | Cylindrical spaces. Excellent for vibrant gradients, as they interpolate around the color wheel instead of cutting through the middle. |
The hue Option
When interpolating in a cylindrical space (like hsl, lch, or oklch), the hue channel is an angle (0-360°). Saturon needs to know which direction around the color wheel it should travel.
You control this using the W3C standard hue interpolation strategies:
Color.interpolate([red, blue], { in: "oklch", hue: "shorter" });| Strategy | Behavior |
|---|---|
"shorter" (Default) | Takes the shortest path around the wheel. E.g., transitioning from 10° to 350° will cross through 0°, traveling a total of 20°. |
"longer" | Takes the longest path around the wheel. E.g., from 10° to 350°, it will travel 340° in the opposite direction, creating a rainbow effect. |
"increasing" | Always travels clockwise (increasing angles), regardless of distance. |
"decreasing" | Always travels counter-clockwise (decreasing angles), regardless of distance. |
Working with Color Instances
Discover how to convert, transform, extract, and format color channel values using in(), to(), with(), and data extraction methods on Color instances.
Accessibility & Color Difference Checks
Ensure your colors are readable and accessible using the static contrast() and deltaE*() methods to measure legibility and perceptual differences.