@mint-ui/map 1.2.0-test.63 → 1.2.0-test.66
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/CanvasMarkerLayer/CanvasMarkerLayer.d.ts +2 -122
- package/dist/components/mint-map/core/advanced/CanvasMarkerLayer/CanvasMarkerLayer.js +129 -153
- package/dist/components/mint-map/core/advanced/CanvasMarkerLayer/index.d.ts +1 -0
- package/dist/components/mint-map/core/advanced/CanvasMarkerLayer/types.d.ts +252 -0
- package/dist/components/mint-map/core/advanced/CanvasPolygonLayer/CanvasPolygonLayer.d.ts +2 -258
- package/dist/components/mint-map/core/advanced/CanvasPolygonLayer/CanvasPolygonLayer.js +16 -3
- package/dist/components/mint-map/core/advanced/CanvasPolygonLayer/index.d.ts +1 -0
- package/dist/components/mint-map/core/advanced/CanvasPolygonLayer/types.d.ts +280 -0
- package/dist/index.es.js +145 -156
- package/dist/index.umd.js +145 -156
- package/package.json +1 -1
|
@@ -1,128 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
import { CanvasData, CustomRenderBase, CustomRenderEvent } from '../shared';
|
|
2
|
+
import type { CanvasMarkerLayerProps } from './types';
|
|
4
3
|
export { CanvasDataType, CanvasProvider, LRUCache, SpatialHashGrid } from '../shared';
|
|
5
4
|
export type { CanvasData, CanvasOption, CustomRenderBase, CustomRenderEvent, MarkerBoundingBox, RenderBaseParams, RenderEventParams, RenderUtils } from '../shared';
|
|
6
|
-
|
|
7
|
-
* CanvasMarkerLayer Props (renderEvent가 없는 경우 - 인터랙션 불가)
|
|
8
|
-
*
|
|
9
|
-
* @template T 마커 데이터의 추가 속성 타입
|
|
10
|
-
*/
|
|
11
|
-
interface CanvasMarkerLayerPropsWithoutEvent<T> extends Pick<MarkerOptions, 'zIndex' | 'anchor' | 'visible'> {
|
|
12
|
-
/** 렌더링할 마커 데이터 배열 */
|
|
13
|
-
data: CanvasData<T>[];
|
|
14
|
-
/** 뷰포트 컬링 활성화 여부 (기본값: false) */
|
|
15
|
-
enableViewportCulling?: boolean;
|
|
16
|
-
/** 뷰포트 컬링 여유 공간 (픽셀 단위, 기본값: 100) */
|
|
17
|
-
cullingMargin?: number;
|
|
18
|
-
/** LRU 캐시 최대 크기 (기본값: 10000) */
|
|
19
|
-
maxCacheSize?: number;
|
|
20
|
-
/** Base Layer 렌더링 함수 (필수) */
|
|
21
|
-
renderBase: CustomRenderBase<T>;
|
|
22
|
-
/** Event Layer 렌더링 함수가 없으면 인터랙션 관련 props 사용 불가 */
|
|
23
|
-
renderEvent?: never;
|
|
24
|
-
/** 인터랙션 관련 props는 renderEvent가 있을 때만 사용 가능 */
|
|
25
|
-
onClick?: never;
|
|
26
|
-
onMouseOver?: never;
|
|
27
|
-
onMouseOut?: never;
|
|
28
|
-
enableMultiSelect?: never;
|
|
29
|
-
topOnHover?: never;
|
|
30
|
-
selectedItems?: never;
|
|
31
|
-
selectedItem?: never;
|
|
32
|
-
disableInteraction?: never;
|
|
33
|
-
topStageZIndex?: never;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* CanvasMarkerLayer Props (renderEvent가 있는 경우 - 인터랙션 가능)
|
|
37
|
-
* topStageZIndex가 없을 때
|
|
38
|
-
*
|
|
39
|
-
* @template T 마커 데이터의 추가 속성 타입
|
|
40
|
-
*/
|
|
41
|
-
interface CanvasMarkerLayerPropsWithEventBase<T> extends Pick<MarkerOptions, 'zIndex' | 'anchor' | 'visible'> {
|
|
42
|
-
/** 렌더링할 마커 데이터 배열 */
|
|
43
|
-
data: CanvasData<T>[];
|
|
44
|
-
/** 마커 클릭 시 호출되는 콜백 함수 */
|
|
45
|
-
onClick?: (payload: CanvasData<T>, selectedIds: Set<string>) => void;
|
|
46
|
-
/** 마커에 마우스 오버 시 호출되는 콜백 함수 */
|
|
47
|
-
onMouseOver?: (payload: CanvasData<T>) => void;
|
|
48
|
-
/** 마커에서 마우스 아웃 시 호출되는 콜백 함수 */
|
|
49
|
-
onMouseOut?: (payload: CanvasData<T>) => void;
|
|
50
|
-
/** 다중 선택 활성화 여부 (기본값: false) */
|
|
51
|
-
enableMultiSelect?: boolean;
|
|
52
|
-
/** hover 시 마커를 최상단으로 표시할지 여부 (기본값: false) */
|
|
53
|
-
topOnHover?: boolean;
|
|
54
|
-
/** 뷰포트 컬링 활성화 여부 (기본값: false) */
|
|
55
|
-
enableViewportCulling?: boolean;
|
|
56
|
-
/** 뷰포트 컬링 여유 공간 (픽셀 단위, 기본값: 100) */
|
|
57
|
-
cullingMargin?: number;
|
|
58
|
-
/** LRU 캐시 최대 크기 (기본값: 10000) */
|
|
59
|
-
maxCacheSize?: number;
|
|
60
|
-
/** 외부에서 제어하는 선택된 항목 배열 */
|
|
61
|
-
selectedItems?: CanvasData<T>[];
|
|
62
|
-
/** 외부에서 전달된 단일 선택 아이템 */
|
|
63
|
-
selectedItem?: CanvasData<T> | null;
|
|
64
|
-
/** 상호작용 비활성화 여부 (기본값: false) */
|
|
65
|
-
disableInteraction?: boolean;
|
|
66
|
-
/** Base Layer 렌더링 함수 (필수) */
|
|
67
|
-
renderBase: CustomRenderBase<T>;
|
|
68
|
-
/** Event Layer 렌더링 함수 (필수 - 인터랙션 사용 시) */
|
|
69
|
-
renderEvent: CustomRenderEvent<T>;
|
|
70
|
-
/** Top Layer의 zIndex (hover된 항목을 최상단에 렌더링하기 위한 레이어, topOnHover가 true일 때만 사용 가능) */
|
|
71
|
-
topStageZIndex?: never;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* CanvasMarkerLayer Props (renderEvent가 있는 경우 - 인터랙션 가능)
|
|
75
|
-
* topStageZIndex가 있을 때 (topOnHover가 반드시 true여야 함)
|
|
76
|
-
*
|
|
77
|
-
* @template T 마커 데이터의 추가 속성 타입
|
|
78
|
-
*/
|
|
79
|
-
interface CanvasMarkerLayerPropsWithEventWithTopStage<T> extends Pick<MarkerOptions, 'zIndex' | 'anchor' | 'visible'> {
|
|
80
|
-
/** 렌더링할 마커 데이터 배열 */
|
|
81
|
-
data: CanvasData<T>[];
|
|
82
|
-
/** 마커 클릭 시 호출되는 콜백 함수 */
|
|
83
|
-
onClick?: (payload: CanvasData<T>, selectedIds: Set<string>) => void;
|
|
84
|
-
/** 마커에 마우스 오버 시 호출되는 콜백 함수 */
|
|
85
|
-
onMouseOver?: (payload: CanvasData<T>) => void;
|
|
86
|
-
/** 마커에서 마우스 아웃 시 호출되는 콜백 함수 */
|
|
87
|
-
onMouseOut?: (payload: CanvasData<T>) => void;
|
|
88
|
-
/** 다중 선택 활성화 여부 (기본값: false) */
|
|
89
|
-
enableMultiSelect?: boolean;
|
|
90
|
-
/** hover 시 마커를 최상단으로 표시할지 여부 (topStageZIndex 사용 시 반드시 true) */
|
|
91
|
-
topOnHover: true;
|
|
92
|
-
/** 뷰포트 컬링 활성화 여부 (기본값: false) */
|
|
93
|
-
enableViewportCulling?: boolean;
|
|
94
|
-
/** 뷰포트 컬링 여유 공간 (픽셀 단위, 기본값: 100) */
|
|
95
|
-
cullingMargin?: number;
|
|
96
|
-
/** LRU 캐시 최대 크기 (기본값: 10000) */
|
|
97
|
-
maxCacheSize?: number;
|
|
98
|
-
/** 외부에서 제어하는 선택된 항목 배열 */
|
|
99
|
-
selectedItems?: CanvasData<T>[];
|
|
100
|
-
/** 외부에서 전달된 단일 선택 아이템 */
|
|
101
|
-
selectedItem?: CanvasData<T> | null;
|
|
102
|
-
/** 상호작용 비활성화 여부 (기본값: false) */
|
|
103
|
-
disableInteraction?: boolean;
|
|
104
|
-
/** Base Layer 렌더링 함수 (필수) */
|
|
105
|
-
renderBase: CustomRenderBase<T>;
|
|
106
|
-
/** Event Layer 렌더링 함수 (필수 - 인터랙션 사용 시) */
|
|
107
|
-
renderEvent: CustomRenderEvent<T>;
|
|
108
|
-
/** Top Layer의 zIndex (hover된 항목을 최상단에 렌더링하기 위한 레이어, topOnHover가 true일 때만 사용 가능) */
|
|
109
|
-
topStageZIndex: number;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* CanvasMarkerLayer Props (renderEvent가 있는 경우 - 인터랙션 가능)
|
|
113
|
-
*
|
|
114
|
-
* @template T 마커 데이터의 추가 속성 타입
|
|
115
|
-
*/
|
|
116
|
-
declare type CanvasMarkerLayerPropsWithEvent<T> = CanvasMarkerLayerPropsWithEventBase<T> | CanvasMarkerLayerPropsWithEventWithTopStage<T>;
|
|
117
|
-
/**
|
|
118
|
-
* CanvasMarkerLayer Props
|
|
119
|
-
*
|
|
120
|
-
* renderEvent가 없으면 인터랙션 관련 props를 사용할 수 없습니다.
|
|
121
|
-
* renderEvent가 있으면 모든 인터랙션 관련 props를 사용할 수 있습니다.
|
|
122
|
-
*
|
|
123
|
-
* @template T 마커 데이터의 추가 속성 타입
|
|
124
|
-
*/
|
|
125
|
-
export declare type CanvasMarkerLayerProps<T> = CanvasMarkerLayerPropsWithoutEvent<T> | CanvasMarkerLayerPropsWithEvent<T>;
|
|
5
|
+
export type { CanvasMarkerLayerProps, CanvasMarkerLayerPropsWithEvent, CanvasMarkerLayerPropsWithEventWithoutSelection, CanvasMarkerLayerPropsWithEventWithSelectedItem, CanvasMarkerLayerPropsWithEventWithSelectedItems, CanvasMarkerLayerPropsWithEventWithTopStageWithoutSelection, CanvasMarkerLayerPropsWithEventWithTopStageWithSelectedItem, CanvasMarkerLayerPropsWithEventWithTopStageWithSelectedItems, CanvasMarkerLayerPropsWithoutEvent } from './types';
|
|
126
6
|
declare const CanvasMarkerLayer: <T>(props: CanvasMarkerLayerProps<T>) => JSX.Element;
|
|
127
7
|
/**
|
|
128
8
|
* CanvasMarkerLayer - Konva 기반 고성능 마커 렌더링 컴포넌트
|
|
@@ -40,32 +40,26 @@ var CanvasMarkerLayer = function (props) {
|
|
|
40
40
|
|
|
41
41
|
var _d = hasRenderEvent && 'renderEvent' in props ? props : {
|
|
42
42
|
disableInteraction: false,
|
|
43
|
-
enableMultiSelect: false,
|
|
44
43
|
onClick: undefined,
|
|
45
44
|
onMouseOut: undefined,
|
|
46
45
|
onMouseOver: undefined,
|
|
47
46
|
renderEvent: undefined,
|
|
48
47
|
selectedItem: undefined,
|
|
49
48
|
selectedItems: undefined,
|
|
50
|
-
topOnHover: false,
|
|
51
49
|
topStageZIndex: undefined
|
|
52
50
|
},
|
|
53
51
|
_e = _d.disableInteraction,
|
|
54
52
|
disableInteraction = _e === void 0 ? false : _e,
|
|
55
|
-
_f = _d.enableMultiSelect,
|
|
56
|
-
enableMultiSelect = _f === void 0 ? false : _f,
|
|
57
53
|
onClick = _d.onClick,
|
|
58
54
|
onMouseOut = _d.onMouseOut,
|
|
59
55
|
onMouseOver = _d.onMouseOver,
|
|
60
56
|
renderEvent = _d.renderEvent,
|
|
61
57
|
externalSelectedItem = _d.selectedItem,
|
|
62
58
|
externalSelectedItems = _d.selectedItems,
|
|
63
|
-
rawTopStageZIndex = _d.topStageZIndex
|
|
64
|
-
_g = _d.topOnHover,
|
|
65
|
-
topOnHover = _g === void 0 ? false : _g; // topOnHover가 false이거나 없으면 topStageZIndex를 사용하지 못하도록 제한
|
|
59
|
+
rawTopStageZIndex = _d.topStageZIndex; // topStageZIndex가 있으면 hover 최상단 표시 활성화, 없으면 비활성화 (성능 우선)
|
|
66
60
|
|
|
67
61
|
|
|
68
|
-
var topStageZIndex =
|
|
62
|
+
var topStageZIndex = rawTopStageZIndex;
|
|
69
63
|
var controller = MintMapProvider.useMintMapController();
|
|
70
64
|
var context$1 = context.useCanvasContext();
|
|
71
65
|
var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
|
|
@@ -175,44 +169,24 @@ var CanvasMarkerLayer = function (props) {
|
|
|
175
169
|
|
|
176
170
|
var visibleItems = enableViewportCullingRef.current ? dataRef.current.filter(function (item) {
|
|
177
171
|
return isInViewport(item);
|
|
178
|
-
}) : dataRef.current; // topStageZIndex가
|
|
179
|
-
// topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
|
|
172
|
+
}) : dataRef.current; // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리
|
|
180
173
|
|
|
181
|
-
if (topStageZIndex !== undefined &&
|
|
174
|
+
if (topStageZIndex !== undefined && hovered) {
|
|
182
175
|
visibleItems = visibleItems.filter(function (item) {
|
|
183
176
|
return item.id !== hovered.id;
|
|
184
177
|
});
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return item.id !== hovered.id;
|
|
188
|
-
});
|
|
189
|
-
} // 일반 항목들 먼저 렌더링
|
|
190
|
-
// topOnHover가 false이고 renderEvent가 있으면 선택된 항목도 Base Layer에서 렌더링
|
|
191
|
-
// (Event Layer에서 선택된 항목을 렌더링하지 않으므로)
|
|
192
|
-
// topOnHover가 true이거나 renderEvent가 없으면 선택된 항목은 Base Layer에서 스킵됨
|
|
178
|
+
} // Base Layer는 기본 마커만 렌더링 (성능 최적화)
|
|
179
|
+
// hover/selected는 Event Layer에서 덧그리므로 Base Layer에서는 제외
|
|
193
180
|
|
|
194
181
|
|
|
195
|
-
var baseSelectedIds = !topOnHover && renderEvent ? selectedIdsRef.current : new Set();
|
|
196
182
|
renderBase({
|
|
197
183
|
ctx: ctx,
|
|
198
|
-
hoveredItem:
|
|
184
|
+
hoveredItem: null,
|
|
199
185
|
items: visibleItems,
|
|
200
|
-
selectedIds:
|
|
186
|
+
selectedIds: new Set(),
|
|
201
187
|
utils: renderUtils
|
|
202
188
|
}); // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리하므로 여기서는 스킵
|
|
203
|
-
// hover된
|
|
204
|
-
|
|
205
|
-
if (topStageZIndex === undefined && topOnHover && !renderEvent && hovered) {
|
|
206
|
-
if (!enableViewportCullingRef.current || isInViewport(hovered)) {
|
|
207
|
-
renderBase({
|
|
208
|
-
ctx: ctx,
|
|
209
|
-
hoveredItem: hovered,
|
|
210
|
-
items: [hovered],
|
|
211
|
-
selectedIds: selectedIdsRef.current,
|
|
212
|
-
utils: renderUtils
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
189
|
+
// topStageZIndex가 없으면 성능 우선으로 Base Layer 재렌더링 안 함 (hover된 항목이 뒤편 마커 위로 올라갈 수 있음)
|
|
216
190
|
}
|
|
217
191
|
});
|
|
218
192
|
layer.add(shape);
|
|
@@ -236,64 +210,45 @@ var CanvasMarkerLayer = function (props) {
|
|
|
236
210
|
sceneFunc: function (konvaContext) {
|
|
237
211
|
var ctx = konvaContext;
|
|
238
212
|
var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current);
|
|
239
|
-
var hovered = hoveredItemRef.current; //
|
|
213
|
+
var hovered = hoveredItemRef.current; // selectedItem이 있으면 selectedItems 배열에 포함 (renderMarkerEvent가 selectedItems만 사용하므로)
|
|
214
|
+
|
|
215
|
+
if (selectedItemRef.current) {
|
|
216
|
+
// selectedItem이 이미 selectedItems에 포함되어 있지 않으면 추가
|
|
217
|
+
var selectedItemId_1 = selectedItemRef.current.id;
|
|
218
|
+
|
|
219
|
+
if (!selectedItems.some(function (item) {
|
|
220
|
+
return item.id === selectedItemId_1;
|
|
221
|
+
})) {
|
|
222
|
+
selectedItems = tslib.__spreadArray(tslib.__spreadArray([], selectedItems, true), [selectedItemRef.current], false);
|
|
223
|
+
}
|
|
224
|
+
} // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리
|
|
240
225
|
// event 레이어에서는 hover된 항목을 완전히 제외하고 선택된 항목만 렌더링
|
|
241
226
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
227
|
+
|
|
228
|
+
if (topStageZIndex !== undefined && hovered) {
|
|
229
|
+
// hover된 항목을 제외한 선택된 항목들 (성능 최적화: 필요할 때만 필터링)
|
|
230
|
+
var selectedItemsWithoutHovered = selectedItems.length > 0 ? selectedItems.filter(function (item) {
|
|
245
231
|
return item.id !== hovered.id;
|
|
246
|
-
}); // 선택된 항목만 그리기 (hover된 항목은 Top Layer에서 처리)
|
|
232
|
+
}) : selectedItems; // 선택된 항목만 그리기 (hover된 항목은 Top Layer에서 처리)
|
|
247
233
|
|
|
248
234
|
renderEvent({
|
|
249
235
|
ctx: ctx,
|
|
250
236
|
hoveredItem: null,
|
|
251
237
|
selectedItem: selectedItemRef.current,
|
|
252
238
|
selectedItems: selectedItemsWithoutHovered,
|
|
253
|
-
topOnHover:
|
|
254
|
-
utils: renderUtils
|
|
255
|
-
});
|
|
256
|
-
} else if (topOnHover && hovered) {
|
|
257
|
-
renderEvent({
|
|
258
|
-
ctx: ctx,
|
|
259
|
-
hoveredItem: null,
|
|
260
|
-
selectedItem: selectedItemRef.current,
|
|
261
|
-
selectedItems: selectedItems.filter(function (item) {
|
|
262
|
-
return item.id !== hovered.id;
|
|
263
|
-
}),
|
|
264
|
-
topOnHover: topOnHover,
|
|
239
|
+
topOnHover: true,
|
|
265
240
|
utils: renderUtils
|
|
266
241
|
});
|
|
267
|
-
|
|
268
|
-
if (!enableViewportCullingRef.current || isInViewport(hovered)) {
|
|
269
|
-
var hoveredIsSelected = selectedItems.some(function (item) {
|
|
270
|
-
return item.id === hovered.id;
|
|
271
|
-
});
|
|
272
|
-
var hoverSelectedItems = hoveredIsSelected ? [hovered] : [];
|
|
273
|
-
renderEvent({
|
|
274
|
-
ctx: ctx,
|
|
275
|
-
hoveredItem: hovered,
|
|
276
|
-
selectedItem: selectedItemRef.current,
|
|
277
|
-
selectedItems: hoverSelectedItems,
|
|
278
|
-
topOnHover: topOnHover,
|
|
279
|
-
utils: renderUtils
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
242
|
} else {
|
|
283
|
-
//
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
// renderEvent 함수 내부에서 topOnHover가 false일 때는 hover된 항목을 마지막에 그리지 않도록 함
|
|
287
|
-
var hoveredIsSelected = hovered ? selectedItems.some(function (item) {
|
|
288
|
-
return item.id === hovered.id;
|
|
289
|
-
}) : false;
|
|
290
|
-
var finalSelectedItems = hovered && !hoveredIsSelected && !topOnHover ? tslib.__spreadArray(tslib.__spreadArray([], selectedItems, true), [hovered], false) : selectedItems;
|
|
243
|
+
// topStageZIndex가 없으면 hover된 항목을 selectedItems에 추가하지 않음 (성능 우선)
|
|
244
|
+
// renderEvent 함수가 hoveredItem을 별도로 처리하므로, selectedItems는 그대로 전달
|
|
245
|
+
// 이렇게 하면 hover 변경 시 선택된 항목들을 다시 그리지 않고 hover된 항목만 업데이트됨
|
|
291
246
|
renderEvent({
|
|
292
247
|
ctx: ctx,
|
|
293
248
|
hoveredItem: hovered,
|
|
294
249
|
selectedItem: selectedItemRef.current,
|
|
295
|
-
selectedItems:
|
|
296
|
-
topOnHover:
|
|
250
|
+
selectedItems: selectedItems,
|
|
251
|
+
topOnHover: false,
|
|
297
252
|
utils: renderUtils
|
|
298
253
|
});
|
|
299
254
|
}
|
|
@@ -309,7 +264,7 @@ var CanvasMarkerLayer = function (props) {
|
|
|
309
264
|
var doRenderTop = function () {
|
|
310
265
|
var stage = topStageRef.current;
|
|
311
266
|
var layer = topLayerRef.current;
|
|
312
|
-
if (!stage || !layer || topStageZIndex === undefined
|
|
267
|
+
if (!stage || !layer || topStageZIndex === undefined) return;
|
|
313
268
|
var hovered = hoveredItemRef.current;
|
|
314
269
|
var shape = layer.findOne('.top-render-shape'); // hover된 항목이 없으면 shape 제거
|
|
315
270
|
|
|
@@ -337,6 +292,8 @@ var CanvasMarkerLayer = function (props) {
|
|
|
337
292
|
|
|
338
293
|
|
|
339
294
|
shape.sceneFunc(function (konvaContext) {
|
|
295
|
+
var _a;
|
|
296
|
+
|
|
340
297
|
var ctx = konvaContext;
|
|
341
298
|
var currentHovered = hoveredItemRef.current; // hover된 항목이 없으면 아무것도 그리지 않음
|
|
342
299
|
|
|
@@ -346,10 +303,11 @@ var CanvasMarkerLayer = function (props) {
|
|
|
346
303
|
return;
|
|
347
304
|
}
|
|
348
305
|
|
|
349
|
-
var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current);
|
|
306
|
+
var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current); // selectedItem이 있으면 hover된 항목이 선택되었는지 확인
|
|
307
|
+
|
|
350
308
|
var hoveredIsSelected = selectedItems.some(function (item) {
|
|
351
309
|
return item.id === currentHovered.id;
|
|
352
|
-
}); // Top Layer에서는 hover된 마커만 hover 스타일로 그리기
|
|
310
|
+
}) || ((_a = selectedItemRef.current) === null || _a === void 0 ? void 0 : _a.id) === currentHovered.id; // Top Layer에서는 hover된 마커만 hover 스타일로 그리기
|
|
353
311
|
// renderEvent가 있으면: base는 그리지 않고 event만 그리기 (hover 스타일 적용)
|
|
354
312
|
// renderEvent가 없으면: base를 hover 스타일로 그리기
|
|
355
313
|
|
|
@@ -361,7 +319,7 @@ var CanvasMarkerLayer = function (props) {
|
|
|
361
319
|
hoveredItem: currentHovered,
|
|
362
320
|
selectedItem: selectedItemRef.current,
|
|
363
321
|
selectedItems: hoverSelectedItems,
|
|
364
|
-
topOnHover:
|
|
322
|
+
topOnHover: true,
|
|
365
323
|
utils: renderUtils
|
|
366
324
|
});
|
|
367
325
|
} else {
|
|
@@ -392,13 +350,13 @@ var CanvasMarkerLayer = function (props) {
|
|
|
392
350
|
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
393
351
|
}
|
|
394
352
|
|
|
395
|
-
if (topStageZIndex !== undefined
|
|
353
|
+
if (topStageZIndex !== undefined) {
|
|
396
354
|
doRenderTop();
|
|
397
355
|
}
|
|
398
356
|
}; // 지도 이벤트 핸들러 생성
|
|
399
357
|
|
|
400
358
|
|
|
401
|
-
var
|
|
359
|
+
var _f = hooks.createMapEventHandlers({
|
|
402
360
|
accumTranslateRef: accumTranslateRef,
|
|
403
361
|
boundingBoxCacheRef: boundingBoxCacheRef,
|
|
404
362
|
containerRef: containerRef,
|
|
@@ -409,12 +367,30 @@ var CanvasMarkerLayer = function (props) {
|
|
|
409
367
|
prevCenterOffsetRef: prevCenterOffsetRef,
|
|
410
368
|
renderAllImmediate: renderAllImmediate
|
|
411
369
|
}),
|
|
412
|
-
|
|
413
|
-
handleZoomStart =
|
|
414
|
-
handleZoomEnd =
|
|
415
|
-
|
|
416
|
-
handleDragStartShared =
|
|
417
|
-
handleDragEndShared =
|
|
370
|
+
handleIdleShared = _f.handleIdle,
|
|
371
|
+
handleZoomStart = _f.handleZoomStart,
|
|
372
|
+
handleZoomEnd = _f.handleZoomEnd,
|
|
373
|
+
handleCenterChangedShared = _f.handleCenterChanged,
|
|
374
|
+
handleDragStartShared = _f.handleDragStart,
|
|
375
|
+
handleDragEndShared = _f.handleDragEnd; // handleIdle 래핑: topStage transform 제거 추가
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
var handleIdle = function () {
|
|
379
|
+
handleIdleShared(); // 드래그 완료 시 topStage의 transform도 제거 (메인 stage와 동기화)
|
|
380
|
+
|
|
381
|
+
if (topStageZIndex !== undefined && topContainerRef.current) {
|
|
382
|
+
topContainerRef.current.style.transform = '';
|
|
383
|
+
}
|
|
384
|
+
}; // handleCenterChanged 래핑: topStage transform 동기화 추가
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
var handleCenterChanged = function () {
|
|
388
|
+
handleCenterChangedShared(); // 드래그 중 메인 stage의 transform을 topStage에도 동기화 (반대 방향 이동 방지)
|
|
389
|
+
|
|
390
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
391
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
392
|
+
}
|
|
393
|
+
};
|
|
418
394
|
|
|
419
395
|
var handleDragStart = function () {
|
|
420
396
|
handleDragStartShared(); // 드래그 시작 시점의 hover 상태 저장
|
|
@@ -442,8 +418,8 @@ var CanvasMarkerLayer = function (props) {
|
|
|
442
418
|
|
|
443
419
|
|
|
444
420
|
var findData = function (offset) {
|
|
445
|
-
//
|
|
446
|
-
if (
|
|
421
|
+
// topStageZIndex가 설정되어 있으면 hover된 항목을 최우선으로 확인
|
|
422
|
+
if (topStageZIndex !== undefined && hoveredItemRef.current) {
|
|
447
423
|
var hovered = hoveredItemRef.current;
|
|
448
424
|
|
|
449
425
|
if (utils.isPointInMarkerData(offset, hovered, getOrComputeMarkerOffset)) {
|
|
@@ -480,57 +456,40 @@ var CanvasMarkerLayer = function (props) {
|
|
|
480
456
|
controller.setMapCursor(hoveredData ? 'pointer' : 'grab');
|
|
481
457
|
}
|
|
482
458
|
|
|
483
|
-
if (topStageZIndex !== undefined
|
|
484
|
-
// topStageZIndex가
|
|
485
|
-
//
|
|
486
|
-
|
|
459
|
+
if (topStageZIndex !== undefined) {
|
|
460
|
+
// topStageZIndex가 설정된 경우 Top Layer에서 hover된 항목 렌더링
|
|
461
|
+
// Base Layer는 hover 상태 변경 시 재렌더링 불필요 (sceneFunc 내에서 hover 항목 제외 처리)
|
|
462
|
+
// Event Layer는 선택된 항목만 렌더링하므로 업데이트 필요
|
|
487
463
|
doRenderEvent();
|
|
488
464
|
doRenderTop();
|
|
489
465
|
} else if (renderEvent) {
|
|
490
|
-
// renderEvent가 있을 때는 Event Layer 업데이트
|
|
491
|
-
//
|
|
492
|
-
|
|
493
|
-
doRenderBase();
|
|
494
|
-
}
|
|
495
|
-
|
|
466
|
+
// renderEvent가 있을 때는 Event Layer만 업데이트
|
|
467
|
+
// topStageZIndex가 없으면 Base Layer는 정적이므로 재렌더링 불필요 (성능 우선)
|
|
468
|
+
// hover 효과는 Event Layer에서만 처리하면 됨
|
|
496
469
|
doRenderEvent();
|
|
497
|
-
} else if (topOnHover) {
|
|
498
|
-
doRenderBase();
|
|
499
470
|
}
|
|
500
|
-
}; // 클릭 처리: 선택 상태 업데이트
|
|
471
|
+
}; // 클릭 처리: 선택 상태 업데이트 (단일 선택만 지원)
|
|
501
472
|
|
|
502
473
|
|
|
503
474
|
var handleLocalClick = function (clickedData) {
|
|
504
|
-
|
|
505
|
-
var newSelected = new Set(selectedIdsRef.current);
|
|
475
|
+
var newSelected = new Set();
|
|
506
476
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
newSelected.add(clickedData.id);
|
|
512
|
-
selectedItemsMapRef.current.set(clickedData.id, clickedData);
|
|
513
|
-
}
|
|
477
|
+
if (!selectedIdsRef.current.has(clickedData.id)) {
|
|
478
|
+
newSelected.add(clickedData.id);
|
|
479
|
+
selectedItemsMapRef.current.clear();
|
|
480
|
+
selectedItemsMapRef.current.set(clickedData.id, clickedData); // externalSelectedItem이 있을 때를 대비해 selectedItemRef도 업데이트
|
|
514
481
|
|
|
515
|
-
|
|
482
|
+
selectedItemRef.current = clickedData;
|
|
516
483
|
} else {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (!selectedIdsRef.current.has(clickedData.id)) {
|
|
520
|
-
newSelected.add(clickedData.id);
|
|
521
|
-
selectedItemsMapRef.current.clear();
|
|
522
|
-
selectedItemsMapRef.current.set(clickedData.id, clickedData);
|
|
523
|
-
} else {
|
|
524
|
-
selectedItemsMapRef.current.clear();
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
selectedIdsRef.current = newSelected;
|
|
484
|
+
selectedItemsMapRef.current.clear();
|
|
485
|
+
selectedItemRef.current = null;
|
|
528
486
|
}
|
|
529
487
|
|
|
530
|
-
|
|
488
|
+
selectedIdsRef.current = newSelected; // 선택 상태 변경은 Event Layer에서만 처리 (Base Layer는 정적이므로 재렌더링 불필요)
|
|
489
|
+
|
|
531
490
|
doRenderEvent();
|
|
532
491
|
|
|
533
|
-
if (topStageZIndex !== undefined
|
|
492
|
+
if (topStageZIndex !== undefined) {
|
|
534
493
|
doRenderTop();
|
|
535
494
|
}
|
|
536
495
|
}; // 클릭 이벤트 핸들러
|
|
@@ -594,18 +553,15 @@ var CanvasMarkerLayer = function (props) {
|
|
|
594
553
|
hoveredItemRef.current = null;
|
|
595
554
|
controller.setMapCursor('grab');
|
|
596
555
|
|
|
597
|
-
if (topStageZIndex !== undefined
|
|
598
|
-
//
|
|
599
|
-
|
|
556
|
+
if (topStageZIndex !== undefined) {
|
|
557
|
+
// Base Layer는 hover 상태 변경 시 재렌더링 불필요 (sceneFunc 내에서 hover 항목 제외 처리)
|
|
558
|
+
// Event Layer는 선택된 항목만 렌더링하므로 업데이트 필요
|
|
600
559
|
doRenderEvent();
|
|
601
560
|
doRenderTop();
|
|
602
561
|
} else if (renderEvent) {
|
|
603
|
-
// renderEvent가 있을 때는 Event Layer 업데이트
|
|
604
|
-
//
|
|
605
|
-
|
|
606
|
-
doRenderBase();
|
|
607
|
-
}
|
|
608
|
-
|
|
562
|
+
// renderEvent가 있을 때는 Event Layer만 업데이트
|
|
563
|
+
// topStageZIndex가 없으면 Base Layer는 정적이므로 재렌더링 불필요 (성능 우선)
|
|
564
|
+
// hover 효과 제거는 Event Layer에서만 처리하면 됨
|
|
609
565
|
doRenderEvent();
|
|
610
566
|
}
|
|
611
567
|
|
|
@@ -614,9 +570,9 @@ var CanvasMarkerLayer = function (props) {
|
|
|
614
570
|
|
|
615
571
|
|
|
616
572
|
React.useEffect(function () {
|
|
617
|
-
divElement.style.width = 'fit-content'; // Top Layer용 div도 초기화 (topStageZIndex가
|
|
573
|
+
divElement.style.width = 'fit-content'; // Top Layer용 div도 초기화 (topStageZIndex가 설정된 경우)
|
|
618
574
|
|
|
619
|
-
if (topStageZIndex !== undefined
|
|
575
|
+
if (topStageZIndex !== undefined) {
|
|
620
576
|
topDivElement.style.width = 'fit-content';
|
|
621
577
|
}
|
|
622
578
|
|
|
@@ -802,10 +758,10 @@ var CanvasMarkerLayer = function (props) {
|
|
|
802
758
|
|
|
803
759
|
renderAllImmediate();
|
|
804
760
|
}
|
|
805
|
-
}, [enableViewportCulling]); // Top Layer용 별도 캔버스 DOM 생성 (topStageZIndex가
|
|
761
|
+
}, [enableViewportCulling]); // Top Layer용 별도 캔버스 DOM 생성 (topStageZIndex가 설정된 경우)
|
|
806
762
|
|
|
807
763
|
React.useEffect(function () {
|
|
808
|
-
if (topStageZIndex === undefined
|
|
764
|
+
if (topStageZIndex === undefined) return;
|
|
809
765
|
if (!topContainerRef.current) return;
|
|
810
766
|
var mapDiv = controller.mapDivElement; // Top Layer용 div 요소 설정
|
|
811
767
|
|
|
@@ -874,13 +830,14 @@ var CanvasMarkerLayer = function (props) {
|
|
|
874
830
|
|
|
875
831
|
|
|
876
832
|
var handleTopIdle = function () {
|
|
877
|
-
// topMarker의 position을 메인 marker와 동일하게 업데이트
|
|
833
|
+
// 드래그 완료 후 topMarker의 position을 메인 marker와 동일하게 업데이트
|
|
878
834
|
updateTopMarkerPosition(); // topStage 크기 업데이트
|
|
879
835
|
|
|
880
836
|
if (topStageRef.current) {
|
|
881
837
|
topStageRef.current.width(mapDiv.offsetWidth);
|
|
882
838
|
topStageRef.current.height(mapDiv.offsetHeight);
|
|
883
|
-
} //
|
|
839
|
+
} // 드래그 완료 후 transform은 handleIdle에서 제거되므로 여기서는 동기화만
|
|
840
|
+
// (handleIdle이 먼저 실행되어 transform을 제거한 후, 여기서 position 업데이트)
|
|
884
841
|
|
|
885
842
|
|
|
886
843
|
if (topContainerRef.current && containerRef.current) {
|
|
@@ -909,13 +866,18 @@ var CanvasMarkerLayer = function (props) {
|
|
|
909
866
|
};
|
|
910
867
|
|
|
911
868
|
var handleTopCenterChanged = function () {
|
|
912
|
-
//
|
|
913
|
-
|
|
869
|
+
// 드래그 중에는 transform만 동기화 (position 업데이트는 드래그 완료 후에만)
|
|
870
|
+
// 드래그 중에 position을 업데이트하면 transform과 충돌하여 반대 방향으로 이동하는 버그 발생
|
|
871
|
+
if (!draggingRef.current) {
|
|
872
|
+
// 드래그가 아닐 때만 topMarker의 position을 업데이트
|
|
873
|
+
updateTopMarkerPosition();
|
|
874
|
+
} // topStage 크기 업데이트
|
|
875
|
+
|
|
914
876
|
|
|
915
877
|
if (topStageRef.current) {
|
|
916
878
|
topStageRef.current.width(mapDiv.offsetWidth);
|
|
917
879
|
topStageRef.current.height(mapDiv.offsetHeight);
|
|
918
|
-
} // 메인 stage의 transform을 topStage에도 동기화
|
|
880
|
+
} // 메인 stage의 transform을 topStage에도 동기화 (드래그 중 필수)
|
|
919
881
|
|
|
920
882
|
|
|
921
883
|
if (topContainerRef.current && containerRef.current) {
|
|
@@ -957,25 +919,39 @@ var CanvasMarkerLayer = function (props) {
|
|
|
957
919
|
}, [topStageZIndex, renderEvent, options]); // 외부 selectedItems 동기화
|
|
958
920
|
|
|
959
921
|
React.useEffect(function () {
|
|
960
|
-
if (!stageRef.current) return;
|
|
961
|
-
|
|
962
|
-
|
|
922
|
+
if (!stageRef.current) return; // externalSelectedItems가 있으면 selectedItem은 무시 (공존 불가)
|
|
923
|
+
|
|
924
|
+
if (externalSelectedItems !== undefined) {
|
|
925
|
+
selectedItemRef.current = undefined;
|
|
926
|
+
hooks.syncExternalSelectedItems(externalSelectedItems, selectedIdsRef, selectedItemsMapRef);
|
|
927
|
+
} // 선택 상태 변경은 Event Layer에서만 처리 (Base Layer는 정적이므로 재렌더링 불필요)
|
|
928
|
+
|
|
929
|
+
|
|
963
930
|
doRenderEvent();
|
|
964
931
|
|
|
965
|
-
if (topStageZIndex !== undefined
|
|
932
|
+
if (topStageZIndex !== undefined) {
|
|
966
933
|
doRenderTop();
|
|
967
934
|
}
|
|
968
935
|
}, [externalSelectedItems]); // 외부 selectedItem 변경 시 Event Layer 리렌더링
|
|
969
936
|
|
|
970
937
|
React.useEffect(function () {
|
|
971
|
-
if (!stageRef.current) return;
|
|
972
|
-
|
|
938
|
+
if (!stageRef.current) return; // externalSelectedItem이 있으면 selectedItems는 무시 (공존 불가)
|
|
939
|
+
|
|
940
|
+
if (externalSelectedItem !== undefined) {
|
|
941
|
+
selectedIdsRef.current.clear();
|
|
942
|
+
selectedItemsMapRef.current.clear();
|
|
943
|
+
selectedItemRef.current = externalSelectedItem;
|
|
944
|
+
} else if (externalSelectedItems === undefined) {
|
|
945
|
+
// 둘 다 없으면 selectedItemRef만 업데이트 (내부 클릭으로 선택한 항목은 유지)
|
|
946
|
+
selectedItemRef.current = externalSelectedItem;
|
|
947
|
+
}
|
|
948
|
+
|
|
973
949
|
doRenderEvent();
|
|
974
950
|
|
|
975
|
-
if (topStageZIndex !== undefined
|
|
951
|
+
if (topStageZIndex !== undefined) {
|
|
976
952
|
doRenderTop();
|
|
977
953
|
}
|
|
978
|
-
}, [externalSelectedItem]); // 데이터 변경 시 렌더링 (캐시 정리 및 선택 상태 동기화)
|
|
954
|
+
}, [externalSelectedItem, externalSelectedItems]); // 데이터 변경 시 렌더링 (캐시 정리 및 선택 상태 동기화)
|
|
979
955
|
|
|
980
956
|
React.useEffect(function () {
|
|
981
957
|
if (!stageRef.current) return;
|