Skip to content
File

Blob: worker/src/client/exhibit/diagram/wire-layout.ts

typescript39 lines
1import { BRANCHES } from './diagram-model.ts';
2import type { Branch } from './diagram-model.ts';
3 
4export type Point = { x: number; y: number };
5export type BranchPoints = { source: Point; relayIn: Point; relayOut: Point; receiver: Point };
6export type Wire = { branch: Branch | 'wifi'; segment: 'source' | 'receiver'; d: string };
7export type WireLayout =
8 | { mode: 'desktop'; branches: Record<Branch, BranchPoints> }
9 | { mode: 'mobile'; source: Point; relay: Point; boardBottom: number };
10 
11/** Coordinates are relative to the diagram's inner border, independent of DOM measurement. */
12export function layoutWires(layout: WireLayout): Wire[] {
13 if (layout.mode === 'mobile') {
14 const { source, relay, boardBottom } = layout;
15 const gutter = source.x + 10,
16 lane = boardBottom + 18,
17 radius = 6;
18 // Route through the gap beside the PCB, then below the core labels.
19 return [
20 {
21 branch: 'wifi',
22 segment: 'source',
23 d: `M ${source.x} ${source.y} H ${gutter - radius} Q ${gutter} ${source.y} ${gutter} ${source.y + radius} V ${lane - radius} Q ${gutter} ${lane} ${gutter + radius} ${lane} H ${relay.x - radius} Q ${relay.x} ${lane} ${relay.x} ${lane + radius} V ${relay.y}`,
24 },
25 ];
26 }
27 const curve = (a: Point, b: Point) => {
28 const midpoint = (a.x + b.x) / 2;
29 return `M ${a.x} ${a.y} C ${midpoint} ${a.y}, ${midpoint} ${b.y}, ${b.x} ${b.y}`;
30 };
31 return BRANCHES.flatMap((branch): Wire[] => {
32 const points = layout.branches[branch];
33 return [
34 { branch, segment: 'source', d: curve(points.source, points.relayIn) },
35 { branch, segment: 'receiver', d: curve(points.relayOut, points.receiver) },
36 ];
37 });
38}