Back to Color Thief

Color Thief v3

index.html

3.3.15.1 KB
Original Source

01

Loading the Library

Color Thief works in browsers and Node.js. Pick the method that fits your setup.

Install

npm install colorthief

ESM (bundlers & Node.js)

import { getColorSync, getPaletteSync } from 'colorthief';

CommonJS (Node.js)

const { getColor, getPalette } = require('colorthief');

Script tag (no build step)

`<script src="https://unpkg.com/colorthief@3/dist/umd/color-thief.global.js"></script>

<script> const color = ColorThief.getColorSync(img); </script>`

ES module in the browser (no bundler)

<script type="module"> import { getColorSync } from 'https://unpkg.com/colorthief@3/dist/index.js'; </script> 02

getColorSync()

The simplest way to use Color Thief. Extract the single dominant color from an image, synchronously.

const color = getColorSync(img); color.hex(); // '#e84393' color.textColor; // '#000000'

03

getPaletteSync()

Extract a multi-color palette. Each color in the palette is a full Color object.

const palette = getPaletteSync(img, { colorCount: 8 }); palette.forEach(c => console.log(c.hex()));

04

Color Object

Every extracted color is a rich object with format conversions, accessibility metadata, and contrast ratios.

`const color = getColorSync(img);

color.rgb() // { r, g, b } color.hex() // '#rrggbb' color.hsl() // { h, s, l } color.oklch() // { l, c, h } color.css() // 'rgb(255, 128, 0)' — also 'hsl' and 'oklch' color.array() // [r, g, b] color.toString() // '#rrggbb' — works in template literals color.textColor // '#ffffff' or '#000000' color.isDark // true/false color.isLight // true/false color.contrast // { white, black, foreground } color.population // raw pixel count color.proportion // 0–1 share of total`

05

getSwatchesSync()

Classify palette colors into six semantic roles: Vibrant, Muted, DarkVibrant, DarkMuted, LightVibrant, LightMuted. Each swatch includes text color recommendations.

const swatches = getSwatchesSync(img); swatches.Vibrant?.color.hex(); // '#e84393' swatches.DarkMuted?.titleTextColor.hex(); // '#ffffff'

06

OKLCH vs RGB Quantization

OKLCH quantization produces more perceptually uniform palettes. Colors that "feel" evenly spaced to the human eye.

`// Default — quantize in sRGB const rgb = getPaletteSync(img, { colorCount: 8 });

// Perceptual — quantize in OKLCH const oklch = getPaletteSync(img, { colorCount: 8, colorSpace: 'oklch' });`

RGB (default)

OKLCH

07

Quality Settings

The quality option controls how many pixels are sampled. Lower values sample more pixels (slower, more accurate). Default is 10.

getPaletteSync(img, { quality: 1 }); // Every pixel getPaletteSync(img, { quality: 10 }); // Every 10th pixel (default) getPaletteSync(img, { quality: 50 }); // Every 50th pixel

08

Async API & Web Workers

The async API works on both browser and Node.js. With worker: true, quantization runs off the main thread.

`// Async (works in browser and Node.js) const palette = await getPalette(img, { colorCount: 6 });

// Offload to Web Worker (browser only) const palette = await getPalette(img, { colorCount: 6, worker: true });`

09

getPaletteProgressive()

Progressively extract a palette in 3 passes. Show a rough result instantly, then refine it. Useful for large images where full extraction takes time.

for await (const { palette, progress, done } of getPaletteProgressive(img)) { updateUI(palette, progress); // progress: 0.06 → 0.25 → 1.0 }

10

AbortController

Cancel in-flight extractions with a standard AbortSignal. Useful when the user navigates away before extraction completes.

`const controller = new AbortController(); controller.abort(); // cancel immediately

try { await getColor(img, { signal: controller.signal }); } catch (e) { console.log(e.name); // 'AbortError' }`

11

createColor()

Build a Color object manually from RGB values. Useful for creating colors programmatically or working with known values.

const color = createColor(232, 67, 147, 1); color.hex(); // '#e84393' color.isDark; // false color.textColor; // '#000000' ${color}; // '#e84393' — toString() returns hex

12

observe()

Reactively watch a source and get palette updates whenever it changes. Works with <video>, <canvas>, and `` elements. For video, extraction runs on each animation frame (throttled) while playing, and on seek. For canvas, it polls via rAF. For images, it uses a MutationObserver to detect src changes.

`const controller = observe(videoElement, { throttle: 200, // ms between updates colorCount: 5, onChange(palette) { const dominant = palette[0]; document.body.style.background = dominant.css(); }, });

controller.stop(); // clean up`

Dominant