Make attachment point code more DRY.

pull/4/head
Atul Varma 2021-02-15 09:13:00 -05:00
rodzic 2384d1eac3
commit 11c27b905f
4 zmienionych plików z 100 dodań i 105 usunięć

Wyświetl plik

@ -1,10 +1,16 @@
import type { AttachmentPointType } from "./specs";
export const STROKE_REPLACEMENT_COLOR = "#000000"; export const STROKE_REPLACEMENT_COLOR = "#000000";
export const FILL_REPLACEMENT_COLOR = "#ffffff"; export const FILL_REPLACEMENT_COLOR = "#ffffff";
export const TAIL_ATTACHMENT_COLOR = "#ff0000"; export const ATTACHMENT_POINT_COLORS: {
export const LEG_ATTACHMENT_COLOR = "#ffff00"; [key in AttachmentPointType]: string;
export const ARM_ATTACHMENT_COLOR = "#00ff00"; } = {
export const HORN_ATTACHMENT_COLOR = "#00ffff"; tail: "#ff0000",
export const CROWN_ATTACHMENT_COLOR = "#0000ff"; leg: "#ffff00",
arm: "#00ff00",
horn: "#00ffff",
crown: "#0000ff",
};
export const NESTING_BOUNDING_BOX_COLOR = "#ff00ff"; export const NESTING_BOUNDING_BOX_COLOR = "#ff00ff";

Wyświetl plik

