@mint-ui/map 1.2.0-test.62 → 1.2.0-test.65
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 +91 -6
- package/dist/components/mint-map/core/advanced/CanvasMarkerLayer/CanvasMarkerLayer.js +411 -57
- package/dist/components/mint-map/core/advanced/CanvasPolygonLayer/CanvasPolygonLayer.d.ts +46 -25
- package/dist/components/mint-map/core/advanced/CanvasPolygonLayer/CanvasPolygonLayer.js +16 -3
- package/dist/components/mint-map/core/advanced/shared/types.d.ts +2 -0
- package/dist/index.es.js +427 -60
- package/dist/index.umd.js +427 -60
- package/package.json +1 -1
|
@@ -24,28 +24,48 @@ var Konva__default = /*#__PURE__*/_interopDefaultLegacy(Konva);
|
|
|
24
24
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
25
25
|
|
|
26
26
|
var CanvasMarkerLayer = function (props) {
|
|
27
|
+
// 타입 가드: renderEvent가 있는지 확인
|
|
28
|
+
var hasRenderEvent = 'renderEvent' in props && props.renderEvent !== undefined; // renderEvent가 있는 경우와 없는 경우를 구분하여 props 추출
|
|
29
|
+
|
|
27
30
|
var data = props.data,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
topOnHover = _b === void 0 ? false : _b,
|
|
35
|
-
_c = props.enableViewportCulling,
|
|
36
|
-
enableViewportCulling = _c === void 0 ? false : _c,
|
|
37
|
-
_d = props.cullingMargin,
|
|
38
|
-
cullingMargin = _d === void 0 ? performance.DEFAULT_CULLING_MARGIN : _d,
|
|
39
|
-
_e = props.maxCacheSize,
|
|
40
|
-
maxCacheSize = _e === void 0 ? performance.DEFAULT_MAX_CACHE_SIZE : _e,
|
|
41
|
-
externalSelectedItems = props.selectedItems,
|
|
42
|
-
externalSelectedItem = props.selectedItem,
|
|
43
|
-
_f = props.disableInteraction,
|
|
44
|
-
disableInteraction = _f === void 0 ? false : _f,
|
|
31
|
+
_a = props.enableViewportCulling,
|
|
32
|
+
enableViewportCulling = _a === void 0 ? false : _a,
|
|
33
|
+
_b = props.cullingMargin,
|
|
34
|
+
cullingMargin = _b === void 0 ? performance.DEFAULT_CULLING_MARGIN : _b,
|
|
35
|
+
_c = props.maxCacheSize,
|
|
36
|
+
maxCacheSize = _c === void 0 ? performance.DEFAULT_MAX_CACHE_SIZE : _c,
|
|
45
37
|
renderBase = props.renderBase,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
38
|
+
options = tslib.__rest(props, ["data", "enableViewportCulling", "cullingMargin", "maxCacheSize", "renderBase"]); // renderEvent가 있는 경우에만 인터랙션 관련 props 추출
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
var _d = hasRenderEvent && 'renderEvent' in props ? props : {
|
|
42
|
+
disableInteraction: false,
|
|
43
|
+
enableMultiSelect: false,
|
|
44
|
+
onClick: undefined,
|
|
45
|
+
onMouseOut: undefined,
|
|
46
|
+
onMouseOver: undefined,
|
|
47
|
+
renderEvent: undefined,
|
|
48
|
+
selectedItem: undefined,
|
|
49
|
+
selectedItems: undefined,
|
|
50
|
+
topOnHover: false,
|
|
51
|
+
topStageZIndex: undefined
|
|
52
|
+
},
|
|
53
|
+
_e = _d.disableInteraction,
|
|
54
|
+
disableInteraction = _e === void 0 ? false : _e,
|
|
55
|
+
_f = _d.enableMultiSelect,
|
|
56
|
+
enableMultiSelect = _f === void 0 ? false : _f,
|
|
57
|
+
onClick = _d.onClick,
|
|
58
|
+
onMouseOut = _d.onMouseOut,
|
|
59
|
+
onMouseOver = _d.onMouseOver,
|
|
60
|
+
renderEvent = _d.renderEvent,
|
|
61
|
+
externalSelectedItem = _d.selectedItem,
|
|
62
|
+
externalSelectedItems = _d.selectedItems,
|
|
63
|
+
rawTopStageZIndex = _d.topStageZIndex,
|
|
64
|
+
_g = _d.topOnHover,
|
|
65
|
+
topOnHover = _g === void 0 ? false : _g; // topOnHover가 false이거나 없으면 topStageZIndex를 사용하지 못하도록 제한
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
var topStageZIndex = topOnHover && rawTopStageZIndex !== undefined ? rawTopStageZIndex : undefined;
|
|
49
69
|
var controller = MintMapProvider.useMintMapController();
|
|
50
70
|
var context$1 = context.useCanvasContext();
|
|
51
71
|
var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
|
|
@@ -53,11 +73,18 @@ var CanvasMarkerLayer = function (props) {
|
|
|
53
73
|
var divRef = React.useRef(document.createElement('div'));
|
|
54
74
|
var divElement = divRef.current;
|
|
55
75
|
var containerRef = React.useRef(null);
|
|
56
|
-
var markerRef = React.useRef(); //
|
|
76
|
+
var markerRef = React.useRef(); // Top Layer용 별도 DOM Refs (topStageZIndex가 설정된 경우에만 사용)
|
|
77
|
+
|
|
78
|
+
var topDivRef = React.useRef(document.createElement('div'));
|
|
79
|
+
var topDivElement = topDivRef.current;
|
|
80
|
+
var topContainerRef = React.useRef(null);
|
|
81
|
+
var topMarkerRef = React.useRef(); // Konva Refs
|
|
57
82
|
|
|
58
83
|
var stageRef = React.useRef(null);
|
|
59
84
|
var baseLayerRef = React.useRef(null);
|
|
60
|
-
var eventLayerRef = React.useRef(null);
|
|
85
|
+
var eventLayerRef = React.useRef(null);
|
|
86
|
+
var topStageRef = React.useRef(null);
|
|
87
|
+
var topLayerRef = React.useRef(null); // 상태 관리 Refs (React 리렌더링 최소화)
|
|
61
88
|
|
|
62
89
|
var dataRef = React.useRef(data);
|
|
63
90
|
var disableInteractionRef = React.useRef(disableInteraction);
|
|
@@ -148,24 +175,34 @@ var CanvasMarkerLayer = function (props) {
|
|
|
148
175
|
|
|
149
176
|
var visibleItems = enableViewportCullingRef.current ? dataRef.current.filter(function (item) {
|
|
150
177
|
return isInViewport(item);
|
|
151
|
-
}) : dataRef.current; // topOnHover
|
|
178
|
+
}) : dataRef.current; // topStageZIndex가 설정되고 topOnHover가 true인 경우 hover된 항목은 Top Layer에서 처리
|
|
179
|
+
// topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
|
|
152
180
|
|
|
153
|
-
if (
|
|
181
|
+
if (topStageZIndex !== undefined && topOnHover && hovered) {
|
|
182
|
+
visibleItems = visibleItems.filter(function (item) {
|
|
183
|
+
return item.id !== hovered.id;
|
|
184
|
+
});
|
|
185
|
+
} else if (topOnHover && !renderEvent && hovered) {
|
|
154
186
|
visibleItems = visibleItems.filter(function (item) {
|
|
155
187
|
return item.id !== hovered.id;
|
|
156
188
|
});
|
|
157
189
|
} // 일반 항목들 먼저 렌더링
|
|
190
|
+
// topOnHover가 false이고 renderEvent가 있으면 선택된 항목도 Base Layer에서 렌더링
|
|
191
|
+
// (Event Layer에서 선택된 항목을 렌더링하지 않으므로)
|
|
192
|
+
// topOnHover가 true이거나 renderEvent가 없으면 선택된 항목은 Base Layer에서 스킵됨
|
|
158
193
|
|
|
159
194
|
|
|
195
|
+
var baseSelectedIds = !topOnHover && renderEvent ? selectedIdsRef.current : new Set();
|
|
160
196
|
renderBase({
|
|
161
197
|
ctx: ctx,
|
|
162
198
|
hoveredItem: hovered,
|
|
163
199
|
items: visibleItems,
|
|
164
|
-
selectedIds:
|
|
200
|
+
selectedIds: baseSelectedIds,
|
|
165
201
|
utils: renderUtils
|
|
166
|
-
}); // hover된
|
|
202
|
+
}); // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리하므로 여기서는 스킵
|
|
203
|
+
// hover된 항목을 마지막에 렌더링하여 최상위에 표시
|
|
167
204
|
|
|
168
|
-
if (topOnHover && !renderEvent && hovered) {
|
|
205
|
+
if (topStageZIndex === undefined && topOnHover && !renderEvent && hovered) {
|
|
169
206
|
if (!enableViewportCullingRef.current || isInViewport(hovered)) {
|
|
170
207
|
renderBase({
|
|
171
208
|
ctx: ctx,
|
|
@@ -199,9 +236,24 @@ var CanvasMarkerLayer = function (props) {
|
|
|
199
236
|
sceneFunc: function (konvaContext) {
|
|
200
237
|
var ctx = konvaContext;
|
|
201
238
|
var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current);
|
|
202
|
-
var hovered = hoveredItemRef.current;
|
|
239
|
+
var hovered = hoveredItemRef.current; // topStageZIndex가 설정되고 topOnHover가 true이면 hover된 항목은 Top Layer에서 처리
|
|
240
|
+
// event 레이어에서는 hover된 항목을 완전히 제외하고 선택된 항목만 렌더링
|
|
241
|
+
|
|
242
|
+
if (topStageZIndex !== undefined && topOnHover && hovered) {
|
|
243
|
+
// hover된 항목을 제외한 선택된 항목들
|
|
244
|
+
var selectedItemsWithoutHovered = selectedItems.filter(function (item) {
|
|
245
|
+
return item.id !== hovered.id;
|
|
246
|
+
}); // 선택된 항목만 그리기 (hover된 항목은 Top Layer에서 처리)
|
|
203
247
|
|
|
204
|
-
|
|
248
|
+
renderEvent({
|
|
249
|
+
ctx: ctx,
|
|
250
|
+
hoveredItem: null,
|
|
251
|
+
selectedItem: selectedItemRef.current,
|
|
252
|
+
selectedItems: selectedItemsWithoutHovered,
|
|
253
|
+
topOnHover: topOnHover,
|
|
254
|
+
utils: renderUtils
|
|
255
|
+
});
|
|
256
|
+
} else if (topOnHover && hovered) {
|
|
205
257
|
renderEvent({
|
|
206
258
|
ctx: ctx,
|
|
207
259
|
hoveredItem: null,
|
|
@@ -209,6 +261,7 @@ var CanvasMarkerLayer = function (props) {
|
|
|
209
261
|
selectedItems: selectedItems.filter(function (item) {
|
|
210
262
|
return item.id !== hovered.id;
|
|
211
263
|
}),
|
|
264
|
+
topOnHover: topOnHover,
|
|
212
265
|
utils: renderUtils
|
|
213
266
|
});
|
|
214
267
|
|
|
@@ -222,15 +275,25 @@ var CanvasMarkerLayer = function (props) {
|
|
|
222
275
|
hoveredItem: hovered,
|
|
223
276
|
selectedItem: selectedItemRef.current,
|
|
224
277
|
selectedItems: hoverSelectedItems,
|
|
278
|
+
topOnHover: topOnHover,
|
|
225
279
|
utils: renderUtils
|
|
226
280
|
});
|
|
227
281
|
}
|
|
228
282
|
} else {
|
|
283
|
+
// topOnHover가 false일 때는 hover된 항목을 나중에 그리지 않음
|
|
284
|
+
// 하지만 hover 스타일은 적용해야 하므로, hover된 항목이 selectedItems에 포함되어 있지 않으면 추가
|
|
285
|
+
// renderEvent 함수에 topOnHover 정보를 전달하여,
|
|
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;
|
|
229
291
|
renderEvent({
|
|
230
292
|
ctx: ctx,
|
|
231
293
|
hoveredItem: hovered,
|
|
232
294
|
selectedItem: selectedItemRef.current,
|
|
233
|
-
selectedItems:
|
|
295
|
+
selectedItems: finalSelectedItems,
|
|
296
|
+
topOnHover: topOnHover,
|
|
234
297
|
utils: renderUtils
|
|
235
298
|
});
|
|
236
299
|
}
|
|
@@ -239,6 +302,79 @@ var CanvasMarkerLayer = function (props) {
|
|
|
239
302
|
layer.add(shape);
|
|
240
303
|
}
|
|
241
304
|
|
|
305
|
+
layer.batchDraw();
|
|
306
|
+
}; // Top Layer 렌더링 (hover된 항목만, 별도 캔버스 DOM에 그리기)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
var doRenderTop = function () {
|
|
310
|
+
var stage = topStageRef.current;
|
|
311
|
+
var layer = topLayerRef.current;
|
|
312
|
+
if (!stage || !layer || topStageZIndex === undefined || !topOnHover) return;
|
|
313
|
+
var hovered = hoveredItemRef.current;
|
|
314
|
+
var shape = layer.findOne('.top-render-shape'); // hover된 항목이 없으면 shape 제거
|
|
315
|
+
|
|
316
|
+
if (!hovered) {
|
|
317
|
+
if (shape) {
|
|
318
|
+
shape.destroy();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
layer.batchDraw();
|
|
322
|
+
return;
|
|
323
|
+
} // shape가 없으면 생성
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
if (!shape) {
|
|
327
|
+
shape = new Konva__default["default"].Shape({
|
|
328
|
+
hitStrokeWidth: 0,
|
|
329
|
+
listening: false,
|
|
330
|
+
name: 'top-render-shape',
|
|
331
|
+
perfectDrawEnabled: false,
|
|
332
|
+
sceneFunc: function () {} // 초기화만
|
|
333
|
+
|
|
334
|
+
});
|
|
335
|
+
layer.add(shape);
|
|
336
|
+
} // sceneFunc를 매번 업데이트하여 최신 상태 반영
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
shape.sceneFunc(function (konvaContext) {
|
|
340
|
+
var ctx = konvaContext;
|
|
341
|
+
var currentHovered = hoveredItemRef.current; // hover된 항목이 없으면 아무것도 그리지 않음
|
|
342
|
+
|
|
343
|
+
if (!currentHovered) return; // 뷰포트 컬링 확인
|
|
344
|
+
|
|
345
|
+
if (enableViewportCullingRef.current && !isInViewport(currentHovered)) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current);
|
|
350
|
+
var hoveredIsSelected = selectedItems.some(function (item) {
|
|
351
|
+
return item.id === currentHovered.id;
|
|
352
|
+
}); // Top Layer에서는 hover된 마커만 hover 스타일로 그리기
|
|
353
|
+
// renderEvent가 있으면: base는 그리지 않고 event만 그리기 (hover 스타일 적용)
|
|
354
|
+
// renderEvent가 없으면: base를 hover 스타일로 그리기
|
|
355
|
+
|
|
356
|
+
if (renderEvent) {
|
|
357
|
+
// renderEvent가 있으면 hover 스타일로만 그리기
|
|
358
|
+
var hoverSelectedItems = hoveredIsSelected ? [currentHovered] : [];
|
|
359
|
+
renderEvent({
|
|
360
|
+
ctx: ctx,
|
|
361
|
+
hoveredItem: currentHovered,
|
|
362
|
+
selectedItem: selectedItemRef.current,
|
|
363
|
+
selectedItems: hoverSelectedItems,
|
|
364
|
+
topOnHover: topOnHover,
|
|
365
|
+
utils: renderUtils
|
|
366
|
+
});
|
|
367
|
+
} else {
|
|
368
|
+
// renderEvent가 없으면 base를 hover 스타일로 그리기
|
|
369
|
+
renderBase({
|
|
370
|
+
ctx: ctx,
|
|
371
|
+
hoveredItem: currentHovered,
|
|
372
|
+
items: [currentHovered],
|
|
373
|
+
selectedIds: selectedIdsRef.current,
|
|
374
|
+
utils: renderUtils
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
});
|
|
242
378
|
layer.batchDraw();
|
|
243
379
|
}; // 전체 즉시 렌더링
|
|
244
380
|
|
|
@@ -250,11 +386,19 @@ var CanvasMarkerLayer = function (props) {
|
|
|
250
386
|
|
|
251
387
|
buildSpatialIndex();
|
|
252
388
|
doRenderBase();
|
|
253
|
-
doRenderEvent();
|
|
389
|
+
doRenderEvent(); // 메인 stage의 transform을 topStage에도 동기화
|
|
390
|
+
|
|
391
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
392
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
396
|
+
doRenderTop();
|
|
397
|
+
}
|
|
254
398
|
}; // 지도 이벤트 핸들러 생성
|
|
255
399
|
|
|
256
400
|
|
|
257
|
-
var
|
|
401
|
+
var _h = hooks.createMapEventHandlers({
|
|
258
402
|
accumTranslateRef: accumTranslateRef,
|
|
259
403
|
boundingBoxCacheRef: boundingBoxCacheRef,
|
|
260
404
|
containerRef: containerRef,
|
|
@@ -265,19 +409,23 @@ var CanvasMarkerLayer = function (props) {
|
|
|
265
409
|
prevCenterOffsetRef: prevCenterOffsetRef,
|
|
266
410
|
renderAllImmediate: renderAllImmediate
|
|
267
411
|
}),
|
|
268
|
-
handleIdle =
|
|
269
|
-
handleZoomStart =
|
|
270
|
-
handleZoomEnd =
|
|
271
|
-
handleCenterChanged =
|
|
272
|
-
handleDragStartShared =
|
|
273
|
-
handleDragEndShared =
|
|
412
|
+
handleIdle = _h.handleIdle,
|
|
413
|
+
handleZoomStart = _h.handleZoomStart,
|
|
414
|
+
handleZoomEnd = _h.handleZoomEnd,
|
|
415
|
+
handleCenterChanged = _h.handleCenterChanged,
|
|
416
|
+
handleDragStartShared = _h.handleDragStart,
|
|
417
|
+
handleDragEndShared = _h.handleDragEnd;
|
|
274
418
|
|
|
275
419
|
var handleDragStart = function () {
|
|
276
420
|
handleDragStartShared(); // 드래그 시작 시점의 hover 상태 저장
|
|
277
421
|
|
|
278
422
|
dragStartHoveredItemRef.current = hoveredItemRef.current;
|
|
279
423
|
draggingRef.current = true;
|
|
280
|
-
controller.setMapCursor('grabbing');
|
|
424
|
+
controller.setMapCursor('grabbing'); // 메인 stage의 transform을 topStage에도 동기화
|
|
425
|
+
|
|
426
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
427
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
428
|
+
}
|
|
281
429
|
};
|
|
282
430
|
|
|
283
431
|
var handleDragEnd = function () {
|
|
@@ -285,7 +433,11 @@ var CanvasMarkerLayer = function (props) {
|
|
|
285
433
|
draggingRef.current = false; // 드래그 종료 후 hover 상태 초기화 (다음 MOUSEMOVE에서 업데이트됨)
|
|
286
434
|
|
|
287
435
|
dragStartHoveredItemRef.current = null;
|
|
288
|
-
controller.setMapCursor('grab');
|
|
436
|
+
controller.setMapCursor('grab'); // 메인 stage의 transform을 topStage에도 동기화
|
|
437
|
+
|
|
438
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
439
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
440
|
+
}
|
|
289
441
|
}; // Hit Test: 특정 좌표의 마커 찾기
|
|
290
442
|
|
|
291
443
|
|
|
@@ -328,7 +480,19 @@ var CanvasMarkerLayer = function (props) {
|
|
|
328
480
|
controller.setMapCursor(hoveredData ? 'pointer' : 'grab');
|
|
329
481
|
}
|
|
330
482
|
|
|
331
|
-
if (
|
|
483
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
484
|
+
// topStageZIndex가 설정되고 topOnHover가 true인 경우 Top Layer에서 hover된 항목 렌더링
|
|
485
|
+
// base 레이어와 event 레이어도 업데이트 (hover된 항목 제외)
|
|
486
|
+
doRenderBase();
|
|
487
|
+
doRenderEvent();
|
|
488
|
+
doRenderTop();
|
|
489
|
+
} else if (renderEvent) {
|
|
490
|
+
// renderEvent가 있을 때는 Event Layer 업데이트
|
|
491
|
+
// topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 적용해야 하므로 Base Layer도 업데이트
|
|
492
|
+
if (!topOnHover) {
|
|
493
|
+
doRenderBase();
|
|
494
|
+
}
|
|
495
|
+
|
|
332
496
|
doRenderEvent();
|
|
333
497
|
} else if (topOnHover) {
|
|
334
498
|
doRenderBase();
|
|
@@ -365,6 +529,10 @@ var CanvasMarkerLayer = function (props) {
|
|
|
365
529
|
|
|
366
530
|
doRenderBase();
|
|
367
531
|
doRenderEvent();
|
|
532
|
+
|
|
533
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
534
|
+
doRenderTop();
|
|
535
|
+
}
|
|
368
536
|
}; // 클릭 이벤트 핸들러
|
|
369
537
|
|
|
370
538
|
|
|
@@ -425,13 +593,33 @@ var CanvasMarkerLayer = function (props) {
|
|
|
425
593
|
if (!prevHovered) return;
|
|
426
594
|
hoveredItemRef.current = null;
|
|
427
595
|
controller.setMapCursor('grab');
|
|
428
|
-
|
|
596
|
+
|
|
597
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
598
|
+
// base 레이어와 event 레이어도 업데이트 (hover된 항목 다시 표시)
|
|
599
|
+
doRenderBase();
|
|
600
|
+
doRenderEvent();
|
|
601
|
+
doRenderTop();
|
|
602
|
+
} else if (renderEvent) {
|
|
603
|
+
// renderEvent가 있을 때는 Event Layer 업데이트
|
|
604
|
+
// topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 제거해야 하므로 Base Layer도 업데이트
|
|
605
|
+
if (!topOnHover) {
|
|
606
|
+
doRenderBase();
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
doRenderEvent();
|
|
610
|
+
}
|
|
611
|
+
|
|
429
612
|
onMouseOut === null || onMouseOut === void 0 ? void 0 : onMouseOut(prevHovered);
|
|
430
613
|
}; // DOM 초기화
|
|
431
614
|
|
|
432
615
|
|
|
433
616
|
React.useEffect(function () {
|
|
434
|
-
divElement.style.width = 'fit-content';
|
|
617
|
+
divElement.style.width = 'fit-content'; // Top Layer용 div도 초기화 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
|
|
618
|
+
|
|
619
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
620
|
+
topDivElement.style.width = 'fit-content';
|
|
621
|
+
}
|
|
622
|
+
|
|
435
623
|
return function () {
|
|
436
624
|
if (!markerRef.current) return;
|
|
437
625
|
controller.clearDrawable(markerRef.current);
|
|
@@ -449,19 +637,18 @@ var CanvasMarkerLayer = function (props) {
|
|
|
449
637
|
|
|
450
638
|
if (markerRef.current) {
|
|
451
639
|
controller.updateMarker(markerRef.current, markerOptions);
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
markerRef.current.element = divElement;
|
|
457
|
-
controller.createMarker(markerRef.current);
|
|
640
|
+
} else {
|
|
641
|
+
markerRef.current = new MapDrawables.Marker(markerOptions);
|
|
642
|
+
markerRef.current.element = divElement;
|
|
643
|
+
controller.createMarker(markerRef.current);
|
|
458
644
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
645
|
+
if (divElement.parentElement) {
|
|
646
|
+
divElement.parentElement.style.pointerEvents = 'none';
|
|
647
|
+
}
|
|
462
648
|
|
|
463
|
-
|
|
464
|
-
|
|
649
|
+
if (options.zIndex !== undefined) {
|
|
650
|
+
controller.setMarkerZIndex(markerRef.current, options.zIndex);
|
|
651
|
+
}
|
|
465
652
|
}
|
|
466
653
|
}, [options]); // Konva 초기화 및 이벤트 리스너 등록
|
|
467
654
|
|
|
@@ -615,19 +802,179 @@ var CanvasMarkerLayer = function (props) {
|
|
|
615
802
|
|
|
616
803
|
renderAllImmediate();
|
|
617
804
|
}
|
|
618
|
-
}, [enableViewportCulling]); //
|
|
805
|
+
}, [enableViewportCulling]); // Top Layer용 별도 캔버스 DOM 생성 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
|
|
806
|
+
|
|
807
|
+
React.useEffect(function () {
|
|
808
|
+
if (topStageZIndex === undefined || !topOnHover) return;
|
|
809
|
+
if (!topContainerRef.current) return;
|
|
810
|
+
var mapDiv = controller.mapDivElement; // Top Layer용 div 요소 설정
|
|
811
|
+
|
|
812
|
+
topDivElement.style.width = 'fit-content';
|
|
813
|
+
var bounds = controller.getCurrBounds();
|
|
814
|
+
|
|
815
|
+
var topMarkerOptions = tslib.__assign({
|
|
816
|
+
position: bounds.nw,
|
|
817
|
+
zIndex: topStageZIndex
|
|
818
|
+
}, options); // Top Layer용 Marker 생성 (zIndex: topStageZIndex로 DOM 마커보다 위에 위치)
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
var topMarker = new MapDrawables.Marker(topMarkerOptions);
|
|
822
|
+
topMarker.element = topDivElement;
|
|
823
|
+
controller.createMarker(topMarker);
|
|
824
|
+
topMarkerRef.current = topMarker;
|
|
825
|
+
|
|
826
|
+
if (topDivElement.parentElement) {
|
|
827
|
+
topDivElement.parentElement.style.pointerEvents = 'none';
|
|
828
|
+
} // Top Layer Marker의 zIndex 명시적으로 설정
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
controller.setMarkerZIndex(topMarker, topStageZIndex); // Top Layer용 Konva Stage 생성
|
|
832
|
+
|
|
833
|
+
var topStage = new Konva__default["default"].Stage({
|
|
834
|
+
container: topContainerRef.current,
|
|
835
|
+
height: mapDiv.offsetHeight,
|
|
836
|
+
width: mapDiv.offsetWidth
|
|
837
|
+
});
|
|
838
|
+
topStageRef.current = topStage;
|
|
839
|
+
var topLayer = new Konva__default["default"].Layer({
|
|
840
|
+
listening: false
|
|
841
|
+
});
|
|
842
|
+
topLayerRef.current = topLayer;
|
|
843
|
+
topStage.add(topLayer); // ResizeObserver: 맵 크기 변경 감지 (RAF로 debounce)
|
|
844
|
+
|
|
845
|
+
var topResizeRafId = null;
|
|
846
|
+
var topResizeObserver = new ResizeObserver(function () {
|
|
847
|
+
if (topResizeRafId !== null) {
|
|
848
|
+
cancelAnimationFrame(topResizeRafId);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
topResizeRafId = requestAnimationFrame(function () {
|
|
852
|
+
topStage.width(mapDiv.offsetWidth);
|
|
853
|
+
topStage.height(mapDiv.offsetHeight);
|
|
854
|
+
doRenderTop();
|
|
855
|
+
topResizeRafId = null;
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
topResizeObserver.observe(mapDiv); // topMarker position 업데이트 함수
|
|
859
|
+
|
|
860
|
+
var updateTopMarkerPosition = function () {
|
|
861
|
+
if (topMarkerRef.current && markerRef.current) {
|
|
862
|
+
var currentBounds = controller.getCurrBounds();
|
|
863
|
+
|
|
864
|
+
var updatedOptions = tslib.__assign(tslib.__assign({}, options), {
|
|
865
|
+
position: currentBounds.nw,
|
|
866
|
+
zIndex: topStageZIndex
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
controller.updateMarker(topMarkerRef.current, updatedOptions); // zIndex 명시적으로 설정
|
|
870
|
+
|
|
871
|
+
controller.setMarkerZIndex(topMarkerRef.current, topStageZIndex);
|
|
872
|
+
}
|
|
873
|
+
}; // 지도 이벤트 핸들러 등록 (topStage 업데이트용)
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
var handleTopIdle = function () {
|
|
877
|
+
// topMarker의 position을 메인 marker와 동일하게 업데이트
|
|
878
|
+
updateTopMarkerPosition(); // topStage 크기 업데이트
|
|
879
|
+
|
|
880
|
+
if (topStageRef.current) {
|
|
881
|
+
topStageRef.current.width(mapDiv.offsetWidth);
|
|
882
|
+
topStageRef.current.height(mapDiv.offsetHeight);
|
|
883
|
+
} // 메인 stage의 transform을 topStage에도 동기화
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
if (topContainerRef.current && containerRef.current) {
|
|
887
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
doRenderTop();
|
|
891
|
+
};
|
|
892
|
+
|
|
893
|
+
var handleTopZoomStart = function () {
|
|
894
|
+
// 메인 stage의 transform을 topStage에도 동기화
|
|
895
|
+
if (topContainerRef.current && containerRef.current) {
|
|
896
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
doRenderTop();
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
var handleTopZoomEnd = function () {
|
|
903
|
+
// 메인 stage의 transform을 topStage에도 동기화
|
|
904
|
+
if (topContainerRef.current && containerRef.current) {
|
|
905
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
doRenderTop();
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
var handleTopCenterChanged = function () {
|
|
912
|
+
// topMarker의 position을 메인 marker와 동일하게 업데이트
|
|
913
|
+
updateTopMarkerPosition(); // topStage 크기 업데이트
|
|
914
|
+
|
|
915
|
+
if (topStageRef.current) {
|
|
916
|
+
topStageRef.current.width(mapDiv.offsetWidth);
|
|
917
|
+
topStageRef.current.height(mapDiv.offsetHeight);
|
|
918
|
+
} // 메인 stage의 transform을 topStage에도 동기화
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
if (topContainerRef.current && containerRef.current) {
|
|
922
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
doRenderTop();
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
controller.addEventListener('IDLE', handleTopIdle);
|
|
929
|
+
controller.addEventListener('ZOOMSTART', handleTopZoomStart);
|
|
930
|
+
controller.addEventListener('ZOOM_CHANGED', handleTopZoomEnd);
|
|
931
|
+
controller.addEventListener('CENTER_CHANGED', handleTopCenterChanged);
|
|
932
|
+
doRenderTop();
|
|
933
|
+
return function () {
|
|
934
|
+
if (topResizeRafId !== null) {
|
|
935
|
+
cancelAnimationFrame(topResizeRafId);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
topResizeObserver.disconnect();
|
|
939
|
+
controller.removeEventListener('IDLE', handleTopIdle);
|
|
940
|
+
controller.removeEventListener('ZOOMSTART', handleTopZoomStart);
|
|
941
|
+
controller.removeEventListener('ZOOM_CHANGED', handleTopZoomEnd);
|
|
942
|
+
controller.removeEventListener('CENTER_CHANGED', handleTopCenterChanged);
|
|
943
|
+
|
|
944
|
+
if (topLayerRef.current) {
|
|
945
|
+
topLayerRef.current.destroyChildren();
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (topStageRef.current) {
|
|
949
|
+
topStageRef.current.destroy();
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
if (topMarkerRef.current) {
|
|
953
|
+
controller.clearDrawable(topMarkerRef.current);
|
|
954
|
+
topMarkerRef.current = undefined;
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
}, [topStageZIndex, renderEvent, options]); // 외부 selectedItems 동기화
|
|
619
958
|
|
|
620
959
|
React.useEffect(function () {
|
|
621
960
|
if (!stageRef.current) return;
|
|
622
961
|
hooks.syncExternalSelectedItems(externalSelectedItems, selectedIdsRef, selectedItemsMapRef);
|
|
623
962
|
doRenderBase();
|
|
624
963
|
doRenderEvent();
|
|
964
|
+
|
|
965
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
966
|
+
doRenderTop();
|
|
967
|
+
}
|
|
625
968
|
}, [externalSelectedItems]); // 외부 selectedItem 변경 시 Event Layer 리렌더링
|
|
626
969
|
|
|
627
970
|
React.useEffect(function () {
|
|
628
971
|
if (!stageRef.current) return;
|
|
629
972
|
selectedItemRef.current = externalSelectedItem;
|
|
630
973
|
doRenderEvent();
|
|
974
|
+
|
|
975
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
976
|
+
doRenderTop();
|
|
977
|
+
}
|
|
631
978
|
}, [externalSelectedItem]); // 데이터 변경 시 렌더링 (캐시 정리 및 선택 상태 동기화)
|
|
632
979
|
|
|
633
980
|
React.useEffect(function () {
|
|
@@ -648,14 +995,21 @@ var CanvasMarkerLayer = function (props) {
|
|
|
648
995
|
selectedItemsMapRef.current = hooks.syncSelectedItems(data, selectedIdsRef.current, selectedItemsMapRef.current);
|
|
649
996
|
renderAllImmediate();
|
|
650
997
|
}, [data]);
|
|
651
|
-
return reactDom.createPortal(React__default["default"].createElement("div", {
|
|
998
|
+
return React__default["default"].createElement(React__default["default"].Fragment, null, reactDom.createPortal(React__default["default"].createElement("div", {
|
|
652
999
|
ref: containerRef,
|
|
653
1000
|
style: {
|
|
654
1001
|
height: '100%',
|
|
655
1002
|
position: 'absolute',
|
|
656
1003
|
width: '100%'
|
|
657
1004
|
}
|
|
658
|
-
}), divElement)
|
|
1005
|
+
}), divElement), topStageZIndex !== undefined && reactDom.createPortal(React__default["default"].createElement("div", {
|
|
1006
|
+
ref: topContainerRef,
|
|
1007
|
+
style: {
|
|
1008
|
+
height: '100%',
|
|
1009
|
+
position: 'absolute',
|
|
1010
|
+
width: '100%'
|
|
1011
|
+
}
|
|
1012
|
+
}), topDivElement));
|
|
659
1013
|
};
|
|
660
1014
|
|
|
661
1015
|
exports.CanvasProvider = context.CanvasProvider;
|