Chroma.js - Documentation

What is Chroma.js?

Chroma.js is a small, fast, and easy-to-use JavaScript library for color manipulation and conversion. It provides a simple and consistent API for working with colors in various formats (hex, RGB, HSL, HSV, and more), allowing you to perform operations like blending, interpolating, and manipulating color properties with ease. Its compact size makes it ideal for inclusion in web projects without significantly impacting performance.

Why use Chroma.js?

Chroma.js offers several advantages over manually handling color calculations:

Setting up Chroma.js

Chroma.js can be easily integrated into your project using a variety of methods:

<script src="chroma.min.js"></script>
npm install chroma-js

Then, import it into your JavaScript file:

import chroma from 'chroma-js';
<script src="https://cdn.jsdelivr.net/npm/chroma-js/chroma.min.js"></script>

Remember to replace "chroma.min.js" with the actual path to the file if necessary.

Basic Usage Examples

Here are some basic examples demonstrating Chroma.js’s core functionality:

1. Creating a Chroma color:

let color = chroma('#FF0000'); // Create a color from a hex string
let color2 = chroma('rgb(0, 255, 0)'); //Create a color from RGB values
let color3 = chroma('hsl(240, 100%, 50%)'); //Create a color from HSL values

console.log(color.hex()); // Output: #ff0000
console.log(color2.rgb()); // Output: [0, 255, 0]
console.log(color3.hsl()); // Output: [240, 1, 0.5]

2. Color manipulation:

let color = chroma('#0000FF');

let lighterColor = color.brighten();
let darkerColor = color.darken();

console.log(lighterColor.hex());
console.log(darkerColor.hex());

3. Color blending:

let color1 = chroma('#FF0000');
let color2 = chroma('#0000FF');
let blendedColor = chroma.mix(color1, color2, 0.5); // Blend with a 50/50 ratio

console.log(blendedColor.hex()); // Output: A purple color (depending on the blending method)

These examples show how easily you can create, manipulate, and blend colors using Chroma.js. Refer to the complete API documentation for a comprehensive list of available functions and methods.

Color Creation and Manipulation

Creating Colors from various inputs (Hex, RGB, HSL, etc.)

Chroma.js offers a flexible and consistent way to create color objects from various input formats. The core chroma() function accepts a wide range of inputs:

All of these inputs will return a Chroma.js color object that can be further manipulated.

Converting between color spaces (RGB, HSL, HSV, LAB, etc.)

Chroma.js simplifies color space conversions. Once you have a Chroma color object, you can easily get its representation in various color spaces using the following methods:

For example:

let color = chroma('#FF0000');
console.log(color.rgb());     // Output: [255, 0, 0]
console.log(color.hsl());     // Output: [0, 1, 0.5]
console.log(color.hex());     // Output: #ff0000
console.log(color.css());    // Output: rgb(255,0,0)

Brightness, Saturation, and Hue adjustments

Chroma.js provides methods to easily adjust the brightness, saturation, and hue of a color:

Example:

let color = chroma('#00FF00');
let brighterColor = color.brighten(0.2);
let moreSaturated = color.saturate(0.5);
console.log(brighterColor.hex());
console.log(moreSaturated.hex());

let adjustedColor = color.adjust([30, 0.2, -0.1]); //increases hue by 30, saturation by 20%, and decreases lightness by 10%
console.log(adjustedColor.hex())

Alpha manipulation

Chroma.js allows you to control the alpha (opacity) value of a color:

Example:

let color = chroma('#0000FF');
let semiTransparent = color.alpha(0.5);
console.log(semiTransparent.rgba()); //Output will include an alpha value of 0.5
console.log(semiTransparent.css()); //Output will include rgba values

Clamping and limiting color values

While Chroma.js generally handles color values appropriately, you might occasionally need to explicitly clamp or limit color component values. This is not directly provided as a built-in function within the core Chroma.js API. You’d typically handle this using standard JavaScript Math.min() and Math.max() functions within your application’s logic after obtaining the color values (RGB, HSL, etc.) from Chroma.js. For example:

let color = chroma('rgb(300, 100, -50)'); // Example with out-of-range values
let rgb = color.rgb();

let clampedRGB = rgb.map(val => Math.max(0, Math.min(255, val))); //Clamp RGB values to 0-255

console.log(clampedRGB);

This ensures your color values remain within the valid ranges for the respective color spaces.

Color Scales and Palettes

Generating color scales

Chroma.js makes it easy to generate color scales using the scale() function. You provide a starting and ending color, and the number of steps, and Chroma.js will generate a smoothly interpolated array of colors. You can also specify a color scale scheme (e.g., ‘YlOrRd’, ‘RdBu’). More details on predefined scales below.

let scale = chroma.scale(['red', 'blue']).colors(10); // Generate a 10-step scale from red to blue
console.log(scale); // Output: Array of 10 hex color strings

let scale2 = chroma.scale('cool').colors(5); // Generates 5 colors from the 'cool' scheme
console.log(scale2);

let scale3 = chroma.scale(['#000', '#fff']).mode('lab').colors(8); //Use lab color space for smoother interpolation
console.log(scale3)

