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}