Skip to content

Manipulation & Interpolation ​

Manipulation ​

lighten(color, amount) ​

string — a #rrggbb color

Increases HSL lightness by amount (0–100), clamped at 100.

darken(color, amount) ​

string — a #rrggbb color

Decreases HSL lightness by amount (0–100), clamped at 0.

saturate(color, amount) ​

string — a #rrggbb color

Increases HSL saturation by amount (0–100), clamped at 100.

desaturate(color, amount) ​

string — a #rrggbb color

Decreases HSL saturation by amount (0–100), clamped at 0.

setAlpha(color, alpha) ​

string — an rgba(r, g, b, alpha) string

Sets the alpha channel (0–1) of any color, regardless of its original format.

getAlpha(color) ​

number — 0–1

Reads the alpha channel of any color; returns 1 when the color has no explicit alpha.

invertColor(color) ​

string — a #rrggbb color

Inverts all three RGB channels (255 - channel).

grayscale(color) ​

string — a #rrggbb color

Converts to grayscale using ITU-R BT.709 perceptual weights (0.2126×r + 0.7152×g + 0.0722×b).

rotateHue(hex, degrees) ​

string — a #rrggbb color

Rotates the hue by the given number of degrees (supports negative values, wraps into 0–360), keeping saturation and lightness unchanged.

adjustHexBrightness(hex, offsetPercent) ​

string — a #rrggbb color

Lightens (positive offsetPercent, -100 to 100) or darkens (negative) by linearly blending each RGB channel toward 255 or 0.

mixColors(c1, c2, t, opts?) ​

ts
function mixColors(
  c1: string,
  c2: string,
  t: number,
  opts?: {
    mode?: 'rgb' | 'hsl' | 'lab' | 'lch' | 'oklab' | 'oklch' // default: 'rgb'
    format?: 'hex' | 'rgb' | 'rgba' | 'hsl' // default: 'hex'
    hueInterpolation?: 'shorter' | 'longer' | 'increasing' | 'decreasing' // default: 'shorter'
  },
): string

string — formatted per opts.format

Interpolates between two colors (c1, c2) in the given color space, at position t (0–1) between them. opts controls the mix mode, output format, and — for hue-based modes — which direction around the color wheel to interpolate.

ts
import { mixColors } from 'color-value-tools'

// RGB mix at midpoint
mixColors('#e74c3c', '#3498db', 0.5)
// → '#8e728c'

// Perceptually even mix in Oklab
mixColors('#e74c3c', '#3498db', 0.5, { mode: 'oklab', format: 'hex' })

// HSL with "longer" hue path
mixColors('#e74c3c', '#3498db', 0.5, { mode: 'hsl', hueInterpolation: 'longer' })

// Get rgba string output
mixColors('#ff0000', '#0000ff', 0.25, { mode: 'lab', format: 'rgba' })

Interpolation & Scales ​

interpolateColors(c1, c2, steps, opts?) ​

string[] — steps colors from c1 to c2, evenly spaced by t

The array-producing counterpart of mixColors (opts takes the same mode/format/hueInterpolation shape) — see generateGradientColors below for a lazy, generator-based equivalent.

createColorScale(anchors, steps, opts?) ​

string[] — a steps-color scale sampled across all anchors

Generates a multi-stop gradient scale, useful for anything beyond a simple two-color mix. anchors accepts either plain colors (evenly spaced) or { color, position } pairs for explicit stops (0–1); opts: { space?: 'rgb' | 'hsl' | 'oklab' | 'oklch'; format?: 'hex' | 'rgb' | 'hsl' } — a narrower space set than mixColors (no lab/lch).

ts
import { createColorScale } from 'color-value-tools'

// Evenly spaced anchors
createColorScale(['#ff0000', '#ffff00', '#00ff00'], 9)

// With explicit positions
createColorScale(
  [
    { color: '#1a1a2e', position: 0 },
    { color: '#e94560', position: 0.4 },
    { color: '#f5a623', position: 1 },
  ],
  12,
  { space: 'oklch' },
)

midpointColor(c1, c2, opts?) ​

string — a #rrggbb color

Shorthand for mixColors(c1, c2, 0.5, { mode: opts.space }) — the perceptual midpoint between two colors. opts: { space?: 'lab' | 'lch' | 'oklab' | 'oklch' }, default 'oklab' — note this option only accepts the 4 perceptual spaces, not rgb/hsl.

Lazy generation ​

generateGradientColors(start, end, steps, opts?) ​

Generator<string>

Lazy, generator-function equivalent of interpolateColors — yields one color at a time instead of building the whole array upfront. Useful for large step counts or frame-by-frame processing. Takes the same start/end/steps as interpolateColors; opts: { mode?: 'rgb' | 'hsl' | 'oklab' | 'oklch'; format?: 'hex' | 'rgb' | 'hsl' } — a narrower option set than mixColors/interpolateColors (no lab/lch modes, no rgba format, no hueInterpolation).

ts
import { generateGradientColors } from 'color-value-tools'

// Process one color at a time — no intermediate array
for (const color of generateGradientColors('#ff0000', '#0000ff', 1000, { mode: 'oklch' })) {
  renderPixel(color)
}