You can also pass a function to scale() for more complex scales:

// A function that will generate rainbow colors
let rainbowScale = chroma.scale(x => chroma.hsl(x * 360, 1, 0.5)).colors(10);
console.log(rainbowScale)

Predefined color scales

Chroma.js includes a number of predefined color scales, based on colorbrewer2.org and other sources. These scales are designed for various purposes and offer perceptually uniform color transitions. You can access them by name (e.g., ‘viridis’, ‘magma’, ‘plasma’, ‘inferno’, ‘cividis’, ‘RdBu’, ‘YlOrRd’, ‘Greens’, etc.). Refer to the Chroma.js documentation or examples for the complete list and their visual representations.

let scale = chroma.scale('viridis').colors(5); //Using the predefined 'viridis' scale
console.log(scale)

Customizing color scales

You can customize the behavior of color scales by using the various options available within chroma.scale(). For example, you can specify the mode for color space interpolation ('rgb', 'lab', 'hsl', 'hsv'), affecting the visual quality and perceived uniformity. The domain option allows you to set the input range for the scale, which is helpful when mapping data values to colors.

let scale = chroma.scale(['blue', 'green', 'yellow', 'red']).domain([0,100]).colors(5);
// Generates 5 colors interpolated between blue, green, yellow, and red based on a 0 to 100 domain.

let labScale = chroma.scale(['blue', 'green']).mode('lab').colors(10); //Use lab interpolation
console.log(labScale);

Interpolating colors

Chroma.js provides interpolate() for creating a color at a specific point along a scale. This function is also implicitly used within colors() method of the scale object.

let scale = chroma.scale(['red', 'blue']);
let interpolatedColor = scale(0.5); // Color halfway between red and blue
console.log(interpolatedColor.hex()); // Output: A purple hex code

let interpolatedColor2 = scale(0.75).hex();
console.log(interpolatedColor2);

The input to scale() is a normalized value between 0 and 1 (inclusive). You can easily map your data (in any numerical range) into that space before passing it to the function.

Working with palettes

While not explicitly defined as a separate “palette” object, the result of chroma.scale().colors() effectively acts as a color palette. You can store the returned array of color strings or objects for later use in your application, for example, to assign colors to chart segments, map features, etc.

let myPalette = chroma.scale('Spectral').colors(7); //Create a 7 color palette based on spectral scale

//Use myPalette to color chart elements, map elements, or any visual elements.

Color Comparisons and Differences

Calculating color difference (Delta E)

Chroma.js allows you to calculate the perceptual difference between two colors using the Delta E (ΔE) metric. Delta E quantifies the difference in color appearance, taking into account human perception. A smaller Delta E value indicates a smaller perceived difference. Chroma.js uses the CIE76 formula by default, but can also calculate using the more accurate CIE94 and CMC formulas by specifying the appropriate method in the deltaE() method.

let color1 = chroma('#FF0000');
let color2 = chroma('#FF0000');
let color3 = chroma('#0000FF');

let deltaE76 = color1.deltaE(color2, '76'); // Default method
let deltaE94 = color1.deltaE(color3, '94'); // Using CIE94
let deltaECMC = color1.deltaE(color3, 'cmc'); // Using CMC

console.log("Delta E (CIE76):", deltaE76); // Output: A very small number close to 0
console.log("Delta E (CIE94):", deltaE94); // Output: A larger number representing a greater difference
console.log("Delta E (CMC):", deltaECMC); // Output: A larger number representing a greater difference

Note that different Delta E formulas will yield different numerical results; however, the relative differences between color pairs should remain consistent regardless of chosen formula.

Comparing color similarity

While not a direct function, you can use the Delta E value to determine the similarity of two colors. A lower Delta E value indicates greater similarity. You can define a threshold based on your application’s requirements to determine if two colors are considered “similar” enough.

let color1 = chroma('#FF0000');
let color2 = chroma('#FF1100');
let threshold = 5; // Example threshold

let deltaE = color1.deltaE(color2);

if (deltaE < threshold) {
  console.log("Colors are similar");
} else {
  console.log("Colors are different");
}

Finding complementary and analogous colors

Chroma.js doesn’t have built-in functions specifically labeled “complementary” or “analogous.” However, you can easily calculate these using color space manipulations.

let color = chroma('#FF0000'); //Red
let hsl = color.hsl();
let complementaryHue = (hsl[0] + 180) % 360;
let complementaryColor = chroma.hsl(complementaryHue, hsl[1], hsl[2]);
console.log(complementaryColor.hex()); //Output: Cyan (approximately)
let color = chroma('#FF0000');
let hsl = color.hsl();
let analogousColor1 = chroma.hsl((hsl[0] + 30) % 360, hsl[1], hsl[2]); //Slightly more orange
let analogousColor2 = chroma.hsl((hsl[0] - 30 + 360) % 360, hsl[1], hsl[2]); //Slightly more purple
console.log(analogousColor1.hex(), analogousColor2.hex());

Remember to adjust the added/subtracted hue value to control the distance between analogous colors. You may also need to adjust saturation and lightness for desired results.

