API Reference
API table of contents
- a98
- average
- averageAngle
- averageNumber
- blend
- blerp
- clampChroma
- clampRgb
- colorsNamed
- converter
- cubehelix
- differenceCie76
- differenceCie94
- differenceCiede2000
- differenceCmc
- differenceEuclidean
- differenceHueChroma
- differenceHueNaive
- differenceHueSaturation
- differenceHyab
- differenceKotsarenkoRamos
- differenceItp
- displayable
- dlab
- dlch
- easingGamma
- easingInOutSine
- easingMidpoint
- easingSmootherstep
- easingSmoothstep
- easingSmoothstepInverse
- filterBrightness
- filterContrast
- filterDeficiencyDeuter
- filterDeficiencyProt
- filterDeficiencyTrit
- filterGrayscale
- filterHueRotate
- filterInvert
- filterSaturate
- filterSepia
- fixupAlpha
- fixupHueDecreasing
- fixupHueIncreasing
- fixupHueLonger
- fixupHueShorter
- formatCss
- formatHex
- formatHex8
- formatHsl
- formatRgb
- getMode
- hsi
- hsl
- hsv
- hwb
- inGamut
- interpolate
- interpolateWith
- interpolateWithPremultipliedAlpha
- interpolatorLinear
- interpolatorPiecewise
- interpolatorSplineBasis
- interpolatorSplineBasisClosed
- interpolatorSplineMonotone
- interpolatorSplineMonotone2
- interpolatorSplineMonotoneClosed
- interpolatorSplineNatural
- interpolatorSplineNaturalClosed
- itp
- jab
- jch
- lab65
- lab
- lch65
- lch
- lchuv
- lerp
- lrgb
- luv
- mapAlphaDivide
- mapAlphaMultiply
- mapTransferGamma
- mapTransferLinear
- mapper
- nearest
- oklab
- oklch
- parse
- p3
- prophoto
- random
- rec2020
- rgb
- round
- samples
- toGamut
- trilerp
- unlerp
- useMode
- wcagContrast
- wcagLuminance
- xyb
- xyz50
- xyz65
- yiq
Colors are plain objects
Culori does not have a Color class. Instead, it uses plain objects to represent colors:
/* A RGB color */
{
mode: 'rgb',
r: 0.1,
g: 0.2,
b: 1,
alpha: 1
}
The object needs to have a mode
property that identifies the color space, and values for each channel in that particular color space (see the Color Spaces page for the channels and ranges expected for each color space). Optionally, the alpha
property is used for the color's alpha channel.
Parsing and conversion
# parse(string) → color or undefined
Parses a string and returns the corresponding color. The color will be in the matching color space, e.g. RGB for hex strings, HSL for hsl(…, …, …)
strings, et cetera. If no built-in parsers can match the string, the function will return undefined
.
import { parse } from 'culori';
/* A named color */
parse('red');
// ⇒ { r: 1, g: 0, b: 0, mode: 'rgb' }
/* A hex color */
parse('#ff0000');
// ⇒ { r: 1, g: 0, b: 0, mode: 'rgb' }
/* A HSL color */
parse('hsl(60 50% 10% / 100%)');
// ⇒ { h: 60, s: 0.5, b: 0.1, alpha: 1, mode: 'hsl' }
/* A Lab color */
parse('lab(100% -50 50)');
// ⇒ { l: 100, a: -50, b: 50, mode: 'lab' }
In most cases, instead of using parse()
directly (which only operates on strings), you'll want to use a converter()
, which accepts strings and color objects and returns objects in a predictable color space.
# converter(mode = "rgb") → function (color or String)
Returns a converter: a function that can convert any color to the mode color space.
import { converter } from 'culori';
let rgb = converter('rgb');
let lab = converter('lab');
rgb('#f0f0f0');
// ⇒ { mode: "rgb", r: 0.49…, g: 0.49…, b: 0.49… }
lab('#f0f0f0');
// ⇒ { mode: "lab", l: 94.79…, a: 0, b: 0 }
Converters accept either strings (which will be parsed with parse()
under the hood) or color objects. If the mode
key is absent from the color object passed to a converter, it's assumed to be in the converter's color space.
Formatting
These methods serialize colors to strings, in various formats.
# formatHex(color or string) → string
Returns the hex string for the given color. The color's alpha
channel is omitted, and the red, green, and blue channels are clamped to the the interval [0, 255]
, i.e. colors that are not displayable are serialized as if they'd been passed through the clampRgb
method.
import { formatHex } from 'culori';
formatHex('red');
// ⇒ "#ff0000"
# formatHex8(color or string) → string
Returns the 8-character hex string for the given color. The red, green, blue, and alpha channels are clamped to the the interval [0, 255]
, i.e. colors that are not displayable are serialized as if they'd been passed through the clampRgb
method.
import { formatHex8 } from 'culori';
formatHex8({ mode: 'rgb', r: 1, g: 0, b: 0, alpha: 0.5 });
// ⇒ "#ff000080"
# formatRgb(color or string) → string
Returns the rgb(…)
/ rgba(…)
string for the given color. Fully opaque colors will be serialized as rgb()
, and semi-transparent colors as rgba()
, in accordance with the CSSOM standard serialization. Like in the case of formatHex
, the red, green, and blue channels are clamped to the interval [0, 255]
.
import { formatRgb } from 'culori';
formatRgb('lab(50 0 0 / 25%)');
// ⇒ "rgba(119, 119, 119, 0.25)"
# formatHsl(color or string) → string
Returns the hsl(…)
/ hsla(…)
string for the given color. Fully opaque colors will be serialized as hsl()
, and semi-transparent colors as hsla()
. All values are rounded to a precision of two digits. The Saturation and Lightness are clamped to the interval [0%, 100%]
.
import { formatHsl } from 'culori';
formatHsl('lab(50 0 0 / 25%)');
// ⇒ 'hsla(194.33, 0%, 46.63%, 0.25)'
# formatCss(color or string) → string
Returns a CSS string for the given color, based on the CSS Color Level 4 specification. A few color spaces, such as hsl
or lab
, have their own functional representation in CSS. We use that whenever possible; the hsl
color space is represented as hsl(h% s l / alpha)
. Predefined color spaces are represented using the color()
notation with the appropriate identifier for the color space, e.g. color(display-p3 r g b / alpha)
. All other colors paces use the color()
notation with a dashed identifier. For example, jab
is represented as color(--jzazbz j a b / alpha)
.
You can find the exact string produced for each color space under the Serialized as entry on the Color Spaces page.
Channel values are serialized as-is, with no change in the precision. To avoid compatibility issues, sRGB colors are represented as color(srgb r g b / alpha)
rather than rgb(r, g, b, alpha)
. For the latter, use the formatRgb()
method instead.
An alpha of exactly 1
is omitted from the representation.
Note: The strings returned by these methods are not widely supported in current browsers and should not be used in CSS as-is.
import { formatCss } from 'culori';
/*
A mode with its own function notation.
*/
formatCss({ mode: 'hsl', h: 30, s: 1, l: 0.5, alpha: 0.5 });
// ⇒ 'hsl(30 100% 50% / 0.5)'
/*
A predefined color space.
*/
formatCss({ mode: 'p3', r: 0.5, s: 0.25, b: 1, alpha: 1 });
// ⇒ 'color(display-p3 0.5 0.25 1)'
/*
sRGB colors.
*/
formatCss({ mode: 'rgb', r: 0.5, s: 0.25, b: 1, alpha: 0.25 });
// ⇒ 'color(srgb 0.5 0.25 1 / 0.25)'
/*
A custom color space.
*/
formatCss({ mode: 'lrgb', r: 0.5, s: 0.25, b: 1, alpha: 0.25 });
// ⇒ 'color(--srgb-linear 0.5 0.25 1 / 0.25)'
Gamut mapping
Some color spaces (Lab and LCh in particular) allow you to express colors that can't be displayed on-screen. The methods below allow you to identify when that's the case and to produce displayable versions of the colors.
# inGamut(mode = "rgb") → function (color | string)
Given a color space, returns a function with which to check whether a particular color is within the gamut of that color space.
This is meant to be used with RGB-based color spaces and their derivates (hsl
, hsv
, etc.). If the color space has no gamut limits, the function will always return true
, regardless of the color passed to it. To find out which color spaces have gamut limits, see the Color Spaces page.
import { inGamut } from 'culori';
const inRgb = inGamut('rgb');
inRgb('red');
// ⇒ true
inRgb('color(srgb 1.1 0 0)');
// ⇒ false
# displayable(color or string) → boolean
Checks whether a particular color fits inside the sRGB gamut. Equivalent to inGamut('rgb')
.
import { displayable } from 'culori';
displayable('red');
// ⇒ true
displayable('color(srgb 1.1 0 0)');
// ⇒ false
# clampRgb(color or string) → color
Obtains a displayable version of the color by clamping the r
, g
, b
channel values of the color's RGB representation to the interval [0, 1]
. The returned color is in the same color space as the original color.
This is the faster, simpler, way to make a color displayable. It's what browsers do when you use a CSS color whose channels exceed the gamut. For example, rgb(300 100 200)
is interpreted as rgb(255 100 200)
.
Because clamping individual red, green, and blue values independently can alter their proportions in the final color, it often changes the color's hue.
import { clampRgb } from 'culori';
// RGB clamping:
clampRgb('lab(50% 100 100)');
// ⇒ { mode: "lab", l: 54.29…, a: 80.81…, b: 69.88… }
# clampGamut(mode = 'rgb') → function(color | string)
This function extends the functionality of clampRgb
to other color spaces. Given a color space, it returns a function with which to obtain colors within the gamut of that color space.
If the color space has no gamut limits, colors are returned unchanged. To find out which color spaces have gamut limits, see the Color Spaces page.
The in-gamut color is always returned in the color space of the original color.
import { formatCss, clampGamut } from 'culori';
const crimson = 'color(display-p3 0.8 0.1 0.3)';
const toRgb = clampGamut('rgb');
formatCss(toRgb(crimson));
// ⇒ 'color(display-p3 0.801… 0.169… 0.302…)'
# clampChroma(color or string, mode = 'lch', rgbGamut = 'rgb') → color
Obtains a displayable version of the color by converting it to a temporary color space containing a Chroma channel, then looking for the closest Chroma value that's displayable for the given Lightness and Hue. Compared to clampRgb
, the function has the advantage of preserving the hue of the original color. The displayable color returned by this function will be converted back to the original color space.
import { clampChroma } from 'culori';
clampChroma('lab(50% 100 100)');
// ⇒ { mode: 'lab', l:50.00…, a: 63.11…, b: 63.11… }
By default, the color is converted to lch
to perform the clamping, but any color space that contains a Chroma dimension can be used by sending an explicit mode
argument.
Likewise, the destination RGB gamut can be overriden with the corresponding parameter.
import { clampChroma } from 'culori';
clampChroma({ mode: 'oklch', l: 0.5, c: 0.16, h: 180 }, 'oklch');
// ⇒ { mode: 'oklch', l: 0.5, c: 0.09, h: 180 }
In general, chroma clamping is more accurate and computationally simpler when performed in the color's original space, where possible. Here's some sample code that uses the color's own mode
for color spaces containing a Chroma dimension, and lch
otherwise:
import { clampChroma } from 'culori';
clampChroma(color, color.c !== undefined ? color.mode : 'lch');
If the chroma-finding algorithm fails to find a displayable color (which can happen when not even the achromatic version, with Chroma = 0
, is displayable), the method falls back to the clampRgb
method, as a last resort.
The function uses the bisection method to speed up the search for the largest Chroma value. However, due to discontinuities in the CIELCh color space, the function is not guaranteed to return the optimal result. See this discussion for details.
# toGamut(dest = 'rgb', mode = 'oklch', delta = differenceEuclidean('oklch'), jnd = 0.02) → function (color | string)
Obtain a color that's in the dest
gamut, by first converting it to the mode
color space and then finding the largest chroma that's in gamut, similar to clampChroma()
.
The color returned is in the dest
color space.
import { p3, toGamut } from 'culori';
const color = 'lch(80% 150 60)';
p3(color);
// ⇒ { mode: "p3", r: 1.229…, g: 0.547…, b: -0.073… }
const toP3 = toGamut('p3');
toP3(color);
// ⇒ { mode: "p3", r: 0.999…, g: 0.696…, b: 0.508… }
To address the shortcomings of clampChroma
, which can sometimes produce colors more desaturated than necessary, the test used in the binary search is replaced with “is color is roughly in gamut”, by comparing the candidate to the clipped version (obtained with clampGamut
). The test passes if the colors are not to dissimilar, judged by the delta
color difference function and an associated jnd
just-noticeable difference value.
The default arguments for this function correspond to the gamut mapping algorithm defined in the CSS Color Module Level 4 spec, but the algorithm itself is slightly different.
The “roughly in gamut” aspect of the algorithm can be disabled by passing null
for the delta
color difference function:
import { toGamut } from 'culori';
const clampToP3 = toGamut('p3', 'oklch', null);
Interpolation
In any color space, colors occupy positions given by their values for each channel. Interpolating colors means tracing a line through the coordinates of these colors, and figuring out what colors reside on the line at various positions.
Above is the path between red and blue in the RGB color space. Going from left to right, we start at red and steadily blend in more and more blue as we progress, until the color is fully blue at destination. This is a linear interpolation between two colors.
# interpolate(colors, mode = "rgb", overrides)
☞ src/interpolate/interpolate.js
Returns an interpolator in the mode color space for an array of colors. The interpolator is a function that accepts a value t in the interval [0, 1]
and returns the interpolated color in the mode color space.
The colors in the array can be in any color space, or they can even be strings.
import { interpolate } from 'culori';
let grays = interpolate(['#fff', '#000']);
grays(0.5);
// ⇒ { mode: 'rgb', r: 0.5, g: 0.5, b: 0.5 }
By default, colors in all spaces are interpolated linearly across all channels. You can override the way specific channels are interpolated with the overrides object, the third argument of interpolate()
.
import { interpolate, interpolatorSplineBasis } from 'culori';
let my_interpolator = interpolate(['blue', 'red'], 'lch', {
// spline instead of linear interpolation:
h: interpolatorSplineBasis
});
There are a few interpolation methods available, listed below. Depending on the channel, the numeric values can be interpreted/interpolated in various modes. The hue channel, for example, is interpolated by taking into account the shortest path around the hue circle (fixupHue
). And the fixupAlpha
mode assumes an undefined alpha is 1
.
Color stop positions
You can specify positions of color stops to interpolate in the way they're defined in the CSS Images Module Level 4 specification:
import { interpolate } from 'culori';
interpolate(['red', ['green', 0.25], 'blue']);
In the image below, you can see the effect of interpolating with evenly-spaced colors (1) vs. positioned colors stops (2):
To specify a positioned color stop, use an array that contains the color followed by its position. The color stops should be specified in ascending order.
For omitted (implicit) positions, we apply the rules from the spec:
- if the first color doesn't have a position, it's assumed to be
0
; if the last color doesn't have a position, it's assumed to be1
; - any other color stops that don't have a position will be evenly distributed along the gradient line between the positioned color stops.
Easing functions
You can add easing functions between any two colors in the array:
import { interpolate } from 'culori';
const easeIn = t => t * t;
interpolate(['red', easeIn, 'green']);
Any function in the colors array will be interpreted as an easing function, which is (for our purposes), a function that takes an argument t ∈ [0, 1]
and returns a value v ∈ [0, 1]
.
To apply the same easing function between all color pairs, instead of individual ones, add the easing as the first element in the array:
import { interpolate } from 'culori';
const easeIn = t => t * t;
// this form:
interpolate([easeIn, 'red', 'green', 'blue']);
// is equivalent to:
interpolate(['red', easeIn, 'green', easeIn, 'blue']);
The easing function can alternatively be applied the hard way:
import { interpolate, interpolatorPiecewise, lerp } from 'culori';
const easeIn = t => t * t;
interpolate(
['red', 'green', 'blue'],
'rgb',
interpolatorPiecewise((a, b, t) => lerp(a, b)(easeIn(t)))
);
This formula can be helpful if you wanted to apply a different easing function per channel:
import { interpolate, interpolatorPiecewise, lerp } from 'culori';
function piecewiseEasing(easingFn) {
return interpolatorPiecewise((a, b, t) => lerp(a, b)(easingFn(t)));
}
interpolate(['red', 'green', 'blue'], 'rgb', {
r: piecewiseEasing(easeIn),
g: piecewiseEasing(easeOut),
b: piecewiseEasing(easeInOut)
});
Culori comes with just a few easing functions, but you can find several online:
- some classic easing functions;
- eases by Matt DesLauriers;
- bezier-easing by Gaëtan Renaudeau builds
cubic-bezier
easings as defined in the CSS Easing Functions Level 1 spec; - d3-scale lets you set the scale's domain and range to
[0, 1]
.
Interpolation hints
Any number in the colors array will be interpreted as an interpolation hint:
import { interpolate } from 'culori';
// interpolation hint:
interpolate(['red', 0.25, 'green']);
As opposed to how current browsers implement the CSS spec (see discussion), interpolation hints do not affect color stop positions in Culori.
Built-in easing functions
# easingMidpoint(H = 0.5)
Proposed here, the midpoint
easing function lets you shift the midpoint of a gradient like in tools such as Adobe Photoshop. You can use it with interpolate()
as an alternative to interpolation hints:
import { interpolate, easingMidpoint } from 'culori';
// Explicit midpoint easing:
interpolate(['red', easingMidpoint(0.25), 'blue']);
// ...is equivalent to:
interpolate(['red', 0.25, 'blue']);
# easingSmoothstep
The Smoothstep easing function.
# easingSmoothstep
The inverse of the Smoothstep easing function.
# easingSmootherstep
Smootherstep is a variant of the Smoothstep easing function.
# easingInOutSine
Sinusoidal in-out easing. Can be used to create, for example, a cosine interpolation as described by Paul Bourke:
import { interpolate, easingInOutSine } from 'culori';
interpolate([easingInOutSine, 'red', 'green', 'blue']);
# easingGamma(γ = 1) → function(t)
The gamma easing.
import { samples, easingGamma } from 'culori';
samples(5).map(easingGamma(2));
// ⇒ [0, 0.0625, 0.25, 0.5625, 1]
Interpolation methods
You'll use these methods when you want to override how colors get interpolated in a specific color space, or when defining the default interpolation for custom color spaces.
# interpolatorLinear(values)
A linear interpolator for values in a channel.
Basis splines
Basis splines (also called B-splines) are available in the following variants:
# interpolatorSplineBasis(values)
☞ src/interpolate/splineBasis.js
A basis spline which uses one-sided finite differences for the slopes at the boundaries.
# interpolatorSplineBasisClosed(values)
☞ src/interpolate/splineBasis.js
A basis spline which considers the values array to be periodic.
Natural splines
Natural interpolating splines are related to basis splines, as explained in this handout by Kirby A. Baker (sections 4 and 5).
# interpolatorSplineNatural(values)
☞ src/interpolate/splineNatural.js
A natural spline which uses one-sided finite differences for the slopes at the boundaries.
# interpolatorSplineNaturalClosed(values)
☞ src/interpolate/splineNatural.js
A natural spline which considers the values array to be periodic.
Monotone splines
The monotone splines are based on the following paper (via d3-shape):
Steffen, M. "A simple method for monotonic interpolation in one dimension." in Astronomy and Astrophysics, Vol. 239, p. 443-450 (Nov. 1990), Provided by the SAO/NASA Astrophysics Data System.
The following variants are available:
# interpolatorSplineMonotone(values)
☞ src/interpolate/splineMonotone.js
A monotone spline that uses one-sided finite differences to find the slopes at the boundaries.
# interpolatorSplineMonotone2(values)
☞ src/interpolate/splineMonotone.js
A monotone spline for which we derive the slopes at the boundaries by tracing a parabola through the first/last three values.
# interpolatorSplineMonotoneClosed(values)
☞ src/interpolate/splineMonotone.js
A monotone spline which considers the values array to be periodic.
Custom piecewise interpolation
# interpolatorPiecewise(interpolator) src/interpolate/piecewise.js
Use a custom piecewise interpolator function in the form function (a, b, t) => value
:
import { interpolate, interpolatorPiecewise } from 'culori';
let linear = (a, b, t) => (1 - t) * a + t * b;
interpolate(['red', 'green'], interpolatorPiecewise(linear));
When one of the two values to be interpolated is undefined, it will mirror the defined value: [undefined, b]
becomes [b, b]
. If both values are undefined, they are left as-is.
The interpolatorLinear()
function uses interpolatorPiecewise()
under the hood.
Interpolation Fixup
By default, channel values that need to be interpolated are treated as normal numbers. However, for some channels, the values hold special singificance and can be fixed up before interpolation for better results.
Hue fixup
Hue is a circular value, so there are two directions in which to interpolate between two hues (clockwise and anti-clockwise). The functions below take an array of hues and adjusts them to impose a certain interpolation direction while maintaining the absolute difference between consecutive hues.
Adjusted hues will not necessarily be in the [0, 360)
interval. All fixup methods leave undefined values, and the values immediately following them, unaltered. The names of the methods come from this discussion.
# fixupHueShorter(values) → Array
Adjusts the hues so that values are interpolated along the shortest path around the hue circle.
This is the default in all built-in color spaces using a hue channel. Below is an extract from the definition of the HSL color space:
/* --- hsl/definition.js --- */
export default {
// ...
interpolate: {
h: {
use: interpolatorLinear,
fixup: fixupHueShorter
},
s: interpolatorLinear,
l: interpolatorLinear,
alpha: {
use: interpolatorLinear,
fixup: fixupAlpha
}
}
// ...
};
To omit the fixup and treat hues as normal numbers, use a custom interpolation on the h
channel, and overwrite the fixup
function with an identity function:
import { interpolate } from 'culori';
let hsl_long = interpolate(['blue', 'red', 'green'], 'hsl', {
h: {
fixup: arr => arr
}
});
Treating the hues array as-is (with an identity function) corresponds to the specified
fixup method in the CSSWG issue mentioned earlier.
# fixupHueLonger(values) → Array
Adjusts the hues so that they are interpolated along the longest path around the hue circle.
# fixupHueIncreasing(values) → Array
Adjusts the hues so that every hue is larger than the previous.
# fixupHueDecreasing(values) → Array
Adjusts the hues so that every hue is smaller than the previous.
Alpha fixup
# fixupAlpha(values) → Array
Turns all undefined
values in the array to 1
(full opacity), unless all values in the array are undefined
, in which case it leaves the values unaltered.
This is the default method for the alpha channel in all built-in color spaces.
Evenly-spaced samples
# samples(n = 2)
Returns an array of n equally-spaced samples in the [0, 1]
range, with 0
and 1
at the ends.
import { samples } from 'culori';
samples(3);
// ⇒ [0, 0.5, 1]
samples(5);
// ⇒ [0, 0.25, 0.5, 0.75, 1]
The samples are useful for interpolate()
to generate color scales:
import { samples, interpolate, formatHex } from 'culori';
let grays = interpolate(['#fff', '#000']);
samples(5).map(grays).map(formatHex);
// ⇒ ["#ffffff", "#bfbfbf", "#808080", "#404040", "#000000"]
As with the interpolate()
method, you can map the samples through an easing function or scale to obtain a different distribution of the samples.
import { samples } from 'culori';
import easing from 'bezier-easing';
// Bezier easing:
let bezier = easing(0, 0, 1, 0.5);
samples(10).map(bezier);
// easeInQuad:
samples(10).map(t => t * t);
Lerp
# lerp(a, b, t) → value
Interpolates between the values a
and b
at the point t ∈ [0, 1]
.
import { lerp } from 'culori';
lerp(5, 10, 0.5);
// ⇒ 7.5
# unlerp(a, b, v) → value
Returns the point t
at which the value v
is located between the values a
and b
. The inverse of lerp
.
# blerp(a00, a01, a10, a11, tx, ty) → value
Perform the bilinear interpolation of the four values a00
, a01
, a10
, and a11
at the point (tx, ty)
, with tx, ty ∈ [0, 1]
. This is the extension of lerp
to two dimensions.
# trilerp(a000, a010, a100, a110, a001, a011, a101, a111, tx, ty, tz) → value
Perform the trilinear interpolation of the eight values a000
, a010
, a100
, a110
, a001
, a011
, a101
, and a111
at the point (tx, ty, tz)
, with tx, ty, tz ∈ [0, 1]
. This is the extension of lerp
to three dimensions.
Mappings
# mapper(fn, mode = "rgb") → function (color | string)
Creates a mapping that applies fn on each channel of the color in the mode color space.
The resulting function accepts a single argument (a color object or a string), which it converts to the mode color space if necessary.
The mode parameter can be set to null
, in which case the mapper will iterate through the channels in the color's original color space.
The fn callback has the following signature:
fn(value, channel, color, mode)
where:
value
is the current value;channel
is the current channel;color
is a reference to the entire color object;mode
is forwarded from the call tomapper
.
Here's the implementation of alpha premultiplication:
import { mapper } from 'culori';
const multiplyAlpha = mapper((val, ch, color) => {
if (ch !== 'alpha') {
return (val || 0) / (color.alpha !== undefined ? color.alpha : 1);
}
return val;
}, 'rgb');
multiplyAlpha({ r: 1, g: 0.6, b: 0.4, a: 0.5 });
// ⇒ { mode: 'rgb', r: 0.5, g: 0.3, b: 0.2, a: 0.5 }
All channels, including alpha
, are included in the mapping. You may want to handle the alpha
channel differently in the callback function, like in the example above.
Returning undefined
or NaN
from the callback function will omit that channel from the resulting color object.
Built-in mappings
# mapAlphaMultiply
Multiplies the color's alpha value into all its other channels:
import { mapper, mapAlphaMultiply } from 'culori';
let multiplyAlpha = mapper(mapAlphaMultiply, 'rgb');
multiplyAlpha({ r: 1, g: 0.6, b: 0.4, a: 0.5 });
// ⇒ { mode: 'rgb', r: 0.5, g: 0.3, b: 0.2, a: 0.5 }
Any undefined
channel value will be considered to be 0
(zero), to enable alpha-premultiplied interpolation with achromatic colors in hue-based color spaces (HSL, LCh, etc.).
# mapAlphaDivide
Divides a color's other channels by its alpha value. It's the opposite of mapAlphaMultiply
, and is used in interpolation with alpha premultiplication:
import { mapper, mapAlphaMultiply, mapAlphaDivide } from 'culori';
let multiplyAlpha = mapper(mapAlphaMultiply, 'rgb');
let divideAlpha = mapper(mapAlphaDivide, 'rgb');
divideAlpha(multiplyAlpha({ r: 1, g: 0.6, b: 0.4, a: 0.5 }));
// ⇒ { mode: 'rgb', r: 1, g: 0.6, b: 0.4, a: 0.5 }
Any undefined
channel value will be considered to be 0
(zero), to enable alpha-premultiplied interpolation with achromatic colors in hue-based color spaces (HSL, LCh, etc.).
# mapTransferLinear(slope = 1, intercept = 0)
# mapTransferGamma(amplitude = 1, exponent = 1, offset = 0)
Interpolating with mappings
# interpolateWith(premap, postmap)
Adds a pre-mapping and a post-mapping to an interpolation, to enable things like alpha premultiplication:
import { interpolateWith, mapAlphaMultiply, mapAlphaDivide } from 'culori';
let interpolateWithAlphaPremult = interpolateWith(
mapAlphaMultiply,
mapAlphaDivide
);
interpolateWithAlphaPremult(['red', 'transparent', 'blue'])(0.25);
To chain more than one mapping:
import { interpolateWith, mapAlphaMultiply, mapAlphaDivide } from 'culori';
const mapChromaMultiply = (v, ch, c, mode) => {
// ...
};
const mapChromaDivide = (v, ch, c, mode) => {
// ...
};
let interpolateWithAlphaChromaPremult = interpolateWith(
(...args) => mapChromaMultiply(mapAlphaMultiply(...args)),
(...args) => mapAlphaDivide(mapChromaDivide(...args))
);
interpolateWithAlphaPremult(['red', 'transparent', 'blue'])(0.25);
# interpolateWithPremultipliedAlpha(colors, mode = "rgb", overrides)
Takes the same arguments as interpolate()
, but applies alpha premultiplication.
import { interpolate, interpolateWithPremultipliedAlpha } from 'culori';
let colors = ['red', 'transparent', 'blue'];
// alpha ignored for the R/G/B channels:
interpolate(colors, 'rgb');
// alpha premultiplied into the R/G/B channels:
interpolateWithPremultipliedAlpha(colors, 'rgb');
Color Difference
These methods are concerned to finding the distance between two colors based on various formulas. Each of these formulas will return a function (colorA, colorB) that lets you measure the distance between two colors.
Euclidean distance
# differenceEuclidean(mode = 'rgb', weights = [1, 1, 1, 0])
Returns a Euclidean distance function in a certain color space.
You can optionally assign different weights to the channels in the color space. See, for example, the Kotsarenko/Ramos distance or ΔEITP.
The default weights [1, 1, 1, 0]
mean that the alpha, which is the fourth channel in all the color spaces Culori defines, is not taken into account. Send [1, 1, 1, 1]
as the weights to include it in the computation.
In cylindrical spaces, the hue is factored into the Euclidean distance in a variety of ways. The functions below are used internally:
# differenceHueChroma(colorA, colorB)
Computes the hue contribution as the geometric mean of chord lengths belonging to the chromas of the two colors. This is the handling of hue in cylindrical forms of CIE-related color spaces: lch
, lchuv
, dlch
, oklch
, jch
.
# differenceHueSaturation(colorA, colorB)
Computes the hue contribution as the geometric mean of chord lengths belonging to the saturations of the two colors. This is the handling of hue in the HSL / HSV / HSI family of color spaces.
# differenceHueNaive(colorA, colorB)
For remaining color spaces (HWB), we consider hues numbers, but apply a shortest path around the hue circle (analogous to fixupHueShorter
). If you insist on using Euclidean distances on these spaces, you can use the weights
to control the contribution of the hue difference towards the total difference.
CIE color difference formulas
All these color difference functions operate on the lab65
color space.
# differenceCie76()
Computes the CIE76 ΔE*ab color difference between the colors a and b. The function is identical to differenceEuclidean('lab65')
.
# differenceCie94(kL = 1, K1 = 0.045, K2 = 0.015)
Computes the CIE94 ΔE*94 color difference between the colors a and b.
# differenceCiede2000(Kl = 1, Kc = 1, Kh = 1)
Computes the CIEDE2000 ΔE*00 color difference between the colors a and b as implemented by G. Sharma.
# differenceCmc()
Computes the CMC l:c (1984) ΔE*CMC color difference between the colors a and b.
ΔE*CMC is not considered a metric since it's not symmetrical, that is the distance from a to b is not always equal to the distance from b to a. Therefore it cannot be reliably used with nearest()
.
# differenceHyab()
Computes the HyAB color difference between the colors a and b, as proposed in:
Abasi S, Amani Tehran M, Fairchild MD. Distance metrics for very large color differences. Color Res Appl. 2019; 1–16. https://doi.org/10.1002/col.22451 (PDF)
The HyAB formula combines the Euclidean and city block distance and has been experimentally shown to work better for large color differences than CIEDE2000, while still holding up well for smaller color differences, making it a "good candidate formula for image processing and computer vision applications".
Other difference formulas
# differenceKotsarenkoRamos()
Computes the Kotsarenko/Ramos color difference between the colors a and b. This is a weighted Euclidean distance in the yiq
color space.
# differenceItp()
Computes the ΔEITP color difference metric between the colors a and b. This is a weighted Euclidean distance in the itp
color space, scaled by a factor of 720 so that a the just-noticeable difference (JND) corresponds to a value of 1.
Nearest color(s)
# nearest(colors, metric = differenceEuclidean(), accessor = identity) → function(color, n = 1, τ = Infinity)
Takes a colors array and a metric color difference formula, and returns a function with which you can find n colors nearest to color, with a maximum distance of τ. Use n = Infinity to get all colors in the array with a maximum distance of τ.
/*
Example: get three CSS named colors closest to any color
*/
import { colorsNamed, nearest, differenceCiede2000 } from 'culori';
let colors = Object.keys(colorsNamed);
let nearestNamedColors = nearest(colors, differenceCiede2000());
nearestNamedColors('lch(50% 70 60)', 3);
// => ["chocolate", "sienna", "peru"]
By default, colors needs to be an array of color values. If your array contains something other than a simple color value, you can provide the accessor
argument to point to the color value associated with each item in the array.
The example below shows a common data structure for a color palette: an object whose keys are the names and whose values are their associated color representations.
import { nearest, differenceEuclidean } from 'culori';
/*
Example: get the closest color from a palette
*/
let palette = {
Burgundy: '#914e72',
Blue: '#0078bf',
Green: '#00a95c',
'Medium Blue': '#3255a4',
'Bright Red': '#f15060'
};
let names = Object.keys(palette);
let nearestColors = nearest(
names,
differenceEuclidean(),
name => palette[name]
);
nearestColors('red', 1);
// => ["Bright Red"]
Blending
Culori makes available the separable blend modes defined in the W3C Compositing and Blending Level 2 specification.
# blend(colors, type = 'normal', mode = 'rgb') → color
A separable blend mode is a simple formula that gets applied to each channel in the color space independently. The available blend modes are color-burn
, color-dodge
, darken
, difference
, exclusion
, hard-light
, lighten
, multiply
, normal
, overlay
, screen
, and soft-light
. They are designed to work on RGB colors, so mode is expected to be rgb
or lrgb
.
An example of blending three colors:
import { blend } from 'culori';
blend(
['rgba(255, 0, 0, 0.5)', 'rgba(0, 255, 0, 0.5)', 'rgba(0, 0, 255, 0.5)'],
'screen'
);
// ⇒ { mode: 'rgb', alpha: 0.875, r: 0.57…, g: 0.57…, b:0.57… }
In addition to strings, the type parameter supports a function (b, s) → v that takes the values of the backdrop and source color to return the blended value. This allows you to write your own (separable) blending functions. For example, an average blending mode:
import { blend } from 'culori';
blend(['red', 'green'], function average(b, s) {
return (b + s) / 2;
});
The non-separable blend modes — color
, hue
, saturation
, and lightness
— are not available. The effect which they mean to produce is better obtained with simple formulas on a cylindrical color space (e.g. HSL).
Average color
# average(colors, mode = 'rgb', overrides)
Returns the average color of the colors array, in the color space specified by the mode argument. The color is obtained by the arithmetic average of values on each individual channel.
Colors with undefined values on a channel don't participate in the average for that channel.
import { average } from 'culori';
average(['salmon', 'tomato'], 'lab');
// ⇒ { 'mode': 'lab', l: 65.41…, a: 53.00…, b: 39.01… }
# averageNumber(values)
The arithmetic mean of values in the values array.
# averageAngle(values)
The function used by default to average hue values in all built-in color spaces, using the formula for the mean of circular quantities.
Random colors
# random(mode = 'rgb', constraints = {})
Obtain a random color from a particular color space, with optional constraints. The resulting color will be in the color space from where it has been picked.
Basic usage:
import { random } from 'culori';
random();
// ⇒ { mode: 'rgb', r: 0.75, g: 0.12, b: 0.99 }
Specifying constraints
Random colors are, by definition, all over the color space and not all of them will look particularly nice. Some color spaces, such as HSL or HSV, are also biased towards colors close to black and/or white, because of the way these color spaces stretch the RGB cube into cylinders.
For more control on how the colors are generated, you can specify constraints for each individual channel in the color space. Constraints can be either a constant number or an interval from where to pick the channel value:
import { random } from 'culori';
random('hsv', {
h: 120, // number
s: [0.25, 0.75] // interval
});
// ⇒ { mode: 'hsv', h: 120, s: 0.51…, v: 0.89… }
The alpha channel is excluded by default. To obtain colors with random alpha values, include a constraint for alpha
:
import { random } from 'culori';
random('lrgb');
// ⇒ { mode: 'lrgb', r: 0.74…, g: 0.15…, b: 0.34… }
random('lrgb', { alpha: [0, 1] });
// ⇒ { mode: 'lrgb', r: 0.33…, g: 0.72…, b: 0.04…, alpha: 0.12… }
Displayable random colors
The value for any channel in the color space for which there are no constraints will be picked from the entire range of that channel. However, some color spaces, such as CIELAB or CIELCH, don't have explicit ranges for certain channels; for these, some approximate ranges have been pre-computed as the limits of the displayable sRGB gamut.
Even with these ranges in place, a combination of channel values may not be displayable. Check if that's the case with displayable()
, and pass the color through a clamp*
function to obtain a displayable version.
WCAG utilities
A couple of utility functions based on the Web Content Acccessibility Guidelines 2.0 specification.
# wcagLuminance(color)
Computes the relative luminance of a color.
import { wcagLuminance } from 'culori';
wcagLuminance('red');
// ⇒ 0.2126
# wcagContrast(colorA, colorB)
Computes the contrast ratio between two colors.
import { wcagContrast } from 'culori';
wcagContrast('red', 'black');
// ⇒ 5.252
Filters
Filters apply certain graphical effects to a color. Culori currently implements two sets of filter functions:
CSS Filter Effects
These correspond to the filter effects defined in the W3C Filter Effects Module Level 1 specification.
The amount parameter is usually in the [0, 1]
interval, but may go above 1
for some filters. The filters were designed for RGB colors, so the mode parameter is expected to be rgb
or lrgb
.
The resulting color is returned in the color space of the original color.
# filterBrightness(amount = 1, mode = 'rgb')
The brightness()
CSS filter. An amount of 1
leaves the color unchanged. Smaller values darken the color (with 0
being fully black), while larger values brighten it.
import { filterBrightness } from 'culori';
let brighten = filterBrightness(2, 'lrgb');
brighten('salmon');
// ⇒ { mode: 'rgb', r: 1.32…, g: 0.68…, b: 0.61… }
# filterContrast(amount = 1, mode = 'rgb')
The contrast()
filter. An amount of 1
leaves the color unchanged. Smaller values decrease the contrast (with 0
being fully gray), while larger values increase it.
# filterSepia(amount = 1, mode = 'rgb')
The sepia()
filter. An amount of 0
leaves the color unchanged, and 1
applies the sepia effect fully.
# filterGrayscale(amount = 1, mode = 'rgb')
The grayscale()
filter. An amount of 0
leaves the color unchanged, and 1
makes the color fully achromatic.
# filterSaturate(amount = 1, mode = 'rgb')
The saturate()
filter. An amount of 1
leaves the color unchanged. Smaller values desaturate the color (with 0
being fully achromatic), while larger values saturate it.
# filterInvert(amount = 1, mode = 'rgb')
The invert()
filter. An amount of 0
leaves the color unchanged, and 1
makes the color fully inverted.
# filterHueRotate(degrees = 0, mode = 'rgb')
The hue-rotate()
filter.
import { samples, interpolate, filterSepia, formatHex } from 'culori';
samples(5)
.map(interpolate(['red', 'green', 'blue']))
.map(filterSepia(0.5))
.map(formatHex);
// ⇒ ["#751800", "#664200", "#576c00", "#1a3e82", "#0010ff"];
Some of the effects may be obtained more straightforwardly with simple calculations in other color spaces. For example, hue rotation can just as well be implemented as color.h += angle
in a cylindrical color space such as HSL.
Color vision deficiency (CVD) simulation
Simulate how a color may be perceived by people with color vision deficiencies (CVD).
# filterDeficiencyProt(severity = 1) → function (color)
Simulate protanomaly and protanopia. The severity
parameter is in the interval [0, 1]
, where 0
corresponds to normal vision and 1
(the default value) corresponds to protanopia.
# filterDeficiencyDeuter(severity = 1) → function (color)
Simulate deuteranomaly and deuteranopia. The severity
parameter is in the interval [0, 1]
, where 0
corresponds to normal vision and 1
(the default value) corresponds to deuteranopia.
# filterDeficiencyTrit(severity = 1) → function (color)
Simuate tritanomaly and tritanopia. The severity
parameter is in the interval [0, 1]
, where 0
corresponds to normal vision and 1
(the default value) corresponds to tritanopia.
Examples:
import { interpolate, filterDeficiencyProt, formatHex } from 'culori';
culori
.samples(5)
.map(interpolate(['red', 'green', 'blue']))
.map(filterDeficiencyProt(0.5))
.map(formatHex);
// ⇒ ["#751800", "#664200", "#576c00", "#1a3e82", "#0010ff"];
Based on the work of Machado, Oliveira and Fernandes (2009), using precomputed matrices provided by the authors. References thanks to the colorspace
package for R.
G. M. Machado, M. M. Oliveira and L. A. F. Fernandes, "A Physiologically-based Model for Simulation of Color Vision Deficiency," in IEEE Transactions on Visualization and Computer Graphics, vol. 15, no. 6, pp. 1291-1298, Nov.-Dec. 2009, doi: 10.1109/TVCG.2009.113.
Miscellaneous
# colorsNamed
An object whose keys are all the CSS named colors.
# round(n = 8)
Returns a rounder: a function with which to round numbers to at most n digits of precision.
import { round } from 'culori';
let approx = round(4);
approx(0.38393993);
// ⇒ 0.3839
# Available color spaces
The default import (culori
) comes with all the color spaces pre-registered into the library. For convenience, you can also import directly mode
as a shortcut to converter(mode)
. For example, instead of converter('hsl')
, you can import hsl
:
// Instead of this:
import { converter } from 'culori';
const hsl = converter('hsl');
// You can do this:
import { hsl } from 'culori';
On the other hand, when importing the tree-shaken version (culori/fn
), color spaces need to be registered manually with useMode()
based on their definition object:
import { useMode, modeHsl } from 'culori/fn';
const hsl = useMode(modeHsl);
The table below summarizes two pieces of information:
- What the
mode
is for a specific color space built into Culori, which is also the name of the shortcut to the converter for that color space. - What the definition object for a color space is called.
The available color spaces are discussed into more detail on the Color Spaces page.
Mode | Color space | Definition object |
---|---|---|
a98 |
A98 RGB color space, compatible with Adobe RGB (1998) | modeA98 |
cubehelix |
Cubehelix color space | modeCubehelix |
dlab |
DIN99o Lab color space | modeDlab |
dlch |
DIN99o LCh color space | modeDlch |
hsi |
HSI color space | modeHsi |
hsl |
HSL color space | modeHsl |
hsv |
HSV color space | modeHsv |
hwb |
HWB color space | modeHwb |
itp |
ICtCp color space | modeItp |
jab |
Jzazbz color space | modeJab |
jch |
Jzazbz in cylindrical form | modeJch |
lab |
CIELAB color space (D50 Illuminant) | modeLab |
lab65 |
CIELAB color space (D65 Illuminant) | modeLab65 |
lch |
CIELCh color space (D50 Illuminant) | modeLch |
lch65 |
CIELCh color space (D65 Illuminant) | modeLch65 |
lchuv |
CIELCHuv color space (D50 Illuminant) | modeLchuv |
lrgb |
Linear-light sRGB color space | modeLrgb |
luv |
CIELUV color space (D50 Illuminant) | modeLuv |
oklab |
Oklab color space | modeOklab |
oklch |
Oklab color space, cylindrical form | modeOklch |
p3 |
Display P3 color space | modeP3 |
prophoto |
ProPhoto RGB color space | modeProphoto |
rec2020 |
Rec. 2020 RGB color space | modeRec2020 |
rgb |
sRGB color space | modeRgb |
xyb |
XYB color space | modeXyb |
xyz50 |
XYZ with D50 white-point | modeXyz50 |
xyz65 |
XYZ with D65 white-point | modeXyz65 |
yiq |
YIQ color space | modeYiq |
Extending culori
# useMode(definition) → function.
Defines a new color space based on its definition. See Color mode definition for the expected object shape.
Returns a converter function for the newly defined mode.
import { useMode } from 'culori';
const hsl = useMode({
mode: 'hsl'
// ...
});
hsl('hsl(50 100% 100% / 100)');
# getMode(mode)
Returns the definition object for the mode color space.
# Color mode definition
The properties a definition needs are the following:
mode
(string)
The string identifier for the color space.
channels
(array)
A list of channels for the color space.
toMode
(object)
A set of functions to convert from the color space we're defining to other color spaces. At least rgb
needs to be included; in case a specific conversion pair between two color spaces is missing, RGB is used as the "buffer" for the conversion.
fromMode
(object)
The opposite of toMode
. A set of function to convert from various color spaces to the color space we're defining. At least rgb
needs to be included.
ranges
(object, optional)
The reference ranges for values in specific channels; if left unspecified, defaults to [0, 1]
.
parse
(array, optional)
Any parsers for the color space that can transform strings into colors. These can be either functions, or strings — the latter is used as the color space's identifier to parse the color(<ident>)
CSS syntax.
serialize
(function or string, optional)
Defines how to serialize the color space to a CSS string with formatCss()
.
If you pass in a function, it receives a color object as its only argument, and should return a string that can be used in CSS. If you pass in a string, it's used as a color profile identifier, and the color is serialized using the color()
CSS syntax. When omitted altogether, the default color profile identifier is --${mode}
.
interpolate
The default interpolations for the color space, one for each channel. Each interpolation is defined by its interpolator (the use
key) and its fixup function (the fixup
key). When defined as a function, a channel interpolation is meant to define its interpolator, with the fixup being a no-op.
difference
The default Euclidean distance method for each channel in the color space; mostly used for the h
channel in cylindrical color spaces.
average
The default average function for each channel in the color space; when left unspecified, defaults to averageNumber
.
All built-in color spaces follow these conventions in regards to the channels
array follows:
- there are four channels in the color space;
- the fourth channel is always
alpha
.
This makes sure differenceEuclidean()
works as expected, but there may be more hidden assumptions in the codebase.
Here's a sample definition for the HSL color space:
{
mode: 'hsl',
fromMode: {
rgb: convertRgbToHsl
},
toMode: {
rgb: convertHslToRgb
},
channels: ['h', 's', 'l', 'alpha'],
ranges: {
h: [0, 360]
},
parse: [parseHsl],
serialize: serializeHsl,
interpolate: {
h: {
use: interpolatorLinear,
fixup: fixupHueShorter
},
s: interpolatorLinear,
l: interpolatorLinear,
alpha: {
use: interpolatorLinear,
fixup: fixupAlpha
}
},
difference: {
h: differenceHueSaturation
},
average: {
h: averageAngle
}
};
# useParser(parser, mode)
Register a new parser. The parser can be:
- a function, in which case the mode argument is not necessary.
- a string representing the identifier to match in the
color()
syntax, in which case the mode argument is required.
import { useParser } from 'culori';
// Register custom parser
useParser(function(str) => {
let color = {};
// parse the string
return color;
});
// Register `color(--oklab)` syntax
useParser('--oklab', 'oklab');
# removeParser(parser)
Remove a previously registered parser function or string, including parsers registered by default.
import { parse, parseNamed, removeParser } from 'culori';
parse('tomato');
// ⇒ Object { mode: "rgb", r: 1, g: 0.38823529411764707, b: 0.2784313725490196 }
removeParser(parseNamed);
parse('tomato');
// ⇒ undefined
# Low-level API
# Parsing functions
# parseHex(string) → color
Parses hex strings of 3, 4, 6, or 8 characters, with or without the #
prefix, and returns rgb
color objects.
import { parseHex } from 'culori';
parseHex('#abc');
parseHex('#abcd');
parseHex('#abcdef');
parseHex('#abcdef12');
# parseHsl(string) → color
Parses hsl(…)
strings in the modern format and returns hsl
color objects.
# parseHslLegacy(string) → color
Parses hsl(…)
/ hsla(…)
strings in the legacy (comma-separated) format and returns hsl
color objects.
# parseHwb(string) → color
Parses hwb(…)
strings and returns hwb
color objects.
# parseLab(string) → color
Parses lab(…)
strings and returns lab
color objects.
# parseLch(string) → color
Parses lch(…)
strings and returns lch
color objects.
# parseNamed(string) → color
Parses named CSS colors (eg. tomato
) and returns rgb
color objects.
# parseOklab(string) → color
Parses oklab(…)
strings and returns oklab
color objects.
# parseOklch(string) → color
Parses oklch(…)
strings and returns oklch
color objects.
# parseRgb(color) → color
Parses rgb(…)
strings in the modern syntax and returns rgb
color objects.
# parseRgbLegacy(color) → color
Parses rgb(…)
/ rgba(…)
strings in the legacy (comma-separated) syntax and returns rgb
color objects.
#parseTransparent(string) → color
Parses the transparent
string and returns a transparent black rgb
color object.
Serialization functions
#serializeHex(color)
Serialize a rgb
color to a 6-character hex code. See formatHex()
for details.
#serializeHex8(color)
Serialize a rgb
color to a 8-character hex code. See formatHex8()
for details.
#serializeHsl(color)
Serialize a hsl
color to a hsl(…)
string. See formatHsl()
for details.
#serializeRgb(color)
Serialize a rgb
color to a rgb(…)
string. See formatRgb()
for details.
Conversion functions
Function | Conversion |
---|---|
convertA98ToXyz65(color) → color | a98 → xyz65 |
convertCubehelixToRgb(color) → color | cubehelix → rgb |
convertDlchToLab65(color) → color | dlch → lab65 |
convertHsiToRgb(color) → color | hsi → rgb |
convertHslToRgb(color) → color | hsl → rgb |
convertHsvToRgb(color) → color | hsv → rgb |
convertHwbToRgb(color) → color | hwb → rgb |
convertJabToJch(color) → color | jab → jch |
convertJabToRgb(color) → color | jab → rgb |
convertJabToXyz65(color) → color | jab → xyz65 |
convertJchToJab(color) → color | jch → jab |
convertLab65ToDlch(color) → color | lab65 → dlch |
convertLab65ToRgb(color) → color | lab65 → rgb |
convertLab65ToXyz65(color) → color | lab65 → xyz65 |
convertLabToLch(color) → color | lab → lch |
convertLabToRgb(color) → color | lab → rgb |
convertLabToXyz50(color) → color | lab → xyz50 |
convertLchToLab(color) → color | lch → lab |
convertLchuvToLuv(color) → color | lchuv → luv |
convertLrgbToOklab(color) → color | lrgb → oklab |
convertLrgbToRgb(color) → color | lrgb → rgb |
convertLuvToLchuv(color) → color | luv → lchuv |
convertLuvToXyz50(color) → color | luv → xyz50 |
convertOkhslToOklab(color) → color | okhsl → oklab |
convertOkhsvToOklab(color) → color | okhsv → oklab |
convertOklabToLrgb(color) → color | oklab → lrgb |
convertOklabToOkhsl(color) → color | oklab → okhsl |
convertOklabToOkhsv(color) → color | oklab → okhsv |
convertOklabToRgb(color) → color | oklab → rgb |
convertP3ToXyz65(color) → color | p3 → xyz65 |
convertProphotoToXyz50(color) → color | prophoto → xyz50 |
convertRec2020ToXyz65(color) → color | rec2020 → xyz65 |
convertRgbToCubehelix(color) → color | rgb → cubehelix |
convertRgbToHsi(color) → color | rgb → hsi |
convertRgbToHsl(color) → color | rgb → hsl |
convertRgbToHsv(color) → color | rgb → hsv |
convertRgbToHwb(color) → color | rgb → hwb |
convertRgbToJab(color) → color | rgb → jab |
convertRgbToLab65(color) → color | rgb → lab65 |
convertRgbToLab(color) → color | rgb → lab |
convertRgbToLrgb(color) → color | rgb → lrgb |
convertRgbToOklab(color) → color | rgb → oklab |
convertRgbToXyb(color) → color | rgb → xyb |
convertRgbToXyz50(color) → color | rgb → xyz50 |
convertRgbToXyz65(color) → color | rgb → xyz65 |
convertRgbToYiq(color) → color | rgb → yiq |
convertXybToRgb(color) → color | xyb → rgb |
convertXyz50ToLab(color) → color | xyz50 → lab |
convertXyz50ToLuv(color) → color | xyz50 → luv |
convertXyz50ToProphoto(color) → color | xyz50 → prophoto |
convertXyz50ToRgb(color) → color | xyz50 → rgb |
convertXyz50ToXyz65(color) → color | xyz50 → xyz65 |
convertXyz65ToA98(color) → color | xyz65 → a98 |
convertXyz65ToJab(color) → color | xyz65 → jab |
convertXyz65ToLab65(color) → color | xyz65 → lab65 |
convertXyz65ToP3(color) → color | xyz65 → p3 |
convertXyz65ToRec2020(color) → color | xyz65 → rec2020 |
convertXyz65ToRgb(color) → color | xyz65 → rgb |
convertXyz65ToXyz50(color) → color | xyz65 → xyz50 |
convertYiqToRgb(color) → color | yiq → rgb |