JavaScript library for color conversions and color scale generation with zero dependencies
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Functions for generating new colors through averaging, mixing, blending, mathematical operations, and procedural color creation.
Calculate the average of multiple colors in a specified color space.
/**
* Average multiple colors
* @param colors - Array of colors to average
* @param mode - Color space for averaging (default: 'lrgb')
* @param weights - Optional weights for each color
* @returns New averaged Color instance
*/
function average(colors: (Color | string)[], mode?: string, weights?: number[]): Color;Available modes:
lrgb - Linear RGB (default, perceptually best)rgb - Standard RGBlab - LAB color spacelch - LCH color spacehsl - HSL color spacehsv - HSV color spaceUsage Examples:
import chroma, { average } from "chroma-js";
// Simple average
const colors = ['#FF0000', '#00FF00', '#0000FF'];
const avg = average(colors);
console.log(avg.hex()); // Averaged color
// Weighted average
const weighted = average(
['#FF0000', '#00FF00'],
'lrgb',
[0.8, 0.2] // 80% red, 20% green
);
// Different color spaces
const labAvg = average(colors, 'lab');
const lchAvg = average(colors, 'lch');
const hslAvg = average(colors, 'hsl');
// Mix Color instances and strings
const mixed = average([
chroma('#FF0000'),
'#00FF00',
chroma.hsl(240, 1, 0.5)
]);Mix two colors with specified ratio and interpolation mode.
/**
* Mix two colors
* @param color1 - First color
* @param color2 - Second color
* @param ratio - Mix ratio (0-1, default: 0.5)
* @param mode - Interpolation mode (default: 'lrgb')
* @returns New mixed Color instance
*/
function mix(color1: Color | string, color2: Color | string, ratio?: number, mode?: string): Color;
/**
* Alias for mix()
*/
function interpolate(color1: Color | string, color2: Color | string, ratio?: number, mode?: string): Color;Usage Examples:
import chroma, { mix } from "chroma-js";
const red = '#FF0000';
const blue = '#0000FF';
// Equal mix (50/50)
const purple = mix(red, blue);
// Custom ratios
const redTinted = mix(red, blue, 0.2); // 80% red, 20% blue
const blueTinted = mix(red, blue, 0.8); // 20% red, 80% blue
// Different interpolation modes
const labMix = mix(red, blue, 0.5, 'lab');
const lchMix = mix(red, blue, 0.5, 'lch');
const hslMix = mix(red, blue, 0.5, 'hsl');
// Create gradients
const gradient = [];
for (let i = 0; i <= 10; i++) {
gradient.push(mix(red, blue, i / 10));
}Blend two colors using Photoshop-style blend modes.
/**
* Blend two colors using blend modes
* @param bottom - Bottom color (base)
* @param top - Top color (overlay)
* @param mode - Blend mode
* @returns New blended Color instance
*/
function blend(bottom: Color | string, top: Color | string, mode: string): Color;Available blend modes:
normal - Normal blendingmultiply - Multiply (darkens)screen - Screen (lightens)overlay - Overlaydarken - Darken onlylighten - Lighten onlydodge - Color dodgeburn - Color burnUsage Examples:
import chroma, { blend } from "chroma-js";
const base = '#FF8040';
const overlay = '#0080FF';
// Different blend modes
const multiplied = blend(base, overlay, 'multiply');
const screened = blend(base, overlay, 'screen');
const overlayed = blend(base, overlay, 'overlay');
const dodged = blend(base, overlay, 'dodge');
// Simulate layer effects
const darkened = blend('#CCCCCC', '#333333', 'multiply');
const lightened = blend('#333333', '#CCCCCC', 'screen');
// Create complex color effects
const effect = blend(
blend(base, '#FF0000', 'overlay'),
'#0000FF',
'screen'
);Generate random colors with optional constraints.
/**
* Generate random color
* @returns New random Color instance
*/
function random(): Color;Usage Examples:
import chroma, { random } from "chroma-js";
// Simple random color
const color1 = random();
console.log(color1.hex());
// Generate multiple random colors
const palette = [];
for (let i = 0; i < 5; i++) {
palette.push(random());
}
// Random colors with constraints (via manipulation)
const brightColors = [];
for (let i = 0; i < 5; i++) {
brightColors.push(
random()
.saturate(2) // Make more saturated
.brighten(1) // Make brighter
);
}
// Random warm colors
const warmColors = [];
for (let i = 0; i < 5; i++) {
const hue = Math.random() * 60; // 0-60 degrees (red-yellow range)
warmColors.push(
chroma.hsl(hue, 0.7 + Math.random() * 0.3, 0.5 + Math.random() * 0.3)
);
}Create smooth color transitions using bezier curves through multiple colors.
/**
* Create bezier interpolation function
* @param colors - Array of colors to interpolate through
* @returns Interpolation function that accepts t parameter (0-1)
*/
function bezier(colors: (Color | string)[]): (t: number) => Color;Usage Examples:
import chroma, { bezier } from "chroma-js";
// Create bezier interpolation through multiple colors
const colors = ['#FF0000', '#FFFF00', '#00FF00', '#0000FF'];
const interpolator = bezier(colors);
// Sample along the curve
const gradient = [];
for (let i = 0; i <= 20; i++) {
const t = i / 20;
gradient.push(interpolator(t));
}
// Create smooth color transitions
const sunset = bezier(['#FF6B35', '#F7931E', '#FFD23F', '#06FFA5']);
const sunsetAt25 = sunset(0.25);
const sunsetAt75 = sunset(0.75);
// Use for data visualization
const heatmap = bezier(['#000080', '#0000FF', '#00FFFF', '#FFFF00', '#FF0000']);
const dataValues = [0.1, 0.3, 0.6, 0.8, 1.0];
const heatmapColors = dataValues.map(value => heatmap(value));Generate colors using the cubehelix algorithm for scientific visualization.
/**
* Create cubehelix color scheme generator
* @param start - Start hue (default: 300)
* @param rotations - Number of rotations (default: -1.5)
* @param hue - Hue parameter (default: 1)
* @param gamma - Gamma correction (default: 1)
* @param lightness - Lightness range (default: [0, 1])
* @returns Cubehelix generator with configuration methods
*/
function cubehelix(start?: number, rotations?: number, hue?: number, gamma?: number, lightness?: number[]): CubehelixGenerator;
interface CubehelixGenerator {
/** Set start hue */
start(hue: number): CubehelixGenerator;
/** Set number of rotations */
rotations(num: number): CubehelixGenerator;
/** Set hue parameter */
hue(value: number | number[]): CubehelixGenerator;
/** Set gamma correction */
gamma(value: number): CubehelixGenerator;
/** Set lightness range */
lightness(range: number[]): CubehelixGenerator;
/** Convert to scale function */
scale(): Scale;
/** Generate single color at position t (0-1) */
(t: number): Color;
}Usage Examples:
import chroma, { cubehelix } from "chroma-js";
// Default cubehelix
const helix1 = cubehelix();
const colors1 = [];
for (let i = 0; i <= 10; i++) {
colors1.push(helix1(i / 10));
}
// Custom cubehelix configuration
const helix2 = cubehelix()
.start(200) // Start at blue
.rotations(-0.5) // Half rotation
.gamma(2.2) // Gamma correction
.lightness([0.3, 0.8]) // Light range
// Generate color scale
const customScale = helix2.scale().colors(7);
// Different configurations for different purposes
const scientific = cubehelix()
.start(120)
.rotations(1.5)
.lightness([0.2, 0.9]);
const artistic = cubehelix()
.start(300)
.rotations(-2)
.hue([0.5, 1.5])
.gamma(1.5);Generate colors based on mathematical functions and algorithms.
// Additional procedural generation using existing functions
/**
* Generate colors at specific intervals
*/
function generateSequence(baseColor: Color | string, operation: string, steps: number): Color[];
/**
* Generate analogous colors (adjacent on color wheel)
*/
function generateAnalogous(baseColor: Color | string, angle?: number, count?: number): Color[];
/**
* Generate complementary colors
*/
function generateComplementary(baseColor: Color | string): Color[];
/**
* Generate triadic colors (120° apart)
*/
function generateTriadic(baseColor: Color | string): Color[];Usage Examples:
// Generate color sequences (not direct API, but achievable combinations)
function generateSequence(baseColor, operation, steps) {
const base = chroma(baseColor);
const colors = [base];
for (let i = 1; i < steps; i++) {
const factor = i * 0.2;
switch (operation) {
case 'darken':
colors.push(base.darken(factor));
break;
case 'brighten':
colors.push(base.brighten(factor));
break;
case 'saturate':
colors.push(base.saturate(factor));
break;
case 'desaturate':
colors.push(base.desaturate(factor));
break;
}
}
return colors;
}
// Generate analogous colors
function generateAnalogous(baseColor, angle = 30, count = 3) {
const base = chroma(baseColor);
const [h, s, l] = base.hsl();
const colors = [base];
for (let i = 1; i < count; i++) {
const newHue = (h + (angle * i)) % 360;
colors.push(chroma.hsl(newHue, s, l));
}
return colors;
}
// Generate complementary colors
function generateComplementary(baseColor) {
const base = chroma(baseColor);
const [h, s, l] = base.hsl();
const complement = chroma.hsl((h + 180) % 360, s, l);
return [base, complement];
}
// Usage
const base = chroma('#FF6B35');
const darkenSequence = generateSequence(base, 'darken', 5);
const analogous = generateAnalogous(base, 25, 4);
const complements = generateComplementary(base);