Add randomizer widget. (#87)

This replaces the "randomize colors" and "randomize" buttons on the creature and mandala pages with a single randomizer widget that allows the user to choose whether they want to randomize the colors, symbols, or both.

By default, both colors and symbols are randomized.

Note that this is really only a temporary solution, though: ideally we'll want to provide a more powerful UI that allows users to mark _any_ parameter for randomization, e.g. via "pinning" values or somesuch.
pull/79/head
Atul Varma 2021-04-08 20:13:54 -04:00 zatwierdzone przez GitHub
rodzic fe069ba2e7
commit 7fc210f671
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 72 dodań i 24 usunięć

Wyświetl plik

@ -26,6 +26,7 @@ import {
createSvgCompositionContext,
} from "../svg-composition-context";
import { Page } from "../page";
import { RandomizerWidget } from "../randomizer-widget";
/** Symbols that can be the "root" (i.e., main body) of a creature. */
const ROOT_SYMBOLS = SvgVocabulary.items.filter(
@ -214,10 +215,11 @@ export const CreaturePage: React.FC<{}> = () => {
onChange={setRandomlyInvert}
/>
</div>
<RandomizerWidget
onColorsChange={(colors) => setCompCtx({ ...compCtx, ...colors })}
onSymbolsChange={newRandomSeed}
/>
<div className="thingy">
<button accessKey="r" onClick={newRandomSeed}>
<u>R</u>andomize!
</button>{" "}
<ExportWidget
basename={getDownloadBasename(randomSeed)}
svgRef={svgRef}

Wyświetl plik

@ -21,6 +21,7 @@ import {
import { Page } from "../page";
import { MandalaCircle, MandalaCircleParams } from "../mandala-circle";
import { useAnimationPct } from "../animation";
import { RandomizerWidget } from "../randomizer-widget";
type ExtendedMandalaCircleParams = MandalaCircleParams & {
scaling: number;
@ -215,11 +216,6 @@ export const MandalaPage: React.FC<{}> = () => {
const [useTwoCircles, setUseTwoCircles] = useState(false);
const [invertCircle2, setInvertCircle2] = useState(true);
const [firstBehindSecond, setFirstBehindSecond] = useState(false);
const randomize = () => {
const rng = new Random(Date.now());
setCircle1({ ...circle1, ...getRandomCircleParams(rng) });
setCircle2({ ...circle2, ...getRandomCircleParams(rng) });
};
const isAnimated = isAnyMandalaCircleAnimated([circle1, circle2]);
const animPct = useAnimationPct(isAnimated ? durationSecs * 1000 : 0);
const symbolCtx = noFillIfShowingSpecs(baseCompCtx);
@ -295,10 +291,16 @@ export const MandalaPage: React.FC<{}> = () => {
{...DURATION_SECS}
/>
)}
<RandomizerWidget
onColorsChange={(colors) =>
setBaseCompCtx({ ...baseCompCtx, ...colors })
}
onSymbolsChange={(rng) => {
setCircle1({ ...circle1, ...getRandomCircleParams(rng) });
setCircle2({ ...circle2, ...getRandomCircleParams(rng) });
}}
/>
<div className="thingy">
<button accessKey="r" onClick={randomize}>
<u>R</u>andomize!
</button>{" "}
<ExportWidget basename="mandala" svgRef={svgRef} />
</div>
</div>

Wyświetl plik

@ -0,0 +1,56 @@
import React, { useState } from "react";
import { Random } from "./random";
import { createRandomColorPalette } from "./random-colors";
import { SvgCompositionContext } from "./svg-composition-context";
type SvgCompositionColors = Pick<
SvgCompositionContext,
"background" | "fill" | "stroke"
>;
function createRandomCompositionColors(): SvgCompositionColors {
const [background, stroke, fill] = createRandomColorPalette(3);
return { background, stroke, fill };
}
export type RandomizerWidgetProps = {
onColorsChange: (changes: SvgCompositionColors) => void;
onSymbolsChange: (rng: Random) => void;
};
export const RandomizerWidget: React.FC<RandomizerWidgetProps> = (props) => {
type RandType = "colors" | "symbols" | "colors and symbols";
const [randType, setRandType] = useState<RandType>("colors and symbols");
const randomize = () => {
if (randType === "colors" || randType === "colors and symbols") {
props.onColorsChange(createRandomCompositionColors());
}
if (randType === "symbols" || randType === "colors and symbols") {
props.onSymbolsChange(new Random(Date.now()));
}
};
const makeRadio = (kind: RandType) => (
<label className="checkbox">
<input
type="radio"
name="randomize_type"
value={kind}
checked={randType === kind}
onChange={(e) => setRandType(e.target.value as RandType)}
/>{" "}
Randomize {kind}
</label>
);
return (
<fieldset>
<legend>Randomizer</legend>
{makeRadio("colors")}
{makeRadio("symbols")}
{makeRadio("colors and symbols")}
<button accessKey="r" onClick={randomize}>
<u>R</u>andomize!
</button>
</fieldset>
);
};

Wyświetl plik

@ -1,7 +1,6 @@
import React from "react";
import { ColorWidget } from "./color-widget";
import { DEFAULT_BG_COLOR } from "./colors";
import { createRandomColorPalette } from "./random-colors";
import { createSvgSymbolContext, SvgSymbolContext } from "./svg-symbol";
import {
SymbolContextWidget,
@ -36,19 +35,8 @@ export function CompositionContextWidget<T extends SvgCompositionContext>({
onChange,
children,
}: CompositionContextWidgetProps<T>): JSX.Element {
const randomizeColors = () => {
const [background, stroke, fill] = createRandomColorPalette(3);
onChange({ ...ctx, background, stroke, fill });
};
const extra = (
<button accessKey="c" onClick={randomizeColors}>
Randomize <u>c</u>olors!
</button>
);
return (
<SymbolContextWidget ctx={ctx} onChange={onChange} extraButtons={extra}>
<SymbolContextWidget ctx={ctx} onChange={onChange}>
{children}
<ColorWidget
label="Background"