diff --git a/lib/pages/creature-page.tsx b/lib/pages/creature-page.tsx index 1fad373..caa3b7b 100644 --- a/lib/pages/creature-page.tsx +++ b/lib/pages/creature-page.tsx @@ -10,6 +10,7 @@ import { AttachmentPointType, PointWithNormal } from "../specs"; import { getAttachmentTransforms } from "../attach"; import { scalePointXY } from "../point"; import { Point } from "../../vendor/bezier-js"; +import { Random } from "../random"; const SYMBOL_MAP = new Map( SvgVocabulary.map((symbol) => [symbol.name, symbol]) @@ -182,13 +183,13 @@ const AttachmentTransform: React.FC = (props) => ( ); +type CreatureSymbolWithDefaultProps = Omit & { + data?: SvgSymbolData; +}; + function createCreatureSymbol( name: string -): React.FC< - Omit & { - data?: SvgSymbolData; - } -> { +): React.FC { const data = getSymbol(name); return (props) => ; } @@ -230,14 +231,28 @@ const EYE_CREATURE = ( ); +function randomlyReplaceParts(rng: Random, creature: JSX.Element): JSX.Element { + return React.cloneElement(creature, { + data: rng.choice(SvgVocabulary), + children: React.Children.map(creature.props.children, (child, i) => { + return randomlyReplaceParts(rng, child); + }), + }); +} + export const CreaturePage: React.FC<{}> = () => { const [showSpecs, setShowSpecs] = useState(false); + const [randomSeed, setRandomSeed] = useState(null); const defaultCtx = useContext(CreatureContext); const ctx: CreatureContextType = { ...defaultCtx, fill: showSpecs ? "none" : defaultCtx.fill, showSpecs, }; + const creature = + randomSeed === null + ? EYE_CREATURE + : randomlyReplaceParts(new Random(randomSeed), EYE_CREATURE); return ( <> @@ -255,10 +270,13 @@ export const CreaturePage: React.FC<{}> = () => { - {EYE_CREATURE} + {creature} +

+ +

); };