2021-02-15 13:34:22 +00:00
|
|
|
import React from "react";
|
|
|
|
import { Random } from "../random";
|
|
|
|
import { SvgVocabulary } from "../svg-vocabulary";
|
2021-02-15 14:56:02 +00:00
|
|
|
import {
|
|
|
|
createSvgSymbolContext,
|
|
|
|
SvgSymbolContent,
|
|
|
|
SvgSymbolData,
|
|
|
|
} from "../svg-symbol";
|
2021-02-15 21:40:47 +00:00
|
|
|
import { AttachmentPointType, PointWithNormal } from "../specs";
|
|
|
|
import { subtractPoints } from "../point";
|
2021-02-15 14:56:02 +00:00
|
|
|
|
|
|
|
const SYMBOL_MAP = new Map(
|
|
|
|
SvgVocabulary.map((symbol) => [symbol.name, symbol])
|
|
|
|
);
|
|
|
|
|
|
|
|
function getSymbol(name: string): SvgSymbolData {
|
|
|
|
const symbol = SYMBOL_MAP.get(name);
|
|
|
|
if (!symbol) {
|
|
|
|
throw new Error(`Unable to find the symbol "${name}"!`);
|
|
|
|
}
|
|
|
|
return symbol;
|
|
|
|
}
|
2021-02-15 13:34:22 +00:00
|
|
|
|
2021-02-15 21:40:47 +00:00
|
|
|
function getAttachmentPoint(
|
|
|
|
s: SvgSymbolData,
|
|
|
|
type: AttachmentPointType,
|
|
|
|
idx: number = 0
|
|
|
|
): PointWithNormal {
|
|
|
|
const { specs } = s;
|
|
|
|
if (!specs) {
|
|
|
|
throw new Error(`Symbol ${s.name} has no specs!`);
|
|
|
|
}
|
|
|
|
const points = specs[type];
|
|
|
|
if (!(points && points.length > idx)) {
|
|
|
|
throw new Error(
|
|
|
|
`Symbol ${s.name} must have at least ${
|
|
|
|
idx + 1
|
|
|
|
} ${type} attachment point(s)!`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return points[idx];
|
|
|
|
}
|
|
|
|
|
2021-02-15 13:34:22 +00:00
|
|
|
export const CreaturePage: React.FC<{}> = () => {
|
|
|
|
const rand = new Random(1);
|
|
|
|
const parts: string[] = [];
|
2021-02-15 21:40:47 +00:00
|
|
|
const ctx = createSvgSymbolContext({ showSpecs: false });
|
2021-02-15 14:56:02 +00:00
|
|
|
const eye = getSymbol("eye");
|
|
|
|
const hand = getSymbol("hand");
|
2021-02-15 13:34:22 +00:00
|
|
|
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
|
|
parts.push(rand.choice(SvgVocabulary).name);
|
|
|
|
}
|
|
|
|
|
2021-02-15 21:40:47 +00:00
|
|
|
const handTail = getAttachmentPoint(hand, "tail");
|
|
|
|
const eyeCrown = getAttachmentPoint(eye, "crown");
|
|
|
|
|
|
|
|
const dist = subtractPoints(eyeCrown.point, handTail.point);
|
|
|
|
|
2021-02-15 13:34:22 +00:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<h1>Creature!</h1>
|
2021-02-15 14:56:02 +00:00
|
|
|
<svg width="1280px" height="720px">
|
|
|
|
<SvgSymbolContent data={eye} {...ctx} />
|
2021-02-15 21:40:47 +00:00
|
|
|
<g transform={`translate(${dist.x} ${dist.y})`}>
|
|
|
|
<g
|
|
|
|
transform-origin={`${handTail.point.x} ${handTail.point.y}`}
|
|
|
|
transform={`scale(0.25 0.25)`}
|
|
|
|
>
|
|
|
|
<SvgSymbolContent data={hand} {...ctx} />
|
|
|
|
</g>
|
2021-02-15 14:56:02 +00:00
|
|
|
</g>
|
|
|
|
</svg>
|
2021-02-15 13:34:22 +00:00
|
|
|
<p>TODO: Make a creature with maybe the following parts:</p>
|
|
|
|
<ul>
|
|
|
|
{parts.map((name, i) => (
|
|
|
|
<li key={i}>{name}</li>
|
|
|
|
))}
|
|
|
|
</ul>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|