- `design_pipe_ids.ts` — 장부(세션 pipe-ids) · pipe-s{차례} · 자리 → id(찾는 거리 안 가장 가까운 것) · followMovedPipe 가 id 를 새 자리로(고름 id 그대로 · 순환 import 없게 design_selection 에서 옮김) · 설계 페이지가 프로젝트를 정함(usePipeIds) · 자리 이름 만들기 열 곳 · 되읽기 둘 걷음 · 측점 계획 주인 = 세션 id(withPipeIds)
- `design_pick_match.ts` — pickLights(① id ② 같은 자리 ③ 고른 부분) · paintPicked(카드 통째 형상 · 부분 · 관 계열 · 포장층은 제 손잡이) · tagShape — 관 세트 벽 · 집수정 · 관 · 세월교 측벽 · 몸체 · BOX 끝 · C군 벽 · 물넘이 콘크리트에 신원표 · 형상 판정면은 통째 형상 · 콘크리트만
- 3D — 부재 맞춤 = pickLights(옛 0.01 걷음) · C군 벽 솔리드 = 구조물 id(덮는 측점 어디서 골라도 한 번 스윕한 벽이 켜짐)
- 322-0 이 깬 것 고침 — 노면공 흐름 도움 파일(165 · 231-1) 정의 판 확인 흉내 · design_view_profile 700줄(322-0 이 704)
- 시험: test_323_5_pick(세션 id · 옮김 · 강조 규칙 · 칠하기) · 옛 시험 도움 파일 흉내 · 기대 글 고침
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
54 lines
2.9 KiB
TypeScript
54 lines
2.9 KiB
TypeScript
/* =============================================================================
|
|
* A00_Common/design/design_pick_match.ts
|
|
* 고름 강조 한 규칙(323-5) — 그린 것(카드 형상 · 3D 부재 · 알약 · 측점선)마다 신원표 `{구조물 id · 부분 · 자리}`
|
|
* 를 달고, 고름 한 칸(`structure-pick`)과 이 함수 하나로 켜짐을 가름.
|
|
*
|
|
* ① 고름 · 그림 둘 다 구조물 id 가 있으면 id 가 같아야(관 = 세션 id `design_pipe_ids` · 옮겨도 그대로)
|
|
* ② 아니면 같은 자리(`PIPE_MATCH_M` — 같은 자리 거리는 이 한 값)
|
|
* ③ 고른 부분(부재키)이 있으면 그 부분만 · 부분을 안 골랐으면 그 구조물 그림 모두
|
|
* DOM 은 `data-structure-id` · `data-part`(`tagShape`) — 부분 그림(관 · 벽 · 날개벽 · 물넘이 콘크리트)은
|
|
* 조정창 손잡이가 같은 고름으로 칠함(`paintPicked` 는 부분 없는 형상만 · 307 「측점 길은 부분 안 켬」).
|
|
* ========================================================================== */
|
|
|
|
import { isNear, type DesignSelection } from "./design_selection";
|
|
|
|
export interface PickTag {
|
|
structureId?: string | null;
|
|
part?: string | null;
|
|
chainageM?: number | null;
|
|
}
|
|
|
|
export type PickSelection =
|
|
(Partial<DesignSelection> & { partKey?: string | null }) | null | undefined;
|
|
|
|
/** 이 그림이 고름에 켜지나 — 위 ① ② ③. */
|
|
export function pickLights(selection: PickSelection, tag: PickTag): boolean {
|
|
if (!selection) return false;
|
|
let here: boolean;
|
|
if (selection.structureId && tag.structureId) here = selection.structureId === tag.structureId;
|
|
else if (selection.chainageM == null || tag.chainageM == null) return false;
|
|
else here = isNear(tag.chainageM, selection.chainageM);
|
|
if (!here) return false;
|
|
return !selection.partKey || tag.part === selection.partKey;
|
|
}
|
|
|
|
/** 그린 형상에 신원표를 닮(부분 없으면 통째 형상). */
|
|
export function tagShape(el: Element, structureId: string | null, part?: string | null): void {
|
|
if (structureId) el.setAttribute("data-structure-id", structureId);
|
|
if (part) el.setAttribute("data-part", part);
|
|
}
|
|
|
|
/** 카드 안 통째 형상 칠하기 — 고른 구조물 id 와 같은 형상만. 부분 그림(`data-part`) · 관 계열(`pipe-`) ·
|
|
* 노면공 포장층은 제 손잡이(조정창 · 포장층 고름)가 칠함 — 측점 길(알약 · 목록 · 측점선)은 부분을 안 켬(307). */
|
|
export function paintPicked(root: ParentNode, selection: PickSelection): void {
|
|
for (const shape of root.querySelectorAll<SVGElement>("[data-structure-id]")) {
|
|
const id = shape.getAttribute("data-structure-id") ?? "";
|
|
if (id.startsWith("pipe-") || shape.getAttribute("data-part") !== null) continue;
|
|
if (shape.getAttribute("data-pave-type") !== null) continue;
|
|
shape.classList.toggle(
|
|
"is-active",
|
|
!!selection?.structureId && pickLights(selection, { structureId: id }),
|
|
);
|
|
}
|
|
}
|