CIELCh (Lightness, Chroma, Hue) color space operations providing the polar representation of CIELAB with intuitive hue-based manipulation. Also known as HCL (Hue, Chroma, Lightness), this space offers perceptual uniformity with cylindrical coordinates.
Create CIELCh colors using the standard LCh parameter order.
/**
* Creates LCh color from numeric values (Lightness, Chroma, Hue)
* @param l - Lightness (typically 0-100)
* @param c - Chroma/saturation (typically 0-230)
* @param h - Hue angle in degrees (0-360)
* @param opacity - Alpha channel (0-1), defaults to 1
* @returns Hcl color object
*/
function lch(l: number, c: number, h: number, opacity?: number): Hcl;
/**
* Creates LCh color from CSS color string
* @param specifier - CSS color string
* @returns Hcl color object
*/
function lch(specifier: string): Hcl;
/**
* Converts any color object to LCh
* @param color - Color object to convert
* @returns Hcl color object
*/
function lch(color: Color): Hcl;Create CIELCh colors using the HCL parameter order (Hue, Chroma, Lightness).
/**
* Creates HCL color from numeric values (Hue, Chroma, Lightness)
* @param h - Hue angle in degrees (0-360)
* @param c - Chroma/saturation (typically 0-230)
* @param l - Lightness (typically 0-100)
* @param opacity - Alpha channel (0-1), defaults to 1
* @returns Hcl color object
*/
function hcl(h: number, c: number, l: number, opacity?: number): Hcl;
/**
* Creates HCL color from CSS color string
* @param specifier - CSS color string
* @returns Hcl color object
*/
function hcl(specifier: string): Hcl;
/**
* Converts any color object to HCL
* @param color - Color object to convert
* @returns Hcl color object
*/
function hcl(color: Color): Hcl;Usage Examples:
import { lch, hcl, rgb } from "d3-color";
// LCh construction (Lightness, Chroma, Hue)
const blueLch = lch(50, 80, 240); // Medium lightness, high chroma, blue hue
const redLch = lch(50, 80, 0); // Same lightness/chroma, red hue
// HCL construction (Hue, Chroma, Lightness) - same color, different parameter order
const blueHcl = hcl(240, 80, 50); // Same as blueLch above
const redHcl = hcl(0, 80, 50); // Same as redLch above
// Convert from other formats
const purpleRgb = rgb(128, 0, 128);
const purpleLch = lch(purpleRgb); // Convert RGB to LCh
// String parsing
const greenLch = lch("green");
const yellowHcl = hcl("#ffff00");CIELCh color representation using cylindrical coordinates for intuitive manipulation.
class Hcl {
/** Hue angle in degrees (0-360, values outside range are valid) */
h: number;
/** Chroma/saturation (0=gray, higher=more colorful, typically 0-230) */
c: number;
/** Lightness (0=black, 100=white, values outside range are valid) */
l: number;
/** Opacity/alpha channel (0-1) */
opacity: number;
constructor(h: number, c: number, l: number, opacity: number);
brighter(k?: number): Hcl;
darker(k?: number): Hcl;
rgb(): Rgb;
displayable(): boolean;
copy(values?: object): Hcl;
formatHex(): string;
formatHex8(): string;
formatRgb(): string;
formatHsl(): string;
toString(): string;
}Adjust brightness using the perceptually uniform lightness channel.
/**
* Returns a brighter copy by increasing L* channel
* @param k - Brightening factor, defaults to 1
* @returns New Hcl color instance
*/
brighter(k?: number): Hcl;
/**
* Returns a darker copy by decreasing L* channel
* @param k - Darkening factor, defaults to 1
* @returns New Hcl color instance
*/
darker(k?: number): Hcl;Brightness Adjustment:
18 * k to the L* channel (same as Lab)18 * k from the L* channel (same as Lab)Usage Examples:
import { hcl } from "d3-color";
const blue = hcl(240, 80, 50); // Medium blue
// Brightness adjustments preserve hue and chroma
const lighterBlue = blue.brighter(); // L* + 18, same hue/chroma
const darkerBlue = blue.darker(); // L* - 18, same hue/chroma
// Custom brightness steps
const veryBright = blue.brighter(2); // L* + 36
const subtle = blue.darker(0.5); // L* - 9
console.log(blue.l); // 50 (original)
console.log(lighterBlue.l); // 68 (brighter)
console.log(darkerBlue.l); // 32 (darker)
// Hue and chroma unchanged
console.log(blue.h, lighterBlue.h, darkerBlue.h); // All 240
console.log(blue.c, lighterBlue.c, darkerBlue.c); // All 80Convert LCh/HCL colors to other color spaces via Lab intermediate.
/**
* Converts HCL color to RGB color space (via Lab)
* @returns New RGB color instance
*/
rgb(): Rgb;Usage Examples:
import { hcl } from "d3-color";
const hclRed = hcl(0, 80, 50); // Red in HCL space
const rgbRed = hclRed.rgb(); // Convert to RGB via Lab
console.log(rgbRed.r, rgbRed.g, rgbRed.b); // RGB valuesCreate modified copies for systematic color variations.
/**
* Creates a copy of this color with optional property overrides
* @param values - Object with properties to override
* @returns New Hcl color instance
*/
copy(values?: {h?: number, c?: number, l?: number, opacity?: number}): Hcl;Usage Examples:
import { hcl } from "d3-color";
const baseColor = hcl(200, 60, 50); // Cyan-ish
// Hue variations (color wheel rotation)
const red = baseColor.copy({h: 0}); // Rotate to red
const yellow = baseColor.copy({h: 60}); // Rotate to yellow
const green = baseColor.copy({h: 120}); // Rotate to green
const blue = baseColor.copy({h: 240}); // Rotate to blue
// Chroma variations (saturation/intensity)
const gray = baseColor.copy({c: 0}); // Remove all color (grayscale)
const muted = baseColor.copy({c: 30}); // Reduce saturation
const vivid = baseColor.copy({c: 100}); // Increase saturation
// Lightness variations (brightness)
const dark = baseColor.copy({l: 20}); // Much darker
const light = baseColor.copy({l: 80}); // Much lighter
// Complex variations
const complementary = baseColor.copy({h: baseColor.h + 180}); // Opposite hue
const pastel = baseColor.copy({c: 30, l: 80}); // Light and mutedHCL colors inherit all base Color formatting methods via RGB conversion.
/**
* Returns 6-digit hexadecimal string (via RGB conversion)
* @returns Hex string like "#ff0000"
*/
formatHex(): string;
/**
* Returns CSS rgb() string (via RGB conversion)
* @returns RGB string like "rgb(255, 0, 0)"
*/
formatRgb(): string;
/**
* Returns CSS hsl() string (via RGB conversion)
* @returns HSL string like "hsl(0, 100%, 50%)"
*/
formatHsl(): string;
/**
* Alias for formatRgb()
* @returns RGB string representation
*/
toString(): string;Usage Examples:
import { hcl } from "d3-color";
const orange = hcl(30, 80, 60); // Orange in HCL
// All output formats available
console.log(orange.formatHex()); // "#ff8000" (approximately)
console.log(orange.formatRgb()); // "rgb(255, 128, 0)" (approximately)
console.log(orange.formatHsl()); // "hsl(30, 100%, 50%)" (approximately)
console.log(orange.toString()); // "rgb(255, 128, 0)" (approximately)Check if HCL colors can be accurately rendered in RGB.
/**
* Checks if color is displayable when converted to RGB (via Lab)
* @returns True if RGB equivalent is displayable
*/
displayable(): boolean;Usage Examples:
import { hcl } from "d3-color";
const normalHcl = hcl(240, 50, 50); // Reasonable blue
const extremeHcl = hcl(240, 200, 50); // Very saturated, might be out of RGB gamut
console.log(normalHcl.displayable()); // true (likely)
console.log(extremeHcl.displayable()); // false (likely, too saturated for RGB)Common patterns for systematic color manipulation using HCL properties.
Usage Examples:
import { hcl } from "d3-color";
// Create color harmonies using hue relationships
const baseHue = 200;
const baseColor = hcl(baseHue, 60, 50);
const colorSchemes = {
monochromatic: [
baseColor,
baseColor.copy({l: 30}), // Darker
baseColor.copy({l: 70}), // Lighter
baseColor.copy({c: 30}), // Less saturated
baseColor.copy({c: 90}) // More saturated
],
analogous: [
baseColor,
baseColor.copy({h: baseHue - 30}), // Adjacent hues
baseColor.copy({h: baseHue + 30})
],
complementary: [
baseColor,
baseColor.copy({h: baseHue + 180}) // Opposite hue
],
triadic: [
baseColor,
baseColor.copy({h: baseHue + 120}), // 120° apart
baseColor.copy({h: baseHue + 240}) // 240° apart
]
};
// Create perceptually uniform gradients
const startColor = hcl(0, 80, 20); // Dark red
const endColor = hcl(240, 80, 80); // Light blue
const gradient = [];
for (let i = 0; i <= 10; i++) {
const t = i / 10;
const h = startColor.h + (endColor.h - startColor.h) * t;
const c = startColor.c + (endColor.c - startColor.c) * t;
const l = startColor.l + (endColor.l - startColor.l) * t;
gradient.push(hcl(h, c, l));
}