@mint-ui/map 1.2.0-test.62 → 1.2.0-test.63
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/shared/types.d.ts +2 -0
- package/dist/index.es.js +411 -57
- package/dist/index.umd.js +411 -57
- package/package.json +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -3939,28 +3939,48 @@
|
|
|
3939
3939
|
});
|
|
3940
3940
|
|
|
3941
3941
|
var CanvasMarkerLayer = function (props) {
|
|
3942
|
+
// 타입 가드: renderEvent가 있는지 확인
|
|
3943
|
+
var hasRenderEvent = 'renderEvent' in props && props.renderEvent !== undefined; // renderEvent가 있는 경우와 없는 경우를 구분하여 props 추출
|
|
3944
|
+
|
|
3942
3945
|
var data = props.data,
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
topOnHover = _b === void 0 ? false : _b,
|
|
3950
|
-
_c = props.enableViewportCulling,
|
|
3951
|
-
enableViewportCulling = _c === void 0 ? false : _c,
|
|
3952
|
-
_d = props.cullingMargin,
|
|
3953
|
-
cullingMargin = _d === void 0 ? DEFAULT_CULLING_MARGIN : _d,
|
|
3954
|
-
_e = props.maxCacheSize,
|
|
3955
|
-
maxCacheSize = _e === void 0 ? DEFAULT_MAX_CACHE_SIZE : _e,
|
|
3956
|
-
externalSelectedItems = props.selectedItems,
|
|
3957
|
-
externalSelectedItem = props.selectedItem,
|
|
3958
|
-
_f = props.disableInteraction,
|
|
3959
|
-
disableInteraction = _f === void 0 ? false : _f,
|
|
3946
|
+
_a = props.enableViewportCulling,
|
|
3947
|
+
enableViewportCulling = _a === void 0 ? false : _a,
|
|
3948
|
+
_b = props.cullingMargin,
|
|
3949
|
+
cullingMargin = _b === void 0 ? DEFAULT_CULLING_MARGIN : _b,
|
|
3950
|
+
_c = props.maxCacheSize,
|
|
3951
|
+
maxCacheSize = _c === void 0 ? DEFAULT_MAX_CACHE_SIZE : _c,
|
|
3960
3952
|
renderBase = props.renderBase,
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3953
|
+
options = tslib.__rest(props, ["data", "enableViewportCulling", "cullingMargin", "maxCacheSize", "renderBase"]); // renderEvent가 있는 경우에만 인터랙션 관련 props 추출
|
|
3954
|
+
|
|
3955
|
+
|
|
3956
|
+
var _d = hasRenderEvent && 'renderEvent' in props ? props : {
|
|
3957
|
+
disableInteraction: false,
|
|
3958
|
+
enableMultiSelect: false,
|
|
3959
|
+
onClick: undefined,
|
|
3960
|
+
onMouseOut: undefined,
|
|
3961
|
+
onMouseOver: undefined,
|
|
3962
|
+
renderEvent: undefined,
|
|
3963
|
+
selectedItem: undefined,
|
|
3964
|
+
selectedItems: undefined,
|
|
3965
|
+
topOnHover: false,
|
|
3966
|
+
topStageZIndex: undefined
|
|
3967
|
+
},
|
|
3968
|
+
_e = _d.disableInteraction,
|
|
3969
|
+
disableInteraction = _e === void 0 ? false : _e,
|
|
3970
|
+
_f = _d.enableMultiSelect,
|
|
3971
|
+
enableMultiSelect = _f === void 0 ? false : _f,
|
|
3972
|
+
onClick = _d.onClick,
|
|
3973
|
+
onMouseOut = _d.onMouseOut,
|
|
3974
|
+
onMouseOver = _d.onMouseOver,
|
|
3975
|
+
renderEvent = _d.renderEvent,
|
|
3976
|
+
externalSelectedItem = _d.selectedItem,
|
|
3977
|
+
externalSelectedItems = _d.selectedItems,
|
|
3978
|
+
rawTopStageZIndex = _d.topStageZIndex,
|
|
3979
|
+
_g = _d.topOnHover,
|
|
3980
|
+
topOnHover = _g === void 0 ? false : _g; // topOnHover가 false이거나 없으면 topStageZIndex를 사용하지 못하도록 제한
|
|
3981
|
+
|
|
3982
|
+
|
|
3983
|
+
var topStageZIndex = topOnHover && rawTopStageZIndex !== undefined ? rawTopStageZIndex : undefined;
|
|
3964
3984
|
var controller = useMintMapController();
|
|
3965
3985
|
var context = useCanvasContext();
|
|
3966
3986
|
var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
|
|
@@ -3968,11 +3988,18 @@
|
|
|
3968
3988
|
var divRef = React.useRef(document.createElement('div'));
|
|
3969
3989
|
var divElement = divRef.current;
|
|
3970
3990
|
var containerRef = React.useRef(null);
|
|
3971
|
-
var markerRef = React.useRef(); //
|
|
3991
|
+
var markerRef = React.useRef(); // Top Layer용 별도 DOM Refs (topStageZIndex가 설정된 경우에만 사용)
|
|
3992
|
+
|
|
3993
|
+
var topDivRef = React.useRef(document.createElement('div'));
|
|
3994
|
+
var topDivElement = topDivRef.current;
|
|
3995
|
+
var topContainerRef = React.useRef(null);
|
|
3996
|
+
var topMarkerRef = React.useRef(); // Konva Refs
|
|
3972
3997
|
|
|
3973
3998
|
var stageRef = React.useRef(null);
|
|
3974
3999
|
var baseLayerRef = React.useRef(null);
|
|
3975
|
-
var eventLayerRef = React.useRef(null);
|
|
4000
|
+
var eventLayerRef = React.useRef(null);
|
|
4001
|
+
var topStageRef = React.useRef(null);
|
|
4002
|
+
var topLayerRef = React.useRef(null); // 상태 관리 Refs (React 리렌더링 최소화)
|
|
3976
4003
|
|
|
3977
4004
|
var dataRef = React.useRef(data);
|
|
3978
4005
|
var disableInteractionRef = React.useRef(disableInteraction);
|
|
@@ -4063,24 +4090,34 @@
|
|
|
4063
4090
|
|
|
4064
4091
|
var visibleItems = enableViewportCullingRef.current ? dataRef.current.filter(function (item) {
|
|
4065
4092
|
return isInViewport$1(item);
|
|
4066
|
-
}) : dataRef.current; // topOnHover
|
|
4093
|
+
}) : dataRef.current; // topStageZIndex가 설정되고 topOnHover가 true인 경우 hover된 항목은 Top Layer에서 처리
|
|
4094
|
+
// topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
|
|
4067
4095
|
|
|
4068
|
-
if (
|
|
4096
|
+
if (topStageZIndex !== undefined && topOnHover && hovered) {
|
|
4097
|
+
visibleItems = visibleItems.filter(function (item) {
|
|
4098
|
+
return item.id !== hovered.id;
|
|
4099
|
+
});
|
|
4100
|
+
} else if (topOnHover && !renderEvent && hovered) {
|
|
4069
4101
|
visibleItems = visibleItems.filter(function (item) {
|
|
4070
4102
|
return item.id !== hovered.id;
|
|
4071
4103
|
});
|
|
4072
4104
|
} // 일반 항목들 먼저 렌더링
|
|
4105
|
+
// topOnHover가 false이고 renderEvent가 있으면 선택된 항목도 Base Layer에서 렌더링
|
|
4106
|
+
// (Event Layer에서 선택된 항목을 렌더링하지 않으므로)
|
|
4107
|
+
// topOnHover가 true이거나 renderEvent가 없으면 선택된 항목은 Base Layer에서 스킵됨
|
|
4073
4108
|
|
|
4074
4109
|
|
|
4110
|
+
var baseSelectedIds = !topOnHover && renderEvent ? selectedIdsRef.current : new Set();
|
|
4075
4111
|
renderBase({
|
|
4076
4112
|
ctx: ctx,
|
|
4077
4113
|
hoveredItem: hovered,
|
|
4078
4114
|
items: visibleItems,
|
|
4079
|
-
selectedIds:
|
|
4115
|
+
selectedIds: baseSelectedIds,
|
|
4080
4116
|
utils: renderUtils
|
|
4081
|
-
}); // hover된
|
|
4117
|
+
}); // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리하므로 여기서는 스킵
|
|
4118
|
+
// hover된 항목을 마지막에 렌더링하여 최상위에 표시
|
|
4082
4119
|
|
|
4083
|
-
if (topOnHover && !renderEvent && hovered) {
|
|
4120
|
+
if (topStageZIndex === undefined && topOnHover && !renderEvent && hovered) {
|
|
4084
4121
|
if (!enableViewportCullingRef.current || isInViewport$1(hovered)) {
|
|
4085
4122
|
renderBase({
|
|
4086
4123
|
ctx: ctx,
|
|
@@ -4114,9 +4151,24 @@
|
|
|
4114
4151
|
sceneFunc: function (konvaContext) {
|
|
4115
4152
|
var ctx = konvaContext;
|
|
4116
4153
|
var selectedItems = mapValuesToArray(selectedItemsMapRef.current);
|
|
4117
|
-
var hovered = hoveredItemRef.current;
|
|
4154
|
+
var hovered = hoveredItemRef.current; // topStageZIndex가 설정되고 topOnHover가 true이면 hover된 항목은 Top Layer에서 처리
|
|
4155
|
+
// event 레이어에서는 hover된 항목을 완전히 제외하고 선택된 항목만 렌더링
|
|
4118
4156
|
|
|
4119
|
-
if (topOnHover && hovered) {
|
|
4157
|
+
if (topStageZIndex !== undefined && topOnHover && hovered) {
|
|
4158
|
+
// hover된 항목을 제외한 선택된 항목들
|
|
4159
|
+
var selectedItemsWithoutHovered = selectedItems.filter(function (item) {
|
|
4160
|
+
return item.id !== hovered.id;
|
|
4161
|
+
}); // 선택된 항목만 그리기 (hover된 항목은 Top Layer에서 처리)
|
|
4162
|
+
|
|
4163
|
+
renderEvent({
|
|
4164
|
+
ctx: ctx,
|
|
4165
|
+
hoveredItem: null,
|
|
4166
|
+
selectedItem: selectedItemRef.current,
|
|
4167
|
+
selectedItems: selectedItemsWithoutHovered,
|
|
4168
|
+
topOnHover: topOnHover,
|
|
4169
|
+
utils: renderUtils
|
|
4170
|
+
});
|
|
4171
|
+
} else if (topOnHover && hovered) {
|
|
4120
4172
|
renderEvent({
|
|
4121
4173
|
ctx: ctx,
|
|
4122
4174
|
hoveredItem: null,
|
|
@@ -4124,6 +4176,7 @@
|
|
|
4124
4176
|
selectedItems: selectedItems.filter(function (item) {
|
|
4125
4177
|
return item.id !== hovered.id;
|
|
4126
4178
|
}),
|
|
4179
|
+
topOnHover: topOnHover,
|
|
4127
4180
|
utils: renderUtils
|
|
4128
4181
|
});
|
|
4129
4182
|
|
|
@@ -4137,15 +4190,25 @@
|
|
|
4137
4190
|
hoveredItem: hovered,
|
|
4138
4191
|
selectedItem: selectedItemRef.current,
|
|
4139
4192
|
selectedItems: hoverSelectedItems,
|
|
4193
|
+
topOnHover: topOnHover,
|
|
4140
4194
|
utils: renderUtils
|
|
4141
4195
|
});
|
|
4142
4196
|
}
|
|
4143
4197
|
} else {
|
|
4198
|
+
// topOnHover가 false일 때는 hover된 항목을 나중에 그리지 않음
|
|
4199
|
+
// 하지만 hover 스타일은 적용해야 하므로, hover된 항목이 selectedItems에 포함되어 있지 않으면 추가
|
|
4200
|
+
// renderEvent 함수에 topOnHover 정보를 전달하여,
|
|
4201
|
+
// renderEvent 함수 내부에서 topOnHover가 false일 때는 hover된 항목을 마지막에 그리지 않도록 함
|
|
4202
|
+
var hoveredIsSelected = hovered ? selectedItems.some(function (item) {
|
|
4203
|
+
return item.id === hovered.id;
|
|
4204
|
+
}) : false;
|
|
4205
|
+
var finalSelectedItems = hovered && !hoveredIsSelected && !topOnHover ? tslib.__spreadArray(tslib.__spreadArray([], selectedItems, true), [hovered], false) : selectedItems;
|
|
4144
4206
|
renderEvent({
|
|
4145
4207
|
ctx: ctx,
|
|
4146
4208
|
hoveredItem: hovered,
|
|
4147
4209
|
selectedItem: selectedItemRef.current,
|
|
4148
|
-
selectedItems:
|
|
4210
|
+
selectedItems: finalSelectedItems,
|
|
4211
|
+
topOnHover: topOnHover,
|
|
4149
4212
|
utils: renderUtils
|
|
4150
4213
|
});
|
|
4151
4214
|
}
|
|
@@ -4154,6 +4217,79 @@
|
|
|
4154
4217
|
layer.add(shape);
|
|
4155
4218
|
}
|
|
4156
4219
|
|
|
4220
|
+
layer.batchDraw();
|
|
4221
|
+
}; // Top Layer 렌더링 (hover된 항목만, 별도 캔버스 DOM에 그리기)
|
|
4222
|
+
|
|
4223
|
+
|
|
4224
|
+
var doRenderTop = function () {
|
|
4225
|
+
var stage = topStageRef.current;
|
|
4226
|
+
var layer = topLayerRef.current;
|
|
4227
|
+
if (!stage || !layer || topStageZIndex === undefined || !topOnHover) return;
|
|
4228
|
+
var hovered = hoveredItemRef.current;
|
|
4229
|
+
var shape = layer.findOne('.top-render-shape'); // hover된 항목이 없으면 shape 제거
|
|
4230
|
+
|
|
4231
|
+
if (!hovered) {
|
|
4232
|
+
if (shape) {
|
|
4233
|
+
shape.destroy();
|
|
4234
|
+
}
|
|
4235
|
+
|
|
4236
|
+
layer.batchDraw();
|
|
4237
|
+
return;
|
|
4238
|
+
} // shape가 없으면 생성
|
|
4239
|
+
|
|
4240
|
+
|
|
4241
|
+
if (!shape) {
|
|
4242
|
+
shape = new Konva__default["default"].Shape({
|
|
4243
|
+
hitStrokeWidth: 0,
|
|
4244
|
+
listening: false,
|
|
4245
|
+
name: 'top-render-shape',
|
|
4246
|
+
perfectDrawEnabled: false,
|
|
4247
|
+
sceneFunc: function () {} // 초기화만
|
|
4248
|
+
|
|
4249
|
+
});
|
|
4250
|
+
layer.add(shape);
|
|
4251
|
+
} // sceneFunc를 매번 업데이트하여 최신 상태 반영
|
|
4252
|
+
|
|
4253
|
+
|
|
4254
|
+
shape.sceneFunc(function (konvaContext) {
|
|
4255
|
+
var ctx = konvaContext;
|
|
4256
|
+
var currentHovered = hoveredItemRef.current; // hover된 항목이 없으면 아무것도 그리지 않음
|
|
4257
|
+
|
|
4258
|
+
if (!currentHovered) return; // 뷰포트 컬링 확인
|
|
4259
|
+
|
|
4260
|
+
if (enableViewportCullingRef.current && !isInViewport$1(currentHovered)) {
|
|
4261
|
+
return;
|
|
4262
|
+
}
|
|
4263
|
+
|
|
4264
|
+
var selectedItems = mapValuesToArray(selectedItemsMapRef.current);
|
|
4265
|
+
var hoveredIsSelected = selectedItems.some(function (item) {
|
|
4266
|
+
return item.id === currentHovered.id;
|
|
4267
|
+
}); // Top Layer에서는 hover된 마커만 hover 스타일로 그리기
|
|
4268
|
+
// renderEvent가 있으면: base는 그리지 않고 event만 그리기 (hover 스타일 적용)
|
|
4269
|
+
// renderEvent가 없으면: base를 hover 스타일로 그리기
|
|
4270
|
+
|
|
4271
|
+
if (renderEvent) {
|
|
4272
|
+
// renderEvent가 있으면 hover 스타일로만 그리기
|
|
4273
|
+
var hoverSelectedItems = hoveredIsSelected ? [currentHovered] : [];
|
|
4274
|
+
renderEvent({
|
|
4275
|
+
ctx: ctx,
|
|
4276
|
+
hoveredItem: currentHovered,
|
|
4277
|
+
selectedItem: selectedItemRef.current,
|
|
4278
|
+
selectedItems: hoverSelectedItems,
|
|
4279
|
+
topOnHover: topOnHover,
|
|
4280
|
+
utils: renderUtils
|
|
4281
|
+
});
|
|
4282
|
+
} else {
|
|
4283
|
+
// renderEvent가 없으면 base를 hover 스타일로 그리기
|
|
4284
|
+
renderBase({
|
|
4285
|
+
ctx: ctx,
|
|
4286
|
+
hoveredItem: currentHovered,
|
|
4287
|
+
items: [currentHovered],
|
|
4288
|
+
selectedIds: selectedIdsRef.current,
|
|
4289
|
+
utils: renderUtils
|
|
4290
|
+
});
|
|
4291
|
+
}
|
|
4292
|
+
});
|
|
4157
4293
|
layer.batchDraw();
|
|
4158
4294
|
}; // 전체 즉시 렌더링
|
|
4159
4295
|
|
|
@@ -4165,11 +4301,19 @@
|
|
|
4165
4301
|
|
|
4166
4302
|
buildSpatialIndex$1();
|
|
4167
4303
|
doRenderBase();
|
|
4168
|
-
doRenderEvent();
|
|
4304
|
+
doRenderEvent(); // 메인 stage의 transform을 topStage에도 동기화
|
|
4305
|
+
|
|
4306
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
4307
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4308
|
+
}
|
|
4309
|
+
|
|
4310
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4311
|
+
doRenderTop();
|
|
4312
|
+
}
|
|
4169
4313
|
}; // 지도 이벤트 핸들러 생성
|
|
4170
4314
|
|
|
4171
4315
|
|
|
4172
|
-
var
|
|
4316
|
+
var _h = createMapEventHandlers({
|
|
4173
4317
|
accumTranslateRef: accumTranslateRef,
|
|
4174
4318
|
boundingBoxCacheRef: boundingBoxCacheRef,
|
|
4175
4319
|
containerRef: containerRef,
|
|
@@ -4180,19 +4324,23 @@
|
|
|
4180
4324
|
prevCenterOffsetRef: prevCenterOffsetRef,
|
|
4181
4325
|
renderAllImmediate: renderAllImmediate
|
|
4182
4326
|
}),
|
|
4183
|
-
handleIdle =
|
|
4184
|
-
handleZoomStart =
|
|
4185
|
-
handleZoomEnd =
|
|
4186
|
-
handleCenterChanged =
|
|
4187
|
-
handleDragStartShared =
|
|
4188
|
-
handleDragEndShared =
|
|
4327
|
+
handleIdle = _h.handleIdle,
|
|
4328
|
+
handleZoomStart = _h.handleZoomStart,
|
|
4329
|
+
handleZoomEnd = _h.handleZoomEnd,
|
|
4330
|
+
handleCenterChanged = _h.handleCenterChanged,
|
|
4331
|
+
handleDragStartShared = _h.handleDragStart,
|
|
4332
|
+
handleDragEndShared = _h.handleDragEnd;
|
|
4189
4333
|
|
|
4190
4334
|
var handleDragStart = function () {
|
|
4191
4335
|
handleDragStartShared(); // 드래그 시작 시점의 hover 상태 저장
|
|
4192
4336
|
|
|
4193
4337
|
dragStartHoveredItemRef.current = hoveredItemRef.current;
|
|
4194
4338
|
draggingRef.current = true;
|
|
4195
|
-
controller.setMapCursor('grabbing');
|
|
4339
|
+
controller.setMapCursor('grabbing'); // 메인 stage의 transform을 topStage에도 동기화
|
|
4340
|
+
|
|
4341
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
4342
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4343
|
+
}
|
|
4196
4344
|
};
|
|
4197
4345
|
|
|
4198
4346
|
var handleDragEnd = function () {
|
|
@@ -4200,7 +4348,11 @@
|
|
|
4200
4348
|
draggingRef.current = false; // 드래그 종료 후 hover 상태 초기화 (다음 MOUSEMOVE에서 업데이트됨)
|
|
4201
4349
|
|
|
4202
4350
|
dragStartHoveredItemRef.current = null;
|
|
4203
|
-
controller.setMapCursor('grab');
|
|
4351
|
+
controller.setMapCursor('grab'); // 메인 stage의 transform을 topStage에도 동기화
|
|
4352
|
+
|
|
4353
|
+
if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
|
|
4354
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4355
|
+
}
|
|
4204
4356
|
}; // Hit Test: 특정 좌표의 마커 찾기
|
|
4205
4357
|
|
|
4206
4358
|
|
|
@@ -4243,7 +4395,19 @@
|
|
|
4243
4395
|
controller.setMapCursor(hoveredData ? 'pointer' : 'grab');
|
|
4244
4396
|
}
|
|
4245
4397
|
|
|
4246
|
-
if (
|
|
4398
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4399
|
+
// topStageZIndex가 설정되고 topOnHover가 true인 경우 Top Layer에서 hover된 항목 렌더링
|
|
4400
|
+
// base 레이어와 event 레이어도 업데이트 (hover된 항목 제외)
|
|
4401
|
+
doRenderBase();
|
|
4402
|
+
doRenderEvent();
|
|
4403
|
+
doRenderTop();
|
|
4404
|
+
} else if (renderEvent) {
|
|
4405
|
+
// renderEvent가 있을 때는 Event Layer 업데이트
|
|
4406
|
+
// topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 적용해야 하므로 Base Layer도 업데이트
|
|
4407
|
+
if (!topOnHover) {
|
|
4408
|
+
doRenderBase();
|
|
4409
|
+
}
|
|
4410
|
+
|
|
4247
4411
|
doRenderEvent();
|
|
4248
4412
|
} else if (topOnHover) {
|
|
4249
4413
|
doRenderBase();
|
|
@@ -4280,6 +4444,10 @@
|
|
|
4280
4444
|
|
|
4281
4445
|
doRenderBase();
|
|
4282
4446
|
doRenderEvent();
|
|
4447
|
+
|
|
4448
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4449
|
+
doRenderTop();
|
|
4450
|
+
}
|
|
4283
4451
|
}; // 클릭 이벤트 핸들러
|
|
4284
4452
|
|
|
4285
4453
|
|
|
@@ -4340,13 +4508,33 @@
|
|
|
4340
4508
|
if (!prevHovered) return;
|
|
4341
4509
|
hoveredItemRef.current = null;
|
|
4342
4510
|
controller.setMapCursor('grab');
|
|
4343
|
-
|
|
4511
|
+
|
|
4512
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4513
|
+
// base 레이어와 event 레이어도 업데이트 (hover된 항목 다시 표시)
|
|
4514
|
+
doRenderBase();
|
|
4515
|
+
doRenderEvent();
|
|
4516
|
+
doRenderTop();
|
|
4517
|
+
} else if (renderEvent) {
|
|
4518
|
+
// renderEvent가 있을 때는 Event Layer 업데이트
|
|
4519
|
+
// topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 제거해야 하므로 Base Layer도 업데이트
|
|
4520
|
+
if (!topOnHover) {
|
|
4521
|
+
doRenderBase();
|
|
4522
|
+
}
|
|
4523
|
+
|
|
4524
|
+
doRenderEvent();
|
|
4525
|
+
}
|
|
4526
|
+
|
|
4344
4527
|
onMouseOut === null || onMouseOut === void 0 ? void 0 : onMouseOut(prevHovered);
|
|
4345
4528
|
}; // DOM 초기화
|
|
4346
4529
|
|
|
4347
4530
|
|
|
4348
4531
|
React.useEffect(function () {
|
|
4349
|
-
divElement.style.width = 'fit-content';
|
|
4532
|
+
divElement.style.width = 'fit-content'; // Top Layer용 div도 초기화 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
|
|
4533
|
+
|
|
4534
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4535
|
+
topDivElement.style.width = 'fit-content';
|
|
4536
|
+
}
|
|
4537
|
+
|
|
4350
4538
|
return function () {
|
|
4351
4539
|
if (!markerRef.current) return;
|
|
4352
4540
|
controller.clearDrawable(markerRef.current);
|
|
@@ -4364,19 +4552,18 @@
|
|
|
4364
4552
|
|
|
4365
4553
|
if (markerRef.current) {
|
|
4366
4554
|
controller.updateMarker(markerRef.current, markerOptions);
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
markerRef.current.element = divElement;
|
|
4372
|
-
controller.createMarker(markerRef.current);
|
|
4555
|
+
} else {
|
|
4556
|
+
markerRef.current = new Marker(markerOptions);
|
|
4557
|
+
markerRef.current.element = divElement;
|
|
4558
|
+
controller.createMarker(markerRef.current);
|
|
4373
4559
|
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4560
|
+
if (divElement.parentElement) {
|
|
4561
|
+
divElement.parentElement.style.pointerEvents = 'none';
|
|
4562
|
+
}
|
|
4377
4563
|
|
|
4378
|
-
|
|
4379
|
-
|
|
4564
|
+
if (options.zIndex !== undefined) {
|
|
4565
|
+
controller.setMarkerZIndex(markerRef.current, options.zIndex);
|
|
4566
|
+
}
|
|
4380
4567
|
}
|
|
4381
4568
|
}, [options]); // Konva 초기화 및 이벤트 리스너 등록
|
|
4382
4569
|
|
|
@@ -4530,19 +4717,179 @@
|
|
|
4530
4717
|
|
|
4531
4718
|
renderAllImmediate();
|
|
4532
4719
|
}
|
|
4533
|
-
}, [enableViewportCulling]); //
|
|
4720
|
+
}, [enableViewportCulling]); // Top Layer용 별도 캔버스 DOM 생성 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
|
|
4721
|
+
|
|
4722
|
+
React.useEffect(function () {
|
|
4723
|
+
if (topStageZIndex === undefined || !topOnHover) return;
|
|
4724
|
+
if (!topContainerRef.current) return;
|
|
4725
|
+
var mapDiv = controller.mapDivElement; // Top Layer용 div 요소 설정
|
|
4726
|
+
|
|
4727
|
+
topDivElement.style.width = 'fit-content';
|
|
4728
|
+
var bounds = controller.getCurrBounds();
|
|
4729
|
+
|
|
4730
|
+
var topMarkerOptions = tslib.__assign({
|
|
4731
|
+
position: bounds.nw,
|
|
4732
|
+
zIndex: topStageZIndex
|
|
4733
|
+
}, options); // Top Layer용 Marker 생성 (zIndex: topStageZIndex로 DOM 마커보다 위에 위치)
|
|
4734
|
+
|
|
4735
|
+
|
|
4736
|
+
var topMarker = new Marker(topMarkerOptions);
|
|
4737
|
+
topMarker.element = topDivElement;
|
|
4738
|
+
controller.createMarker(topMarker);
|
|
4739
|
+
topMarkerRef.current = topMarker;
|
|
4740
|
+
|
|
4741
|
+
if (topDivElement.parentElement) {
|
|
4742
|
+
topDivElement.parentElement.style.pointerEvents = 'none';
|
|
4743
|
+
} // Top Layer Marker의 zIndex 명시적으로 설정
|
|
4744
|
+
|
|
4745
|
+
|
|
4746
|
+
controller.setMarkerZIndex(topMarker, topStageZIndex); // Top Layer용 Konva Stage 생성
|
|
4747
|
+
|
|
4748
|
+
var topStage = new Konva__default["default"].Stage({
|
|
4749
|
+
container: topContainerRef.current,
|
|
4750
|
+
height: mapDiv.offsetHeight,
|
|
4751
|
+
width: mapDiv.offsetWidth
|
|
4752
|
+
});
|
|
4753
|
+
topStageRef.current = topStage;
|
|
4754
|
+
var topLayer = new Konva__default["default"].Layer({
|
|
4755
|
+
listening: false
|
|
4756
|
+
});
|
|
4757
|
+
topLayerRef.current = topLayer;
|
|
4758
|
+
topStage.add(topLayer); // ResizeObserver: 맵 크기 변경 감지 (RAF로 debounce)
|
|
4759
|
+
|
|
4760
|
+
var topResizeRafId = null;
|
|
4761
|
+
var topResizeObserver = new ResizeObserver(function () {
|
|
4762
|
+
if (topResizeRafId !== null) {
|
|
4763
|
+
cancelAnimationFrame(topResizeRafId);
|
|
4764
|
+
}
|
|
4765
|
+
|
|
4766
|
+
topResizeRafId = requestAnimationFrame(function () {
|
|
4767
|
+
topStage.width(mapDiv.offsetWidth);
|
|
4768
|
+
topStage.height(mapDiv.offsetHeight);
|
|
4769
|
+
doRenderTop();
|
|
4770
|
+
topResizeRafId = null;
|
|
4771
|
+
});
|
|
4772
|
+
});
|
|
4773
|
+
topResizeObserver.observe(mapDiv); // topMarker position 업데이트 함수
|
|
4774
|
+
|
|
4775
|
+
var updateTopMarkerPosition = function () {
|
|
4776
|
+
if (topMarkerRef.current && markerRef.current) {
|
|
4777
|
+
var currentBounds = controller.getCurrBounds();
|
|
4778
|
+
|
|
4779
|
+
var updatedOptions = tslib.__assign(tslib.__assign({}, options), {
|
|
4780
|
+
position: currentBounds.nw,
|
|
4781
|
+
zIndex: topStageZIndex
|
|
4782
|
+
});
|
|
4783
|
+
|
|
4784
|
+
controller.updateMarker(topMarkerRef.current, updatedOptions); // zIndex 명시적으로 설정
|
|
4785
|
+
|
|
4786
|
+
controller.setMarkerZIndex(topMarkerRef.current, topStageZIndex);
|
|
4787
|
+
}
|
|
4788
|
+
}; // 지도 이벤트 핸들러 등록 (topStage 업데이트용)
|
|
4789
|
+
|
|
4790
|
+
|
|
4791
|
+
var handleTopIdle = function () {
|
|
4792
|
+
// topMarker의 position을 메인 marker와 동일하게 업데이트
|
|
4793
|
+
updateTopMarkerPosition(); // topStage 크기 업데이트
|
|
4794
|
+
|
|
4795
|
+
if (topStageRef.current) {
|
|
4796
|
+
topStageRef.current.width(mapDiv.offsetWidth);
|
|
4797
|
+
topStageRef.current.height(mapDiv.offsetHeight);
|
|
4798
|
+
} // 메인 stage의 transform을 topStage에도 동기화
|
|
4799
|
+
|
|
4800
|
+
|
|
4801
|
+
if (topContainerRef.current && containerRef.current) {
|
|
4802
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4803
|
+
}
|
|
4804
|
+
|
|
4805
|
+
doRenderTop();
|
|
4806
|
+
};
|
|
4807
|
+
|
|
4808
|
+
var handleTopZoomStart = function () {
|
|
4809
|
+
// 메인 stage의 transform을 topStage에도 동기화
|
|
4810
|
+
if (topContainerRef.current && containerRef.current) {
|
|
4811
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4812
|
+
}
|
|
4813
|
+
|
|
4814
|
+
doRenderTop();
|
|
4815
|
+
};
|
|
4816
|
+
|
|
4817
|
+
var handleTopZoomEnd = function () {
|
|
4818
|
+
// 메인 stage의 transform을 topStage에도 동기화
|
|
4819
|
+
if (topContainerRef.current && containerRef.current) {
|
|
4820
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4821
|
+
}
|
|
4822
|
+
|
|
4823
|
+
doRenderTop();
|
|
4824
|
+
};
|
|
4825
|
+
|
|
4826
|
+
var handleTopCenterChanged = function () {
|
|
4827
|
+
// topMarker의 position을 메인 marker와 동일하게 업데이트
|
|
4828
|
+
updateTopMarkerPosition(); // topStage 크기 업데이트
|
|
4829
|
+
|
|
4830
|
+
if (topStageRef.current) {
|
|
4831
|
+
topStageRef.current.width(mapDiv.offsetWidth);
|
|
4832
|
+
topStageRef.current.height(mapDiv.offsetHeight);
|
|
4833
|
+
} // 메인 stage의 transform을 topStage에도 동기화
|
|
4834
|
+
|
|
4835
|
+
|
|
4836
|
+
if (topContainerRef.current && containerRef.current) {
|
|
4837
|
+
topContainerRef.current.style.transform = containerRef.current.style.transform || '';
|
|
4838
|
+
}
|
|
4839
|
+
|
|
4840
|
+
doRenderTop();
|
|
4841
|
+
};
|
|
4842
|
+
|
|
4843
|
+
controller.addEventListener('IDLE', handleTopIdle);
|
|
4844
|
+
controller.addEventListener('ZOOMSTART', handleTopZoomStart);
|
|
4845
|
+
controller.addEventListener('ZOOM_CHANGED', handleTopZoomEnd);
|
|
4846
|
+
controller.addEventListener('CENTER_CHANGED', handleTopCenterChanged);
|
|
4847
|
+
doRenderTop();
|
|
4848
|
+
return function () {
|
|
4849
|
+
if (topResizeRafId !== null) {
|
|
4850
|
+
cancelAnimationFrame(topResizeRafId);
|
|
4851
|
+
}
|
|
4852
|
+
|
|
4853
|
+
topResizeObserver.disconnect();
|
|
4854
|
+
controller.removeEventListener('IDLE', handleTopIdle);
|
|
4855
|
+
controller.removeEventListener('ZOOMSTART', handleTopZoomStart);
|
|
4856
|
+
controller.removeEventListener('ZOOM_CHANGED', handleTopZoomEnd);
|
|
4857
|
+
controller.removeEventListener('CENTER_CHANGED', handleTopCenterChanged);
|
|
4858
|
+
|
|
4859
|
+
if (topLayerRef.current) {
|
|
4860
|
+
topLayerRef.current.destroyChildren();
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
if (topStageRef.current) {
|
|
4864
|
+
topStageRef.current.destroy();
|
|
4865
|
+
}
|
|
4866
|
+
|
|
4867
|
+
if (topMarkerRef.current) {
|
|
4868
|
+
controller.clearDrawable(topMarkerRef.current);
|
|
4869
|
+
topMarkerRef.current = undefined;
|
|
4870
|
+
}
|
|
4871
|
+
};
|
|
4872
|
+
}, [topStageZIndex, renderEvent, options]); // 외부 selectedItems 동기화
|
|
4534
4873
|
|
|
4535
4874
|
React.useEffect(function () {
|
|
4536
4875
|
if (!stageRef.current) return;
|
|
4537
4876
|
syncExternalSelectedItems(externalSelectedItems, selectedIdsRef, selectedItemsMapRef);
|
|
4538
4877
|
doRenderBase();
|
|
4539
4878
|
doRenderEvent();
|
|
4879
|
+
|
|
4880
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4881
|
+
doRenderTop();
|
|
4882
|
+
}
|
|
4540
4883
|
}, [externalSelectedItems]); // 외부 selectedItem 변경 시 Event Layer 리렌더링
|
|
4541
4884
|
|
|
4542
4885
|
React.useEffect(function () {
|
|
4543
4886
|
if (!stageRef.current) return;
|
|
4544
4887
|
selectedItemRef.current = externalSelectedItem;
|
|
4545
4888
|
doRenderEvent();
|
|
4889
|
+
|
|
4890
|
+
if (topStageZIndex !== undefined && topOnHover) {
|
|
4891
|
+
doRenderTop();
|
|
4892
|
+
}
|
|
4546
4893
|
}, [externalSelectedItem]); // 데이터 변경 시 렌더링 (캐시 정리 및 선택 상태 동기화)
|
|
4547
4894
|
|
|
4548
4895
|
React.useEffect(function () {
|
|
@@ -4563,14 +4910,21 @@
|
|
|
4563
4910
|
selectedItemsMapRef.current = syncSelectedItems(data, selectedIdsRef.current, selectedItemsMapRef.current);
|
|
4564
4911
|
renderAllImmediate();
|
|
4565
4912
|
}, [data]);
|
|
4566
|
-
return reactDom.createPortal(React__default["default"].createElement("div", {
|
|
4913
|
+
return React__default["default"].createElement(React__default["default"].Fragment, null, reactDom.createPortal(React__default["default"].createElement("div", {
|
|
4567
4914
|
ref: containerRef,
|
|
4568
4915
|
style: {
|
|
4569
4916
|
height: '100%',
|
|
4570
4917
|
position: 'absolute',
|
|
4571
4918
|
width: '100%'
|
|
4572
4919
|
}
|
|
4573
|
-
}), divElement)
|
|
4920
|
+
}), divElement), topStageZIndex !== undefined && reactDom.createPortal(React__default["default"].createElement("div", {
|
|
4921
|
+
ref: topContainerRef,
|
|
4922
|
+
style: {
|
|
4923
|
+
height: '100%',
|
|
4924
|
+
position: 'absolute',
|
|
4925
|
+
width: '100%'
|
|
4926
|
+
}
|
|
4927
|
+
}), topDivElement));
|
|
4574
4928
|
};
|
|
4575
4929
|
|
|
4576
4930
|
/* eslint-disable no-restricted-syntax */
|