Files
Aislo/B06_Section/B06_Section_UI_Cross_View_Zoom.ts
T
eomsangdonandClaude Opus 5.5 fc1068a9cd fix(B05·B06): 유토곡선 토량 분배 때 종단 · 표 스크롤 유지 · 횡단 보기 = 보기 반폭 그대로 · 십자선 크기 고정 · 보기 반폭 기본 10 m(79-1~4)
- 토량 분배(전체 맞춤) 중에는 유토곡선 ↔ 종단 스크롤 동기화를 끊음 — 0 으로 되돌던 것 없앰
- 횡단 카드는 사면 교차점 · 배수관 세트 폭으로 줌아웃하지 않음 · 밖은 가운데 버튼 팬 · ⤢ 는 보기값으로
- 줌인해도 중심 십자선 길이 그대로(도형 레이어 배율을 십자선 중심에서 되돌림)
- 횡단 보기 반폭 기본 12 → 10 m(계산 반폭과 따로)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EMfGERKUg5nMMNQsyVZ2j
2026-10-07 23:50:13 +09:00

102 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =============================================================================
* B06_Section_UI_Cross_View_Zoom.ts
* 횡단 카드 그래프의 **확대·축소·팬** 조작구.
*
* ⚠ 줌·팬 **본문은 공용 조각**(`A00_Common/b_svg_zoom_pan.ts`)으로 옮겼다
* (2026-09-12 사용자 지시 「공용화해줘」) — 계획노선 편집 횡단이 같은 코드를 쓴다.
* 여기에는 **B06 것**만 남는다: 카드 여백(`CROSS_PAD`)을 씌운 감싸개, 측점별 배율 기억,
* 우측 상단 버튼 묶음. 동작 규칙(휠은 줌이 아님)은 그대로다 — 카드가 수십 장 깔리는
* 화면에서 휠을 줌에 묶으면 목록을 훑을 수가 없다(2026-08-02 사용자 확정).
* ========================================================================== */
import {
attachSvgZoomPan,
type ContentBounds,
type ZoomPanHandle,
type ZoomPanState,
} from "../A00_Common/b_svg_zoom_pan";
import { CROSS_PAD, L } from "./B06_Section_UI_Section_Common";
export type { ContentBounds, ZoomPanHandle, ZoomPanState };
/**
* 카드 표시 반폭 조작(2026-08-23 사용자 지시). 카드 하단 ◀/▶/↺을 없애고 우측 상단
* 줌 버튼에 합쳤다 — 원배율에서 −는 폭 넓히기, ⤢는 보기값 되돌림이다.
*/
export interface CrossWidthActions {
/** 표시 반폭을 deltaM(m)만큼 조절한다. 계산 반폭을 넘으면 페이지가 재생성까지 처리. */
step: (deltaM: number) => void;
/**
* 초기화 — 표시 반폭을 전역 보기값으로 되돌린다(PLAN 79-2 · 사면 교차점은 팬으로 봄).
*/
fit: () => void;
}
/** 측점별 줌·팬 상태 — 카드를 다시 만들어도 배율이 살아남는다(2026-08-22 사용자 ③). */
export const cardZoomStates = new Map<string, ZoomPanState>();
/** 카드 SVG 에 줌·팬을 붙인다 — 여백만 씌워 공용 조각에 넘긴다. 부르는 꼴은 그대로다. */
export function attachZoomPan(
svg: SVGSVGElement,
plotLayer: SVGGElement,
widthPx: number,
heightPx: number,
/** 이전 카드의 줌·팬 상태 — 조정창 조작으로 카드가 다시 그려져도 배율 유지. */
initial?: ZoomPanState,
/** 상태가 바뀔 때마다 부른다 — 카드 밖(뷰)이 담아 뒀다가 다음 렌더에 되돌린다. */
onChange?: (state: ZoomPanState) => void,
/** 도형이 실제로 그려진 범위(캐시 보유 폭). 확대 상태에서 팬 한계가 여기까지 늘어난다. */
content?: ContentBounds,
): ZoomPanHandle {
return attachSvgZoomPan({
svg,
layer: plotLayer,
widthPx,
heightPx,
pad: CROSS_PAD,
initial,
onChange,
content,
// 휠은 카드 목록을 훑는 몫이다 — 줌에 안 묶는다.
wheelZoom: false,
});
}
/**
* 그래프 우측 상단 줌 버튼(확대/축소/핏). 휠을 대신하는 조작구다.
*
* `width`를 넘기면 **원배율에서만** 버튼이 표시 반폭을 조절한다(2026-08-23 사용자 지시):
* + : 배율 확대(항상)
* − : 배율>1이면 축소, 원배율이면 표시 반폭 +1m(계산 반폭 20m를 넘으면 백엔드 재계산)
* ⤢ : 배율 원복 + 표시 반폭 초기화(전역 보기값)
*/
export function buildZoomControls(handle: ZoomPanHandle, width?: CrossWidthActions): HTMLElement {
const bar = document.createElement("div");
bar.className = "b06-cross-card__zoom";
const add = (label: string, title: string, action: () => void): void => {
const button = document.createElement("button");
button.type = "button";
button.className = "b06-cross-card__zoom-btn";
button.textContent = label;
button.title = title;
button.addEventListener("click", (event) => {
// 카드 선택으로 번지면 그래프가 다시 그려져 방금 맞춘 배율이 날아간다.
event.stopPropagation();
action();
});
bar.append(button);
};
// +는 언제나 배율 확대다 — 원배율에서 폭 좁히기로 바꿔 놨더니 배율이 1에서 못 올라가
// 가운데 버튼 팬(배율>1에서만 열림)까지 막혔다(2026-08-23 사용자 보고).
add("+", L("B06_Profile_View_ZoomIn"), () => handle.zoom(1 / 0.85));
add("−", L("B06_Profile_View_ZoomOut"), () => {
if (!width || handle.scale() > 1 + 1e-6) handle.zoom(0.85);
else width.step(1);
});
add("⤢", L("B06_Profile_View_ZoomFit"), () => {
handle.reset();
width?.fit();
});
return bar;
}