Color
Ripl includes a complete color toolkit for parsing, converting, and serializing colors across multiple color spaces. Any CSS color string you pass to fill or stroke is automatically parsed — but you can also use the color utilities directly for programmatic color manipulation, palette generation, and animation.
NOTE
For the full API, see the Color API Reference.
Demo
Type or pick a color to see it parsed into every supported color space in real time.
Supported Color Spaces
| Space | Parse | Serialise | Example |
|---|---|---|---|
| HEX | parseHEX | serialiseHEX | #3a86ff, #3a86ff80 |
| RGB | parseRGB | serialiseRGB | rgb(58, 134, 255) |
| RGBA | parseRGBA | serialiseRGBA | rgba(58, 134, 255, 0.5) |
| HSL | parseHSL | serialiseHSL | hsl(216, 100%, 61%) |
| HSLA | parseHSLA | serialiseHSLA | hsla(216, 100%, 61%, 0.5) |
| HSV | parseHSV | serialiseHSV | hsv(216, 77%, 100%) |
| HSVA | parseHSVA | serialiseHSVA | hsva(216, 77%, 100%, 0.5) |
Parsing Colors
parseColor auto-detects the format and returns an RGBA tuple [r, g, b, a]:
import {
parseColor,
} from '@ripl/web';
parseColor('#3a86ff'); // [58, 134, 255, 1]
parseColor('rgb(58, 134, 255)'); // [58, 134, 255, 1]
parseColor('hsl(216, 100%, 61%)'); // [58, 134, 255, 1]For a specific format, use the named parser:
import {
parseHEX,
parseRGB,
} from '@ripl/web';
parseHEX('#ff006e'); // [255, 0, 110, 1]
parseRGB('rgb(255, 0, 110)'); // [255, 0, 110, 1]Serializing Colors
Serializers convert RGBA channel values back to a color string:
import {
serialiseHEX,
serialiseRGBA,
} from '@ripl/web';
serialiseHEX(58, 134, 255, 1); // '#3a86ff'
serialiseRGBA(58, 134, 255, 1); // 'rgba(58, 134, 255, 1)'Color Space Conversion
Convert between color spaces using the conversion utilities:
import {
hslToRGBA,
hsvToRGBA,
rgbaToHSL,
rgbaToHSV,
} from '@ripl/web';
rgbaToHSL(58, 134, 255); // [216, 100, 61, 1]
hslToRGBA(216, 100, 61); // [58, 134, 255, 1]
rgbaToHSV(58, 134, 255); // [216, 77, 100, 1]
hsvToRGBA(216, 77, 100); // [58, 134, 255, 1]Modifying Alpha
setColorAlpha parses any color string, replaces its alpha channel, and returns an RGBA string:
import {
setColorAlpha,
} from '@ripl/web';
setColorAlpha('#3a86ff', 0.5); // 'rgba(58, 134, 255, 0.5)'
setColorAlpha('rgb(255, 0, 110)', 0.8); // 'rgba(255, 0, 110, 0.8)'Color Interpolation
When animating between colors via renderer.transition(), Ripl uses interpolateColor under the hood. It parses both colors to RGBA, interpolates each channel linearly, and serializes back:
import {
interpolateColor,
} from '@ripl/web';
const lerp = interpolateColor('#3a86ff', '#ff006e');
lerp(0); // 'rgba(58, 134, 255, 1)'
lerp(0.5); // 'rgba(157, 67, 162, 1)'
lerp(1); // 'rgba(255, 0, 110, 1)'This happens automatically when transitioning fill or stroke between color values.
Color Schemes
Ripl ships a set of perceptually-uniform palettes as arrays of colour stops, each prefixed COLOR_SCHEME_: VIRIDIS, PLASMA, INFERNO, MAGMA, CIVIDIS, TURBO (sequential) and RDBU, BRBG (diverging). Being plain arrays, they compose directly with the interpolation and scale helpers below.
import {
COLOR_SCHEME_VIRIDIS,
interpolateColors,
} from '@ripl/web';
// Build a 0–1 → colour interpolator from a scheme's stops.
const viridis = interpolateColors(COLOR_SCHEME_VIRIDIS);
viridis(0); // first stop
viridis(0.5); // midpoint colour
viridis(1); // last stopinterpolateColors accepts any array of colour stops, so you can pass your own palette just as easily.
Color Scales
scaleSequential maps a numeric domain through a colour interpolator (or an array of stops, such as a COLOR_SCHEME_* palette). Values are clamped to the domain, and the returned scale exposes domain, ticks(), and the underlying interpolator (handy for rendering a legend gradient).
import {
COLOR_SCHEME_VIRIDIS,
scaleSequential,
} from '@ripl/web';
const color = scaleSequential(COLOR_SCHEME_VIRIDIS, [0, 100]);
color(0); // first stop
color(50); // midpoint colour
color(100); // last stop
color.ticks(5); // [0, 25, 50, 75, 100]Passing a three-element domain [min, neutral, max] produces a diverging scale — neutral maps to the interpolator's midpoint, so signed data reads symmetrically around a reference value:
import {
COLOR_SCHEME_RDBU,
scaleSequential,
} from '@ripl/web';
const anomaly = scaleSequential(COLOR_SCHEME_RDBU, [-5, 0, 5]);
anomaly(-5); // deep red
anomaly(0); // neutral midpoint
anomaly(5); // deep blueThis is exactly how the heatmap chart and its continuous-colour legend translate values into colour. Tick generation defers to an underlying continuous scale; formatting is always left to the caller and is never bound to the scale.
Internal Representation
All colors are internally represented as RGBA tuples:
type ColorRGBA = [red: number, green: number, blue: number, alpha: number];red,green,blue: 0–255alpha: 0–1