mysticsymbolic.github.io/lib/random-colors.ts

71 wiersze
2.0 KiB
TypeScript

import { Random } from "./random";
import { range } from "./util";
import * as colorspaces from "colorspaces";
/**
* Clamp the given number to be between 0 and 255, then
* convert it to hexadecimal.
*/
export function clampedByteToHex(value: number): string {
if (value < 0) {
value = 0;
} else if (value > 255) {
value = 255;
}
let hex = value.toString(16);
if (hex.length === 1) {
hex = "0" + hex;
}
return hex;
}
function createRandomColor(rng: Random): string {
const max_luv_samples = 100;
let luv_sample_failed = true;
let rand_color_hex: string = "#000000";
//See if we can pull out a sample inside the LUV solid
for (let i = 0; i < max_luv_samples; i++) {
//bounds from https://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor
let L = rng.inInterval({ min: 0, max: 100 });
let u = rng.inInterval({ min: -134, max: 220 });
let v = rng.inInterval({ min: -140, max: 122 });
let rand_color = colorspaces.make_color("CIELUV", [L, u, v]);
//console.log(`L:${L},u${u},v${v}`);
if (rand_color.is_displayable() && !(L == 0.0 && (u != 0 || v != 0))) {
rand_color_hex = rand_color.as("hex");
//console.log(rand_color_hex);
luv_sample_failed = false;
break;
}
}
//just sample sRGB if I couldn't sample a random LUV color
if (luv_sample_failed) {
//console.log("Sampling sRGB");
let rgb = [0, 0, 0].map(
() => rng.inRange({ min: 0, max: 255, step: 1 }) / 255.0
);
//console.log(rgb);
let rand_color = colorspaces.make_color("sRGB", rgb);
rand_color_hex = rand_color.as("hex");
}
return rand_color_hex;
}
/**
* Create a random color palette with the given number of
* entries, optionally using the given random number generator.
*
* The return value is an Array of strings, where each string is
* a color hex hash (e.g. `#ff0000`).
*/
export function createRandomColorPalette(
numEntries: number,
rng: Random = new Random()
): string[] {
return range(numEntries).map(() => createRandomColor(rng));
}