color
stableColor manipulation library supporting HSL, HSV, LAB, CMYK, hex, CSS strings, blending, palettes, and WCAG accessibility checks.
use plugin color::{rgb_to_hsl, hsl_to_rgb, rgb_to_hsv, …} Functions (31)
- rgb_to_hsl Convert RGB to HSL
- hsl_to_rgb Convert HSL to RGB
- rgb_to_hsv Convert RGB to HSV
- hsv_to_rgb Convert HSV to RGB
- hex_to_rgb Parse a hex color string to RGB
- rgb_to_hex Convert RGB values to a hex string
- lerp_color Linearly interpolate between two colors
- luminance Compute WCAG relative luminance
- contrast_ratio Compute WCAG contrast ratio from two luminances
- complement Get the complement of an RGB color
- darken Darken an RGB color by a factor
- lighten Lighten an RGB color by a factor
- is_dark Check if an RGB color is perceptually dark
- rgb_to_lab Convert RGB to CIE L\*a\*b\*
- lab_to_rgb Convert CIE L\*a\*b\* to RGB
- delta_e Perceptual color difference between two Lab colors
- rgb_to_cmyk Convert RGB to CMYK
- cmyk_to_rgb Convert CMYK to RGB
- temperature_to_rgb Convert color temperature (Kelvin) to RGB
- palette_from_image Extract dominant colors from RGBA bytes
- gradient Generate a color gradient between two colors
- triadic Get three triadic colors from an RGB color
- analogous Get three analogous colors at a given angle
- wcag_contrast_level Classify a contrast ratio as AA, AAA, or fail
- random_color Generate a deterministic random color from a seed
- blend Blend two colors with a named blend mode
- parse Parse a CSS color string to RGB
- to_css_string Convert an RGB table to a CSS rgb() string
- saturate Increase saturation of an RGB color
- desaturate Decrease saturation of an RGB color
- grayscale Convert an RGB color to grayscale
Overview
The color plugin is a stateless toolkit for working with colors across the
spaces designers and engineers actually use: RGB, HSL, HSV, CIE L*a*b*, and
CMYK, plus hex and CSS string forms. There are no handles or objects to manage —
every function is a pure transformation. Channel-based functions take and return
loose numbers (RGB as 0–255, hue in degrees, saturation/lightness as 0–1),
while functions that work on whole colors (gradient, blend, delta_e,
to_css_string) accept and return {r, g, b} (or {l, a, b}) tables. Reach for
it whenever you need color math: building gradients and palettes, generating
harmonious schemes (triadic, analogous, complement), or validating that text
meets WCAG contrast requirements.
Common patterns
Check whether a foreground/background pair is accessible by combining
luminance, contrast_ratio, and wcag_contrast_level:
use plugin color::{luminance, contrast_ratio, wcag_contrast_level}
let fg = luminance(40.0, 40.0, 40.0)
let bg = luminance(255.0, 255.0, 255.0)
let ratio = contrast_ratio(fg, bg)
print("ratio: {ratio} -> {wcag_contrast_level(ratio)}")
Round-trip a CSS string through RGB, tweak it, and emit CSS again:
use plugin color::{parse, darken, to_css_string}
let base = parse("#ff8800")
let darker = darken(base["r"], base["g"], base["b"], 0.25)
print(to_css_string(darker))
Build a smooth gradient between two named colors and read out a stop:
use plugin color::{parse, gradient}
let start = parse("red")
let end = parse("blue")
let stops = gradient(start, end, 7)
let mid = stops[3]
print("middle stop: {mid["r"]}, {mid["g"]}, {mid["b"]}")
Convert RGB to HSL
Converts an RGB color (0–255 each) to HSL. Returns a table with h
(0–360 degrees), s (0–1), and l (0–1).
use plugin color::{rgb_to_hsl}
let hsl = rgb_to_hsl(255.0, 128.0, 0.0)
print("hue: {hsl["h"]}, saturation: {hsl["s"]}, lightness: {hsl["l"]}")
Convert HSL to RGB
Converts HSL to RGB (0–255 each). h is in degrees (0–360), s and l
are 0–1.
use plugin color::{hsl_to_rgb}
let rgb = hsl_to_rgb(120.0, 1.0, 0.5)
print("r: {rgb["r"]}, g: {rgb["g"]}, b: {rgb["b"]}")
Convert RGB to HSV
Converts RGB (0–255) to HSV. Returns h (0–360), s (0–1), v (0–1).
use plugin color::{rgb_to_hsv}
let hsv = rgb_to_hsv(255.0, 0.0, 0.0)
print("h: {hsv["h"]}, s: {hsv["s"]}, v: {hsv["v"]}")
Convert HSV to RGB
Converts HSV to RGB (0–255 each). h is in degrees (0–360), s and v
are 0–1.
use plugin color::{hsv_to_rgb}
let rgb = hsv_to_rgb(200.0, 0.8, 0.9)
print("r: {rgb["r"]}, g: {rgb["g"]}, b: {rgb["b"]}")
Parse a hex color string to RGB
Parses a hex color string (#rgb or #rrggbb) and returns {r, g, b}
(0–255).
use plugin color::{hex_to_rgb}
let rgb = hex_to_rgb("#ff8800")
print("r: {rgb["r"]}, g: {rgb["g"]}, b: {rgb["b"]}")
let short = hex_to_rgb("#f80")
print("r: {short["r"]}")
Convert RGB values to a hex string
Converts RGB values (0–255) to a lowercase hex color string like #ff8800.
use plugin color::{rgb_to_hex}
let hex = rgb_to_hex(255.0, 136.0, 0.0)
print(hex)
Linearly interpolate between two colors
Linearly interpolates between two RGB colors. t is 0–1 where 0 returns
the first color and 1 returns the second.
use plugin color::{lerp_color}
let mid = lerp_color(255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.5)
print("r: {mid["r"]}, g: {mid["g"]}, b: {mid["b"]}")
Compute WCAG relative luminance
Returns the WCAG 2.1 relative luminance (0–1) of an RGB color. Use with
contrast_ratio for accessibility checks.
use plugin color::{luminance}
let lum = luminance(255.0, 255.0, 255.0)
print("white luminance: {lum}")
Compute WCAG contrast ratio from two luminances
Computes the WCAG contrast ratio from two luminance values. A result of 4.5 or higher passes AA for normal text.
use plugin color::{luminance, contrast_ratio, wcag_contrast_level}
let l1 = luminance(0.0, 0.0, 0.0)
let l2 = luminance(255.0, 255.0, 255.0)
let ratio = contrast_ratio(l1, l2)
print("contrast ratio: {ratio}")
Get the complement of an RGB color
Returns the RGB complement (255 - each channel) of a color.
use plugin color::{complement}
let c = complement(255.0, 128.0, 0.0)
print("complement: {c["r"]}, {c["g"]}, {c["b"]}")
Darken an RGB color by a factor
Darkens an RGB color by multiplying each channel by (1 - amount).
amount is 0–1.
use plugin color::{darken}
let dark = darken(200.0, 150.0, 100.0, 0.3)
print("darkened: {dark["r"]}, {dark["g"]}, {dark["b"]}")
Lighten an RGB color by a factor
Lightens an RGB color by blending toward white by amount (0–1).
use plugin color::{lighten}
let light = lighten(100.0, 50.0, 0.0, 0.5)
print("lightened: {light["r"]}, {light["g"]}, {light["b"]}")
Check if an RGB color is perceptually dark
Returns true if the color's relative luminance is below 0.179, indicating a perceptually dark color. Useful for choosing white vs black overlay text.
use plugin color::{is_dark}
print(is_dark(0.0, 0.0, 0.0))
print(is_dark(255.0, 255.0, 255.0))
Convert RGB to CIE L\*a\*b\*
Converts RGB (0–255) to CIE L*a*b* color space. Returns l, a, b
fields. L*a*b* is perceptually uniform and suited for color difference math.
use plugin color::{rgb_to_lab}
let lab = rgb_to_lab(255.0, 0.0, 0.0)
print("L: {lab["l"]}, a: {lab["a"]}, b: {lab["b"]}")
Convert CIE L\*a\*b\* to RGB
Converts CIE L*a*b* back to RGB (0–255). Values are clamped to the sRGB gamut.
use plugin color::{lab_to_rgb}
let rgb = lab_to_rgb(50.0, 25.0, -30.0)
print("r: {rgb["r"]}, g: {rgb["g"]}, b: {rgb["b"]}")
Perceptual color difference between two Lab colors
Computes the CIE76 color difference (Delta E) between two L*a*b* color tables. Values below 2.3 are imperceptible to the human eye.
use plugin color::{rgb_to_lab, delta_e}
let lab1 = rgb_to_lab(255.0, 0.0, 0.0)
let lab2 = rgb_to_lab(250.0, 10.0, 0.0)
let de = delta_e(lab1, lab2)
print("color difference: {de}")
Convert RGB to CMYK
Converts RGB (0–255) to CMYK (0–1 each). Returns c, m, y, k fields.
Useful for print-oriented color workflows.
use plugin color::{rgb_to_cmyk}
let cmyk = rgb_to_cmyk(255.0, 0.0, 0.0)
print("c: {cmyk["c"]}, m: {cmyk["m"]}, y: {cmyk["y"]}, k: {cmyk["k"]}")
Convert CMYK to RGB
Converts CMYK (0–1 each) to RGB (0–255 each).
use plugin color::{cmyk_to_rgb}
let rgb = cmyk_to_rgb(0.0, 1.0, 1.0, 0.0)
print("r: {rgb["r"]}, g: {rgb["g"]}, b: {rgb["b"]}")
Convert color temperature (Kelvin) to RGB
Converts a color temperature in Kelvin to an approximate RGB color. Useful for warm/cool lighting effects. Typical daylight is around 6500K.
use plugin color::{temperature_to_rgb}
let warm = temperature_to_rgb(3000.0)
print("warm light: {warm["r"]}, {warm["g"]}, {warm["b"]}")
let cool = temperature_to_rgb(6500.0)
print("daylight: {cool["r"]}, {cool["g"]}, {cool["b"]}")
Extract dominant colors from RGBA bytes
Extracts n_colors dominant colors from raw RGBA pixel data using k-means
clustering (20 iterations). Returns a table of {r, g, b} tables.
use plugin color::{palette_from_image}
// rgba_bytes would typically come from an image-loading plugin
// let palette = palette_from_image(raw_bytes, 800, 600, 5)
// print("dominant colors: {#palette}")
Generate a color gradient between two colors
Generates a linear gradient of steps colors between two {r, g, b} tables.
Returns a table of {r, g, b} color tables indexed from 0.
use plugin color::{gradient}
let red = #{"r": 255.0, "g": 0.0, "b": 0.0}
let blue = #{"r": 0.0, "g": 0.0, "b": 255.0}
let grad = gradient(red, blue, 5)
print("gradient step 3: {grad[2]["r"]}, {grad[2]["g"]}, {grad[2]["b"]}")
Get three triadic colors from an RGB color
Returns three triadic colors (hue shifts of 0°, 120°, 240°) as a table of
{r, g, b} tables indexed 0, 1, 2.
use plugin color::{triadic}
let colors = triadic(255.0, 0.0, 0.0)
print("first: {colors[0]["r"]}, {colors[0]["g"]}, {colors[0]["b"]}")
print("second: {colors[1]["r"]}, {colors[1]["g"]}, {colors[1]["b"]}")
Get three analogous colors at a given angle
Returns three analogous colors (hue at -angle, original, +angle) as a table
of {r, g, b} tables. A common angle is 30°.
use plugin color::{analogous}
let colors = analogous(255.0, 0.0, 0.0, 30.0)
print("left: {colors[0]["r"]}, {colors[0]["g"]}, {colors[0]["b"]}")
print("right: {colors[2]["r"]}, {colors[2]["g"]}, {colors[2]["b"]}")
Classify a contrast ratio as AA, AAA, or fail
Returns "AAA" if ratio >= 7.0, "AA" if ratio >= 4.5, or "fail"
otherwise. Use after contrast_ratio.
use plugin color::{luminance, contrast_ratio, wcag_contrast_level}
let l1 = luminance(0.0, 0.0, 0.0)
let l2 = luminance(255.0, 255.0, 255.0)
let level = wcag_contrast_level(contrast_ratio(l1, l2))
print("WCAG level: {level}")
Generate a deterministic random color from a seed
Generates a deterministic pseudo-random RGB color from an integer seed. Same seed always produces the same color.
use plugin color::{random_color}
let c = random_color(42)
print("r: {c["r"]}, g: {c["g"]}, b: {c["b"]}")
Blend two colors with a named blend mode
Blends two {r, g, b} color tables using a blend mode. Supported modes:
"multiply", "screen", "overlay", "soft_light".
use plugin color::{blend}
let a = #{"r": 200.0, "g": 100.0, "b": 50.0}
let b = #{"r": 80.0, "g": 160.0, "b": 200.0}
let result = blend(a, b, "multiply")
print("blended: {result["r"]}, {result["g"]}, {result["b"]}")
Parse a CSS color string to RGB
Parses a CSS color string to {r, g, b}. Supports #rgb, #rrggbb,
rgb(r,g,b), and the 17 basic CSS named colors (black, white, red, etc.).
use plugin color::{parse}
let c1 = parse("#ff8800")
let c2 = parse("rgb(255, 128, 0)")
let c3 = parse("orange")
print("r: {c3["r"]}, g: {c3["g"]}, b: {c3["b"]}")
Convert an RGB table to a CSS rgb() string
Converts a {r, g, b} table to a CSS rgb(r, g, b) string.
use plugin color::{to_css_string, parse}
let c = parse("blue")
let css = to_css_string(c)
print(css)
Increase saturation of an RGB color
Increases the saturation of an RGB color by amount (0–1) in HSL space.
use plugin color::{saturate}
let vivid = saturate(150.0, 100.0, 80.0, 0.3)
print("saturated: {vivid["r"]}, {vivid["g"]}, {vivid["b"]}")
Decrease saturation of an RGB color
Decreases the saturation of an RGB color by amount (0–1) in HSL space.
use plugin color::{desaturate}
let muted = desaturate(200.0, 50.0, 30.0, 0.5)
print("desaturated: {muted["r"]}, {muted["g"]}, {muted["b"]}")
Convert an RGB color to grayscale
Converts an RGB color to its grayscale equivalent by zeroing saturation in HSL space.
use plugin color::{grayscale}
let gray = grayscale(200.0, 80.0, 40.0)
print("gray: {gray["r"]}, {gray["g"]}, {gray["b"]}")