diff --git a/resources/tester/test_585_1_kakao_mouse.py b/resources/tester/test_585_1_kakao_mouse.py index dd54c0d82..ff995bbdd 100644 --- a/resources/tester/test_585_1_kakao_mouse.py +++ b/resources/tester/test_585_1_kakao_mouse.py @@ -35,6 +35,8 @@ const requestAnimationFrame = (f: () => void) => setTimeout(f, 0); const API_BASE_URL = ""; (globalThis as any).fetch = async () => ({ ok: true, json: async () => ({ key: "k" }) }); const store: Record = {}; +(globalThis as any).addEventListener = () => undefined; +(globalThis as any).removeEventListener = () => undefined; (globalThis as any).localStorage = { getItem: (k: string) => store[k] ?? null }; const LOG: any = { levels: [], centers: [], labels: [] }; class LatLng { lat: number; lng: number; @@ -62,7 +64,7 @@ const m = editMap({ hint: "h", onMove: () => undefined }); m.set([{ key: "0", name: "지점 1", lon: 127.9, lat: 35.68, movable: true, color: "#123456" }, { key: "1", name: "지점 2", lon: 127.8, lat: 35.6, movable: true }], []); await new Promise((r) => setTimeout(r, 20)); -const ev = (o: any) => ({ preventDefault() {}, stopPropagation() {}, ctrlKey: false, ...o }); +const ev = (o: any) => ({ preventDefault() {}, stopPropagation() {}, ctrlKey: false, pointerType: "mouse", ...o }); const wheel = (deltaY: number, t: number) => handlers.wheel(ev({ deltaY, clientX: 110, clientY: 70, timeStamp: t })); wheel(-100, 1000); // 기본 = 밂 → 앞으로 = 확대(단 −1) @@ -76,8 +78,21 @@ handlers.pointerdown(ev({ button: 1, pointerId: 2, clientX: 50, clientY: 50 })); handlers.pointermove(ev({ pointerId: 2, buttons: 4, clientX: 60, clientY: 45 })); handlers.pointerup(ev({ pointerId: 2 })); handlers.pointermove(ev({ pointerId: 2, buttons: 4, clientX: 90, clientY: 90 })); // 놓은 뒤 = 안 옮김 +const before = LOG.centers.length; +handlers.pointerdown(ev({ button: 2, pointerId: 3, clientX: 50, clientY: 50 })); // 오른쪽 아직 옮기기 아님 +handlers.pointermove(ev({ pointerId: 3, buttons: 2, clientX: 60, clientY: 60 })); +const rightOff = LOG.centers.length - before; +store["aislo:pref:input-prefs"] = JSON.stringify({ wheelZoom: "pull", panButton: "right" }); +handlers.pointerdown(ev({ button: 2, pointerId: 4, clientX: 50, clientY: 50 })); // 오른쪽 = 옮기기 +handlers.pointermove(ev({ pointerId: 4, buttons: 2, clientX: 70, clientY: 40 })); +handlers.pointerup(ev({ pointerId: 4 })); +handlers.pointerdown(ev({ button: 1, pointerId: 5, clientX: 0, clientY: 0 })); // 가운데는 늘 +handlers.pointermove(ev({ pointerId: 5, buttons: 4, clientX: 3, clientY: 3 })); +handlers.pointerup(ev({ pointerId: 5 })); +handlers.pointerdown(ev({ button: 0, pointerId: 6, clientX: 0, clientY: 0 })); // 왼쪽 = 카카오 몫 +handlers.pointermove(ev({ pointerId: 6, buttons: 1, clientX: 9, clientY: 9 })); const [first, second] = LOG.labels; -console.log(JSON.stringify({ levels: LOG.levels, centers: LOG.centers, +console.log(JSON.stringify({ levels: LOG.levels, centers: LOG.centers, rightOff, colored: [first.style.background, first.classList.list], plain: second.style.background ?? null, colors: Array.from({ length: 8 }, (_, i) => pointColor(i)) })); """ @@ -103,7 +118,9 @@ def test_휠_설정_방향_가운데_끌기_지점_색(): # 마우스 자리 = 상자 안 (100, 50) 고정 · 단마다 한 번 assert got["levels"] == [[6, 100, 50], [7, 100, 50], [6, 100, 50]] # 가운데 끌기 (+10, −5) = 중심을 반대로 → 상자 가운데 (200, 150) − 민 만큼 - assert got["centers"] == [[190, 155]] + # 설정 가운데(기본) 일 때 오른쪽 누름 = 안 옮김 · 오른쪽 설정 = (+20, −10) · 가운데 늘 (+3, +3) · 왼쪽 = 안 옮김 + assert got["rightOff"] == 0 + assert got["centers"] == [[190, 155], [180, 160], [197, 147]] assert got["colored"] == ["#123456", ["is-colored"]] and got["plain"] is None # 여섯 색 차례 돌림 · 일곱째 = 첫째 assert len(set(got["colors"][:6])) == 6 and got["colors"][6:] == got["colors"][:2] diff --git a/ui_template/ui_template_kakao_map.ts b/ui_template/ui_template_kakao_map.ts index d9a176551..a47735f15 100644 --- a/ui_template/ui_template_kakao_map.ts +++ b/ui_template/ui_template_kakao_map.ts @@ -8,13 +8,19 @@ * (244-10) SDK 못 받음(도메인 미등록 401) = 지금 주소(location.origin) 등록 안내 한 줄 * (560-3) 바탕 종류 = `setType("ROADMAP" | "HYBRID")`(위성 + 지명) · 단추는 부르는 쪽 부품 * (585-1) 마우스 = ☰ [설정] 따름 — 휠 = 설정 확대 방향(카카오 제 휠은 잡는 단계에서 막음 · 한 단씩) · - * 가운데 끌기 = 옮김 · 왼쪽 끌기 · 손가락 = 카카오 제 것 · 표지 색 = `MapPin.color`(이름표 바탕) + * 옮기기 단추(588-5) = 설정(가운데 늘 · 오른쪽 고르면 오른쪽도) 끌기 = 옮김 · 왼쪽 끌기(표지 누름 포함) + * · 손가락 = 카카오 제 것 · 표지 색 = `MapPin.color`(이름표 바탕) * ========================================================================== */ import "./ui_template_kakao_map.css"; import { API_BASE_URL } from "@config/config_frontend"; import { el } from "./ui_template_elements"; -import { wheelEventIn } from "../A00_Common/input_prefs"; +import { + buttonMask, + guardMenuAfterDrag, + isAuxPanButton, + wheelEventIn, +} from "../A00_Common/input_prefs"; export const NO_MAP = "카카오 JavaScript 키 · 도메인 등록 필요 — 지도 대신 [그림 변경]으로 넣으세요"; @@ -146,7 +152,7 @@ function label(p: MapPin): HTMLElement { } /** 585-1 설정 따름 — 휠(잡는 단계 · 카카오에 안 넘김) = 설정 방향 한 단 · 마우스 자리 고정 · - * 가운데 끌기 = 옮김. 왼쪽 끌기 · 손가락은 카카오 제 것. */ + * 설정 옮기기 단추(가운데 · 오른쪽) 끌기 = 옮김. 왼쪽 끌기 · 손가락은 카카오 제 것(왼쪽 옮김도 같음). */ function followMouse(box: HTMLElement, map: KMap, maps: KakaoMaps): void { const pointAt = (x: number, y: number): LatLng => map.getProjection().coordsFromContainerPoint(new maps.Point(x, y)); @@ -164,14 +170,15 @@ function followMouse(box: HTMLElement, map: KMap, maps: KakaoMaps): void { }, { capture: true, passive: false }, ); - let drag: { id: number; x: number; y: number } | null = null; + let drag: { id: number; x: number; y: number; button: number } | null = null; box.addEventListener( "pointerdown", (event) => { - if (event.button !== 1) return; + if (event.pointerType !== "mouse" || !isAuxPanButton(event.button)) return; event.preventDefault(); // 브라우저 자동 굴림 막음 event.stopPropagation(); - drag = { id: event.pointerId, x: event.clientX, y: event.clientY }; + guardMenuAfterDrag(event); + drag = { id: event.pointerId, x: event.clientX, y: event.clientY, button: event.button }; box.setPointerCapture(event.pointerId); }, { capture: true }, @@ -180,7 +187,7 @@ function followMouse(box: HTMLElement, map: KMap, maps: KakaoMaps): void { "pointermove", (event) => { if (!drag || event.pointerId !== drag.id) return; - if (!(event.buttons & 4)) return void (drag = null); + if (!(event.buttons & buttonMask(drag.button))) return void (drag = null); event.stopPropagation(); const [dx, dy] = [event.clientX - drag.x, event.clientY - drag.y]; [drag.x, drag.y] = [event.clientX, event.clientY];