feat(B05): 배수유역도 필터 버튼을 지도 오버레이로 · 유역 번호 배지를 라운드 사각으로

- 표시 필터 버튼 묶음을 헤더에서 지도 좌측 상단(8px 여백)으로 옮겼다. 버튼 줄과
  상태 문구를 한 오버레이가 세로로 쌓아, 문구가 버튼 아래에서 시작한다
- 버튼 줄은 한 줄 유지. 오른쪽 진행단계 오버레이에 끝이 가려도 창을 넓히거나 그
  오버레이를 접으면 드러난다(사용자 확정) — 두 줄로 접는 쪽이 지도를 더 가린다
- 오버레이 빈 자리는 pointer-events를 흘려 지도 팬·유역 고르기를 막지 않고,
  버튼 위 pointerdown만 지도로 내려가지 않게 끊는다
- 유역 번호 배지를 원에서 라운드 사각으로. 지도 위 다른 숫자가 전부 동그라미라
  크기로만 갈렸다. 크기(지름 22px)는 그대로. B04 지도 배지도 같은 함수라 함께 바뀐다
This commit is contained in:
2026-08-17 20:17:05 +09:00
parent b92ba4592e
commit fdd9c77cb3
3 changed files with 50 additions and 8 deletions
@@ -55,10 +55,13 @@ export function drawFilledRing(
drawRingBadge(context, [sumX / entry.ring.length, sumY / entry.ring.length], color, entry.label);
}
/** 유역 번호 배지 한 개( + 숫자). 화면 좌표를 그대로 받는다.
/** 유역 번호 배지 한 개(라운드 사각 + 숫자). 화면 좌표를 그대로 받는다.
*
* 채움과 따로 떼어 둔 이유: 번호는 **맨 위에** 있어야 한다. 채움과 함께 그리면 그 위에
* 얹히는 등고선·화살표·관 마커에 가려 읽을 수 없다(2026-08-01 사용자 지시). */
* 얹히는 등고선·화살표·관 마커에 가려 읽을 수 없다(2026-08-01 사용자 지시).
*
* 원이 아니라 사각인 이유: 지도 위 다른 숫자들도 전부 동그라미라 크기로만 갈렸다.
* 형태를 바꿔 한눈에 구분되게 했다 — 크기는 그대로다(2026-08-17 사용자 지시). */
export function drawRingBadge(
context: CanvasRenderingContext2D,
center: readonly [number, number],
@@ -66,9 +69,10 @@ export function drawRingBadge(
label: string,
): void {
const [centerX, centerY] = center;
const half = 11;
context.save();
context.beginPath();
context.arc(centerX, centerY, 11, 0, Math.PI * 2);
context.roundRect(centerX - half, centerY - half, half * 2, half * 2, 6);
context.fillStyle = color;
context.fill();
context.strokeStyle = haloColor();
+18 -2
View File
@@ -65,9 +65,13 @@ export function createDrainageChrome(
header.className = "b05-drainage__header";
const title = document.createElement("h3");
title.textContent = labels.title;
// 표시 필터 버튼 묶음 — 헤더가 아니라 지도 좌측 상단에 얹는다(2026-08-17 사용자 지시).
// 지도 위에 있으니 버튼을 누른 포인터가 아래 지도까지 내려가면 안 된다 — 유역 고르기가
// 딸려 일어난다. 배선이 아니라 얹은 자리 때문에 생긴 것이라 여기서 막는다.
const layerButtons = document.createElement("div");
layerButtons.className = "b05-drainage__layers";
header.append(title, layerButtons);
layerButtons.addEventListener("pointerdown", (event) => event.stopPropagation());
header.append(title);
// 세부유역 산정 — B04가 미리 분석해 둔 결과를 읽어 관을 보충하고 세부유역만 나눈다.
// 격자 해석은 하지 않으므로 즉시 끝난다.
@@ -108,7 +112,19 @@ export function createDrainageChrome(
const contextMenu = createMapContextMenu("b05-drainage");
// 유입 강도 색띠 범례 — CSS가 지도 우측 세로로 세운다.
const legend = createFlowLegend();
viewport.append(backgroundImage, canvas, status, progress.root, contextMenu.element, legend.root);
// 지도 좌상단 오버레이 — 필터 버튼 줄과 상태 문구를 세로로 쌓는다. 둘을 각각 지도에
// 절대배치하면 버튼이 두 줄로 접힐 때 문구가 그 아래에 겹친다.
const mapOverlay = document.createElement("div");
mapOverlay.className = "b05-drainage__map-overlay";
mapOverlay.append(layerButtons, status);
viewport.append(
backgroundImage,
canvas,
mapOverlay,
progress.root,
contextMenu.element,
legend.root,
);
const summary = document.createElement("div");
summary.className = "b05-drainage__summary";
+25 -3
View File
@@ -958,15 +958,38 @@
font-size: var(--text-body-sm);
}
/* 지도 좌상단 오버레이 — 표시 필터 버튼 줄 + 상태 문구(2026-08-17 사용자 지시로
헤더에서 옮겼다). 버튼 자체 여백과 별개로 지도 모서리에서 조금 띄운다.
우측 폭을 묶는 이유: 화면 오른쪽 진행단계 오버레이(z-index 200)가 지도 위를
덮어, 여기까지 늘어난 버튼은 눌리지 않는다. 그 폭(패널 절반 + 우측 여백)을 뺀다. */
.b05-drainage__map-overlay {
position: absolute;
z-index: 2;
top: var(--spacing-8);
left: var(--spacing-8);
display: flex;
flex-direction: column;
gap: var(--spacing-4);
/* 오버레이 빈 자리로는 지도 조작(팬·유역 고르기)이 그대로 통해야 한다. */
pointer-events: none;
}
/* 필터 버튼은 한 줄로 둔다 — 오른쪽 진행단계 오버레이에 끝이 가려도 창을 넓히거나
그 오버레이를 접으면 드러난다(2026-08-17 사용자 확정). 두 줄로 접는 쪽이 지도를
더 많이 가린다. */
.b05-drainage__layers {
display: flex;
flex-wrap: wrap;
flex-wrap: nowrap;
gap: var(--spacing-4);
pointer-events: auto;
}
/* 표시 토글 버튼 — B04 지도 레이어 버튼(.b04-map__layer-button--gis)과 같은 양식을 쓴다.
크기(패딩·글자)만 이 패널 기준을 유지한다(2026-08-01 사용자 지시). */
.b05-drainage__layer-button {
/* 한 줄 유지 — 좁아져도 글자가 접히거나 쭈그러들지 않게 크기를 고정한다. */
flex: 0 0 auto;
white-space: nowrap;
padding: 2px var(--spacing-8);
border: 1px solid var(--color-border);
border-radius: var(--radius-inputs);
@@ -1050,9 +1073,8 @@
pointer-events: none;
}
/* 상태 문구는 좌상단 오버레이가 세로로 쌓아 준다 — 필터 버튼 줄 바로 아래. */
.b05-drainage__status {
position: absolute;
inset: var(--spacing-8) var(--spacing-8) auto var(--spacing-8);
color: var(--color-text-secondary);
font-size: var(--text-caption);
pointer-events: none;