Add a 'randomize colors' button to mandala and creature pages. (#68)

The random colors are currently terrible!  Maneesh will help us make them better. :)

Also, there is some annoying code duplication going on here between the creature and mandala pages, but I really wanted to add the button to both and also want to eat dinner soon, so I am filing #67 and saving the refactoring for later.
pull/72/head
Atul Varma 2021-03-30 20:59:45 -04:00 zatwierdzone przez GitHub
rodzic 5e74ce34ea
commit 2c53e5caab
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 88 dodań i 0 usunięć

Wyświetl plik

@ -28,6 +28,7 @@ import { ColorWidget } from "../color-widget";
import { NumericSlider } from "../numeric-slider";
import { DEFAULT_BG_COLOR } from "../colors";
import { Checkbox } from "../checkbox";
import { createRandomColorPalette } from "../random-colors";
/** Symbols that can be the "root" (i.e., main body) of a creature. */
const ROOT_SYMBOLS = SvgVocabulary.items.filter(
@ -192,6 +193,11 @@ export const CreaturePage: React.FC<{}> = () => {
rng: new Random(randomSeed),
randomlyInvert,
});
const randomizeColors = () => {
const [bgColor, stroke, fill] = createRandomColorPalette(3);
setBgColor(bgColor);
setSymbolCtx({ ...symbolCtx, stroke, fill });
};
return (
<>
@ -199,6 +205,11 @@ export const CreaturePage: React.FC<{}> = () => {
<SymbolContextWidget ctx={symbolCtx} onChange={setSymbolCtx}>
<ColorWidget label="Background" value={bgColor} onChange={setBgColor} />{" "}
</SymbolContextWidget>
<div className="thingy">
<button accessKey="c" onClick={randomizeColors}>
Randomize <u>c</u>olors!
</button>
</div>
<div className="thingy">
<NumericSlider
label="Random creature complexity"

Wyświetl plik

@ -29,6 +29,7 @@ import { Random } from "../random";
import { PointWithNormal } from "../specs";
import { getAttachmentTransforms } from "../attach";
import { Checkbox } from "../checkbox";
import { createRandomColorPalette } from "../random-colors";
type ExtendedMandalaCircleParams = MandalaCircleParams & {
scaling: number;
@ -268,6 +269,12 @@ export const MandalaPage: React.FC<{}> = () => {
const circle2SymbolCtx = invertCircle2 ? swapColors(symbolCtx) : symbolCtx;
const randomizeColors = () => {
const [bgColor, stroke, fill] = createRandomColorPalette(3);
setBgColor(bgColor);
setBaseSymbolCtx({ ...baseSymbolCtx, stroke, fill });
};
const circles = [
<ExtendedMandalaCircle key="first" {...circle1} {...symbolCtx} />,
];
@ -293,6 +300,11 @@ export const MandalaPage: React.FC<{}> = () => {
onChange={setBgColor}
/>{" "}
</SymbolContextWidget>
<div className="thingy">
<button accessKey="c" onClick={randomizeColors}>
Randomize <u>c</u>olors!
</button>
</div>
<fieldset>
<legend>First circle</legend>
<ExtendedMandalaCircleParamsWidget

Wyświetl plik

@ -0,0 +1,27 @@
import { clampedByteToHex, createRandomColorPalette } 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");
});
});
test("createRandomColorPalette() works", () => {
const palette = createRandomColorPalette(3);
expect(palette).toHaveLength(3);
for (let color of palette) {
expect(color).toMatch(/^\#[0-9a-f]{6}$/);
}
});

Wyświetl plik

@ -0,0 +1,38 @@
import { Random } from "./random";
import { range } from "./util";
/**
* 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 rgb = range(3).map(() => rng.inRange({ min: 0, max: 255, step: 1 }));
return "#" + rgb.map(clampedByteToHex).join("");
}
/**
* 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));
}