@mint-ui/map 1.2.0-test.34 → 1.2.0-test.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/mint-map/core/advanced/shared/context.d.ts +19 -12
- package/dist/components/mint-map/core/advanced/shared/context.js +54 -75
- package/dist/components/mint-map/core/advanced/shared/helpers.d.ts +20 -0
- package/dist/components/mint-map/core/advanced/shared/helpers.js +40 -0
- package/dist/components/mint-map/core/advanced/shared/hooks.d.ts +74 -0
- package/dist/components/mint-map/core/advanced/shared/hooks.js +189 -0
- package/dist/components/mint-map/core/advanced/shared/index.d.ts +3 -0
- package/dist/components/mint-map/core/advanced/shared/performance.d.ts +12 -110
- package/dist/components/mint-map/core/advanced/shared/performance.js +56 -151
- package/dist/components/mint-map/core/advanced/shared/types.d.ts +18 -153
- package/dist/components/mint-map/core/advanced/shared/types.js +0 -1
- package/dist/components/mint-map/core/advanced/shared/utils.d.ts +36 -27
- package/dist/components/mint-map/core/advanced/shared/utils.js +58 -52
- package/dist/components/mint-map/core/advanced/shared/viewport.d.ts +42 -0
- package/dist/components/mint-map/core/advanced/shared/viewport.js +51 -0
- package/dist/components/mint-map/core/advanced/woongCanvasMarker/WoongCanvasMarker.d.ts +22 -74
- package/dist/components/mint-map/core/advanced/woongCanvasMarker/WoongCanvasMarker.js +156 -617
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/WoongCanvasPolygon.d.ts +26 -76
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/WoongCanvasPolygon.js +152 -551
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/renderer.d.ts +67 -8
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/renderer.js +81 -20
- package/dist/index.es.js +917 -1575
- package/dist/index.js +11 -0
- package/dist/index.umd.js +923 -1573
- package/package.json +1 -1
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Offset } from "../../../types";
|
|
3
|
-
import {
|
|
3
|
+
import { CanvasData } from "./types";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* WoongCanvas 컴포넌트 인스턴스 인터페이스
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* - zIndex 기반 이벤트 우선순위 처리
|
|
9
|
-
* - 전역 클릭/호버 이벤트 조정
|
|
10
|
-
* - 여러 레이어 간 상호작용 관리
|
|
7
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
11
8
|
*/
|
|
12
9
|
export interface ComponentInstance<T> {
|
|
13
10
|
zIndex: number;
|
|
14
11
|
hitTest: (offset: Offset) => boolean;
|
|
15
|
-
onClick?: (payload:
|
|
16
|
-
onMouseOver?: (payload:
|
|
17
|
-
onMouseOut?: (payload:
|
|
18
|
-
findData: (offset: Offset) =>
|
|
19
|
-
setHovered: (data:
|
|
20
|
-
handleLocalClick: (data:
|
|
12
|
+
onClick?: (payload: CanvasData<T>, selectedIds: Set<string>) => void;
|
|
13
|
+
onMouseOver?: (payload: CanvasData<T>) => void;
|
|
14
|
+
onMouseOut?: (payload: CanvasData<T>) => void;
|
|
15
|
+
findData: (offset: Offset) => CanvasData<T> | null;
|
|
16
|
+
setHovered: (data: CanvasData<T> | null) => void;
|
|
17
|
+
handleLocalClick: (data: CanvasData<T>) => void;
|
|
21
18
|
getSelectedIds: () => Set<string>;
|
|
22
19
|
isInteractionDisabled: () => boolean;
|
|
23
20
|
}
|
|
@@ -25,8 +22,18 @@ interface WoongCanvasContextValue {
|
|
|
25
22
|
registerComponent: <T>(instance: ComponentInstance<T>) => void;
|
|
26
23
|
unregisterComponent: <T>(instance: ComponentInstance<T>) => void;
|
|
27
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* WoongCanvasProvider 컴포넌트
|
|
27
|
+
*
|
|
28
|
+
* 다중 WoongCanvas 인스턴스를 관리하고 zIndex 기반 이벤트 우선순위를 처리합니다.
|
|
29
|
+
*/
|
|
28
30
|
export declare const WoongCanvasProvider: React.FC<{
|
|
29
31
|
children: React.ReactNode;
|
|
30
32
|
}>;
|
|
33
|
+
/**
|
|
34
|
+
* WoongCanvas Context Hook
|
|
35
|
+
*
|
|
36
|
+
* @returns WoongCanvasContextValue 또는 null (Provider 없으면)
|
|
37
|
+
*/
|
|
31
38
|
export declare const useWoongCanvasContext: () => WoongCanvasContextValue | null;
|
|
32
39
|
export {};
|
|
@@ -10,31 +10,28 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
10
10
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
11
11
|
|
|
12
12
|
var WoongCanvasContext = React.createContext(null);
|
|
13
|
+
/**
|
|
14
|
+
* WoongCanvasProvider 컴포넌트
|
|
15
|
+
*
|
|
16
|
+
* 다중 WoongCanvas 인스턴스를 관리하고 zIndex 기반 이벤트 우선순위를 처리합니다.
|
|
17
|
+
*/
|
|
18
|
+
|
|
13
19
|
var WoongCanvasProvider = function (_a) {
|
|
14
20
|
var children = _a.children;
|
|
15
|
-
var controller = MintMapProvider.useMintMapController();
|
|
16
|
-
|
|
21
|
+
var controller = MintMapProvider.useMintMapController();
|
|
17
22
|
var componentsRef = React.useRef([]);
|
|
18
23
|
var currentHoveredRef = React.useRef(null);
|
|
19
24
|
var currentHoveredDataRef = React.useRef(null);
|
|
20
|
-
var draggingRef = React.useRef(false);
|
|
21
|
-
/**
|
|
22
|
-
* 컴포넌트 등록 (zIndex 내림차순 정렬)
|
|
23
|
-
* 높은 zIndex가 먼저 처리됨
|
|
24
|
-
*/
|
|
25
|
+
var draggingRef = React.useRef(false); // 컴포넌트 등록 (zIndex 내림차순 정렬)
|
|
25
26
|
|
|
26
27
|
var registerComponent = React.useCallback(function (instance) {
|
|
27
28
|
componentsRef.current.push(instance);
|
|
28
29
|
componentsRef.current.sort(function (a, b) {
|
|
29
30
|
return b.zIndex - a.zIndex;
|
|
30
31
|
});
|
|
31
|
-
}, []);
|
|
32
|
-
/**
|
|
33
|
-
* 컴포넌트 등록 해제
|
|
34
|
-
*/
|
|
32
|
+
}, []); // 컴포넌트 등록 해제
|
|
35
33
|
|
|
36
34
|
var unregisterComponent = React.useCallback(function (instance) {
|
|
37
|
-
// Hover 중이던 컴포넌트면 초기화
|
|
38
35
|
if (currentHoveredRef.current === instance) {
|
|
39
36
|
currentHoveredRef.current = null;
|
|
40
37
|
currentHoveredDataRef.current = null;
|
|
@@ -43,99 +40,77 @@ var WoongCanvasProvider = function (_a) {
|
|
|
43
40
|
componentsRef.current = componentsRef.current.filter(function (c) {
|
|
44
41
|
return c !== instance;
|
|
45
42
|
});
|
|
46
|
-
}, []);
|
|
47
|
-
/**
|
|
48
|
-
* 전역 클릭 핸들러 (zIndex 우선순위)
|
|
49
|
-
*/
|
|
43
|
+
}, []); // 전역 클릭 핸들러 (zIndex 우선순위)
|
|
50
44
|
|
|
51
45
|
var handleGlobalClick = React.useCallback(function (event) {
|
|
52
|
-
var _a;
|
|
46
|
+
var _a, _b;
|
|
53
47
|
|
|
54
48
|
if (!((_a = event === null || event === void 0 ? void 0 : event.param) === null || _a === void 0 ? void 0 : _a.position)) return;
|
|
55
|
-
var clickedOffset = controller.positionToOffset(event.param.position); // zIndex
|
|
56
|
-
|
|
57
|
-
for (var _i = 0, _b = componentsRef.current; _i < _b.length; _i++) {
|
|
58
|
-
var component = _b[_i]; // 🚫 상호작용이 비활성화된 컴포넌트는 스킵
|
|
49
|
+
var clickedOffset = controller.positionToOffset(event.param.position); // zIndex 내림차순으로 정렬된 컴포넌트 순회 (높은 zIndex가 먼저 처리)
|
|
59
50
|
|
|
51
|
+
for (var _i = 0, _c = componentsRef.current; _i < _c.length; _i++) {
|
|
52
|
+
var component = _c[_i];
|
|
60
53
|
if (component.isInteractionDisabled()) continue;
|
|
61
54
|
var data = component.findData(clickedOffset);
|
|
55
|
+
if (!data) continue; // 첫 번째로 찾은 항목만 처리하고 종료 (zIndex 우선순위)
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (component.onClick) {
|
|
67
|
-
component.onClick(data, component.getSelectedIds());
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return; // 첫 번째 히트만 처리
|
|
71
|
-
}
|
|
57
|
+
component.handleLocalClick(data);
|
|
58
|
+
(_b = component.onClick) === null || _b === void 0 ? void 0 : _b.call(component, data, component.getSelectedIds());
|
|
59
|
+
return;
|
|
72
60
|
}
|
|
73
|
-
}, [controller]);
|
|
74
|
-
/**
|
|
75
|
-
* 전역 마우스 이동 핸들러 (zIndex 우선순위)
|
|
76
|
-
*/
|
|
61
|
+
}, [controller]); // 전역 마우스 이동 핸들러 (zIndex 우선순위)
|
|
77
62
|
|
|
78
63
|
var handleGlobalMouseMove = React.useCallback(function (event) {
|
|
79
64
|
var _a;
|
|
80
65
|
|
|
81
66
|
if (draggingRef.current || !((_a = event === null || event === void 0 ? void 0 : event.param) === null || _a === void 0 ? void 0 : _a.position)) return;
|
|
82
|
-
var mouseOffset = controller.positionToOffset(event.param.position);
|
|
83
|
-
|
|
67
|
+
var mouseOffset = controller.positionToOffset(event.param.position);
|
|
84
68
|
var newHoveredComponent = null;
|
|
85
|
-
var newHoveredData = null;
|
|
69
|
+
var newHoveredData = null; // zIndex 내림차순으로 정렬된 컴포넌트 순회 (높은 zIndex가 먼저 처리)
|
|
86
70
|
|
|
87
71
|
for (var _i = 0, _b = componentsRef.current; _i < _b.length; _i++) {
|
|
88
|
-
var component = _b[_i];
|
|
89
|
-
|
|
72
|
+
var component = _b[_i];
|
|
90
73
|
if (component.isInteractionDisabled()) continue;
|
|
91
74
|
var data = component.findData(mouseOffset);
|
|
75
|
+
if (!data) continue; // 첫 번째로 찾은 항목만 hover 처리 (zIndex 우선순위)
|
|
92
76
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
} // Hover 상태 변경 감지 (최적화: 별도 ref로 직접 비교)
|
|
99
|
-
|
|
77
|
+
newHoveredComponent = component;
|
|
78
|
+
newHoveredData = data;
|
|
79
|
+
break;
|
|
80
|
+
} // hover 상태가 변경되지 않았으면 종료 (불필요한 렌더링 방지)
|
|
100
81
|
|
|
101
|
-
if (currentHoveredRef.current !== newHoveredComponent || currentHoveredDataRef.current !== newHoveredData) {
|
|
102
|
-
// 이전 hover 해제
|
|
103
|
-
if (currentHoveredRef.current) {
|
|
104
|
-
currentHoveredRef.current.setHovered(null);
|
|
105
82
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
} // 새 hover 설정
|
|
83
|
+
if (currentHoveredRef.current === newHoveredComponent && currentHoveredDataRef.current === newHoveredData) {
|
|
84
|
+
return;
|
|
85
|
+
} // 기존 hover 항목에 mouseOut 이벤트 발생
|
|
110
86
|
|
|
111
87
|
|
|
112
|
-
|
|
113
|
-
|
|
88
|
+
if (currentHoveredRef.current) {
|
|
89
|
+
currentHoveredRef.current.setHovered(null);
|
|
114
90
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
91
|
+
if (currentHoveredRef.current.onMouseOut && currentHoveredDataRef.current) {
|
|
92
|
+
currentHoveredRef.current.onMouseOut(currentHoveredDataRef.current);
|
|
118
93
|
}
|
|
94
|
+
} // 새 hover 항목에 mouseOver 이벤트 발생
|
|
95
|
+
|
|
119
96
|
|
|
120
|
-
|
|
121
|
-
|
|
97
|
+
if (newHoveredComponent && newHoveredData) {
|
|
98
|
+
newHoveredComponent.setHovered(newHoveredData);
|
|
99
|
+
|
|
100
|
+
if (newHoveredComponent.onMouseOver) {
|
|
101
|
+
newHoveredComponent.onMouseOver(newHoveredData);
|
|
102
|
+
}
|
|
122
103
|
}
|
|
123
|
-
}, [controller]);
|
|
124
|
-
/**
|
|
125
|
-
* 줌/드래그 시작 (마우스 이동 이벤트 무시)
|
|
126
|
-
*/
|
|
127
104
|
|
|
105
|
+
currentHoveredRef.current = newHoveredComponent;
|
|
106
|
+
currentHoveredDataRef.current = newHoveredData;
|
|
107
|
+
}, [controller]);
|
|
128
108
|
var handleZoomStart = React.useCallback(function () {
|
|
129
109
|
draggingRef.current = true;
|
|
130
110
|
}, []);
|
|
131
|
-
/**
|
|
132
|
-
* 지도 idle (마우스 이동 이벤트 재개)
|
|
133
|
-
*/
|
|
134
|
-
|
|
135
111
|
var handleIdle = React.useCallback(function () {
|
|
136
112
|
draggingRef.current = false;
|
|
137
|
-
}, []);
|
|
138
|
-
|
|
113
|
+
}, []);
|
|
139
114
|
React.useEffect(function () {
|
|
140
115
|
controller.addEventListener('CLICK', handleGlobalClick);
|
|
141
116
|
controller.addEventListener('MOUSEMOVE', handleGlobalMouseMove);
|
|
@@ -147,8 +122,7 @@ var WoongCanvasProvider = function (_a) {
|
|
|
147
122
|
controller.removeEventListener('ZOOMSTART', handleZoomStart);
|
|
148
123
|
controller.removeEventListener('IDLE', handleIdle);
|
|
149
124
|
};
|
|
150
|
-
}, [controller, handleGlobalClick, handleGlobalMouseMove, handleZoomStart, handleIdle]);
|
|
151
|
-
|
|
125
|
+
}, [controller, handleGlobalClick, handleGlobalMouseMove, handleZoomStart, handleIdle]);
|
|
152
126
|
var contextValue = React.useMemo(function () {
|
|
153
127
|
return {
|
|
154
128
|
registerComponent: registerComponent,
|
|
@@ -159,9 +133,14 @@ var WoongCanvasProvider = function (_a) {
|
|
|
159
133
|
value: contextValue
|
|
160
134
|
}, children);
|
|
161
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* WoongCanvas Context Hook
|
|
138
|
+
*
|
|
139
|
+
* @returns WoongCanvasContextValue 또는 null (Provider 없으면)
|
|
140
|
+
*/
|
|
141
|
+
|
|
162
142
|
var useWoongCanvasContext = function () {
|
|
163
|
-
|
|
164
|
-
return context;
|
|
143
|
+
return React.useContext(WoongCanvasContext);
|
|
165
144
|
};
|
|
166
145
|
|
|
167
146
|
exports.WoongCanvasProvider = WoongCanvasProvider;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EventParam, MapUIEventParam } from "../../../types";
|
|
2
|
+
import type { MintMapController } from "../../MintMapController";
|
|
3
|
+
import type { Offset } from "../../../types";
|
|
4
|
+
/**
|
|
5
|
+
* 이벤트 유효성 검증 및 좌표 변환
|
|
6
|
+
*
|
|
7
|
+
* @param event 이벤트 파라미터
|
|
8
|
+
* @param context WoongCanvasContext 인스턴스
|
|
9
|
+
* @param controller MintMapController 인스턴스
|
|
10
|
+
* @returns 유효한 화면 좌표 또는 null
|
|
11
|
+
*/
|
|
12
|
+
export declare const validateEvent: (event: EventParam<MapUIEventParam> | null | undefined, context: any, controller: MintMapController) => Offset | null;
|
|
13
|
+
/**
|
|
14
|
+
* Map의 values를 배열로 변환
|
|
15
|
+
*
|
|
16
|
+
* @template T Map 값의 타입
|
|
17
|
+
* @param map 변환할 Map
|
|
18
|
+
* @returns Map의 값 배열
|
|
19
|
+
*/
|
|
20
|
+
export declare const mapValuesToArray: <T>(map: Map<string, T>) => T[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 이벤트 유효성 검증 및 좌표 변환
|
|
7
|
+
*
|
|
8
|
+
* @param event 이벤트 파라미터
|
|
9
|
+
* @param context WoongCanvasContext 인스턴스
|
|
10
|
+
* @param controller MintMapController 인스턴스
|
|
11
|
+
* @returns 유효한 화면 좌표 또는 null
|
|
12
|
+
*/
|
|
13
|
+
var validateEvent = function (event, context, controller) {
|
|
14
|
+
var _a;
|
|
15
|
+
|
|
16
|
+
if (context) return null;
|
|
17
|
+
if (!((_a = event === null || event === void 0 ? void 0 : event.param) === null || _a === void 0 ? void 0 : _a.position)) return null;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
return controller.positionToOffset(event.param.position);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error('[WoongCanvas] validateEvent error:', error);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Map의 values를 배열로 변환
|
|
28
|
+
*
|
|
29
|
+
* @template T Map 값의 타입
|
|
30
|
+
* @param map 변환할 Map
|
|
31
|
+
* @returns Map의 값 배열
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
var mapValuesToArray = function (map) {
|
|
35
|
+
if (map.size === 0) return [];
|
|
36
|
+
return Array.from(map.values());
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
exports.mapValuesToArray = mapValuesToArray;
|
|
40
|
+
exports.validateEvent = validateEvent;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { MutableRefObject } from "react";
|
|
2
|
+
import type { MintMapController } from "../../MintMapController";
|
|
3
|
+
import type { Marker, MarkerOptions } from "../../../types";
|
|
4
|
+
import type { CanvasData } from "./types";
|
|
5
|
+
import type { BoundingBox } from "./viewport";
|
|
6
|
+
import type { SpatialHashGrid } from "./performance";
|
|
7
|
+
/**
|
|
8
|
+
* 공통 이벤트 핸들러 의존성 인터페이스
|
|
9
|
+
*
|
|
10
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* 지도 이벤트 핸들러 생성 시 필요한 모든 의존성을 포함합니다.
|
|
14
|
+
*/
|
|
15
|
+
export interface EventHandlerDeps<T> {
|
|
16
|
+
controller: MintMapController;
|
|
17
|
+
containerRef: MutableRefObject<HTMLDivElement | null>;
|
|
18
|
+
markerRef: MutableRefObject<Marker | undefined>;
|
|
19
|
+
options: Pick<MarkerOptions, 'zIndex' | 'anchor' | 'visible'>;
|
|
20
|
+
prevCenterOffsetRef: MutableRefObject<{
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
} | null>;
|
|
24
|
+
accumTranslateRef: MutableRefObject<{
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
}>;
|
|
28
|
+
offsetCacheRef: MutableRefObject<any>;
|
|
29
|
+
boundingBoxCacheRef: MutableRefObject<Map<string, BoundingBox>>;
|
|
30
|
+
renderAllImmediate: () => void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 지도 이벤트 핸들러 생성 함수
|
|
34
|
+
*
|
|
35
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
36
|
+
* @param deps 이벤트 핸들러 생성에 필요한 의존성
|
|
37
|
+
* @returns 지도 이벤트 핸들러 객체
|
|
38
|
+
*/
|
|
39
|
+
export declare const createMapEventHandlers: <T>(deps: EventHandlerDeps<T>) => {
|
|
40
|
+
handleIdle: () => void;
|
|
41
|
+
handleZoomStart: () => void;
|
|
42
|
+
handleZoomEnd: () => void;
|
|
43
|
+
handleCenterChanged: () => void;
|
|
44
|
+
handleDragStart: () => void;
|
|
45
|
+
handleDragEnd: () => void;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* 공간 인덱스 빌드 (빠른 Hit Test를 위한 자료구조)
|
|
49
|
+
*
|
|
50
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
51
|
+
* @param data 공간 인덱스에 삽입할 데이터 배열
|
|
52
|
+
* @param spatialIndex Spatial Hash Grid 인스턴스
|
|
53
|
+
* @param computeBoundingBox 바운딩 박스 계산 함수
|
|
54
|
+
*/
|
|
55
|
+
export declare const buildSpatialIndex: <T>(data: CanvasData<T>[], spatialIndex: SpatialHashGrid<CanvasData<T>>, computeBoundingBox: (item: CanvasData<T>) => BoundingBox | null) => void;
|
|
56
|
+
/**
|
|
57
|
+
* 선택 상태 동기화 (화면 밖 데이터도 선택 상태 유지)
|
|
58
|
+
*
|
|
59
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
60
|
+
* @param data 최신 데이터 배열
|
|
61
|
+
* @param selectedIds 선택된 항목 ID Set
|
|
62
|
+
* @param selectedItemsMap 현재 선택된 항목 Map
|
|
63
|
+
* @returns 업데이트된 선택된 항목 Map
|
|
64
|
+
*/
|
|
65
|
+
export declare const syncSelectedItems: <T>(data: CanvasData<T>[], selectedIds: Set<string>, selectedItemsMap: Map<string, CanvasData<T>>) => Map<string, CanvasData<T>>;
|
|
66
|
+
/**
|
|
67
|
+
* 외부 selectedItems를 내부 상태로 동기화
|
|
68
|
+
*
|
|
69
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
70
|
+
* @param externalSelectedItems 외부에서 전달된 선택된 항목 배열
|
|
71
|
+
* @param selectedIdsRef 선택된 ID Set ref
|
|
72
|
+
* @param selectedItemsMapRef 선택된 항목 Map ref
|
|
73
|
+
*/
|
|
74
|
+
export declare const syncExternalSelectedItems: <T>(externalSelectedItems: CanvasData<T>[] | undefined, selectedIdsRef: MutableRefObject<Set<string>>, selectedItemsMapRef: MutableRefObject<Map<string, CanvasData<T>>>) => void;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 지도 이벤트 핸들러 생성 함수
|
|
9
|
+
*
|
|
10
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
11
|
+
* @param deps 이벤트 핸들러 생성에 필요한 의존성
|
|
12
|
+
* @returns 지도 이벤트 핸들러 객체
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
var createMapEventHandlers = function (deps) {
|
|
16
|
+
var controller = deps.controller,
|
|
17
|
+
containerRef = deps.containerRef,
|
|
18
|
+
markerRef = deps.markerRef,
|
|
19
|
+
options = deps.options,
|
|
20
|
+
prevCenterOffsetRef = deps.prevCenterOffsetRef,
|
|
21
|
+
accumTranslateRef = deps.accumTranslateRef,
|
|
22
|
+
offsetCacheRef = deps.offsetCacheRef,
|
|
23
|
+
boundingBoxCacheRef = deps.boundingBoxCacheRef,
|
|
24
|
+
renderAllImmediate = deps.renderAllImmediate; // 지도 이동/줌 완료 시 처리 (캐시 초기화 및 렌더링)
|
|
25
|
+
|
|
26
|
+
var handleIdle = function () {
|
|
27
|
+
prevCenterOffsetRef.current = null;
|
|
28
|
+
accumTranslateRef.current = {
|
|
29
|
+
x: 0,
|
|
30
|
+
y: 0
|
|
31
|
+
}; // 캐시 정리 (지도 이동/줌으로 좌표 변환 결과가 바뀜)
|
|
32
|
+
|
|
33
|
+
offsetCacheRef.current.clear();
|
|
34
|
+
boundingBoxCacheRef.current.clear(); // 마커 위치 업데이트
|
|
35
|
+
|
|
36
|
+
var bounds = controller.getCurrBounds();
|
|
37
|
+
|
|
38
|
+
var markerOptions = tslib.__assign({
|
|
39
|
+
position: bounds.nw
|
|
40
|
+
}, options);
|
|
41
|
+
|
|
42
|
+
markerRef.current && controller.updateMarker(markerRef.current, markerOptions); // transform 제거 전에 새 데이터로 즉시 렌더링 (transform 제거 시 잠깐 빈 화면이 보이는 것 방지)
|
|
43
|
+
|
|
44
|
+
if (containerRef.current) {
|
|
45
|
+
containerRef.current.style.transform = '';
|
|
46
|
+
containerRef.current.style.visibility = '';
|
|
47
|
+
} // 새 위치에서 렌더링 (캐시는 이미 초기화됨)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
renderAllImmediate();
|
|
51
|
+
}; // 줌 시작 시 처리 (일시적으로 숨김)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
var handleZoomStart = function () {
|
|
55
|
+
if (!containerRef.current) return;
|
|
56
|
+
containerRef.current.style.visibility = 'hidden';
|
|
57
|
+
}; // 줌 종료 시 처리 (다시 표시)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
var handleZoomEnd = function () {
|
|
61
|
+
if (!containerRef.current) return;
|
|
62
|
+
containerRef.current.style.visibility = '';
|
|
63
|
+
}; // 지도 중심 변경 시 처리 (transform으로 이동 추적, 캐시 유지)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
var handleCenterChanged = function () {
|
|
67
|
+
var center = controller.getCurrBounds().getCenter();
|
|
68
|
+
var curr = controller.positionToOffset(center);
|
|
69
|
+
var prev = prevCenterOffsetRef.current; // 첫 번째 호출 시 이전 위치 저장만 하고 종료
|
|
70
|
+
|
|
71
|
+
if (!prev) {
|
|
72
|
+
prevCenterOffsetRef.current = {
|
|
73
|
+
x: curr.x,
|
|
74
|
+
y: curr.y
|
|
75
|
+
};
|
|
76
|
+
return;
|
|
77
|
+
} // 이전 위치와 현재 위치의 차이 계산 (이동 거리)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
var dx = prev.x - curr.x;
|
|
81
|
+
var dy = prev.y - curr.y; // 누적 이동 거리 저장 (transform으로 화면만 이동, 캐시는 유지하여 성능 최적화)
|
|
82
|
+
|
|
83
|
+
accumTranslateRef.current = {
|
|
84
|
+
x: accumTranslateRef.current.x + dx,
|
|
85
|
+
y: accumTranslateRef.current.y + dy
|
|
86
|
+
};
|
|
87
|
+
prevCenterOffsetRef.current = {
|
|
88
|
+
x: curr.x,
|
|
89
|
+
y: curr.y
|
|
90
|
+
}; // CSS transform으로 컨테이너 이동 (캐시된 좌표는 그대로 유지)
|
|
91
|
+
|
|
92
|
+
if (containerRef.current) {
|
|
93
|
+
containerRef.current.style.transform = "translate(".concat(accumTranslateRef.current.x, "px, ").concat(accumTranslateRef.current.y, "px)");
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
var handleDragStart = function () {// 커서는 각 컴포넌트에서 처리
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
var handleDragEnd = function () {// 커서는 각 컴포넌트에서 처리
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
handleIdle: handleIdle,
|
|
105
|
+
handleZoomStart: handleZoomStart,
|
|
106
|
+
handleZoomEnd: handleZoomEnd,
|
|
107
|
+
handleCenterChanged: handleCenterChanged,
|
|
108
|
+
handleDragStart: handleDragStart,
|
|
109
|
+
handleDragEnd: handleDragEnd
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* 공간 인덱스 빌드 (빠른 Hit Test를 위한 자료구조)
|
|
114
|
+
*
|
|
115
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
116
|
+
* @param data 공간 인덱스에 삽입할 데이터 배열
|
|
117
|
+
* @param spatialIndex Spatial Hash Grid 인스턴스
|
|
118
|
+
* @param computeBoundingBox 바운딩 박스 계산 함수
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
var buildSpatialIndex = function (data, spatialIndex, computeBoundingBox) {
|
|
122
|
+
spatialIndex.clear();
|
|
123
|
+
|
|
124
|
+
for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
|
|
125
|
+
var item = data_1[_i];
|
|
126
|
+
var bbox = computeBoundingBox(item);
|
|
127
|
+
|
|
128
|
+
if (bbox) {
|
|
129
|
+
spatialIndex.insert(item, bbox.minX, bbox.minY, bbox.maxX, bbox.maxY);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* 선택 상태 동기화 (화면 밖 데이터도 선택 상태 유지)
|
|
135
|
+
*
|
|
136
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
137
|
+
* @param data 최신 데이터 배열
|
|
138
|
+
* @param selectedIds 선택된 항목 ID Set
|
|
139
|
+
* @param selectedItemsMap 현재 선택된 항목 Map
|
|
140
|
+
* @returns 업데이트된 선택된 항목 Map
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
var syncSelectedItems = function (data, selectedIds, selectedItemsMap) {
|
|
144
|
+
var dataMap = new Map(data.map(function (m) {
|
|
145
|
+
return [m.id, m];
|
|
146
|
+
}));
|
|
147
|
+
var newSelectedItemsMap = new Map();
|
|
148
|
+
selectedIds.forEach(function (id) {
|
|
149
|
+
// 현재 data에 있으면 최신 데이터 사용
|
|
150
|
+
var currentItem = dataMap.get(id);
|
|
151
|
+
|
|
152
|
+
if (currentItem) {
|
|
153
|
+
newSelectedItemsMap.set(id, currentItem);
|
|
154
|
+
} else {
|
|
155
|
+
// 화면 밖이면 기존 데이터 유지
|
|
156
|
+
var prevItem = selectedItemsMap.get(id);
|
|
157
|
+
|
|
158
|
+
if (prevItem) {
|
|
159
|
+
newSelectedItemsMap.set(id, prevItem);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return newSelectedItemsMap;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* 외부 selectedItems를 내부 상태로 동기화
|
|
167
|
+
*
|
|
168
|
+
* @template T 마커/폴리곤 데이터의 추가 속성 타입
|
|
169
|
+
* @param externalSelectedItems 외부에서 전달된 선택된 항목 배열
|
|
170
|
+
* @param selectedIdsRef 선택된 ID Set ref
|
|
171
|
+
* @param selectedItemsMapRef 선택된 항목 Map ref
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
var syncExternalSelectedItems = function (externalSelectedItems, selectedIdsRef, selectedItemsMapRef) {
|
|
175
|
+
if (externalSelectedItems === undefined) return;
|
|
176
|
+
var newSelectedIds = new Set();
|
|
177
|
+
var newSelectedItemsMap = new Map();
|
|
178
|
+
externalSelectedItems.forEach(function (item) {
|
|
179
|
+
newSelectedIds.add(item.id);
|
|
180
|
+
newSelectedItemsMap.set(item.id, item);
|
|
181
|
+
});
|
|
182
|
+
selectedIdsRef.current = newSelectedIds;
|
|
183
|
+
selectedItemsMapRef.current = newSelectedItemsMap;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
exports.buildSpatialIndex = buildSpatialIndex;
|
|
187
|
+
exports.createMapEventHandlers = createMapEventHandlers;
|
|
188
|
+
exports.syncExternalSelectedItems = syncExternalSelectedItems;
|
|
189
|
+
exports.syncSelectedItems = syncSelectedItems;
|