diff --git a/D03_PlanAnalysis/D03_PlanAnalysis_UI_Edit.ts b/D03_PlanAnalysis/D03_PlanAnalysis_UI_Edit.ts index 259eb0f29..4feb44586 100644 --- a/D03_PlanAnalysis/D03_PlanAnalysis_UI_Edit.ts +++ b/D03_PlanAnalysis/D03_PlanAnalysis_UI_Edit.ts @@ -61,6 +61,9 @@ export type { PlanScope, PlanSelection } from "./D03_PlanAnalysis_UI_Select"; const DRAG_PX = 4; /** 마크를 선에서 이만큼(px) 넘게 끌어내면 지움. */ const MARK_OFF_PX = 3 * SNAP_PX; +/** 고름 강조 — 노랑 줄 굵기 · 검은 테 한쪽 두께(px). */ +export const PICK_LINE_PX = 8; +export const PICK_HALO_PX = 4; export interface PlanEditParams { network: () => PlanNetwork; @@ -319,7 +322,12 @@ export function createPlanEdit(params: PlanEditParams): PlanEdit { if (i) context.lineTo(sx, sy); else context.moveTo(sx, sy); }); - strokeCased(context, colors.active, 8); // 밝은 바탕 대비 = 검은 테(600-1) + // 밝은 위성 위에서도 윤곽이 읽히게 검은 테를 한쪽 4 px 로 두껍게(613-2) + context.setLineDash([]); + context.lineWidth = PICK_LINE_PX + 2 * PICK_HALO_PX; + context.strokeStyle = colors.casing; + context.stroke(); + strokeCased(context, colors.active, PICK_LINE_PX); } // 꺾임점 손잡이(고른 것이 든 선) const lines = pickedLines(network); diff --git a/resources/tester/test_551_2_draw_tokens.py b/resources/tester/test_551_2_draw_tokens.py index 2be72965d..74130a9a1 100644 --- a/resources/tester/test_551_2_draw_tokens.py +++ b/resources/tester/test_551_2_draw_tokens.py @@ -190,3 +190,23 @@ def test_paint_network_uses_cased_route_lines(): body = src[src.index("export function paintNetwork") : src.index("export function pointLayer")] assert "strokeCased(context, color, width)" in body assert "routeColor(index)" in body + + +def test_pick_highlight_readable_on_any_map_background(): + """613-2 고름 강조 = 노랑 줄(`--draw-map-sketch`) + 검은 테 — 바탕(위성 · 어두운 지도)이 어떤 밝기여도 + 줄 · 검은 테 중 큰 쪽이 ≥ 3 : 1 · 테 한쪽 4 px 이상 · 노랑 줄은 검은 테와 함께 그림.""" + blocks = _blocks(THEME.read_text(encoding="utf-8")) + yellow = _lum(blocks["light"]["--draw-map-sketch"]) + for step in range(201): + ground = step / 200 + line = ( + (yellow + 0.05) / (ground + 0.05) + if yellow > ground + else (ground + 0.05) / (yellow + 0.05) + ) + casing = (ground + 0.05) / 0.05 + assert max(line, casing) >= 3, ground + src = (ROOT / "D03_PlanAnalysis/D03_PlanAnalysis_UI_Edit.ts").read_text(encoding="utf-8") + assert int(re.search(r"PICK_HALO_PX = (\d+)", src).group(1)) >= 4 + assert "strokeCased(context, colors.active, PICK_LINE_PX)" in src + assert "context.strokeStyle = colors.casing;" in src