@ -3,7 +3,7 @@ import { BBox } from "../../vendor/bezier-js";
import { dilateBoundingBox, getBoundingBoxSize } from "../bounding-box"; import { 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 * as colors from "../colors";
import { PointWithNormal, Specs } from "../specs"; import { iterAttachmentPoints, AttachmentPoint, Specs } from "../specs";
import type { SvgSymbolData, SvgSymbolElement } from "../vocabulary"; import type { SvgSymbolData, SvgSymbolElement } from "../vocabulary";
import { SvgVocabulary } from "../svg-vocabulary"; import { SvgVocabulary } from "../svg-vocabulary";
@ -61,36 +61,28 @@ const ATTACHMENT_POINT_NORMAL_LENGTH = 50;
const ATTACHMENT_POINT_NORMAL_STROKE = 4; const ATTACHMENT_POINT_NORMAL_STROKE = 4;
const AttachmentPoints: React.FC<{ const VisibleAttachmentPoint: React.FC<{
color: string; point: AttachmentPoint;
points: PointWithNormal[]; }> = ({ point: ap }) => {
}> = (props) => ( const { x, y } = ap.point;
<> const x2 = x + ap.normal.x * ATTACHMENT_POINT_NORMAL_LENGTH;
{props.points.map((pwn, i) => { const y2 = y + ap.normal.y * ATTACHMENT_POINT_NORMAL_LENGTH;
const { x, y } = pwn.point; const color = colors.ATTACHMENT_POINT_COLORS[ap.type];
const x2 = x + pwn.normal.x * ATTACHMENT_POINT_NORMAL_LENGTH;
const y2 = y + pwn.normal.y * ATTACHMENT_POINT_NORMAL_LENGTH;
return ( return (
<React.Fragment key={i}> <>
<circle <circle fill={color} r={ATTACHMENT_POINT_RADIUS} cx={x} cy={y} />
fill={props.color}
r={ATTACHMENT_POINT_RADIUS}
cx={x}
cy={y}
/>
<line <line
x1={x} x1={x}
y1={y} y1={y}
x2={x2} x2={x2}
y2={y2} y2={y2}
stroke={props.color} stroke={color}
strokeWidth={ATTACHMENT_POINT_NORMAL_STROKE} strokeWidth={ATTACHMENT_POINT_NORMAL_STROKE}
/> />
</React.Fragment>
);
})}
</> </>
); );
};
const BoundingBoxes: React.FC<{ fill: string; bboxes: BBox[] }> = (props) => ( const BoundingBoxes: React.FC<{ fill: string; bboxes: BBox[] }> = (props) => (
<> <>
@ -113,36 +105,9 @@ const BoundingBoxes: React.FC<{ fill: string; bboxes: BBox[] }> = (props) => (
const SvgSymbolSpecs: React.FC<{ specs: Specs }> = ({ specs }) => { const SvgSymbolSpecs: React.FC<{ specs: Specs }> = ({ specs }) => {
return ( return (
<> <>
{specs.tail && ( {Array.from(iterAttachmentPoints(specs)).map((point, i) => (
<AttachmentPoints <VisibleAttachmentPoint key={i} point={point} />
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 && ( {specs.nesting && (
<BoundingBoxes <BoundingBoxes
fill={colors.NESTING_BOUNDING_BOX_COLOR} fill={colors.NESTING_BOUNDING_BOX_COLOR}

Wyświetl plik

@ -11,14 +11,45 @@ export type PointWithNormal = {
normal: Point; normal: Point;
}; };
export type Specs = { type AttachmentPointSpecs = {
tail?: PointWithNormal[]; tail: PointWithNormal[];
leg?: PointWithNormal[]; leg: PointWithNormal[];
arm?: PointWithNormal[]; arm: PointWithNormal[];
horn?: PointWithNormal[]; horn: PointWithNormal[];
crown?: PointWithNormal[]; crown: PointWithNormal[];
nesting?: BBox[];
}; };
type FullSpecs = AttachmentPointSpecs & {
nesting: BBox[];
};
export type Specs = Partial<FullSpecs>;
export type AttachmentPointType = keyof AttachmentPointSpecs;
export type AttachmentPoint = PointWithNormal & {
type: AttachmentPointType;
};
export const ATTACHMENT_POINT_TYPES: AttachmentPointType[] = [
"tail",
"leg",
"arm",
"horn",
"crown",
];
export function* iterAttachmentPoints(specs: Specs): Iterable<AttachmentPoint> {
for (let type of ATTACHMENT_POINT_TYPES) {
const points = specs[type];
if (points) {
for (let point of points) {
yield { ...point, type };
}
}
}
}
const NUM_ARROW_POINTS = 4; const NUM_ARROW_POINTS = 4;
const ARROW_TOP_POINT_IDX = 0; const ARROW_TOP_POINT_IDX = 0;
const ARROW_BOTTOM_POINT_IDX = 2; const ARROW_BOTTOM_POINT_IDX = 2;
@ -76,34 +107,24 @@ function concat<T>(first: T[] | undefined, second: T[]): T[] {
return first ? [...first, ...second] : second; return first ? [...first, ...second] : second;
} }
const ATTACHMENT_COLOR_MAP = new Map(
ATTACHMENT_POINT_TYPES.map((type) => [
colors.ATTACHMENT_POINT_COLORS[type],
type,
])
);
function updateSpecs(fill: string, path: string, specs: Specs): Specs { function updateSpecs(fill: string, path: string, specs: Specs): Specs {
switch (fill) { const attachmentType = ATTACHMENT_COLOR_MAP.get(fill);
case colors.TAIL_ATTACHMENT_COLOR:
if (attachmentType) {
return { return {
...specs, ...specs,
tail: concat(specs.tail, getArrowPoints(path)), [attachmentType]: concat(specs[attachmentType], getArrowPoints(path)),
}; };
case colors.LEG_ATTACHMENT_COLOR: }
return {
...specs, if (fill === colors.NESTING_BOUNDING_BOX_COLOR) {
leg: concat(specs.leg, getArrowPoints(path)),
};
case colors.ARM_ATTACHMENT_COLOR:
return {
...specs,
arm: concat(specs.arm, getArrowPoints(path)),
};
case colors.HORN_ATTACHMENT_COLOR:
return {
...specs,
horn: concat(specs.horn, getArrowPoints(path)),
};
case colors.CROWN_ATTACHMENT_COLOR:
return {
...specs,
crown: concat(specs.crown, getArrowPoints(path)),
};
case colors.NESTING_BOUNDING_BOX_COLOR:
return { return {
...specs, ...specs,
nesting: concat(specs.nesting, getBoundingBoxes(path)), nesting: concat(specs.nesting, getBoundingBoxes(path)),

Wyświetl plik

@ -27,5 +27,8 @@
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"typescript": "^4.1.3" "typescript": "^4.1.3"
} },
"browserslist": [
"since 2017-06"
]
} }