- 조정창(오버레이): 읽기 줄 · 줄 이름 · 머리줄 집수정 ↺ 지움 · 끄는 중 미리 보기 글만 · 좌측 사본 그대로 - 끌기: 벽 · 집수정 · 세월교 = 수평 + 1:1.2 사면 · 다단 · 독립 벽 = 수평 + 수직 · BOX = 길이 + 표고 - 한계(±10 m · 노견 안쪽 · 노면 위 · 다단 선반 · BOX 길이 0)면 가장 가까운 허용 자리 · 반영 한 번 - 시험 test_108_drag_box_hit(끌기 · 걸음 · 미리 보기 = placePipeWall 결과 · 한계 · BOX 판정면) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
66 lines
2.7 KiB
TypeScript
66 lines
2.7 KiB
TypeScript
/* =============================================================================
|
|
* B06_Section_UI_Cross_View_Ford.ts
|
|
* 횡단 카드 ↔ **세월교 조정창** 배선 — 카드 렌더러(`_UI_Cross_View.ts`)에서 700줄
|
|
* 제한으로 분리했다(2026-08-25). 조정창이 부르는 동작을 제어기로 넘기는 얇은 층이고,
|
|
* 기하나 그리기는 하지 않는다.
|
|
* ========================================================================== */
|
|
|
|
import type { CrossSection } from "./B06_Section_Api_Fetch";
|
|
import type { FordPanelDeps, FordControl } from "./B06_Section_UI_Cross_Ford_Panel";
|
|
import type { FordLayout, FordWallRole } from "./B06_Section_UI_Cross_Ford";
|
|
|
|
/** 조정창 배선에 필요한 카드 상태. 계산 결과는 그릴 때마다 바뀌므로 함수로 받는다. */
|
|
export interface FordPanelContext {
|
|
section: CrossSection;
|
|
ford: FordControl;
|
|
/** 마지막 계산의 측벽 높이(m) — 읽기 줄. */
|
|
heightFor: (role: FordWallRole) => number;
|
|
/** 마지막 계산의 바닥판 길이(m). */
|
|
slabLengthM: () => number;
|
|
close: () => void;
|
|
}
|
|
|
|
/** 화면 좌(◀) 방향을 벽 기준 바깥 부호로 환산한다. 유입 = 상단측. */
|
|
function outwardOf(section: CrossSection, role: FordWallRole): number {
|
|
return ((section.uphill_side ?? "left") === "left") === (role === "inlet") ? 1 : -1;
|
|
}
|
|
|
|
export function fordPanelDeps(context: FordPanelContext): FordPanelDeps {
|
|
const { section, ford } = context;
|
|
const chainage = section.chainage_m;
|
|
return {
|
|
adjustFor: (role) => ford.adjustFor(chainage)[role],
|
|
heightFor: context.heightFor,
|
|
nudge: (role, screenDeltaM) =>
|
|
ford.update(chainage, role, {
|
|
lateralM: ford.adjustFor(chainage)[role].lateralM + screenDeltaM * outwardOf(section, role),
|
|
}),
|
|
nudgeSlope: (role, deltaM) =>
|
|
ford.update(chainage, role, {
|
|
slopeM: ford.adjustFor(chainage)[role].slopeM + deltaM,
|
|
}),
|
|
outwardOf: (role) => outwardOf(section, role),
|
|
move: (role, screenDeltaM, slopeDeltaM) => {
|
|
const from = ford.adjustFor(chainage)[role];
|
|
ford.update(chainage, role, {
|
|
lateralM: from.lateralM + screenDeltaM * outwardOf(section, role),
|
|
slopeM: from.slopeM + slopeDeltaM,
|
|
});
|
|
},
|
|
reset: (role) => ford.reset(chainage, role),
|
|
slabLengthM: context.slabLengthM,
|
|
close: context.close,
|
|
};
|
|
}
|
|
|
|
/** 조정창이 쓸 세월교 카드 상태 — 마지막 기하 결과에서 뽑는다(카드 렌더러 700줄 분리). */
|
|
export function fordCardState(layout: FordLayout): {
|
|
slabLengthM: number;
|
|
heights: Map<FordWallRole, number>;
|
|
} {
|
|
return {
|
|
slabLengthM: layout.slabLengthM,
|
|
heights: new Map(layout.sides.map((side) => [side.role, side.heightM])),
|
|
};
|
|
}
|