Add checkbox toggle to show specs.

pull/1/head
Atul Varma 2021-02-13 21:13:04 -05:00
rodzic 5321d9aa48
commit a135b6930b
2 zmienionych plików z 102 dodań i 6 usunięć

Wyświetl plik

@ -28,7 +28,7 @@ export function getBoundingBoxCenter(bbox: Bbox): Point {
};
}
function dilateBoundingBox(bbox: Bbox, amount: number): Bbox {
export function dilateBoundingBox(bbox: Bbox, amount: number): Bbox {
return {
minX: bbox.minX - amount,
maxX: bbox.maxX + amount,

Wyświetl plik

@ -1,7 +1,10 @@
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { getBoundingBoxSize } from "./bounding-box";
import { Point } from "../vendor/bezier-js";
import { Bbox, dilateBoundingBox, getBoundingBoxSize } from "./bounding-box";
import { FILL_REPLACEMENT_COLOR, STROKE_REPLACEMENT_COLOR } from "./colors";
import * as colors from "./colors";
import { Specs } from "./specs";
import _SvgVocabulary from "./svg-vocabulary.json";
import type { SvgSymbolData, SvgSymbolElement } from "./vocabulary";
@ -19,6 +22,7 @@ if (!appEl) {
type SvgSymbolContext = {
stroke: string;
fill: string;
showSpecs: boolean;
};
type SvgSymbolProps = {
@ -56,19 +60,101 @@ function reactifySvgSymbolElement(
);
}
const ATTACHMENT_POINT_RADIUS = 20;
const AttachmentPoints: React.FC<{ color: string; points: Point[] }> = (
props
) => (
<>
{props.points.map((p, i) => (
<circle
key={i}
fill={props.color}
r={ATTACHMENT_POINT_RADIUS}
cx={p.x}
cy={p.y}
/>
))}
</>
);
const BoundingBoxes: React.FC<{ fill: string; bboxes: Bbox[] }> = (props) => (
<>
{props.bboxes.map((b, i) => {
const [width, height] = getBoundingBoxSize(b);
return (
<rect
key={i}
x={b.minX}
y={b.minY}
width={width}
height={height}
fill={props.fill}
/>
);
})}
</>
);
const SvgSymbolSpecs: React.FC<{ specs: Specs }> = ({ specs }) => {
return (
<>
{specs.tail && (
<AttachmentPoints
color={colors.TAIL_ATTACHMENT_COLOR}
points={specs.tail}
/>
)}
{specs.leg && (
<AttachmentPoints
color={colors.LEG_ATTACHMENT_COLOR}
points={specs.leg}
/>
)}
{specs.arm && (
<AttachmentPoints
color={colors.ARM_ATTACHMENT_COLOR}
points={specs.arm}
/>
)}
{specs.horn && (
<AttachmentPoints
color={colors.HORN_ATTACHMENT_COLOR}
points={specs.horn}
/>
)}
{specs.crown && (
<AttachmentPoints
color={colors.CROWN_ATTACHMENT_COLOR}
points={specs.crown}
/>
)}
{specs.nesting && (
<BoundingBoxes
fill={colors.NESTING_BOUNDING_BOX_COLOR}
bboxes={specs.nesting}
/>
)}
</>
);
};
const BBOX_DILATION = 50;
const SvgSymbol: React.FC<SvgSymbolProps> = (props) => {
const d = props.data;
const bbox = dilateBoundingBox(d.bbox, BBOX_DILATION);
const scale = props.scale || 1;
const [width, height] = getBoundingBoxSize(d.bbox);
const [width, height] = getBoundingBoxSize(bbox);
return (
<svg
viewBox={`${d.bbox.minX} ${d.bbox.minY} ${width} ${height}`}
viewBox={`${bbox.minX} ${bbox.minY} ${width} ${height}`}
width={px(width * scale)}
height={px(height * scale)}
style={{ margin: "10px" }}
>
{props.data.layers.map(reactifySvgSymbolElement.bind(null, props))}
{props.showSpecs && d.specs && <SvgSymbolSpecs specs={d.specs} />}
</svg>
);
};
@ -76,6 +162,7 @@ const SvgSymbol: React.FC<SvgSymbolProps> = (props) => {
const App: React.FC<{}> = () => {
const [stroke, setStroke] = useState("#000000");
const [fill, setFill] = useState("#ffffff");
const [showSpecs, setShowSpecs] = useState(false);
return (
<>
@ -94,7 +181,15 @@ const App: React.FC<{}> = () => {
value={fill}
onChange={(e) => setFill(e.target.value)}
id="fill"
/>
/>{" "}
<label>
<input
type="checkbox"
checked={showSpecs}
onChange={(e) => setShowSpecs(e.target.checked)}
/>{" "}
Show specs
</label>
</p>
{SvgVocabulary.map((symbolData) => (
<div
@ -120,6 +215,7 @@ const App: React.FC<{}> = () => {
scale={0.25}
stroke={stroke}
fill={fill}
showSpecs={showSpecs}
/>
</div>
</div>