Add checkbox toggle to show specs.
rodzic
5321d9aa48
commit
a135b6930b
|
@ -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 {
|
return {
|
||||||
minX: bbox.minX - amount,
|
minX: bbox.minX - amount,
|
||||||
maxX: bbox.maxX + amount,
|
maxX: bbox.maxX + amount,
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import ReactDOM from "react-dom";
|
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 { FILL_REPLACEMENT_COLOR, STROKE_REPLACEMENT_COLOR } from "./colors";
|
||||||
|
import * as colors from "./colors";
|
||||||
|
import { Specs } from "./specs";
|
||||||
|
|
||||||
import _SvgVocabulary from "./svg-vocabulary.json";
|
import _SvgVocabulary from "./svg-vocabulary.json";
|
||||||
import type { SvgSymbolData, SvgSymbolElement } from "./vocabulary";
|
import type { SvgSymbolData, SvgSymbolElement } from "./vocabulary";
|
||||||
|
@ -19,6 +22,7 @@ if (!appEl) {
|
||||||
type SvgSymbolContext = {
|
type SvgSymbolContext = {
|
||||||
stroke: string;
|
stroke: string;
|
||||||
fill: string;
|
fill: string;
|
||||||
|
showSpecs: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SvgSymbolProps = {
|
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 SvgSymbol: React.FC<SvgSymbolProps> = (props) => {
|
||||||
const d = props.data;
|
const d = props.data;
|
||||||
|
const bbox = dilateBoundingBox(d.bbox, BBOX_DILATION);
|
||||||
const scale = props.scale || 1;
|
const scale = props.scale || 1;
|
||||||
const [width, height] = getBoundingBoxSize(d.bbox);
|
const [width, height] = getBoundingBoxSize(bbox);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
viewBox={`${d.bbox.minX} ${d.bbox.minY} ${width} ${height}`}
|
viewBox={`${bbox.minX} ${bbox.minY} ${width} ${height}`}
|
||||||
width={px(width * scale)}
|
width={px(width * scale)}
|
||||||
height={px(height * scale)}
|
height={px(height * scale)}
|
||||||
style={{ margin: "10px" }}
|
|
||||||
>
|
>
|
||||||
{props.data.layers.map(reactifySvgSymbolElement.bind(null, props))}
|
{props.data.layers.map(reactifySvgSymbolElement.bind(null, props))}
|
||||||
|
{props.showSpecs && d.specs && <SvgSymbolSpecs specs={d.specs} />}
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -76,6 +162,7 @@ const SvgSymbol: React.FC<SvgSymbolProps> = (props) => {
|
||||||
const App: React.FC<{}> = () => {
|
const App: React.FC<{}> = () => {
|
||||||
const [stroke, setStroke] = useState("#000000");
|
const [stroke, setStroke] = useState("#000000");
|
||||||
const [fill, setFill] = useState("#ffffff");
|
const [fill, setFill] = useState("#ffffff");
|
||||||
|
const [showSpecs, setShowSpecs] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -94,7 +181,15 @@ const App: React.FC<{}> = () => {
|
||||||
value={fill}
|
value={fill}
|
||||||
onChange={(e) => setFill(e.target.value)}
|
onChange={(e) => setFill(e.target.value)}
|
||||||
id="fill"
|
id="fill"
|
||||||
/>
|
/>{" "}
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={showSpecs}
|
||||||
|
onChange={(e) => setShowSpecs(e.target.checked)}
|
||||||
|
/>{" "}
|
||||||
|
Show specs
|
||||||
|
</label>
|
||||||
</p>
|
</p>
|
||||||
{SvgVocabulary.map((symbolData) => (
|
{SvgVocabulary.map((symbolData) => (
|
||||||
<div
|
<div
|
||||||
|
@ -120,6 +215,7 @@ const App: React.FC<{}> = () => {
|
||||||
scale={0.25}
|
scale={0.25}
|
||||||
stroke={stroke}
|
stroke={stroke}
|
||||||
fill={fill}
|
fill={fill}
|
||||||
|
showSpecs={showSpecs}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Ładowanie…
Reference in New Issue