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
rodzic
fe069ba2e7
commit
7fc210f671
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
|
@ -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"
|
||||
|
|
Ładowanie…
Reference in New Issue