Advanced Techniques

Blending colors

Chroma.js offers several ways to blend colors:

let color1 = chroma('#FF0000');
let color2 = chroma('#0000FF');

let blendedLRGB = chroma.mix(color1, color2, 0.5, 'lrgb');
let blendedLAB = chroma.mix(color1, color2, 0.5, 'lab');

console.log(blendedLRGB.hex());
console.log(blendedLAB.hex());

The choice of blending mode significantly impacts the result. Experiment to find the mode best suited to your needs.

Color quantization

Color quantization reduces the number of colors in an image or dataset. Chroma.js doesn’t directly perform image quantization, but you can use its color manipulation capabilities in conjunction with other libraries (like those for image processing) to achieve this. A basic approach involves iterating through pixels, calculating their dominant color using averaging or clustering methods, and then mapping them to a reduced palette generated with Chroma.js’s scale() function.

//Illustrative example, requires external image processing library
//This is a simplified example, a real application would require a proper image processing library
const palette = chroma.scale(['red', 'green', 'blue']).colors(3); //Create a 3-color palette

//Simulate pixel data; replace with actual pixel data from your image
const pixelData = [
  [200, 100, 50],
  [100, 200, 50],
  [50, 100, 200]
]


const quantizedPixels = pixelData.map(pixel => {
  //Find closest color in the palette (simplified example, would use a more sophisticated algorithm)
  let closestColor = palette[0]

  return closestColor;
})
console.log(quantizedPixels);

Working with images

Chroma.js primarily focuses on color manipulation. Direct image processing isn’t a core feature. To work with images, you’ll need to use a separate image processing library (like a canvas-based library or a dedicated image manipulation library) to load, access pixel data, and then use Chroma.js to process the colors of the individual pixels.

Custom color spaces

Chroma.js doesn’t directly support defining entirely new custom color spaces. Its strength lies in its handling of common color spaces (RGB, HSL, HSV, LAB). However, you can extend its functionality by creating custom functions to perform transformations between a new color model and one of Chroma.js’s supported spaces. These functions would handle conversions to and from, for example, RGB, allowing you to work with your custom color space indirectly. This would involve implementing your own conversion algorithms.

Utilities and Helper Functions

Formatting and parsing colors

Chroma.js provides several helper functions for working with color formats:

These functions provide a convenient way to get a specific color format from a Chroma color object or any valid Chroma color input. They handle the conversion automatically.

Example:

let color = chroma('#FF0000');
console.log(chroma.hex(color));      // Output: #ff0000
console.log(chroma.rgb(color));      // Output: [255, 0, 0]
console.log(chroma.hsl(color));      // Output: [0, 1, 0.5]
console.log(chroma.css(color));     // Output: #f00
console.log(chroma.gl(color));     // Output: [1, 0, 0, 1]

Working with color strings

Chroma.js inherently handles various color string formats as input to the chroma() function and its conversion methods. However, there isn’t a dedicated set of functions solely for manipulating color strings beyond what’s available via conversion functions described above. If you have more complex string parsing tasks involving color codes, you might need to use standard JavaScript string manipulation functions (split, substring, parseInt, etc.).

Other utility functions

Besides color formatting and parsing, Chroma.js provides other useful functions:

let color1 = chroma('#000');
let color2 = chroma('#fff');
let contrastRatio = chroma.contrast(color1, color2);
console.log(contrastRatio); // Output: A number representing the contrast ratio

These utility functions offer additional support for common color-related tasks beyond color creation and manipulation. They enhance the usability and efficiency of Chroma.js in your projects.

Best Practices and Common Pitfalls

Performance considerations

While Chroma.js is generally performant, keep these points in mind for optimal performance, especially when dealing with large numbers of color calculations:

Error handling and debugging

Chroma.js generally handles invalid color inputs gracefully. However, it is good practice to include checks to ensure that your inputs are indeed valid color representations. The chroma.valid(color) function can help in this.

For debugging, standard JavaScript debugging tools can be used. Console logging of intermediate values (color components, results of calculations) can be helpful in identifying the source of errors or unexpected behavior.

Common mistakes and solutions

By avoiding these common pitfalls and following the best practices, you can effectively use Chroma.js to perform robust and efficient color manipulations in your applications.

Appendix

Glossary of terms

List of color spaces

Chroma.js supports conversions between several color spaces:

Chroma.js API reference

(Note: A comprehensive API reference would be too extensive for this context. A real developer manual would include a detailed API listing with descriptions of all functions, parameters, and return values. This is a placeholder.)

The Chroma.js API includes functions for:

Consult the official Chroma.js documentation for the complete and up-to-date API reference.

Contributing to Chroma.js

(Note: This section should link to the project’s contribution guidelines on GitHub or a similar platform.)

If you’re interested in contributing to Chroma.js, please refer to the project’s contribution guidelines on [GitHub Link]. Contributions are welcome, including bug fixes, new features, improved documentation, and performance optimizations. Before submitting a pull request, ensure you follow the project’s coding style and testing procedures. Your contributions will help improve Chroma.js for the benefit of all users.