From d742f4156a538ca0b2ec66cb5d1f20f6c939d3cf Mon Sep 17 00:00:00 2001 From: Atul Varma Date: Sun, 28 Mar 2021 08:27:57 -0400 Subject: [PATCH] Add an optional second mandala circle (#24). --- lib/pages/mandala-page.tsx | 182 +++++++++++++++++++++++++++---------- 1 file changed, 132 insertions(+), 50 deletions(-) diff --git a/lib/pages/mandala-page.tsx b/lib/pages/mandala-page.tsx index 7d04a33..47b79b0 100644 --- a/lib/pages/mandala-page.tsx +++ b/lib/pages/mandala-page.tsx @@ -12,6 +12,7 @@ import { SvgSymbolContent, SvgSymbolContext, SvgSymbolData, + swapColors, } from "../svg-symbol"; import { VocabularyWidget } from "../vocabulary-widget"; import { @@ -26,8 +27,39 @@ import { NumericRange, range } from "../util"; import { Random } from "../random"; import { PointWithNormal } from "../specs"; import { getAttachmentTransforms } from "../attach"; +import { Checkbox } from "../checkbox"; -const EYE = SvgVocabulary.get("eye_vertical"); +const CIRCLE_1_DEFAULTS: MandalaCircleParams = { + data: SvgVocabulary.get("eye_vertical"), + radius: 50, + numSymbols: 6, +}; + +const CIRCLE_2_DEFAULTS: MandalaCircleParams = { + data: SvgVocabulary.get("leg"), + radius: 0, + numSymbols: 3, +}; + +const CIRCLE_2_DEFAULT_SCALE = 0.5; + +const RADIUS: NumericRange = { + min: 0, + max: 1000, + step: 1, +}; + +const NUM_SYMBOLS: NumericRange = { + min: 1, + max: 30, + step: 1, +}; + +const SCALE: NumericRange = { + min: 0.1, + max: 2, + step: 0.1, +}; /** * Returns the anchor point of the given symbol; if it doesn't have @@ -44,13 +76,15 @@ function getAnchorOrCenter(symbol: SvgSymbolData): PointWithNormal { ); } -const MandalaCircle: React.FC< - { - data: SvgSymbolData; - radius: number; - numSymbols: number; - } & SvgSymbolContext -> = (props) => { +type MandalaCircleParams = { + data: SvgSymbolData; + radius: number; + numSymbols: number; +}; + +const MandalaCircle: React.FC = ( + props +) => { const degreesPerItem = 360 / props.numSymbols; const { translation, rotation } = getAttachmentTransforms( { @@ -83,62 +117,110 @@ const MandalaCircle: React.FC< return <>{symbols}; }; -type NumericParams = NumericRange & { default: number }; - -const RADIUS: NumericParams = { - min: 0, - max: 1000, - step: 1, - default: 50, +const MandalaCircleParamsWidget: React.FC<{ + idPrefix: string; + value: MandalaCircleParams; + onChange: (value: MandalaCircleParams) => void; +}> = ({ idPrefix, value, onChange }) => { + return ( +
+ onChange({ ...value, data })} + choices={SvgVocabulary} + /> + onChange({ ...value, radius })} + {...RADIUS} + /> + onChange({ ...value, numSymbols })} + {...NUM_SYMBOLS} + /> +
+ ); }; -const NUM_SYMBOLS: NumericParams = { - min: 1, - max: 30, - step: 1, - default: 6, -}; +function getRandomCircleParams(rng: Random): MandalaCircleParams { + return { + data: rng.choice(SvgVocabulary.items), + radius: rng.inRange(RADIUS), + numSymbols: rng.inRange(NUM_SYMBOLS), + }; +} export const MandalaPage: React.FC<{}> = () => { const svgRef = useRef(null); const [bgColor, setBgColor] = useState(DEFAULT_BG_COLOR); - const [symbol, setSymbol] = useState(EYE); + const [circle1, setCircle1] = useState( + CIRCLE_1_DEFAULTS + ); + const [circle2, setCircle2] = useState( + CIRCLE_2_DEFAULTS + ); const [symbolCtx, setSymbolCtx] = useState(createSvgSymbolContext()); - const [radius, setRadius] = useState(RADIUS.default); - const [numSymbols, setNumSymbols] = useState(NUM_SYMBOLS.default); + const [useTwoCircles, setUseTwoCircles] = useState(false); + const [invertCircle2, setInvertCircle2] = useState(true); + const [circle2Scale, setCircle2Scale] = useState(CIRCLE_2_DEFAULT_SCALE); const randomize = () => { const rng = new Random(Date.now()); - setRadius(rng.inRange(RADIUS)); - setNumSymbols(rng.inRange(NUM_SYMBOLS)); - setSymbol(rng.choice(SvgVocabulary.items)); + setCircle1(getRandomCircleParams(rng)); + setCircle2(getRandomCircleParams(rng)); + setCircle2Scale(rng.inRange(SCALE)); }; + const circle2SymbolCtx = invertCircle2 ? swapColors(symbolCtx) : symbolCtx; + return ( <>

Mandala!

{" "} +
+ First circle + +
- - -
+ {useTwoCircles && ( +
+ Second circle + + + +
+ )}