diff --git a/lib/colors.ts b/lib/colors.ts
index bd469b2..76881c9 100644
--- a/lib/colors.ts
+++ b/lib/colors.ts
@@ -1,10 +1,16 @@
+import type { AttachmentPointType } from "./specs";
+
export const STROKE_REPLACEMENT_COLOR = "#000000";
export const FILL_REPLACEMENT_COLOR = "#ffffff";
-export const TAIL_ATTACHMENT_COLOR = "#ff0000";
-export const LEG_ATTACHMENT_COLOR = "#ffff00";
-export const ARM_ATTACHMENT_COLOR = "#00ff00";
-export const HORN_ATTACHMENT_COLOR = "#00ffff";
-export const CROWN_ATTACHMENT_COLOR = "#0000ff";
+export const ATTACHMENT_POINT_COLORS: {
+ [key in AttachmentPointType]: string;
+} = {
+ tail: "#ff0000",
+ leg: "#ffff00",
+ arm: "#00ff00",
+ horn: "#00ffff",
+ crown: "#0000ff",
+};
export const NESTING_BOUNDING_BOX_COLOR = "#ff00ff";
diff --git a/lib/pages/vocabulary-page.tsx b/lib/pages/vocabulary-page.tsx
index 2db64fe..da42b3f 100644
--- a/lib/pages/vocabulary-page.tsx
+++ b/lib/pages/vocabulary-page.tsx
@@ -3,7 +3,7 @@ import { BBox } from "../../vendor/bezier-js";
import { dilateBoundingBox, getBoundingBoxSize } from "../bounding-box";
import { FILL_REPLACEMENT_COLOR, STROKE_REPLACEMENT_COLOR } 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 { SvgVocabulary } from "../svg-vocabulary";
@@ -61,36 +61,28 @@ const ATTACHMENT_POINT_NORMAL_LENGTH = 50;
const ATTACHMENT_POINT_NORMAL_STROKE = 4;
-const AttachmentPoints: React.FC<{
- color: string;
- points: PointWithNormal[];
-}> = (props) => (
- <>
- {props.points.map((pwn, i) => {
- const { x, y } = pwn.point;
- const x2 = x + pwn.normal.x * ATTACHMENT_POINT_NORMAL_LENGTH;
- const y2 = y + pwn.normal.y * ATTACHMENT_POINT_NORMAL_LENGTH;
- return (
-
-
-
-
- );
- })}
- >
-);
+const VisibleAttachmentPoint: React.FC<{
+ point: AttachmentPoint;
+}> = ({ point: ap }) => {
+ const { x, y } = ap.point;
+ const x2 = x + ap.normal.x * ATTACHMENT_POINT_NORMAL_LENGTH;
+ const y2 = y + ap.normal.y * ATTACHMENT_POINT_NORMAL_LENGTH;
+ const color = colors.ATTACHMENT_POINT_COLORS[ap.type];
+
+ return (
+ <>
+
+
+ >
+ );
+};
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 }) => {
return (
<>
- {specs.tail && (
-
- )}
- {specs.leg && (
-
- )}
- {specs.arm && (
-
- )}
- {specs.horn && (
-
- )}
- {specs.crown && (
-
- )}
+ {Array.from(iterAttachmentPoints(specs)).map((point, i) => (
+
+ ))}
{specs.nesting && (
;
+
+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 {
+ 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 ARROW_TOP_POINT_IDX = 0;
const ARROW_BOTTOM_POINT_IDX = 2;
@@ -76,38 +107,28 @@ function concat(first: T[] | undefined, second: T[]): T[] {
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 {
- switch (fill) {
- case colors.TAIL_ATTACHMENT_COLOR:
- return {
- ...specs,
- tail: concat(specs.tail, getArrowPoints(path)),
- };
- case colors.LEG_ATTACHMENT_COLOR:
- return {
- ...specs,
- 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 {
- ...specs,
- nesting: concat(specs.nesting, getBoundingBoxes(path)),
- };
+ const attachmentType = ATTACHMENT_COLOR_MAP.get(fill);
+
+ if (attachmentType) {
+ return {
+ ...specs,
+ [attachmentType]: concat(specs[attachmentType], getArrowPoints(path)),
+ };
+ }
+
+ if (fill === colors.NESTING_BOUNDING_BOX_COLOR) {
+ return {
+ ...specs,
+ nesting: concat(specs.nesting, getBoundingBoxes(path)),
+ };
}
throw new Error(`Not sure what to do with specs path with fill "${fill}"!`);
diff --git a/package.json b/package.json
index 2d81519..0b4d6aa 100644
--- a/package.json
+++ b/package.json
@@ -27,5 +27,8 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"typescript": "^4.1.3"
- }
+ },
+ "browserslist": [
+ "since 2017-06"
+ ]
}