Skip to content

Instantly share code, notes, and snippets.

@AndreasHerz
Last active November 3, 2023 08:52
Show Gist options
  • Save AndreasHerz/e9fd4f813b192943c5386f84a07638f6 to your computer and use it in GitHub Desktop.
Save AndreasHerz/e9fd4f813b192943c5386f84a07638f6 to your computer and use it in GitHub Desktop.
generates a color for a value in a given range of values
import { Injectable } from '@angular/core';
import * as shuffleSeed from 'shuffle-seed';
export interface HslColor {
hue: number;
saturation: number;
lightness: number;
}
@Injectable({
providedIn: 'root'
})
export class ColorGeneratorService {
/**
* The calculation is done with 335 and not with 360,
* because the color circle is getting closed.
* Min- and max- value would otherwise have the same color
*/
private readonly maxColorWheelValue = 335;
private readonly saturationStep = 10;
/** constants for @function generateRandomHslColorArray() */
private readonly defaultStepSize = 2;
private readonly defaultMaxHueValue = 360;
private readonly defaultMinSaturationPercentage = 40;
private readonly defaultMaxSaturationPercentage = 100;
private readonly defaultSeed = (Math.random() * 1000).toString();
private readonly defaultLightnessPercentage = 50;
constructor() {}
/**
* This method generates a color for a value in a given range of values.
* Use it for gradients.
* @param actualValue Value for desired color
* @param startValue start value of value range
* @param endValue End value of value range
* @param lightness HSL lightness value; default is 50; Must be between 0 and 100
* @returns hslColor
*/
public generateColorForValueRange(actualValue: number, startValue: number, endValue: number, lightness?: number): HslColor {
const generatedColor: HslColor = { hue: 0, saturation: 100, lightness: undefined };
!lightness || lightness < 0 || lightness > 100 ? (generatedColor.lightness = 50) : (generatedColor.lightness = lightness);
endValue = endValue - startValue;
actualValue = actualValue - startValue;
if (endValue < this.maxColorWheelValue) {
generatedColor.hue = +((this.maxColorWheelValue / endValue) * actualValue).toFixed();
} else {
const steps = Math.ceil(endValue / this.maxColorWheelValue - 1);
for (let step = 1; step <= steps; step++) {
if (actualValue < this.maxColorWheelValue) {
generatedColor.hue = +((this.maxColorWheelValue - 1 / endValue) * actualValue).toFixed();
generatedColor.saturation = generatedColor.saturation - this.saturationStep * (step - 1);
step = steps;
} else {
actualValue = actualValue - this.maxColorWheelValue - 1;
}
}
}
return generatedColor;
}
/**
* Generates random hsl-color array
* @param seed seed for randomizer; if not provided, value is randum
* @param stepSize saturation step size; if not provided, value is 2
* @param maxHueValue max hue value; if not provided, value is 360
* @param minSaturationPercentage min saturation percentage; if not provided, value is 40
* @param maxSaturationPercentage max saturation percentage; if not provided, value is 100
* @param lightnessPercentage lightness percentage; if not provided, value is 50
* @returns hslColor
*/
public generateRandomHslColorArray(
seed?: string,
stepSize?: number,
maxHueValue?: number,
minSaturationPercentage?: number,
maxSaturationPercentage?: number,
lightnessPercentage?: number
): HslColor[] {
const colors: HslColor[] = [];
!stepSize ? (stepSize = this.defaultStepSize) : (stepSize = stepSize);
!maxHueValue ? (maxHueValue = this.defaultMaxHueValue) : (maxHueValue = maxHueValue);
!minSaturationPercentage
? (minSaturationPercentage = this.defaultMinSaturationPercentage)
: (minSaturationPercentage = minSaturationPercentage);
!maxSaturationPercentage
? (maxSaturationPercentage = this.defaultMaxSaturationPercentage)
: (maxSaturationPercentage = maxSaturationPercentage);
!lightnessPercentage || lightnessPercentage < 0 || lightnessPercentage > 100
? (lightnessPercentage = this.defaultLightnessPercentage)
: (lightnessPercentage = lightnessPercentage);
!seed ? (seed = this.defaultSeed) : (seed = seed);
for (
let saturationValue = maxSaturationPercentage;
saturationValue > minSaturationPercentage;
saturationValue = saturationValue - stepSize
) {
for (let hueValue = maxHueValue; hueValue > 0; hueValue = hueValue - 1) {
colors.push({ hue: hueValue, saturation: saturationValue, lightness: lightnessPercentage });
}
}
return shuffleSeed.shuffle(colors, seed);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment