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