@mint-ui/map 1.2.0-test.16 → 1.2.0-test.18

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/index.es.js CHANGED
@@ -5535,9 +5535,12 @@ var renderPolygonBase = function (baseFillColor, baseStrokeColor, baseLineWidth)
5535
5535
  /**
5536
5536
  * 폴리곤 Event 렌더링 함수
5537
5537
  *
5538
- * @param selectedFillColor 선택된 폴리곤 채우기 색상
5539
- * @param selectedStrokeColor 선택된 폴리곤 테두리 색상
5540
- * @param selectedLineWidth 선택된 폴리곤 테두리 두께
5538
+ * @param baseFillColor 기본 폴리곤 채우기 색상 (필수, fallback용)
5539
+ * @param baseStrokeColor 기본 폴리곤 테두리 색상 (필수, fallback용)
5540
+ * @param baseLineWidth 기본 폴리곤 테두리 두께 (필수, fallback용)
5541
+ * @param selectedFillColor 선택된 폴리곤 채우기 색상 (선택, 기본값: baseFillColor)
5542
+ * @param selectedStrokeColor 선택된 폴리곤 테두리 색상 (선택, 기본값: baseStrokeColor)
5543
+ * @param selectedLineWidth 선택된 폴리곤 테두리 두께 (선택, 기본값: baseLineWidth)
5541
5544
  * @param activeFillColor 마지막 선택된 폴리곤 채우기 색상 (선택, 기본값: selectedFillColor)
5542
5545
  * @param activeStrokeColor 마지막 선택된 폴리곤 테두리 색상 (선택, 기본값: selectedStrokeColor)
5543
5546
  * @param activeLineWidth 마지막 선택된 폴리곤 테두리 두께 (선택, 기본값: selectedLineWidth)
@@ -5548,29 +5551,34 @@ var renderPolygonBase = function (baseFillColor, baseStrokeColor, baseLineWidth)
5548
5551
  *
5549
5552
  * @example
5550
5553
  * const renderEvent = renderPolygonEvent(
5551
- * 'rgba(255, 193, 7, 0.7)',
5552
- * 'rgba(255, 152, 0, 1)',
5553
- * 4,
5554
- * 'rgba(255, 0, 0, 0.8)',
5555
- * undefined,
5556
- * undefined,
5557
- * 'rgba(100, 150, 255, 0.8)'
5554
+ * 'rgba(255, 100, 100, 0.5)', // baseFillColor
5555
+ * 'rgba(200, 50, 50, 0.8)', // baseStrokeColor
5556
+ * 2, // baseLineWidth
5557
+ * 'rgba(255, 193, 7, 0.7)', // selectedFillColor
5558
+ * 'rgba(255, 152, 0, 1)', // selectedStrokeColor
5559
+ * 4 // selectedLineWidth
5558
5560
  * );
5559
5561
  */
5560
5562
 
5561
- var renderPolygonEvent = function (selectedFillColor, selectedStrokeColor, selectedLineWidth, activeFillColor, activeStrokeColor, activeLineWidth, hoveredFillColor, hoveredStrokeColor, hoveredLineWidth) {
5562
- // 기본값 설정 (selected 기준)
5563
- var _activeFillColor = activeFillColor || selectedFillColor;
5563
+ var renderPolygonEvent = function (baseFillColor, baseStrokeColor, baseLineWidth, selectedFillColor, selectedStrokeColor, selectedLineWidth, activeFillColor, activeStrokeColor, activeLineWidth, hoveredFillColor, hoveredStrokeColor, hoveredLineWidth) {
5564
+ // 기본값 설정 (base 기준)
5565
+ var _selectedFillColor = selectedFillColor || baseFillColor;
5564
5566
 
5565
- var _activeStrokeColor = activeStrokeColor || selectedStrokeColor;
5567
+ var _selectedStrokeColor = selectedStrokeColor || baseStrokeColor;
5566
5568
 
5567
- var _activeLineWidth = activeLineWidth || selectedLineWidth;
5569
+ var _selectedLineWidth = selectedLineWidth || baseLineWidth;
5568
5570
 
5569
- var _hoveredFillColor = hoveredFillColor || selectedFillColor;
5571
+ var _activeFillColor = activeFillColor || _selectedFillColor;
5570
5572
 
5571
- var _hoveredStrokeColor = hoveredStrokeColor || selectedStrokeColor;
5573
+ var _activeStrokeColor = activeStrokeColor || _selectedStrokeColor;
5572
5574
 
5573
- var _hoveredLineWidth = hoveredLineWidth || selectedLineWidth;
5575
+ var _activeLineWidth = activeLineWidth || _selectedLineWidth;
5576
+
5577
+ var _hoveredFillColor = hoveredFillColor || _selectedFillColor;
5578
+
5579
+ var _hoveredStrokeColor = hoveredStrokeColor || _selectedStrokeColor;
5580
+
5581
+ var _hoveredLineWidth = hoveredLineWidth || _selectedLineWidth;
5574
5582
 
5575
5583
  return function (_a) {
5576
5584
  var ctx = _a.ctx,
@@ -5591,9 +5599,9 @@ var renderPolygonEvent = function (selectedFillColor, selectedStrokeColor, selec
5591
5599
  ctx: ctx,
5592
5600
  polygonOffsets: polygonOffsets,
5593
5601
  isDonutPolygon: item.isDonutPolygon || false,
5594
- fillColor: selectedFillColor,
5595
- strokeColor: selectedStrokeColor,
5596
- lineWidth: selectedLineWidth
5602
+ fillColor: _selectedFillColor,
5603
+ strokeColor: _selectedStrokeColor,
5604
+ lineWidth: _selectedLineWidth
5597
5605
  });
5598
5606
  }
5599
5607
  } // 2. 마지막 선택된 항목 그리기 (호버되지 않은 경우)
