or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

analysis.mdchannels.mdconstruction.mdconversion.mdindex.mdmanipulation.md
tile.json

manipulation.mddocs/

Color Manipulation

Immutable color manipulation methods for adjusting lightness, saturation, hue, alpha values, and performing advanced color operations.

Capabilities

Lightness Manipulation

Adjust the perceived lightness of colors using HSL color space operations.

/**
 * Increase lightness by a ratio
 * @param ratio - Multiplier for lightness increase (0-1+)
 * @returns New ColorInstance with increased lightness
 */
lighten(ratio: number): ColorInstance;

/**
 * Decrease lightness by a ratio
 * @param ratio - Multiplier for lightness decrease (0-1+)
 * @returns New ColorInstance with decreased lightness
 */
darken(ratio: number): ColorInstance;

Usage Examples:

import Color from "color";

const originalBlue = Color('#0066CC');

// Lighten by 30% (ratio of 0.3)
const lighterBlue = originalBlue.lighten(0.3);
console.log(lighterBlue.hex()); // '#4D88D9'

// Darken by 20%
const darkerBlue = originalBlue.darken(0.2);
console.log(darkerBlue.hex()); // '#0052A3'

// Chain operations
const result = Color('red')
  .lighten(0.2)
  .darken(0.1);

// Multiple lightness adjustments
const steps = [0.1, 0.2, 0.3, 0.4, 0.5];
const lightenedColors = steps.map(ratio => originalBlue.lighten(ratio));

Saturation Manipulation

Adjust color saturation in HSL color space for more or less vivid colors.

/**
 * Increase saturation by a ratio
 * @param ratio - Multiplier for saturation increase (0-1+)
 * @returns New ColorInstance with increased saturation
 */
saturate(ratio: number): ColorInstance;

/**
 * Decrease saturation by a ratio
 * @param ratio - Multiplier for saturation decrease (0-1+)
 * @returns New ColorInstance with decreased saturation
 */
desaturate(ratio: number): ColorInstance;

/**
 * Remove all saturation (convert to grayscale)
 * @returns New ColorInstance in grayscale
 */
grayscale(): ColorInstance;

Usage Examples:

const vibrantRed = Color('#FF4444');

// Increase saturation by 50%
const moreVibrant = vibrantRed.saturate(0.5);

// Decrease saturation by 30% 
const lessVibrant = vibrantRed.desaturate(0.3);

// Convert to grayscale
const grayVersion = vibrantRed.grayscale();
console.log(grayVersion.hex()); // '#808080'

// Create saturation spectrum
function createSaturationSpectrum(color, steps = 5) {
  const spectrum = [];
  for (let i = 0; i <= steps; i++) {
    const ratio = i / steps;
    spectrum.push(color.desaturate(ratio));
  }
  spectrum.push(color.grayscale()); // Fully desaturated
  return spectrum;
}

HWB (Whiteness/Blackness) Manipulation

Adjust colors using the HWB color model for whitening and blackening effects.

/**
 * Increase whiteness by a ratio
 * @param ratio - Multiplier for whiteness increase (0-1+)
 * @returns New ColorInstance with increased whiteness
 */
whiten(ratio: number): ColorInstance;

/**
 * Increase blackness by a ratio
 * @param ratio - Multiplier for blackness increase (0-1+)
 * @returns New ColorInstance with increased blackness
 */
blacken(ratio: number): ColorInstance;

Usage Examples:

const pureRed = Color('#FF0000');

// Add whiteness (tint)
const tintedRed = pureRed.whiten(0.3);
console.log(tintedRed.hex()); // Lighter, pinker red

// Add blackness (shade)
const shadedRed = pureRed.blacken(0.3);
console.log(shadedRed.hex()); // Darker red

// Create tint and shade palettes
function createTintShadeScale(color, steps = 3) {
  const scale = [];
  
  // Shades (add black)
  for (let i = steps; i > 0; i--) {
    scale.push(color.blacken(i * 0.2));
  }
  
  // Original color
  scale.push(color);
  
  // Tints (add white)
  for (let i = 1; i <= steps; i++) {
    scale.push(color.whiten(i * 0.2));
  }
  
  return scale;
}

Alpha (Transparency) Manipulation

Control color transparency with alpha channel operations.

/**
 * Decrease alpha (increase transparency) by a ratio
 * @param ratio - Multiplier for alpha decrease (0-1+)
 * @returns New ColorInstance with reduced alpha
 */
fade(ratio: number): ColorInstance;

/**
 * Increase alpha (decrease transparency) by a ratio
 * @param ratio - Multiplier for alpha increase (0-1+)
 * @returns New ColorInstance with increased alpha
 */
opaquer(ratio: number): ColorInstance;

Usage Examples:

const solidRed = Color('#FF0000'); // Alpha = 1.0

// Make semi-transparent (fade by 50%)
const semiTransparent = solidRed.fade(0.5);
console.log(semiTransparent.alpha()); // 0.5

// Make more opaque from semi-transparent state
const moreOpaque = semiTransparent.opaquer(0.4);
console.log(moreOpaque.alpha()); // 0.7

