Product
Introducing Ruby Support in Socket
Socket is launching Ruby support for all users. Enhance your Rails projects with AI-powered security scans for vulnerabilities and supply chain threats. Now in Beta!
The 'culori' npm package is a comprehensive color library for JavaScript that provides a wide range of functionalities for color manipulation, conversion, and analysis. It supports various color spaces and formats, making it a versatile tool for developers working with colors in web development, data visualization, and other applications.
Color Conversion
This feature allows you to convert colors between different color spaces. In the example, an RGB color is converted to the LAB color space.
const culori = require('culori');
const rgbColor = culori.rgb('#ff0000');
const labColor = culori.lab(rgbColor);
console.log(labColor);
Color Manipulation
This feature provides functions to manipulate colors, such as lightening or darkening them. The example demonstrates how to lighten an HSL color.
const culori = require('culori');
const color = culori.hsl({ h: 0, s: 1, l: 0.5 });
const lighterColor = culori.lighten(color, 0.2);
console.log(lighterColor);
Color Parsing
This feature allows you to parse color strings into color objects. The example shows how to parse a hex color string into an RGB color object.
const culori = require('culori');
const color = culori.parse('#ff0000');
console.log(color);
Color Interpolation
This feature enables color interpolation between two or more colors. The example demonstrates how to find a color that is halfway between red and blue.
const culori = require('culori');
const interpolate = culori.interpolate(['#ff0000', '#0000ff']);
const midColor = interpolate(0.5);
console.log(midColor);
Color Difference
This feature allows you to calculate the difference between two colors. The example shows how to compute the Euclidean difference between red and green colors.
const culori = require('culori');
const color1 = culori.rgb('#ff0000');
const color2 = culori.rgb('#00ff00');
const difference = culori.differenceEuclidean(color1, color2);
console.log(difference);
Chroma.js is another popular color library for JavaScript that provides similar functionalities for color manipulation, conversion, and analysis. It supports various color spaces and offers a rich set of features for working with colors. Compared to 'culori', Chroma.js has a more extensive API for color scales and palettes, making it particularly useful for data visualization.
The 'color' npm package is a versatile library for color conversion and manipulation. It supports a wide range of color spaces and provides methods for color transformations. While 'culori' focuses on a broader set of color spaces and more advanced color science features, 'color' is simpler and easier to use for basic color operations.
TinyColor2 is a lightweight color manipulation library that offers basic functionalities for color conversion, manipulation, and analysis. It is designed to be small and fast, making it suitable for performance-sensitive applications. Compared to 'culori', TinyColor2 has a more limited feature set but is easier to integrate into projects where minimal overhead is desired.
Culori is a general-purpose color library for JavaScript. It incorporates, and extends, ideas from Mike Bostock's D3.js and Gregor Aisch's chroma.js.
Color Spaces. Culori supports all the formats defined in the CSS Colors Level 4: Named colors, Hex colors (3 to 8 digits), RGB, HSL, HWB, Lab and LCh, and Grays. Additionally, the Linear RGB, HSV (also known as HSB), HSI, and Cubehelix color spaces are supported.
Color Differences. Culori can compute color differences with either a simple Euclidean distance or the CIELAB Delta E* metric as formulated by CIE76, CIE94, CIEDE2000 and CMC l:c (1984). They're also available as a D3 plugin. It can also find the closest N colors from a set of colors based on any of these differences.
⚠ Note: The API may change as we near the first stable release (1.0.0). Keep an eye on the CHANGELOG.
If you're thinking Do we really need another JavaScript color library?, I hear you. Reader, for the most part, we don't. Mike Bostock's d3-color, and Gregor Aisch's chroma.js are two robust libraries that provide most of what you need for working with colors on the web1. I'll admit culori2 is foremost a reflection of my own curiousity in understanding color spaces at a deeper level. But it also ended up a fairly fast, and fairly comprehensive, toolkit for manipulating colors — and with an implementation that has certain advantages.
The alpha channel which governs a color's opacity is treated differently than in other libaries, in that we don't equate an undefined alpha with an alpha of 1. The hex string #ff0000 should eventually be interpreted as a fully-opaque red color, but at the color-manipulation level we want to draw the distinction between #ff0000 and #ff0000ff, which has an explicit alpha channel.
When developing the API, I tried to balance brevity, convenience and flexibility. It ended up a more-or-less functional API, i.e. a collection of functions you can pipe data through. It's not as readable as a fluent API where you chain methods, but it's much more flexible, I think.
1 Other popular libraries you may want to look at are TinyColor by Brian Grinstead, color by Heather Arthur, color.js by Andrew Brehaut et al, and chromatist by Jacob Rus.
2 from the Romanian word for ‘colors’.
You can use npm.runkit.com/culori as a playground to test various methods in from the API without installing culori in your project. Observable is another great place to tinker with the library.
culori is bundled as UMD and ES on npm. Install it using npm
or yarn
:
# using npm
npm install culori
# using yarn
yarn add culori
You can then import culori in your project:
// CJS-style
var culori = require('culori');
// ES-style
import { rgb } from 'culori';
<script>
tagTo import culori as a <script>
tag to use in a web page, load it from unpkg:
<script src='https://unpkg.com/culori'/>
Culori does not have a Color class. Instead, it uses plain objects to represent colors:
// A color in the RGB space
{
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 section for the channels expected of each color space. Optionally, the alpha
property is used for the color's alpha channel.
TODO explain Functional style and its benefits.
# culori.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.
// named colors
culori.parse('red'); // ⇒ { r: 1, g: 0, b: 0, mode: 'rgb' }
// hex strings
culori.parse('#ff0000'); // ⇒ { r: 1, g: 0, b: 0, mode: 'rgb' }
// HSL color
culori.parse('hsl(60 50% 10% / 100%)'); // ⇒ { h: 60, s: 0.5, b: 0.1, alpha: 1, mode: 'hsl' }
// Lab color
culori.parse('lab(100 -50 50)'); // ⇒ { l: 100, a: -50, b: 50, mode: 'lab' }
# culori.converter(mode = "rgb") → function (color or String) <>
Returns a function that can then convert any color to the mode color space:
var rgb = culori.converter('rgb');
rgb('#f0f0f0'); // ⇒ { "mode": "rgb", "r": 0.4980392156862745, "g": 0.4980392156862745, "b": 0.4980392156862745 }
Converters accept either strings (which will be parsed with culori.parse
) or color objects. If the mode
key is absent from the color, it's assumed to be in the converter's color space.
The available modes (color spaces) are listed below. Each color space has a convenience method for converting to that color space.
Mode | For | Shortcut |
---|---|---|
rgb | RGB color space | culori( color ) and culori.rgb( color ) |
hsl | HSL color space | culori.hsl(color) |
hsv | HSV color space | culori.hsv(color) |
hsi | HSI color space | culori.hsi(color) |
hwb | HWB color space | culori.hwb(color) |
lab | Lab color space | culori.lab(color) |
lch | LCh color space | culori.lch(color) |
lrgb | Linearized RGB color space | culori.lrgb(color) |
cubehelix | Cubehelix color space | culori.cubehelix(color) |
dlab | DIN99o Lab color space | culori.dlab(color) |
dlch | DIN99o LCh color space | culori.dlch(color) |
# culori.formatter(format = 'rgb') → function (color) <>
Returns a formatter function that can transform colors to useful string representations.
let hex = culori.formatter('hex');
hex('red'); // ⇒ "#ff0000"
Available formats:
Format | Description |
---|---|
hex | Returns the hex string for a color |
rgb | Returns the rgb(…) / rgba(…) string for a color |
# culori.displayable(color or String) <>
For some color spaces — particularly Lab and LCh — not all colors that can be expressed can be displayed on-screen. This function lets you check whether a particular color fits inside the sRGB gamut, i.e. that its r
, g
, and b
channels are in the interval [0, 1]
.
culori.displayable('red'); // ⇒ true
culori.displayable('rgb(300 255 255)'); // ⇒ false
# culori.clamp(method = 'rgb') → function (color) <>
Returns a function which you can then use to retreive a representation of any color that's displayable on the screen, i.e. fits within the sRGB gamut. There are two available methods:
method = 'rgb'
clamps the r
, g
, b
channel values of the color's RGB representation to the interval [0, 1]
;method = 'lch'
converts the color to the LCh space and finds the largest Chroma channel value that's displayable for the given Lightness and Hue; if not even the achromatic version (Chroma = 0) of the LCh color is displayable, it falls back to the rgb
method.culori.clamp('lch')('lch(50 120 5)'); // ⇒ { mode: 'lch', l: 50, c: 77.48291015625, h: 5 }
A (rather miscellaneous) utility that returns a function with which to round numbers to at most n digits of precision.
let approximate = culori.round(4);
approximate(0.38393993); // => 0.3839
# culori.interpolate(colors, mode = "rgb") <>
Returns an interpolator between an array of colors in the mode color space.
# culori.samples(n = 2, γ = 1) <>
Returns an array of n equally-spaced samples from the [0, 1]
range, with 0
and 1
at the ends. The function also accepts a γ (gamma) parameter which will map each value t to tγ.
culori.samples(3); // => [0, 0.5, 1]
culori.samples(5); // => [0, 0.25, 0.5, 0.75, 1]
The samples are useful for culori.interpolate() to generate color scales:
let grays = culori.interpolate(['#fff', '#000']);
samples(5).map(grays);
# culori.interpolateFunctionLinear <>
# culori.interpolateFunctionSpline <>
# culori.interpolateFunctionMonotone <>
# culori.interpolateFunctionCosine <>
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. Also available as a separate d3 plugin.
# culori.differenceEuclidean(mode = 'rgb') <>
Returns a Euclidean distance function in a certain color space.
Computes the CIE76 ΔE*ab color difference between the colors a and b. The computation is done in the Lab color space and it is analogous to culori.differenceEuclidean('lab').
# culori.differenceCie94(kL = 1, K1 = 0.045, K2 = 0.015) <>
Computes the CIE94 ΔE*94 color difference between the colors a and b. The computation is done in the Lab color space.
# culori.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. The computation is done in the Lab color space.
Returns a CIEDE2000 Delta E* function.
Computes the CMC l:c (1984) ΔE*CMC color difference between the colors a and b. The computation is done in the Lab color space.
Note: ΔE*CMC is not considered a metric since it's not symmetrical, i.e. the distance from a to b is not always equal to the distance from b to a. Therefore it cannot be reliably used with culori.nearest().
# culori.differenceDin99o() <>
Computes the DIN99o ΔE*99o color difference between the colors a and b. The computation is done in the DIN99o color space.
# culori.nearest(colors, metric = differenceEuclidean(), accessor = identity) → function(color, n = 1, τ = Infinity) <>
For a given metric color difference formula, and an array of colors, returns a function with which you can find n colors nearest to color, with a maximum distance of τ.
Pass n = Infinity to get all colors in the array with a maximum distance of τ.
TODO
The figure above shows a slice of the HSL color space for a particular hue:
The figure above shows a slice of the HSV color space for a particular hue:
The figure above shows a slice of the HSI color space for a particular hue:
The relative luminance of a color is defined as:
L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
Where R, G, and B are the components from the LRGB color space.
To compute it in culori:
function luminance(color) {
let c = culori.lrgb(color);
return 0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b;
}
Note: The WCAG defines the luminance using a deprecated value for converting sRGB to LRGB. If you'd like a strict implementation, you'll need to write your own sRGB → LRGB conversion.
Using the luminance()
function above, the contrast()
ratio is simply the ratio between the luminances of two colors, with the values shifted by 0.05 to avoid division by zero when comparing against black.
function contrast(colorA, colorB) {
let L1 = luminance(colorA);
let L2 = luminance(colorB);
return (L1 + 0.05) / (L2 + 0.05);
}
TODO
These libraries add more functionality to culori:
FAQs
A general-purpose color library for JavaScript
The npm package culori receives a total of 204,862 weekly downloads. As such, culori popularity was classified as popular.
We found that culori demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket is launching Ruby support for all users. Enhance your Rails projects with AI-powered security scans for vulnerabilities and supply chain threats. Now in Beta!
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.