lib.ts

 1import chroma, { Scale } from "chroma-js";
 2
 3export type Color = string;
 4export type ColorRampStep = { value: Color; type: "color"; step: number };
 5export type ColorRamp = {
 6  [index: number]: ColorRampStep;
 7};
 8
 9export function colorRamp(
10  color: Color | [Color, Color],
11  options?: { steps?: number; increment?: number }
12): ColorRamp {
13  let scale: Scale;
14  if (Array.isArray(color)) {
15    const [startColor, endColor] = color;
16    scale = chroma.scale([startColor, endColor]);
17  } else {
18    let hue = Math.round(chroma(color).hsl()[0]);
19    let startColor = chroma.hsl(hue, 0.88, 0.96);
20    let endColor = chroma.hsl(hue, 0.68, 0.32);
21    scale = chroma
22      .scale([startColor, color, endColor])
23      .domain([0, 0.5, 1])
24      .mode("hsl")
25      .gamma(1)
26      .correctLightness(true)
27      .padding([0, 0.15]);
28  }
29
30  const ramp: ColorRamp = {};
31  const steps = options?.steps || 10;
32  const increment = options?.increment || 100;
33
34  scale.colors(steps, "hex").forEach((color, ix) => {
35    const step = ix * increment;
36    ramp[step] = {
37      value: color,
38      step,
39      type: "color",
40    };
41  });
42
43  return ramp;
44}