fix(B05): 종단 그래프에서 측점을 골라도 선택이 풀리던 것 수정
끌어서 이동이 pointerdown 즉시 `setPointerCapture` 를 걸어, 뒤따르는 click 의 대상이 측점 `<g>` 가 아니라 스크롤러가 됐다. 그래서 측점 클릭이 배경 클릭으로 처리돼 선택이 그 자리에서 풀렸다(사용자 보고: 측점을 골라도 하이라이트가 안 됨). - 포인터 잡기를 **끌기 문턱을 넘긴 뒤로** 미룸. 단순 클릭은 캡처가 없어 측점에 그대로 닿고, 실제로 끌기 시작한 뒤에는 잡아 두어 창 밖에서 손을 떼도 이어진다. - 문턱 4px → 6px. 손 떨림에 쉽게 넘어가 측점을 고르기 어려웠다. 검증(공용 브라우저, 실제 마우스 입력): 측점 클릭 → 선택·하이라이트 정상(420m), 끌기 → 선택 유지하며 팬 이동(scrollLeft 1660 → 1780). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,9 @@ const EASE = 0.35;
|
||||
/** 이보다 가까우면 도착으로 보고 딱 맞춘다(px). */
|
||||
const SNAP_PX = 0.5;
|
||||
/** 이만큼 넘게 움직여야 "끌기"로 본다(px). 그 아래는 클릭(측점 선택)으로 흘려보낸다. */
|
||||
const DRAG_THRESHOLD_PX = 4;
|
||||
/** 이만큼 움직여야 「끌기」로 본다 — 그 아래는 클릭이다.
|
||||
* 4px 은 손 떨림에도 넘어가 측점을 고르기 어려웠다(2026-09-06 사용자 지적). */
|
||||
const DRAG_THRESHOLD_PX = 6;
|
||||
/** 끌기를 시작하면 안 되는 조작 부품 — 이 위에서 누른 것은 그 부품의 몫이다.
|
||||
* 구조물 마크는 자기 `pointerdown`에서 전파를 끊으므로 여기 적지 않아도 된다. */
|
||||
const DRAG_BLOCK_SELECTOR =
|
||||
@@ -95,9 +97,15 @@ export function attachWheelHorizontalScroll(scroller: HTMLElement): void {
|
||||
);
|
||||
|
||||
/* ── 끌어서 이동 ─────────────────────────────────────────────────────────
|
||||
* 좌클릭(0)·휠 버튼(1)으로 잡아 끈다. 문턱(4px)을 넘긴 뒤에야 이동으로 보고, 넘긴
|
||||
* 경우에만 뒤따르는 click을 한 번 삼킨다 — 그래야 "그림을 조금 움직였는데 측점 선택이
|
||||
* 풀리는" 일이 없다. 창 밖에서 손을 떼도 풀리도록 포인터를 잡아 둔다.
|
||||
* 좌클릭(0)·휠 버튼(1)으로 잡아 끈다. 문턱을 넘긴 뒤에야 이동으로 보고, 넘긴 경우에만
|
||||
* 뒤따르는 click을 한 번 삼킨다 — 그래야 "그림을 조금 움직였는데 측점 선택이 풀리는"
|
||||
* 일이 없다.
|
||||
*
|
||||
* ⚠ 포인터 잡기(`setPointerCapture`)는 **문턱을 넘긴 뒤에만** 한다(2026-09-06).
|
||||
* 누르는 즉시 잡으면 뒤따르는 click 의 대상이 측점 `<g>` 가 아니라 스크롤러가 되어,
|
||||
* 측점 클릭이 배경 클릭으로 처리되고 선택이 그 자리에서 풀렸다 — 「측점을 골라도
|
||||
* 하이라이트가 안 된다」는 증상의 원인. 끌기가 실제로 시작된 뒤에는 잡아 두어야
|
||||
* 창 밖에서 손을 떼도 이동이 풀리지 않는다.
|
||||
*/
|
||||
let dragId: number | null = null;
|
||||
let dragX = 0;
|
||||
@@ -137,7 +145,7 @@ export function attachWheelHorizontalScroll(scroller: HTMLElement): void {
|
||||
dragLeft = scroller.scrollLeft;
|
||||
dragTop = scroller.scrollTop;
|
||||
dragMoved = false;
|
||||
scroller.setPointerCapture(event.pointerId);
|
||||
// 여기서는 포인터를 잡지 않는다 — 위 주석 참고(클릭이 측점에 닿아야 한다).
|
||||
// 휠 버튼은 브라우저 자동 스크롤이 뜨므로 막는다.
|
||||
if (event.button === 1) event.preventDefault();
|
||||
});
|
||||
@@ -150,6 +158,8 @@ export function attachWheelHorizontalScroll(scroller: HTMLElement): void {
|
||||
if (!dragMoved) {
|
||||
dragMoved = true;
|
||||
scroller.style.cursor = "grabbing";
|
||||
// 이제부터 진짜 끌기다 — 창 밖으로 나가도 이어지도록 포인터를 잡는다.
|
||||
scroller.setPointerCapture(event.pointerId);
|
||||
}
|
||||
scroller.scrollLeft = dragLeft - dx;
|
||||
scroller.scrollTop = dragTop - dy;
|
||||
|
||||
Reference in New Issue
Block a user