toosoon-utils
Version:
Utility functions & classes
125 lines (124 loc) • 3.95 kB
JavaScript
import Color from './Color';
import ColorScale from './ColorScale';
/**
* Utility class for generating color palettes
*
* @exports
* @class ColorPalette
*/
export default class ColorPalette {
isColorPalette = true;
type = 'ColorPalette';
_base = new Color();
/**
* Object containing this color palette color scales
*/
scales = {};
/**
* Object containing this color palette generators
*/
generators = {};
/**
* @param {Color|ColorRepresentation} color Base color
* @param {object} generators Object containing generators
*/
constructor(color, generators = {}) {
this.base = color;
this.generators = generators;
this.update();
}
/**
* Pick an interpolated color from one of this color palette color scale
*
* @param {string} key Name of the color scale
* @param {number} t Normalized time value to interpolate
* @returns {Color} Interpolated color
*/
getColor(key, t) {
return this.scales[key]?.getColor(t) ?? this.base.clone();
}
/**
* Add a given generator to this color palette
*
* @param {string} key Name of the generator
* @param {ColorPaletteGenerator} generator Generator to add
*/
subscribe(key, generator) {
this.generators[key] = generator;
this.scales[key] = this.generate(generator);
}
/**
* Generate a color scale
*
* @param {ColorPaletteGenerator} generator Generator interface to use for generation
* @param {ColorInterpolation} generator.interpolation Type of interpolation used for generation
* @param {number} generator.length Amount of colors to generate
* @param {Color} [generator.target] Target color to interpolate towards
* @param {ColorScaleProcessingParameters} [generator.processing] Target color processing parameters, for processing the target color before generation
* @param {object} [generator.params] Interpolation parameters
* @returns {ColorScale} Generated color scale
*/
generate(generator) {
const { interpolation, length, target: color, processing, params } = generator;
const base = ColorScale.processColor(this.base.clone(), params?.preprocessing);
const target = ColorScale.processColor(color ?? this.base.clone(), processing);
return new ColorScale().generate(interpolation, length, base, target, params).process(params?.postprocessing);
}
/**
* Update this color palette color scales
*/
update() {
for (let key in this.generators) {
const generator = this.generators[key];
this.scales[key] = this.generate(generator);
}
}
/**
* Base color of this color palette
*/
set base(color) {
this._base.set(color);
this.update();
}
get base() {
return this._base;
}
}
/** Generators */
const length = 9;
export const LightScaleGenerator = {
interpolation: 'hsl',
length,
processing: { hsl: { lightness: 1 - 1 / length } },
params: {
preprocessing: { hsl: { lightness: 0.5 } },
postprocessing: {}
}
};
export const DarkScaleGenerator = {
interpolation: 'hsl',
length,
processing: { hsl: { lightness: 1 / length } },
params: {
preprocessing: { hsl: { lightness: 0.5 } },
postprocessing: {}
}
};
export const SequentialLightGenerator = {
interpolation: 'sequential',
length,
processing: { hcl: { luminance: 100 } },
params: {
preprocessing: { hcl: { luminance: 50 } },
postprocessing: {}
}
};
export const SequentialDarkGenerator = {
interpolation: 'sequential',
length,
processing: { hcl: { luminance: 0 } },
params: {
preprocessing: { hcl: { luminance: 50 } },
postprocessing: {}
}
};