// Create transparency gradient
function createAlphaGradient(color, steps = 10) {
  const gradient = [];
  for (let i = 0; i <= steps; i++) {
    const alpha = i / steps;
    gradient.push(color.alpha(alpha));
  }
  return gradient;
}

// Fade animations sequence
const fadeSteps = [0.1, 0.2, 0.3, 0.4, 0.5];
const fadeSequence = fadeSteps.map(ratio => solidRed.fade(ratio));

Hue Manipulation

Rotate colors around the color wheel to create complementary and analogous color schemes.

/**
 * Rotate hue by specified degrees
 * @param degrees - Degrees to rotate hue (-360 to 360)
 * @returns New ColorInstance with rotated hue
 */
rotate(degrees: number): ColorInstance;

Usage Examples:

const originalColor = Color('#FF8000'); // Orange

// Rotate to complementary color (180°)
const complement = originalColor.rotate(180);
console.log(complement.hex()); // Blue

// Create triadic color scheme (120° apart)
const triadic = [
  originalColor,
  originalColor.rotate(120),
  originalColor.rotate(240)
];

// Create analogous colors (30° increments)
const analogous = [
  originalColor.rotate(-30),
  originalColor,
  originalColor.rotate(30)
];

// Full rotation creates spectrum
function createHueSpectrum(color, steps = 12) {
  const spectrum = [];
  const increment = 360 / steps;
  for (let i = 0; i < steps; i++) {
    spectrum.push(color.rotate(i * increment));
  }
  return spectrum;
}

// Negative rotation
const rotatedBack = originalColor.rotate(-90);

Color Inversion

Create negative/inverted colors for high contrast effects.

/**
 * Invert/negate the color (RGB complement)
 * @returns New ColorInstance with inverted RGB values
 */
negate(): ColorInstance;

Usage Examples:

const white = Color('#FFFFFF');
const black = Color('#000000');
const red = Color('#FF0000');

// Basic inversion
console.log(white.negate().hex());  // '#000000' (black)
console.log(black.negate().hex());  // '#FFFFFF' (white)
console.log(red.negate().hex());    // '#00FFFF' (cyan)

// Double inversion returns original
const original = Color('#FF8800');
const doubleNegated = original.negate().negate();
console.log(original.hex() === doubleNegated.hex()); // true

// High contrast pairs
function createContrastPair(color) {
  return {
    original: color,
    inverted: color.negate()
  };
}

Color Mixing

Blend two colors together with customizable weight distribution.

/**
 * Mix current color with another color
 * @param mixinColor - Color to mix with
 * @param weight - Mix weight (0-1, default: 0.5)
 * @returns New ColorInstance representing the mixed result
 */
mix(mixinColor: ColorInstance, weight?: number): ColorInstance;

Usage Examples:

const red = Color('#FF0000');
const blue = Color('#0000FF');

// Equal mix (50/50)
const purple = red.mix(blue);
console.log(purple.hex()); // '#800080'

// Weighted mix (70% red, 30% blue)
const reddishPurple = red.mix(blue, 0.7);

// Mix with weight favoring second color
const bluishPurple = red.mix(blue, 0.3);

// Create color gradients
function createGradient(color1, color2, steps = 10) {
  const gradient = [];
  for (let i = 0; i <= steps; i++) {
    const weight = i / steps;
    gradient.push(color1.mix(color2, weight));
  }
  return gradient;
}

// Multi-color mixing
function mixMultipleColors(colors, weights) {
  let result = colors[0];
  for (let i = 1; i < colors.length; i++) {
    const weight = weights[i] || 0.5;
    result = result.mix(colors[i], weight);
  }
  return result;
}

// Alpha preservation in mixing
const transparentRed = Color('#FF0000').alpha(0.5);
const solidBlue = Color('#0000FF');
const mixedWithAlpha = transparentRed.mix(solidBlue, 0.6);
console.log(mixedWithAlpha.alpha()); // Calculated alpha blend

Method Chaining

All manipulation methods return new ColorInstance objects, enabling fluent chaining:

const finalColor = Color('#FF0000')
  .lighten(0.2)           // Lighten by 20%
  .saturate(0.3)          // Increase saturation by 30%
  .rotate(15)             // Rotate hue by 15 degrees
  .fade(0.1)              // Reduce alpha by 10%
  .mix(Color('blue'), 0.1); // Mix with 10% blue

// Complex color theme generation
function generateColorTheme(baseColor) {
  return {
    primary: baseColor,
    secondary: baseColor.rotate(180).desaturate(0.2),
    accent: baseColor.rotate(90).saturate(0.3),
    light: baseColor.lighten(0.4).desaturate(0.3),
    dark: baseColor.darken(0.3).saturate(0.1),
    muted: baseColor.desaturate(0.6).darken(0.1)
  };
}

Immutability Guarantee

All manipulation methods preserve the original Color instance:

const original = Color('#FF8000');
const modified1 = original.lighten(0.5);
const modified2 = original.darken(0.3);

console.log(original.hex());  // '#FF8000' (unchanged)
console.log(modified1.hex()); // Lightened version
console.log(modified2.hex()); // Darkened version

// Safe to reuse original for multiple operations
const variations = [
  original.lighten(0.2),
  original.darken(0.2),
  original.saturate(0.3),
  original.desaturate(0.3)
];