feat(B05): 평면 도구줄 = 공용 지도 도구줄 아이콘 14 (PLAN 568-2 · 요구 395-1)
- 글자 유리 단추 줄 · [?] 안내 판 · 나눔선 다섯 → createMapTools 한 줄(긴 설명은 마우스 글 · 누름 동작 · 단축키 그대로)
- 3D 단추 = mapToolButton("view3d") · 클래스 b05-route__3d-open 유지 · 거리 재기 aria-pressed 맞춤
- 가이드 촬영 선택자(.b05-routeedit__tools · [data-act="hint-toggle"] · .b05-routeedit__hint.is-open) 그대로
- 시험 고침 — 옛 글자 단추 · 나눔선 · 안내 판 CSS 를 잡던 다섯(차례 · 안내 판 · 절/성토선 이름 · 3D 막이)
- 부품 — 빈 묶음 건너뜀 · [hidden] 숨김 규칙
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { createIconButton } from "@ui/ui_template_elements";
|
||||
import { createMapTools, mapToolButton } from "@ui/ui_template_map_tools";
|
||||
import { createSidePanels } from "@ui/ui_template_side_panels";
|
||||
import { bindFootprintToggle } from "./B05_Profile_UI_RouteEdit_Footprint";
|
||||
import { bindMarkToggle } from "./B05_Profile_UI_RouteEdit_Marks";
|
||||
@@ -15,7 +16,7 @@ import { bottomRowNarrow, infoLiftPx } from "./logic/B05_Profile_RouteEdit_InfoL
|
||||
* (지도 왼쪽 위 · ☰ 비킴), [?] 조작 설명은 도구줄 아래 2열, 상태·범례는 왼쪽 아래, 잰 값은 오른쪽
|
||||
* 아래. 횡단 두 판은 지도 오른쪽을 덮는 판(아래 종단 판이 그 위).
|
||||
* 도구줄 차례(366-2 · 381-2) — [?] | ↶ ↷ | 3D | ⟲ ⟳ · 1m 등고선 · 측점 · 기울기 · 절/성토선 · 거리 재기 |
|
||||
* 측점 스냅 · 분석 지형.
|
||||
* 측점 스냅 · 간격 | 분석 지형. 단추는 공용 지도 도구줄(568-2 · `ui_template_map_tools`) 아이콘 — 긴 설명은 마우스 글.
|
||||
*
|
||||
* 자리(345-3) — 모달이 아니라 종단 보기 가운데 위 본문(옛 3D 자리)에 붙는다. 덮개 · 전체 화면 ·
|
||||
* 닫기 단추는 걷었다 · [취소] · [확인] · [노선 반영] · [저장 전으로]는 없앰(346-3 · 352-2 — 노선은 페이지
|
||||
@@ -67,6 +68,17 @@ const SIDE_HANDLE_PX = 32;
|
||||
|
||||
// 글판 접기 기억(345-5 덧 3) — 페이지 동안만(모듈 값) · 다시 열어도 그대로.
|
||||
let hintOpen = false;
|
||||
const HINT_LINES = [
|
||||
"노드 끌기 = 옮기기",
|
||||
"노드 클릭 = R 라벨",
|
||||
"선 두 번 클릭 = 노드 추가",
|
||||
"노드 오른쪽 클릭 = 삭제",
|
||||
"측점 눈금 클릭 = 횡단 미리보기",
|
||||
"Shift+클릭 = 거리·기울기",
|
||||
"가운데(휠) 버튼 끌기 = 지도 이동",
|
||||
"휠 = 확대",
|
||||
"Ctrl+휠 = 돌리기(한 칸 5°)",
|
||||
];
|
||||
let infoCollapsed = false;
|
||||
|
||||
/** 뼈대를 만들어 `parent` 에 붙이고, 자주 쓰는 요소를 집어 돌려준다. */
|
||||
@@ -79,56 +91,7 @@ export function createRouteEditChrome(
|
||||
overlay.innerHTML = `
|
||||
<div class="b05-routeedit__canvas-wrap" aria-label="계획노선 편집">
|
||||
<canvas class="b05-routeedit__canvas"></canvas>
|
||||
<div class="b05-route__view-controls b05-routeedit__tools">
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass b05-routeedit__hint-toggle"
|
||||
data-act="hint-toggle" aria-expanded="false" title="조작 도움말 펼치기 · 접기">?</button>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="undo"
|
||||
title="되돌리기 (Ctrl+Z)" aria-label="되돌리기" disabled>${HISTORY_ICON.undo}</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="redo"
|
||||
title="다시하기 (Ctrl+Y)" aria-label="다시하기" disabled>${HISTORY_ICON.redo}</button>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<span data-slot="tools"></span>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="rotate-ccw"
|
||||
title="반시계로 돌리기" aria-label="반시계로 돌리기">${HALF_TURN_ICON.ccw}</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="rotate-cw"
|
||||
title="시계로 돌리기" aria-label="시계로 돌리기">${HALF_TURN_ICON.cw}</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="contour-minor"
|
||||
aria-pressed="false" disabled
|
||||
title="1m 간격 등고선을 얇고 옅게 겹칩니다 (확대하면 보임)">1m 등고선</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="stations"
|
||||
title="측점 눈금 · 번호를 평면에 보이기 · 숨기기 (시점 · 종점 이름표는 늘 보임)">측점</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="slopes"
|
||||
title="측점 사이 기울기(%)를 평면에 보이기 · 숨기기 (확대해야 보임)">기울기</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="footprint"
|
||||
title="도로 끝 · 비탈 끝(깎기 붉음 · 쌓기 청록)을 평면에 겹칩니다">절/성토선</button>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="measure"
|
||||
title="노선 위 두 점을 눌러 거리·기울기를 잽니다 (Shift+클릭도 같음)">거리 재기</button>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="station-snap"
|
||||
aria-pressed="false"
|
||||
title="켜면 고친 곡선의 가운데(MC)를 고른 간격 배수에 맞춥니다 — 일반측점(20 m)은 그대로 · MC 가 일반측점 위가 아니면 「No.N+10 (MC)」 특별측점을 더함 · 손대지 않은 곡선은 그 자리 유지 · 고정 교각점은 그대로 · 못 맞춘 곡선은 상태줄 「측점 밖 곡선」 · [저장] 때 저장">측점 스냅</button>
|
||||
<label class="b05-routeedit__terrain b05-routeedit__snap-step"
|
||||
title="측점 스냅 간격 — 곡선 가운데(MC)를 이 간격 배수에 맞춥니다(측점 No. = 측점 간격)">간격
|
||||
<select class="ui-select ui-select--sm" data-size="32" data-act="snap-step">
|
||||
<option value="10">10 m</option>
|
||||
<option value="station">측점 No.</option>
|
||||
</select>
|
||||
</label>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<span class="b05-routeedit__terrain" data-slot="terrain-name" hidden
|
||||
title="설계 지형 — 바꾸기는 [노선 추천] 창에서 지형을 골라 [적용]"></span>
|
||||
</div>
|
||||
<div class="b05-routeedit__hint">
|
||||
<div class="b05-routeedit__hint-body">
|
||||
<span>노드 끌기 = 옮기기</span><span>노드 클릭 = R 라벨</span>
|
||||
<span>선 두 번 클릭 = 노드 추가</span><span>노드 오른쪽 클릭 = 삭제</span>
|
||||
<span>측점 눈금 클릭 = 횡단 미리보기</span><span>Shift+클릭 = 거리·기울기</span>
|
||||
<span>가운데(휠) 버튼 끌기 = 지도 이동</span><span>휠 = 확대</span>
|
||||
<span>Ctrl+휠 = 돌리기(한 칸 5°)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div data-slot="map-tools"></div>
|
||||
<div class="b05-routeedit__measure" hidden>
|
||||
<span class="b05-routeedit__measure-text"></span>
|
||||
<span data-slot="measure-close"></span>
|
||||
@@ -149,12 +112,61 @@ export function createRouteEditChrome(
|
||||
<div class="b05-routeedit__busy" hidden><span></span></div>
|
||||
<aside class="b05-routeedit__side-wrap"></aside>`;
|
||||
parent.append(overlay);
|
||||
// 부른 쪽 단추([3D])도 같은 유리 단추로 — 지도 위에 떠 있는 도구줄.
|
||||
tools.forEach((tool) => {
|
||||
tool.classList.replace("ui-btn--ghost", "ui-btn--glass");
|
||||
tool.setAttribute("data-size", "32"); // 도구줄 단 32(553-2)
|
||||
// 스냅 간격 고르기 · 설계 지형 이름 칩 — 단추 아님(도구줄에 요소로 끼움).
|
||||
const extras = document.createElement("div");
|
||||
extras.innerHTML = `
|
||||
<label class="b05-routeedit__terrain b05-routeedit__snap-step"
|
||||
title="측점 스냅 간격 — 곡선 가운데(MC)를 이 간격 배수에 맞춥니다(측점 No. = 측점 간격)">간격
|
||||
<select class="ui-select ui-select--sm" data-size="32" data-act="snap-step">
|
||||
<option value="10">10 m</option>
|
||||
<option value="station">측점 No.</option>
|
||||
</select>
|
||||
</label>
|
||||
<span class="b05-routeedit__terrain" data-slot="terrain-name" hidden
|
||||
title="설계 지형 — 바꾸기는 [노선 추천] 창에서 지형을 골라 [적용]"></span>`;
|
||||
const [snapStep, terrainName] = extras.children as unknown as [HTMLElement, HTMLElement];
|
||||
const mapTools = createMapTools({
|
||||
label: "평면 도구",
|
||||
hint: { lines: HINT_LINES, open: hintOpen, onToggle: (open) => (hintOpen = open) },
|
||||
groups: [
|
||||
[
|
||||
mapToolButton("undo", { title: "되돌리기 (Ctrl+Z)", disabled: true }),
|
||||
mapToolButton("redo", { title: "다시하기 (Ctrl+Y)", disabled: true }),
|
||||
],
|
||||
tools, // 부른 쪽 단추([3D])
|
||||
[
|
||||
"rotate-ccw",
|
||||
"rotate-cw",
|
||||
mapToolButton("contour-minor", {
|
||||
title: "1m 등고선 — 1m 간격 등고선을 얇고 옅게 겹칩니다 (확대하면 보임)",
|
||||
disabled: true,
|
||||
}),
|
||||
mapToolButton("stations", {
|
||||
title: "측점 — 측점 눈금 · 번호를 평면에 보이기 · 숨기기 (시점 · 종점 이름표는 늘 보임)",
|
||||
}),
|
||||
mapToolButton("slopes", {
|
||||
title: "기울기 — 측점 사이 기울기(%)를 평면에 보이기 · 숨기기 (확대해야 보임)",
|
||||
}),
|
||||
mapToolButton("footprint", {
|
||||
title: "절/성토선 — 도로 끝 · 비탈 끝(깎기 붉음 · 쌓기 청록)을 평면에 겹칩니다",
|
||||
}),
|
||||
mapToolButton("measure", {
|
||||
title: "거리 재기 — 노선 위 두 점을 눌러 거리·기울기를 잽니다 (Shift+클릭도 같음)",
|
||||
}),
|
||||
],
|
||||
[
|
||||
mapToolButton("station-snap", {
|
||||
title:
|
||||
"측점 스냅 — 켜면 고친 곡선의 가운데(MC)를 고른 간격 배수에 맞춥니다 — 일반측점(20 m)은 그대로 · MC 가 일반측점 위가 아니면 「No.N+10 (MC)」 특별측점을 더함 · 손대지 않은 곡선은 그 자리 유지 · 고정 교각점은 그대로 · 못 맞춘 곡선은 상태줄 「측점 밖 곡선」 · [저장] 때 저장",
|
||||
}),
|
||||
snapStep,
|
||||
],
|
||||
[terrainName],
|
||||
],
|
||||
});
|
||||
overlay.querySelector('[data-slot="tools"]')!.replaceWith(...tools);
|
||||
mapTools.root.classList.add("b05-routeedit__tools");
|
||||
mapTools.hint!.classList.add("b05-routeedit__hint"); // 가이드 촬영 · 엿보기 숨김이 잡음
|
||||
overlay.querySelector('[data-slot="map-tools"]')!.replaceWith(mapTools.root);
|
||||
|
||||
// 횡단 미리보기 = 패널 양식(382-1 · 손잡이 · 머리 · 폭 끌기 · 열림 · 폭 기억) · 자리는 지도 위 덮개 그대로 ·
|
||||
// 기본 접힘(393-1 · 키 -v2 = 옛 열림 기억 한 번 버림) · 열림 · 닫힘은 손잡이만(513-2) · 잰 값 창이 판을 비킴(--b05-side-open).
|
||||
@@ -177,17 +189,6 @@ export function createRouteEditChrome(
|
||||
overlay.querySelector(".b05-routeedit__side-wrap")!.append(panels.root);
|
||||
setSideOpen();
|
||||
|
||||
// 도움말 = 기본 접힘 · [?] 한 번에 펼침(345-5 덧 3).
|
||||
const hint = overlay.querySelector<HTMLElement>(".b05-routeedit__hint")!;
|
||||
const hintToggle = overlay.querySelector<HTMLButtonElement>('[data-act="hint-toggle"]')!;
|
||||
const setHint = (open: boolean): void => {
|
||||
hintOpen = open;
|
||||
hint.classList.toggle("is-open", open);
|
||||
hintToggle.setAttribute("aria-expanded", String(open));
|
||||
};
|
||||
setHint(hintOpen);
|
||||
hintToggle.addEventListener("click", () => setHint(!hintOpen));
|
||||
|
||||
// 상태 · 범례 접기 — 접으면 한 줄 「계획노선 N m」(상태 글에서 읽음 · 345-5 덧 3).
|
||||
const info = overlay.querySelector<HTMLElement>(".b05-routeedit__info")!;
|
||||
const infoToggle = info.querySelector<HTMLButtonElement>('[data-act="info-toggle"]')!;
|
||||
@@ -243,16 +244,13 @@ export function createRouteEditChrome(
|
||||
syncSummary();
|
||||
const measureBox = overlay.querySelector<HTMLElement>(".b05-routeedit__measure")!;
|
||||
const measureText = overlay.querySelector<HTMLElement>(".b05-routeedit__measure-text")!;
|
||||
const measureButton = overlay.querySelector<HTMLButtonElement>('[data-act="measure"]')!;
|
||||
const measureButton = mapTools.button("measure")!;
|
||||
const busy = overlay.querySelector<HTMLElement>(".b05-routeedit__busy")!;
|
||||
const minorContourButton = overlay.querySelector<HTMLButtonElement>(
|
||||
'[data-act="contour-minor"]',
|
||||
)!;
|
||||
const terrainName = overlay.querySelector<HTMLElement>('[data-slot="terrain-name"]')!;
|
||||
const stationSnapButton = overlay.querySelector<HTMLButtonElement>('[data-act="station-snap"]')!;
|
||||
bindFootprintToggle(overlay.querySelector<HTMLButtonElement>('[data-act="footprint"]')!);
|
||||
bindMarkToggle(overlay.querySelector<HTMLButtonElement>('[data-act="stations"]')!, "stations");
|
||||
bindMarkToggle(overlay.querySelector<HTMLButtonElement>('[data-act="slopes"]')!, "slopes");
|
||||
const minorContourButton = mapTools.button("contour-minor")!;
|
||||
const stationSnapButton = mapTools.button("station-snap")!;
|
||||
bindFootprintToggle(mapTools.button("footprint")!);
|
||||
bindMarkToggle(mapTools.button("stations")!, "stations");
|
||||
bindMarkToggle(mapTools.button("slopes")!, "slopes");
|
||||
|
||||
return {
|
||||
overlay,
|
||||
|
||||
Reference in New Issue
Block a user