feat(B06): 횡단 줌 조작 일원화 + 교차점 맞춤 자동 확대

- 카드 하단 ◀/▶/↺(개별 표시 반폭) 삭제. 조작구는 우측 상단 줌 버튼 하나로.
- 줌 버튼 역할 확장(원배율에서만 반폭 조작):
  − 배율>1이면 축소, 원배율이면 표시 반폭 +1m
  + 배율>1이면 확대, 원배율이면 표시 반폭 −1m(하한 2m)
  ⤢ 배율 원복 + 절·성토 교차점이 다 보이는 폭으로 맞춤
- 교차점 맞춤(_UI_Cross_Fit): 보유 샘플(계산 반폭 20m) 안에서 교차점을 찾고,
  샘플 끝까지 안 만나면 끝단 사면·지반 기울기 차로 만나는 자리를 추세 외삽해
  올림 +1m을 요청 반폭으로 쓴다(상한 60m).
- 요청 반폭 > 보유 샘플이면 그 폭으로 재생성(regenerate) 후 해당 측점만 세션
  반폭으로 넓게 표시. 계산 기본 20m·캐시는 그대로, 확정 시 기존 경로대로
  display_half_width_m에 영구 저장.
- 재생성 로직을 _UI_Page_Common.createSampleWidener로 분리(700줄 제한),
  [전체 측점 반영]도 같은 경로 사용. 연타 중복 요청 차단.

자체검증: node tmp/tests/test_toe_extrapolate.mjs (외삽 좌/우·발산 지형·+1m 올림),
tsc --noEmit 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-23 18:16:31 +09:00
co-authored by Claude Opus 5
parent ec514a4560
commit f2ad5508f5
7 changed files with 224 additions and 96 deletions
+36 -6
View File
@@ -16,6 +16,19 @@ export interface ZoomPanHandle {
/** 1보다 크면 확대, 작으면 축소. 플롯 영역의 중앙을 붙잡는다. */
zoom: (factor: number) => void;
reset: () => void;
/** 현재 배율 — 원배율(1)일 때는 버튼이 배율 대신 **표시 반폭**을 조절한다. */
scale: () => number;
}
/**
* 카드 표시 반폭 조작(2026-08-23 사용자 지시). 카드 하단 ◀/▶/↺을 없애고 우측 상단
* 줌 버튼에 합쳤다 — 원배율에서 −는 폭 넓히기, +는 폭 좁히기, ⤢는 교차점 맞춤이다.
*/
export interface CrossWidthActions {
/** 표시 반폭을 deltaM(m)만큼 조절한다. 계산 반폭을 넘으면 페이지가 재생성까지 처리. */
step: (deltaM: number) => void;
/** 절·성토 교차점이 모두 보이는 폭으로 맞춘다. */
fit: () => void;
}
/** 줌·팬 상태 — 카드가 다시 그려질 때 배율을 되살리는 데 쓴다(2026-08-22 사용자 ③). */
@@ -123,6 +136,7 @@ export function attachZoomPan(
svg.addEventListener("click", (event) => {
if (moved) event.stopPropagation();
});
const currentScale = (): number => scale;
const reset = (): void => {
scale = 1;
tx = 0;
@@ -134,11 +148,18 @@ export function attachZoomPan(
event.stopPropagation();
reset();
});
return { zoom, reset };
return { zoom, reset, scale: currentScale };
}
/** 그래프 우측 상단 줌 버튼(확대/축소/핏). 휠을 대신하는 조작구다. */
export function buildZoomControls(handle: ZoomPanHandle): HTMLElement {
/**
* 그래프 우측 상단 줌 버튼(확대/축소/핏). 휠을 대신하는 조작구다.
*
* `width`를 넘기면 **원배율에서만** 버튼이 표시 반폭을 조절한다(2026-08-23 사용자 지시):
* − : 배율>1이면 축소, 원배율이면 반폭 +1m(계산 반폭 20m를 넘으면 백엔드 재계산)
* + : 배율>1이면 확대, 원배율이면 반폭 −1m
* ⤢ : 배율 원복 + 절·성토 교차점이 다 보이는 폭으로 맞춤
*/
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 => {
@@ -154,8 +175,17 @@ export function buildZoomControls(handle: ZoomPanHandle): HTMLElement {
});
bar.append(button);
};
add("+", L("B06_Profile_View_ZoomIn"), () => handle.zoom(1 / 0.85));
add("−", L("B06_Profile_View_ZoomOut"), () => handle.zoom(0.85));
add("⤢", L("B06_Profile_View_ZoomFit"), () => handle.reset());
add("+", L("B06_Profile_View_ZoomIn"), () => {
if (!width || handle.scale() > 1 + 1e-6) handle.zoom(1 / 0.85);
else width.step(-1);
});
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;
}