Fast color parsing and manipulation library with comprehensive conversion and accessibility features
—
Methods for generating color schemes including complements, triads, tetrads, analogous colors, and monochromatic variations. These methods help create harmonious color palettes for design systems and user interfaces.
Returns the complement color (opposite on the color wheel).
/**
* Returns the complement color (180 degrees opposite)
* @returns new tinycolor instance representing the complement
*/
complement(): tinycolor;Usage Examples:
import tinycolor from "tinycolor2";
const red = tinycolor("red");
const complement = red.complement();
console.log(red.toHexString()); // "#ff0000"
console.log(complement.toHexString()); // "#00ffff" (cyan)
const blue = tinycolor("#0066cc");
const blueComplement = blue.complement();
console.log(blue.toHexString()); // "#0066cc"
console.log(blueComplement.toHexString()); // "#cc6600"
// Create complementary color pairs
function getComplementaryPair(color) {
const base = tinycolor(color);
return {
primary: base.toHexString(),
complement: base.complement().toHexString()
};
}Returns an array containing the original color and its split complements.
/**
* Returns split complement colors (base + two colors adjacent to complement)
* @returns array of 3 tinycolor instances [original, splitComp1, splitComp2]
*/
splitcomplement(): tinycolor[];Usage Examples:
const orange = tinycolor("#ff8000");
const splitComps = orange.splitcomplement();
console.log("Original:", splitComps[0].toHexString()); // "#ff8000"
console.log("Split 1:", splitComps[1].toHexString()); // "#0080ff"
console.log("Split 2:", splitComps[2].toHexString()); // "#8000ff"
// Use for triadic harmony with more subtle contrast
function createSplitComplementPalette(baseColor) {
const colors = tinycolor(baseColor).splitcomplement();
return {
primary: colors[0].toHexString(),
secondary: colors[1].toHexString(),
tertiary: colors[2].toHexString()
};
}Returns an array of analogous colors (colors adjacent on the color wheel).
/**
* Returns analogous colors (adjacent colors on the color wheel)
* @param results - Number of colors to return (default 6)
* @param slices - Number of slices to divide the color wheel (default 30)
* @returns array of tinycolor instances
*/
analogous(results?: number, slices?: number): tinycolor[];Usage Examples:
const green = tinycolor("#00ff00");
// Default analogous colors (6 colors)
const analogous = green.analogous();
console.log("Analogous colors:");
analogous.forEach((color, i) => {
console.log(`${i}: ${color.toHexString()}`);
});
// Custom number of colors
const fiveAnalogous = green.analogous(5);
const tenAnalogous = green.analogous(10);
// Custom slicing for finer control
const fineAnalogous = green.analogous(6, 60); // 60 slices instead of default 30
// Create harmonious color palette
function createAnalogousPalette(baseColor, count = 5) {
return tinycolor(baseColor)
.analogous(count)
.map(color => color.toHexString());
}
const bluePalette = createAnalogousPalette("#3498db", 7);Returns an array of monochromatic variations (same hue, different saturation/lightness).
/**
* Returns monochromatic variations of the color
* @param results - Number of variations to return (default 6)
* @returns array of tinycolor instances with same hue
*/
monochromatic(results?: number): tinycolor[];Usage Examples:
const purple = tinycolor("#8e44ad");
// Default monochromatic variations (6 colors)
const mono = purple.monochromatic();
console.log("Monochromatic variations:");
mono.forEach((color, i) => {
console.log(`${i}: ${color.toHexString()}`);
});
// Custom number of variations
const monoFive = purple.monochromatic(5);
const monoTen = purple.monochromatic(10);
// Create tonal palette for UI design
function createTonalPalette(baseColor, count = 8) {
const variations = tinycolor(baseColor).monochromatic(count);
// Sort by lightness for organized palette
variations.sort((a, b) => b.getLuminance() - a.getLuminance());
return variations.map(color => color.toHexString());
}
const grayScale = createTonalPalette("#666666", 10);Returns a triad color scheme (3 evenly spaced colors on the color wheel).
/**
* Returns triad colors (3 colors evenly spaced on color wheel)
* @returns array of 3 tinycolor instances [original, +120°, +240°]
*/
triad(): tinycolor[];Usage Examples:
const red = tinycolor("#ff0000");
const triad = red.triad();
console.log("Triad colors:");
console.log("Primary:", triad[0].toHexString()); // "#ff0000" (red)
console.log("Secondary:", triad[1].toHexString()); // "#00ff00" (green)
console.log("Tertiary:", triad[2].toHexString()); // "#0000ff" (blue)
// Create balanced color scheme
function createTriadicScheme(baseColor) {
const colors = tinycolor(baseColor).triad();
return {
primary: colors[0].toHexString(),
secondary: colors[1].toHexString(),
tertiary: colors[2].toHexString(),
// Add tinted versions
primaryLight: colors[0].lighten(20).toHexString(),
secondaryLight: colors[1].lighten(20).toHexString(),
tertiaryLight: colors[2].lighten(20).toHexString()
};
}Returns a tetrad color scheme (4 colors forming a rectangle on the color wheel).
/**
* Returns tetrad colors (4 colors forming rectangle on color wheel)
* @returns array of 4 tinycolor instances
*/
tetrad(): tinycolor[];Usage Examples:
const orange = tinycolor("#ff8000");
const tetrad = orange.tetrad();
console.log("Tetrad colors:");
tetrad.forEach((color, i) => {
console.log(`Color ${i + 1}: ${color.toHexString()}`);
});
// Create rich 4-color palette
function createTetradScheme(baseColor) {
const colors = tinycolor(baseColor).tetrad();
return {
primary: colors[0].toHexString(),
secondary: colors[1].toHexString(),
tertiary: colors[2].toHexString(),
quaternary: colors[3].toHexString()
};
}
// Use for complex designs requiring 4 distinct colors
const complexPalette = createTetradScheme("#e74c3c");function generateCompletePalette(baseColor) {
const base = tinycolor(baseColor);
return {
// Base color
base: base.toHexString(),
// Monochromatic (tonal variations)
monochromatic: base.monochromatic(5).map(c => c.toHexString()),
// Analogous (harmonious)
analogous: base.analogous(5).map(c => c.toHexString()),
// Complementary
complement: base.complement().toHexString(),
// Split complementary
splitComplement: base.splitcomplement().map(c => c.toHexString()),
// Triadic
triad: base.triad().map(c => c.toHexString()),
// Tetradic
tetrad: base.tetrad().map(c => c.toHexString()),
// Variations
variations: {
light: base.lighten(20).toHexString(),
dark: base.darken(20).toHexString(),
muted: base.desaturate(30).toHexString(),
vibrant: base.saturate(20).toHexString()
}
};
}
const palette = generateCompletePalette("#3498db");function createMaterialPalette(primaryColor) {
const primary = tinycolor(primaryColor);
// Generate material design-like color variations
const palette = {
50: primary.clone().lighten(45).desaturate(50).toHexString(),
100: primary.clone().lighten(40).desaturate(30).toHexString(),
200: primary.clone().lighten(30).desaturate(20).toHexString(),
300: primary.clone().lighten(20).desaturate(10).toHexString(),
400: primary.clone().lighten(10).toHexString(),
500: primary.toHexString(), // Base color
600: primary.clone().darken(10).toHexString(),
700: primary.clone().darken(20).toHexString(),
800: primary.clone().darken(30).toHexString(),
900: primary.clone().darken(40).toHexString(),
// Accent colors
A100: primary.clone().lighten(30).saturate(30).toHexString(),
A200: primary.clone().lighten(10).saturate(20).toHexString(),
A400: primary.clone().saturate(20).toHexString(),
A700: primary.clone().darken(10).saturate(20).toHexString()
};
return palette;
}function createThemeFromBase(baseColor, options = {}) {
const {
includeAnalogous = true,
includeComplementary = true,
includeMonochromatic = true,
accentCount = 2
} = options;
const base = tinycolor(baseColor);
const theme = {
primary: {
main: base.toHexString(),
light: base.lighten(20).toHexString(),
dark: base.darken(20).toHexString()
}
};
if (includeComplementary) {
const complement = base.complement();
theme.secondary = {
main: complement.toHexString(),
light: complement.lighten(20).toHexString(),
dark: complement.darken(20).toHexString()
};
}
if (includeAnalogous) {
const analogous = base.analogous(accentCount + 1).slice(1); // Exclude base
theme.accents = analogous.map(color => ({
main: color.toHexString(),
light: color.lighten(15).toHexString(),
dark: color.darken(15).toHexString()
}));
}
if (includeMonochromatic) {
const mono = base.monochromatic(5);
theme.grays = mono.map(color => color.toHexString());
}
return theme;
}
// Usage
const blueTheme = createThemeFromBase("#2196F3", {
includeAnalogous: true,
includeComplementary: true,
accentCount: 3
});function analyzeColorHarmony(colors) {
const tinyColors = colors.map(c => tinycolor(c));
const analysis = {
isMonochromatic: false,
isAnalogous: false,
isComplementary: false,
isTriadic: false,
isTetradic: false
};
if (tinyColors.length === 2) {
// Check if complementary (hue difference ~180°)
const hue1 = tinyColors[0].toHsl().h;
const hue2 = tinyColors[1].toHsl().h;
const hueDiff = Math.abs(hue1 - hue2);
analysis.isComplementary = Math.abs(hueDiff - 180) < 15;
}
if (tinyColors.length === 3) {
// Check if triadic (hue differences ~120°)
const hues = tinyColors.map(c => c.toHsl().h);
// Implementation for triadic check...
}
// Check if monochromatic (same hue, different saturation/lightness)
const hues = tinyColors.map(c => c.toHsl().h);
const uniqueHues = [...new Set(hues.map(h => Math.round(h / 5) * 5))]; // Group similar hues
analysis.isMonochromatic = uniqueHues.length <= 1;
return analysis;
}Install with Tessl CLI
npx tessl i tessl/npm-tinycolor2