Factor out color-util.ts. (#130)
This fixes #129 and also factors out a new function, `clampedBytesToRGBColor()`.pull/131/head
rodzic
902dfa23fa
commit
f3ab28f70d
|
@ -0,0 +1,25 @@
|
|||
import { clampedBytesToRGBColor, clampedByteToHex } from "./color-util";
|
||||
|
||||
describe("clampedBytesToRGBColor", () => {
|
||||
it("works", () => {
|
||||
expect(clampedBytesToRGBColor([999, 5, 171])).toBe("#ff05ab");
|
||||
});
|
||||
});
|
||||
|
||||
describe("clampedByteToHex", () => {
|
||||
it("clamps values over 255 to 255", () => {
|
||||
expect(clampedByteToHex(500)).toBe("ff");
|
||||
});
|
||||
|
||||
it("clamps values under 0 to 0", () => {
|
||||
expect(clampedByteToHex(-50)).toBe("00");
|
||||
});
|
||||
|
||||
it("zero-pads values", () => {
|
||||
expect(clampedByteToHex(10)).toBe("0a");
|
||||
});
|
||||
|
||||
it("works with numbers that don't need zero-padding", () => {
|
||||
expect(clampedByteToHex(22)).toBe("16");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given array of numbers to an RGB hex value.
|
||||
*/
|
||||
export function clampedBytesToRGBColor(values: number[]): string {
|
||||
return "#" + values.map(clampedByteToHex).join("");
|
||||
}
|
|
@ -7,7 +7,6 @@ import type {
|
|||
AvroSvgCompositionContext,
|
||||
} from "./mandala-design.avsc";
|
||||
import * as avro from "avro-js";
|
||||
import { clampedByteToHex } from "../../random-colors";
|
||||
import {
|
||||
MANDALA_DESIGN_DEFAULTS,
|
||||
ExtendedMandalaCircleParams,
|
||||
|
@ -15,6 +14,7 @@ import {
|
|||
getCirclesFromDesign,
|
||||
} from "./core";
|
||||
import { fromBase64, toBase64 } from "../../base64";
|
||||
import { clampedBytesToRGBColor } from "../../color-util";
|
||||
|
||||
const avroMandalaDesign = avro.parse<AvroMandalaDesign>(MandalaAvsc);
|
||||
|
||||
|
@ -70,7 +70,7 @@ export const ColorPacker: Packer<string, number> = {
|
|||
const red = (number >> 16) & 0xff;
|
||||
const green = (number >> 8) & 0xff;
|
||||
const blue = number & 0xff;
|
||||
return "#" + [red, green, blue].map(clampedByteToHex).join("");
|
||||
return clampedBytesToRGBColor([red, green, blue]);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,27 +1,8 @@
|
|||
import {
|
||||
clampedByteToHex,
|
||||
createRandomColorPalette,
|
||||
RANDOM_PALETTE_ALGORITHMS,
|
||||
} from "./random-colors";
|
||||
|
||||
describe("clampedByteToHex", () => {
|
||||
it("clamps values over 255 to 255", () => {
|
||||
expect(clampedByteToHex(500)).toBe("ff");
|
||||
});
|
||||
|
||||
it("clamps values under 0 to 0", () => {
|
||||
expect(clampedByteToHex(-50)).toBe("00");
|
||||
});
|
||||
|
||||
it("zero-pads values", () => {
|
||||
expect(clampedByteToHex(10)).toBe("0a");
|
||||
});
|
||||
|
||||
it("works with numbers that don't need zero-padding", () => {
|
||||
expect(clampedByteToHex(22)).toBe("16");
|
||||
});
|
||||
});
|
||||
|
||||
describe("createRandomColorPalette()", () => {
|
||||
for (let alg of RANDOM_PALETTE_ALGORITHMS) {
|
||||
it(`works using the '${alg}' algorithm`, () => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Random } from "./random";
|
|||
import { range, clamp } from "./util";
|
||||
import * as colorspaces from "colorspaces";
|
||||
import { ColorTuple, hsluvToHex } from "hsluv";
|
||||
import { clampedBytesToRGBColor } from "./color-util";
|
||||
|
||||
type RandomPaletteGenerator = (numEntries: number, rng: Random) => string[];
|
||||
//type ColorFunction = (rng: Random) => string[];
|
||||
|
@ -18,26 +19,9 @@ export type RandomPaletteAlgorithm = "RGB" | "CIELUV" | "threevals";
|
|||
export const DEFAULT_RANDOM_PALETTE_ALGORITHM: RandomPaletteAlgorithm =
|
||||
"threevals";
|
||||
|
||||
/**
|
||||
* 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 createRandomRGBColor(rng: Random): string {
|
||||
const rgb = range(3).map(() => rng.inRange({ min: 0, max: 255, step: 1 }));
|
||||
return "#" + rgb.map(clampedByteToHex).join("");
|
||||
return clampedBytesToRGBColor(rgb);
|
||||
}
|
||||
|
||||
function createRandomCIELUVColor(rng: Random): string {
|
||||
|
|
|
@ -11,8 +11,8 @@ import {
|
|||
} from "./svg-symbol";
|
||||
import toml from "toml";
|
||||
import { validateSvgSymbolMetadata } from "./svg-symbol-metadata";
|
||||
import { clampedByteToHex } from "./random-colors";
|
||||
import { withoutNulls } from "./util";
|
||||
import { clampedBytesToRGBColor } from "./color-util";
|
||||
|
||||
const SUPPORTED_SVG_TAG_ARRAY: SvgSymbolElement["tagName"][] = ["g", "path"];
|
||||
const SUPPORTED_SVG_TAGS = new Set(SUPPORTED_SVG_TAG_ARRAY);
|
||||
|
@ -108,7 +108,7 @@ function parseRadialGradient(el: cheerio.TagElement): SvgSymbolDef {
|
|||
.map((value) => parseInt(value));
|
||||
stops.push({
|
||||
offset: getNonEmptyAttrib(child, "offset"),
|
||||
color: "#" + rgb.map(clampedByteToHex).join(""),
|
||||
color: clampedBytesToRGBColor(rgb),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue