import React from "react"; import { getAttachmentTransforms } from "./attach"; import { getBoundingBoxCenter } from "./bounding-box"; import { PointWithNormal } from "./specs"; import { safeGetAttachmentPoint, SvgSymbolContent, SvgSymbolContext, SvgSymbolData, swapColors, } from "./svg-symbol"; import { svgRotate, SvgTransform, svgTranslate } from "./svg-transform"; import { isEvenNumber, range } from "./util"; /** * Returns the anchor point of the given symbol; if it doesn't have * an anchor point, return a reasonable default one by taking the * center of the symbol and having the normal point along the negative * y-axis (i.e., up). */ function getAnchorOrCenter(symbol: SvgSymbolData): PointWithNormal { return ( safeGetAttachmentPoint(symbol, "anchor") || { point: getBoundingBoxCenter(symbol.bbox), normal: { x: 0, y: -1 }, } ); } export type MandalaCircleParams = { data: SvgSymbolData; radius: number; numSymbols: number; symbolTransforms?: SvgTransform[]; invertEveryOtherSymbol: boolean; }; export type MandalaCircleProps = MandalaCircleParams & SvgSymbolContext; export const MandalaCircle: React.FC = (props) => { const degreesPerItem = 360 / props.numSymbols; const { translation, rotation } = getAttachmentTransforms( { point: { x: 0, y: 0 }, normal: { x: 0, y: -1 }, }, getAnchorOrCenter(props.data) ); const transform: SvgTransform[] = [ // Remember that transforms are applied in reverse order, // so read the following from the end first! // Finally, move the symbol out along the radius of the circle. svgTranslate({ x: 0, y: -props.radius }), // Then apply any individual symbol transformations. ...(props.symbolTransforms || []), // First, re-orient the symbol so its anchor point is at // the origin and facing the proper direction. svgRotate(rotation), svgTranslate(translation), ]; const invertEveryOtherSymbol = isEvenNumber(props.numSymbols) && props.invertEveryOtherSymbol; const symbols = range(props.numSymbols) .reverse() .map((i) => ( {invertEveryOtherSymbol && isEvenNumber(i) ? ( ) : ( )} )); return <>{symbols}; };