@@ -5636,7 +5644,7 @@ var renderPolygonEvent = function (selectedFillColor, selectedStrokeColor, selec
5636
5644
  // 메인 컴포넌트
5637
5645
  // ============================================================================
5638
5646
 
5639
- var WoongCanvasLayerComponent = function (props) {
5647
+ var WoongCanvasLayer = function (props) {
5640
5648
  var data = props.data,
5641
5649
  dataType = props.dataType,
5642
5650
  onClick = props.onClick,
@@ -5778,55 +5786,11 @@ var WoongCanvasLayerComponent = function (props) {
5778
5786
  var bbox = boundingBoxCacheRef.current.get(item.id);
5779
5787
 
5780
5788
  if (!bbox) {
5781
- // 폴리곤인 경우
5782
- if (dataType === CanvasDataType.POLYGON) {
5783
- var offsets = getOrComputePolygonOffsets(item);
5784
- if (!offsets) return false; // 바운딩 박스 계산 (최적화: 직접 비교)
5785
-
5786
- var minX = Infinity,
5787
- minY = Infinity,
5788
- maxX = -Infinity,
5789
- maxY = -Infinity;
5790
-
5791
- for (var _i = 0, offsets_1 = offsets; _i < offsets_1.length; _i++) {
5792
- var multiPolygon = offsets_1[_i];
5793
-
5794
- for (var _a = 0, multiPolygon_1 = multiPolygon; _a < multiPolygon_1.length; _a++) {
5795
- var polygonGroup = multiPolygon_1[_a];
5796
-
5797
- for (var _b = 0, polygonGroup_1 = polygonGroup; _b < polygonGroup_1.length; _b++) {
5798
- var _c = polygonGroup_1[_b],
5799
- x = _c[0],
5800
- y = _c[1];
5801
- if (x < minX) minX = x;
5802
- if (y < minY) minY = y;
5803
- if (x > maxX) maxX = x;
5804
- if (y > maxY) maxY = y;
5805
- }
5806
- }
5807
- }
5808
-
5809
- bbox = {
5810
- minX: minX,
5811
- minY: minY,
5812
- maxX: maxX,
5813
- maxY: maxY
5814
- };
5815
- boundingBoxCacheRef.current.set(item.id, bbox);
5816
- } // 마커인 경우
5817
- else {
5818
- var offset = getOrComputeMarkerOffset(item);
5819
- if (!offset) return false;
5820
- var boxWidth = item.boxWidth || 50;
5821
- var boxHeight = item.boxHeight || 28;
5822
- bbox = {
5823
- minX: offset.x - boxWidth / 2,
5824
- minY: offset.y - boxHeight - 6,
5825
- maxX: offset.x + boxWidth / 2,
5826
- maxY: offset.y
5827
- };
5828
- boundingBoxCacheRef.current.set(item.id, bbox);
5829
- }
5789
+ // 바운딩 박스 계산 (공통 함수 사용)
5790
+ var computed = computeBoundingBox(item);
5791
+ if (!computed) return false;
5792
+ bbox = computed;
5793
+ boundingBoxCacheRef.current.set(item.id, bbox);
5830
5794
  } // 바운딩 박스와 viewport 교차 체크
5831
5795
 
5832
5796
 
@@ -5872,6 +5836,65 @@ var WoongCanvasLayerComponent = function (props) {
5872
5836
 
5873
5837
  return result;
5874
5838
  }; // --------------------------------------------------------------------------
5839
+ // 유틸리티 함수: 바운딩 박스 계산
5840
+ // --------------------------------------------------------------------------
5841
+
5842
+ /**
5843
+ * 아이템의 바운딩 박스 계산 (폴리곤/마커 공통)
5844
+ *
5845
+ * @param item 마커 또는 폴리곤 데이터
5846
+ * @returns 바운딩 박스 또는 null
5847
+ */
5848
+
5849
+
5850
+ var computeBoundingBox = function (item) {
5851
+ if (dataType === CanvasDataType.POLYGON) {
5852
+ // 폴리곤: 모든 좌표의 최소/최대값 계산
5853
+ var offsets = getOrComputePolygonOffsets(item);
5854
+ if (!offsets) return null;
5855
+ var minX = Infinity,
5856
+ minY = Infinity,
5857
+ maxX = -Infinity,
5858
+ maxY = -Infinity;
5859
+
5860
+ for (var _i = 0, offsets_1 = offsets; _i < offsets_1.length; _i++) {
5861
+ var multiPolygon = offsets_1[_i];
5862
+
5863
+ for (var _a = 0, multiPolygon_1 = multiPolygon; _a < multiPolygon_1.length; _a++) {
5864
+ var polygonGroup = multiPolygon_1[_a];
5865
+
5866
+ for (var _b = 0, polygonGroup_1 = polygonGroup; _b < polygonGroup_1.length; _b++) {
5867
+ var _c = polygonGroup_1[_b],
5868
+ x = _c[0],
5869
+ y = _c[1];
5870
+ if (x < minX) minX = x;
5871
+ if (y < minY) minY = y;
5872
+ if (x > maxX) maxX = x;
5873
+ if (y > maxY) maxY = y;
5874
+ }
5875
+ }
5876
+ }
5877
+
5878
+ return {
5879
+ minX: minX,
5880
+ minY: minY,
5881
+ maxX: maxX,
5882
+ maxY: maxY
5883
+ };
5884
+ } else {
5885
+ // 마커: 중심점 기준 박스 크기 계산
5886
+ var offset = getOrComputeMarkerOffset(item);
5887
+ if (!offset) return null;
5888
+ var boxWidth = item.boxWidth || 50;
5889
+ var boxHeight = item.boxHeight || 28;
5890
+ return {
5891
+ minX: offset.x - boxWidth / 2,
5892
+ minY: offset.y - boxHeight - 6,
5893
+ maxX: offset.x + boxWidth / 2,
5894
+ maxY: offset.y
5895
+ };
5896
+ }
5897
+ }; // --------------------------------------------------------------------------
5875
5898
  // 유틸리티 함수: 공간 인덱싱
5876
5899
  // --------------------------------------------------------------------------
5877
5900
 
@@ -5886,52 +5909,12 @@ var WoongCanvasLayerComponent = function (props) {
5886
5909
  var currentMarkers = markersRef.current;
5887
5910
 
5888
5911
  for (var _i = 0, currentMarkers_1 = currentMarkers; _i < currentMarkers_1.length; _i++) {
5889
- var item = currentMarkers_1[_i];
5912
+ var item = currentMarkers_1[_i]; // 바운딩 박스 계산 (공통 함수 사용)
5890
5913
 
5891
- if (dataType === CanvasDataType.POLYGON) {
5892
- // 폴리곤: 바운딩 박스 계산 (최적화: 직접 비교)
5893
- var offsets = getOrComputePolygonOffsets(item);
5894
-
5895
- if (offsets) {
5896
- var minX = Infinity,
5897
- minY = Infinity,
5898
- maxX = -Infinity,
5899
- maxY = -Infinity;
5900
-
5901
- for (var _a = 0, offsets_2 = offsets; _a < offsets_2.length; _a++) {
5902
- var multiPolygon = offsets_2[_a];
5903
-
5904
- for (var _b = 0, multiPolygon_2 = multiPolygon; _b < multiPolygon_2.length; _b++) {
5905
- var polygonGroup = multiPolygon_2[_b];
5906
-
5907
- for (var _c = 0, polygonGroup_2 = polygonGroup; _c < polygonGroup_2.length; _c++) {
5908
- var _d = polygonGroup_2[_c],
5909
- x = _d[0],
5910
- y = _d[1];
5911
- if (x < minX) minX = x;
5912
- if (y < minY) minY = y;
5913
- if (x > maxX) maxX = x;
5914
- if (y > maxY) maxY = y;
5915
- }
5916
- }
5917
- }
5914
+ var bbox = computeBoundingBox(item);
5918
5915
 
5919
- spatial.insert(item, minX, minY, maxX, maxY);
5920
- }
5921
- } else {
5922
- // 마커: 점 기반 바운딩 박스
5923
- var offset = getOrComputeMarkerOffset(item);
5924
-
5925
- if (offset) {
5926
- var boxWidth = item.boxWidth || 50;
5927
- var boxHeight = item.boxHeight || 28;
5928
- var tailHeight = 6;
5929
- var minX = offset.x - boxWidth / 2;
5930
- var minY = offset.y - boxHeight - tailHeight;
5931
- var maxX = offset.x + boxWidth / 2;
5932
- var maxY = offset.y;
5933
- spatial.insert(item, minX, minY, maxX, maxY);
5934
- }
5916
+ if (bbox) {
5917
+ spatial.insert(item, bbox.minX, bbox.minY, bbox.maxX, bbox.maxY);
5935
5918
  }
5936
5919
  }
5937
5920
  }; // --------------------------------------------------------------------------
@@ -5960,7 +5943,7 @@ var WoongCanvasLayerComponent = function (props) {
5960
5943
  var renderAnimation = dataType === CanvasDataType.MARKER ? props.renderAnimation : undefined;
5961
5944
  var renderEvent = dataType === CanvasDataType.MARKER ? props.renderEvent : function () {
5962
5945
  var polygonProps = props;
5963
- return renderPolygonEvent(polygonProps.selectedFillColor, polygonProps.selectedStrokeColor, polygonProps.selectedLineWidth, polygonProps.activeFillColor, polygonProps.activeStrokeColor, polygonProps.activeLineWidth, polygonProps.hoveredFillColor, polygonProps.hoveredStrokeColor, polygonProps.hoveredLineWidth);
5946
+ return renderPolygonEvent(polygonProps.baseFillColor, polygonProps.baseStrokeColor, polygonProps.baseLineWidth, polygonProps.selectedFillColor, polygonProps.selectedStrokeColor, polygonProps.selectedLineWidth, polygonProps.activeFillColor, polygonProps.activeStrokeColor, polygonProps.activeLineWidth, polygonProps.hoveredFillColor, polygonProps.hoveredStrokeColor, polygonProps.hoveredLineWidth);
5964
5947
  }();
5965
5948
  /**
5966
5949
  * Base 레이어 렌더링 (뷰포트 컬링 적용, 선택된 마커 제외)
@@ -5969,6 +5952,10 @@ var WoongCanvasLayerComponent = function (props) {
5969
5952
  * 1. Shape 재사용으로 객체 생성/파괴 오버헤드 제거
5970
5953
  * 2. sceneFunc 한 번만 설정 (함수 재생성 제거)
5971
5954
  * 3. 클로저로 최신 데이터 참조
5955
+ *
5956
+ * 🎯 topOnHover 지원:
5957
+ * - renderEvent가 없을 때 Base Layer에서 hover 처리 (fallback)
5958
+ * - renderEvent가 있으면 Event Layer에서 처리 (성능 최적화)
5972
5959
  */
5973
5960
 
5974
5961
  var doRenderBase = function () {
@@ -5983,17 +5970,40 @@ var WoongCanvasLayerComponent = function (props) {
5983
5970
  shape = new Konva.Shape({
5984
5971
  name: 'base-render-shape',
5985
5972
  sceneFunc: function (context, shape) {
5986
- var ctx = context; // 클로저로 최신 ref 값 참조
5973
+ var ctx = context;
5974
+ var hovered = hoveredItemRef.current; // 클로저로 최신 ref 값 참조
5987
5975
 
5988
5976
  var visibleMarkers = enableViewportCulling ? markersRef.current.filter(function (item) {
5989
5977
  return isInViewport(item);
5990
- }) : markersRef.current;
5978
+ }) : markersRef.current; // topOnHover가 true이고 renderEvent가 없으면 Base Layer에서 hover 처리
5979
+
5980
+ if (topOnHover && !renderEvent && hovered) {
5981
+ // hover된 항목 제외하고 렌더링
5982
+ visibleMarkers = visibleMarkers.filter(function (item) {
5983
+ return item.id !== hovered.id;
5984
+ });
5985
+ } // 일반 항목 렌더링
5986
+
5987
+
5991
5988
  renderBase({
5992
5989
  ctx: ctx,
5993
5990
  items: visibleMarkers,
5994
5991
  selectedIds: selectedIdsRef.current,
5995
5992
  utils: renderUtils
5996
- });
5993
+ }); // hover된 항목을 최상단에 렌더링 (renderEvent가 없을 때만)
5994
+
5995
+ if (topOnHover && !renderEvent && hovered) {
5996
+ var isHoveredInViewport = enableViewportCulling ? isInViewport(hovered) : true;
5997
+
5998
+ if (isHoveredInViewport) {
5999
+ renderBase({
6000
+ ctx: ctx,
6001
+ items: [hovered],
6002
+ selectedIds: selectedIdsRef.current,
6003
+ utils: renderUtils
6004
+ });
6005
+ }
6006
+ }
5997
6007
  },
5998
6008
  perfectDrawEnabled: false,
5999
6009
  listening: false,
@@ -6038,13 +6048,6 @@ var WoongCanvasLayerComponent = function (props) {
6038
6048
  var doRenderEvent = function () {
6039
6049
  var layer = eventLayerRef.current;
6040
6050
  if (!layer) return;
6041
-
6042
- if (!onClick && !onMouseOver && !onMouseOut) {
6043
- layer.destroyChildren();
6044
- layer.batchDraw();
6045
- return;
6046
- }
6047
-
6048
6051
  if (!renderEvent) return; // 🔥 Shape 재사용: 이미 존재하면 재사용, 없으면 생성
6049
6052
 
6050
6053
  var shape = layer.findOne('.event-render-shape');
@@ -6233,17 +6236,19 @@ var WoongCanvasLayerComponent = function (props) {
6233
6236
  return null;
6234
6237
  };
6235
6238
  /**
6236
- * Hover 상태 설정 및 Event 레이어 렌더링
6239
+ * Hover 상태 설정 및 레이어 렌더링
6237
6240
  *
6238
6241
  * @param data hover된 마커/폴리곤 데이터 또는 null
6239
6242
  *
6240
6243
  * 최적화: RAF 제거하여 즉시 렌더링 (16ms 지연 제거)
6241
- * topOnHover가 true일 때는 Base 레이어도 다시 그려서 z-order 변경
6244
+ *
6245
+ * 🎯 topOnHover 지원:
6246
+ * - renderEvent가 있으면: Event Layer에서만 처리 (성능 최적화)
6247
+ * - renderEvent가 없고 topOnHover=true면: Base Layer에서 처리
6242
6248
  */
6243
6249
 
6244
6250
 
6245
6251
  var setHovered = function (data) {
6246
- if (!onMouseOver && !onMouseOut) return;
6247
6252
  hoveredItemRef.current = data;
6248
6253
 
6249
6254
  if (draggingRef.current) {
@@ -6251,10 +6256,15 @@ var WoongCanvasLayerComponent = function (props) {
6251
6256
  } else {
6252
6257
  controller.setMapCursor(data ? 'pointer' : 'grab');
6253
6258
  } // 즉시 렌더링 (RAF 없이)
6254
- // topOnHover는 Event Layer에서만 처리 (Base Layer 재렌더링 제거로 성능 향상)
6255
6259
 
6256
6260
 
6257
- doRenderEvent();
6261
+ if (renderEvent) {
6262
+ // renderEvent가 있으면 Event Layer에서만 처리 (성능 최적화)
6263
+ doRenderEvent();
6264
+ } else if (topOnHover) {
6265
+ // renderEvent가 없고 topOnHover가 true면 Base Layer에서 처리
6266
+ doRenderBase();
6267
+ }
6258
6268
  };
6259
6269
  /**
6260
6270
  * 클릭 처리 (단일/다중 선택)
@@ -6268,8 +6278,7 @@ var WoongCanvasLayerComponent = function (props) {
6268
6278
 
6269
6279
 
6270
6280
  var handleLocalClick = function (data) {
6271
- if (!onClick) return; // 1. 선택 상태 업데이트
6272
-
6281
+ // 1. 선택 상태 업데이트
6273
6282
  if (enableMultiSelect) {
6274
6283
  // 다중 선택: Set과 Map 동시 업데이트
6275
6284
  var newSelected = new Set(selectedIdsRef.current);
@@ -6321,7 +6330,6 @@ var WoongCanvasLayerComponent = function (props) {
6321
6330
 
6322
6331
  if (disableInteractionRef.current) return; // 🚫 상호작용 비활성화 시 즉시 반환
6323
6332
 
6324
- if (!onClick) return;
6325
6333
  if (context || !((_a = event === null || event === void 0 ? void 0 : event.param) === null || _a === void 0 ? void 0 : _a.position)) return;
6326
6334
 
6327
6335
  try {
@@ -6330,7 +6338,10 @@ var WoongCanvasLayerComponent = function (props) {
6330
6338
 
6331
6339
  if (data_1) {
6332
6340
  handleLocalClick(data_1);
6333
- onClick(data_1, selectedIdsRef.current);
6341
+
6342
+ if (onClick) {
6343
+ onClick(data_1, selectedIdsRef.current);
6344
+ }
6334
6345
  }
6335
6346
  } catch (error) {
6336
6347
  console.error('[WoongKonvaMarker] handleClick error:', error);
@@ -6346,7 +6357,6 @@ var WoongCanvasLayerComponent = function (props) {
6346
6357
 
6347
6358
  if (disableInteractionRef.current) return; // 🚫 상호작용 비활성화 시 즉시 반환
6348
6359
 
6349
- if (!onMouseOver && !onMouseOut) return;
6350
6360
  if (context || !((_a = event === null || event === void 0 ? void 0 : event.param) === null || _a === void 0 ? void 0 : _a.position)) return;
6351
6361
 
6352
6362
  try {
@@ -6389,7 +6399,6 @@ var WoongCanvasLayerComponent = function (props) {
6389
6399
  var handleMouseLeave = function () {
6390
6400
  if (disableInteractionRef.current) return; // 🚫 상호작용 비활성화 시 즉시 반환
6391
6401
 
6392
- if (!onMouseOver && !onMouseOut) return;
6393
6402
  var prevHovered = hoveredItemRef.current;
6394
6403
 
6395
6404
  if (prevHovered) {
@@ -6674,116 +6683,6 @@ var WoongCanvasLayerComponent = function (props) {
6674
6683
  }
6675
6684
  }), divElement);
6676
6685
  };
6677
- /**
6678
- * 🚀 WoongCanvasLayer - Konva 기반 초고성능 마커/폴리곤 렌더링 컴포넌트
6679
- *
6680
- * ## 📌 주요 특징
6681
- * - **30,000개 이상의 폴리곤/마커를 60fps로 렌더링**
6682
- * - **Multi-Layer 아키텍처**: Base/Animation/Event 레이어 분리
6683
- * - **Spatial Hash Grid**: O(1) 수준의 빠른 Hit Test
6684
- * - **LRU 캐시**: 좌표 변환 결과 캐싱으로 성능 최적화
6685
- * - **Viewport Culling**: 화면에 보이는 영역만 렌더링
6686
- * - **Discriminated Union Props**: 타입 안전한 MARKER/POLYGON 모드
6687
- *
6688
- * ## 🎯 사용 방법
6689
- *
6690
- * ### 1️⃣ POLYGON 모드 (자동 렌더링)
6691
- * ```tsx
6692
- * <WoongCanvasLayer
6693
- * dataType={CanvasDataType.POLYGON}
6694
- * data={polygons}
6695
- * baseFillColor="rgba(255, 100, 100, 0.5)"
6696
- * baseStrokeColor="rgba(200, 50, 50, 0.8)"
6697
- * baseLineWidth={2}
6698
- * selectedFillColor="rgba(255, 193, 7, 0.7)"
6699
- * selectedStrokeColor="rgba(255, 152, 0, 1)"
6700
- * selectedLineWidth={4}
6701
- * hoveredFillColor="rgba(100, 150, 255, 0.8)" // optional
6702
- * hoveredStrokeColor="rgba(0, 100, 200, 1)" // optional
6703
- * hoveredLineWidth={3} // optional
6704
- * enableMultiSelect={true}
6705
- * onClick={handleClick}
6706
- * />
6707
- * ```
6708
- *
6709
- * ### 2️⃣ MARKER 모드 (커스텀 렌더링)
6710
- * ```tsx
6711
- * <WoongCanvasLayer
6712
- * dataType={CanvasDataType.MARKER}
6713
- * data={markers}
6714
- * renderBase={renderMarkerBase} // required
6715
- * renderAnimation={renderMarkerAnimation} // optional
6716
- * renderEvent={renderMarkerEvent} // optional
6717
- * topOnHover={true}
6718
- * onClick={handleClick}
6719
- * />
6720
- * ```
6721
- *
6722
- * ## 📊 데이터 형식
6723
- * ```typescript
6724
- * const data: KonvaCanvasData<T>[] = [
6725
- * {
6726
- * id: 'unique-id',
6727
- * position: new Position(lat, lng),
6728
- * // POLYGON: paths 필수
6729
- * paths: [[[lat, lng], [lat, lng], ...]],
6730
- * // MARKER: boxWidth/boxHeight 권장 (Hit Test 정확도)
6731
- * boxWidth: 60,
6732
- * boxHeight: 75,
6733
- * // 커스텀 데이터
6734
- * ...customData
6735
- * }
6736
- * ];
6737
- * ```
6738
- *
6739
- * ## ⚡ 성능 최적화 팁
6740
- * 1. **동적 boxWidth 계산**: `measureText()`로 실제 너비 계산 후 전달
6741
- * 2. **enableViewportCulling**: 대량 데이터 시 필수 (기본 true)
6742
- * 3. **selectedItems 외부 관리**: 상태를 외부에서 관리하여 리렌더링 최소화
6743
- * 4. **React.memo 최적화**: 컴포넌트가 자동으로 불필요한 리렌더링 방지
6744
- *
6745
- * @template T 마커/폴리곤 데이터의 추가 속성 타입
6746
- *
6747
- * @example
6748
- * // 동적 boxWidth 계산 예시
6749
- * const tempCtx = document.createElement('canvas').getContext('2d');
6750
- * tempCtx.font = 'bold 15px Arial';
6751
- * const boxWidth = Math.max(60, tempCtx.measureText(text).width + 20);
6752
- *
6753
- * @see {@link https://github.com/your-repo/docs/WoongCanvasLayer.md} 전체 문서
6754
- */
6755
-
6756
-
6757
- var WoongCanvasLayer = React.memo(WoongCanvasLayerComponent, function (prevProps, nextProps) {
6758
- // // 1. data 비교
6759
- // const prevData = prevProps.data;
6760
- // const nextData = nextProps.data;
6761
- // // 참조가 같으면 스킵
6762
- // if (prevData !== nextData) {
6763
- // // 길이가 다르면 변경됨
6764
- // if (prevData.length !== nextData.length) return false;
6765
- // // 각 데이터의 ID 비교
6766
- // for (let i = 0; i < prevData.length; i++) {
6767
- // if (prevData[i].id !== nextData[i].id) {
6768
- // return false; // 변경됨 → 리렌더링
6769
- // }
6770
- // }
6771
- // }
6772
- // 2. selectedItems 비교 (참조만 비교)
6773
- if (prevProps.selectedItems !== nextProps.selectedItems) {
6774
- return false; // 변경됨 → 리렌더링
6775
- }
6776
-
6777
- if (prevProps.selectedItem !== nextProps.selectedItem) {
6778
- return false; // 변경됨 → 리렌더링
6779
- }
6780
-
6781
- if (prevProps.disableInteraction !== nextProps.disableInteraction) {
6782
- return false; // 변경됨 → 리렌더링
6783
- }
6784
-
6785
- return true; // 같음 → 리렌더링 스킵
6786
- });
6787
6686
 
6788
6687
  var css_248z = ".MintMapWrapper-module_mint-map-control-wrapper-container__DONh7 {\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n pointer-events: none;\n z-index: 101;\n}\n\n.MintMapWrapper-module_mint-map-overlay-wrapper__Jn4wV {\n position: absolute;\n z-index: 1;\n}";
6789
6688
  var styles = {"mint-map-control-wrapper-container":"MintMapWrapper-module_mint-map-control-wrapper-container__DONh7","mint-map-overlay-wrapper":"MintMapWrapper-module_mint-map-overlay-wrapper__Jn4wV"};