Last active
November 3, 2023 08:52
-
-
Save AndreasHerz/e9fd4f813b192943c5386f84a07638f6 to your computer and use it in GitHub Desktop.
generates a color for a value in a given range of values
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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