@mint-ui/map 1.2.0-test.20 → 1.2.0-test.21

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.
@@ -59,20 +59,20 @@ var WoongCanvasLayer = function (props) {
59
59
  var divElement = divRef.current;
60
60
  var containerRef = React.useRef(null);
61
61
  var markerRef = React.useRef(); // --------------------------------------------------------------------------
62
- // Konva Refs
62
+ // Konva Refs - Multi-Layer 아키텍처
63
63
  // --------------------------------------------------------------------------
64
64
 
65
65
  var stageRef = React.useRef(null);
66
66
  var baseLayerRef = React.useRef(null);
67
67
  var animationLayerRef = React.useRef(null);
68
68
  var eventLayerRef = React.useRef(null); // --------------------------------------------------------------------------
69
- // Data Refs - 선택Hover 상태 관리
69
+ // Data Refs - 데이터 동기화 및 상태 관리
70
70
  // --------------------------------------------------------------------------
71
71
 
72
72
  /** data prop을 ref로 추적 (stale closure 방지, useEffect에서 동기화) */
73
73
 
74
74
  var dataRef = React.useRef(data); // --------------------------------------------------------------------------
75
- // State Refs - 선택 및 Hover 상태 관리
75
+ // State Refs - 선택 및 Hover 상태 관리 (성능 최적화)
76
76
  // --------------------------------------------------------------------------
77
77
 
78
78
  /** 상호작용 비활성화 상태 (Ref로 관리하여 클로저 문제 해결) */
@@ -113,7 +113,7 @@ var WoongCanvasLayer = function (props) {
113
113
  */
114
114
 
115
115
  var selectedItemsMapRef = React.useRef(new Map()); // --------------------------------------------------------------------------
116
- // Drag Refs
116
+ // Drag Refs - 지도 드래그 상태 관리
117
117
  // --------------------------------------------------------------------------
118
118
 
119
119
  var draggingRef = React.useRef(false);
@@ -122,7 +122,7 @@ var WoongCanvasLayer = function (props) {
122
122
  x: 0,
123
123
  y: 0
124
124
  }); // --------------------------------------------------------------------------
125
- // Performance Refs (캐싱 & 최적화)
125
+ // Performance Refs - 성능 최적화 (캐싱 & 인덱싱)
126
126
  // --------------------------------------------------------------------------
127
127
 
128
128
  /** 좌표 변환 결과 LRU 캐시 */
@@ -137,7 +137,7 @@ var WoongCanvasLayer = function (props) {
137
137
  /** 뷰포트 경계 캐시 (Viewport Culling) */
138
138
 
139
139
  var viewportRef = React.useRef(null); // --------------------------------------------------------------------------
140
- // 유틸리티 함수: 뷰포트 관리
140
+ // 유틸리티 함수: 뷰포트 관리 (Viewport Culling)
141
141
  // --------------------------------------------------------------------------
142
142
 
143
143
  /**
@@ -216,7 +216,7 @@ var WoongCanvasLayer = function (props) {
216
216
 
217
217
  return result;
218
218
  }; // --------------------------------------------------------------------------
219
- // 유틸리티 함수: 바운딩 박스 계산
219
+ // 유틸리티 함수: 바운딩 박스 계산 (Viewport Culling 최적화)
220
220
  // --------------------------------------------------------------------------
221
221
 
222
222
  /**
@@ -330,11 +330,14 @@ var WoongCanvasLayer = function (props) {
330
330
  var renderEvent = dataType === types.CanvasDataType.MARKER ? props.renderEvent : function () {
331
331
  var polygonProps = props;
332
332
  return renderer.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);
333
- }();
333
+ }(); // --------------------------------------------------------------------------
334
+ // 렌더링 함수: Base Layer (기본 상태 렌더링)
335
+ // --------------------------------------------------------------------------
336
+
334
337
  /**
335
338
  * Base 레이어 렌더링 (뷰포트 컬링 적용, 선택된 마커 제외)
336
339
  *
337
- * 🔥 최적화:
340
+ * 🔥 성능 최적화:
338
341
  * 1. Shape 재사용으로 객체 생성/파괴 오버헤드 제거
339
342
  * 2. sceneFunc 한 번만 설정 (함수 재생성 제거)
340
343
  * 3. 클로저로 최신 데이터 참조
@@ -400,11 +403,14 @@ var WoongCanvasLayer = function (props) {
400
403
 
401
404
 
402
405
  layer.batchDraw();
403
- };
406
+ }; // --------------------------------------------------------------------------
407
+ // 렌더링 함수: Animation Layer (선택된 항목 애니메이션)
408
+ // --------------------------------------------------------------------------
409
+
404
410
  /**
405
411
  * Animation 레이어 렌더링 (선택된 마커 애니메이션)
406
412
  *
407
- * 🔥 최적화: sceneFunc 내부에서 최신 items 참조
413
+ * 🔥 성능 최적화: sceneFunc 내부에서 최신 items 참조
408
414
  * - 선택 변경 시에만 재생성
409
415
  * - 지도 이동 시에는 기존 Animation 계속 실행
410
416
  */
@@ -420,11 +426,14 @@ var WoongCanvasLayer = function (props) {
420
426
  items: dataRef.current,
421
427
  utils: renderUtils
422
428
  });
423
- };
429
+ }; // --------------------------------------------------------------------------
430
+ // 렌더링 함수: Event Layer (상호작용 상태 렌더링)
431
+ // --------------------------------------------------------------------------
432
+
424
433
  /**
425
434
  * Event 레이어 렌더링 (hover + 선택 상태 표시)
426
435
  *
427
- * 🔥 최적화:
436
+ * 🔥 성능 최적화:
428
437
  * 1. Shape 재사용으로 객체 생성/파괴 오버헤드 제거
429
438
  * 2. sceneFunc 한 번만 설정 (함수 재생성 제거)
430
439
  * 3. 클로저로 최신 데이터 참조
@@ -450,10 +459,11 @@ var WoongCanvasLayer = function (props) {
450
459
  shape = new Konva__default["default"].Shape({
451
460
  name: 'event-render-shape',
452
461
  sceneFunc: function (context, shape) {
453
- var ctx = context; // 클로저로 최신 ref 값 참조
462
+ var ctx = context; // 클로저로 최신 ref 값 참조 (안전한 처리)
454
463
 
455
464
  var selectedItems = Array.from(selectedItemsMapRef.current.values());
456
- var hovered = hoveredItemRef.current; // topOnHover가 true이면 hover된 항목을 최상단에 렌더링
465
+ var hovered = hoveredItemRef.current;
466
+ var selectedItem = selectedItemRef.current; // topOnHover가 true이면 hover된 항목을 최상단에 렌더링
457
467
 
458
468
  if (topOnHover && hovered) {
459
469
  // 1. 먼저 일반 항목들 렌더링 (hover된 항목 제외)
@@ -462,9 +472,9 @@ var WoongCanvasLayer = function (props) {
462
472
  hoveredItem: null,
463
473
  utils: renderUtils,
464
474
  selectedItems: selectedItems.filter(function (item) {
465
- return item.id !== hovered.id;
475
+ return item && item.id !== hovered.id;
466
476
  }),
467
- selectedItem: selectedItemRef.current
477
+ selectedItem: selectedItem
468
478
  }); // 2. hover된 항목을 최상단에 렌더링
469
479
 
470
480
  var isHoveredInViewport = enableViewportCulling ? isInViewport(hovered) : true;
@@ -475,7 +485,7 @@ var WoongCanvasLayer = function (props) {
475
485
  hoveredItem: hovered,
476
486
  utils: renderUtils,
477
487
  selectedItems: selectedItems,
478
- selectedItem: selectedItemRef.current
488
+ selectedItem: selectedItem
479
489
  });
480
490
  }
481
491
  } else {
@@ -485,7 +495,7 @@ var WoongCanvasLayer = function (props) {
485
495
  hoveredItem: hovered,
486
496
  utils: renderUtils,
487
497
  selectedItems: selectedItems,
488
- selectedItem: selectedItemRef.current
498
+ selectedItem: selectedItem
489
499
  });
490
500
  }
491
501
  },
@@ -598,7 +608,7 @@ var WoongCanvasLayer = function (props) {
598
608
  containerRef.current.style.transform = "translate(".concat(accumTranslateRef.current.x, "px, ").concat(accumTranslateRef.current.y, "px)");
599
609
  }
600
610
  }; // --------------------------------------------------------------------------
601
- // Hit Test & 상태 관리
611
+ // Hit Test & 상태 관리 (이벤트 처리)
602
612
  // --------------------------------------------------------------------------
603
613
 
604
614
  /**
@@ -768,7 +778,7 @@ var WoongCanvasLayer = function (props) {
768
778
  }
769
779
  };
770
780
  /**
771
- * 마우스 이동 이벤트 처리 (hover 감지)
781
+ * 마우스 이동 이벤트 처리 (hover 감지 및 상태 업데이트)
772
782
  */
773
783
 
774
784
 
@@ -812,7 +822,7 @@ var WoongCanvasLayer = function (props) {
812
822
  controller.setMapCursor('grab');
813
823
  };
814
824
  /**
815
- * 마우스가 canvas를 벗어날 때 hover cleanup
825
+ * 마우스가 canvas를 벗어날 때 hover 상태 정리
816
826
  */
817
827
 
818
828
 
@@ -872,7 +882,7 @@ var WoongCanvasLayer = function (props) {
872
882
  }
873
883
  }
874
884
  }, [options]); // --------------------------------------------------------------------------
875
- // Lifecycle: Konva 초기화 및 이벤트 리스너 등록
885
+ // Lifecycle: Konva 초기화 및 이벤트 리스너 등록 (컴포넌트 마운트)
876
886
  // --------------------------------------------------------------------------
877
887
 
878
888
  React.useEffect(function () {
@@ -998,26 +1008,32 @@ var WoongCanvasLayer = function (props) {
998
1008
  };
999
1009
  }, []); // 초기화는 한 번만
1000
1010
  // --------------------------------------------------------------------------
1001
- // Lifecycle: disableInteraction 동기화
1011
+ // Lifecycle: disableInteraction 동기화 (상호작용 상태 관리)
1002
1012
  // --------------------------------------------------------------------------
1003
1013
 
1004
1014
  React.useEffect(function () {
1005
1015
  disableInteractionRef.current = disableInteraction;
1006
1016
  }, [disableInteraction]); // --------------------------------------------------------------------------
1007
- // Lifecycle: 외부 selectedItems 동기화
1017
+ // Lifecycle: 외부 selectedItems 동기화 (선택 상태 관리)
1008
1018
  // --------------------------------------------------------------------------
1009
1019
 
1010
1020
  React.useEffect(function () {
1011
1021
  if (!stageRef.current) return; // externalSelectedItems가 undefined면 외부 제어 안 함
1012
1022
 
1013
- if (externalSelectedItems === undefined) return; // 외부에서 전달된 selectedItems로 동기화
1023
+ if (externalSelectedItems === undefined) return; // 외부에서 전달된 selectedItems로 동기화 (안전한 처리)
1014
1024
 
1015
1025
  var newSelectedIds = new Set();
1016
- var newSelectedItemsMap = new Map();
1017
- externalSelectedItems.forEach(function (item) {
1018
- newSelectedIds.add(item.id);
1019
- newSelectedItemsMap.set(item.id, item);
1020
- });
1026
+ var newSelectedItemsMap = new Map(); // selectedItems가 배열인지 확인하고 안전하게 처리
1027
+
1028
+ if (Array.isArray(externalSelectedItems)) {
1029
+ externalSelectedItems.forEach(function (item) {
1030
+ if (item && item.id) {
1031
+ newSelectedIds.add(item.id);
1032
+ newSelectedItemsMap.set(item.id, item);
1033
+ }
1034
+ });
1035
+ }
1036
+
1021
1037
  selectedIdsRef.current = newSelectedIds;
1022
1038
  selectedItemsMapRef.current = newSelectedItemsMap; // 렌더링
1023
1039
 
@@ -1026,17 +1042,17 @@ var WoongCanvasLayer = function (props) {
1026
1042
  doRenderEvent();
1027
1043
  }, [externalSelectedItems]); // 배열 자체를 dependency로 사용
1028
1044
  // --------------------------------------------------------------------------
1029
- // Lifecycle: 외부 selectedItem 변경 시 Event Layer 리렌더링
1045
+ // Lifecycle: 외부 selectedItem 변경 시 Event Layer 리렌더링 (단일 선택 관리)
1030
1046
  // --------------------------------------------------------------------------
1031
1047
 
1032
1048
  React.useEffect(function () {
1033
- if (!stageRef.current) return; // Ref 동기화
1049
+ if (!stageRef.current) return; // Ref 동기화 (안전한 처리)
1034
1050
 
1035
- selectedItemRef.current = externalSelectedItem; // selectedItem이 변경되면 Event Layer만 다시 그림
1051
+ selectedItemRef.current = externalSelectedItem || null; // selectedItem이 변경되면 Event Layer만 다시 그림
1036
1052
 
1037
1053
  doRenderEvent();
1038
1054
  }, [externalSelectedItem]); // --------------------------------------------------------------------------
1039
- // Lifecycle: 데이터 변경 시 렌더링
1055
+ // Lifecycle: 데이터 변경 시 렌더링 (데이터 동기화 및 최적화)
1040
1056
  // --------------------------------------------------------------------------
1041
1057
 
1042
1058
  React.useEffect(function () {
@@ -1093,7 +1109,10 @@ var WoongCanvasLayer = function (props) {
1093
1109
  selectedItemsMapRef.current = newSelectedItemsMap; // 즉시 렌더링
1094
1110
 
1095
1111
  renderAllImmediate();
1096
- }, [data]);
1112
+ }, [data]); // --------------------------------------------------------------------------
1113
+ // Render - React Portal을 통한 DOM 렌더링
1114
+ // --------------------------------------------------------------------------
1115
+
1097
1116
  return reactDom.createPortal(React__default["default"].createElement("div", {
1098
1117
  ref: containerRef,
1099
1118
  style: {
@@ -1,3 +1,13 @@
1
+ /**
2
+ * @fileoverview WoongCanvasLayer 모듈의 메인 엔트리 포인트
3
+ *
4
+ * 이 파일은 WoongCanvasLayer 컴포넌트와 관련된 모든 타입, 유틸리티,
5
+ * 성능 최적화 클래스들을 외부로 노출합니다.
6
+ *
7
+ * @version 2.2.1
8
+ * @since 2.0.0
9
+ * @author 박건웅
10
+ */
1
11
  export { default as WoongCanvasLayer } from "./WoongCanvasLayer";
2
12
  export * from "./WoongCanvasLayer";
3
13
  export * from "./shared";
@@ -2,31 +2,99 @@ import React from "react";
2
2
  import { Offset } from "../../../../types";
3
3
  import { KonvaCanvasData } from "./types";
4
4
  /**
5
- * 다중 WoongKonvaMarker 인스턴스를 관리하기 위한 Context
5
+ * @fileoverview 다중 WoongCanvasLayer 인스턴스를 관리하기 위한 React Context
6
6
  *
7
- * 용도:
8
- * - zIndex 기반 이벤트 우선순위 처리
9
- * - 전역 클릭/호버 이벤트 조정
10
- * - 여러 레이어 간 상호작용 관리
7
+ * 이 Context는 여러 개의 WoongCanvasLayer가 동시에 사용될 때 이벤트 우선순위를
8
+ * 관리하고 전역 클릭/호버 이벤트를 조정합니다.
9
+ *
10
+ * ## 주요 기능
11
+ * - **zIndex 기반 이벤트 우선순위**: 높은 zIndex를 가진 레이어가 먼저 이벤트 처리
12
+ * - **전역 이벤트 관리**: 지도 전체의 클릭/호버 이벤트를 중앙에서 관리
13
+ * - **다중 레이어 상호작용**: 여러 레이어 간의 이벤트 충돌 방지
14
+ * - **상호작용 비활성화 지원**: disableInteraction prop 지원
15
+ *
16
+ * ## 사용 방법
17
+ * ```tsx
18
+ * <KonvaMarkerProvider>
19
+ * <WoongCanvasLayer zIndex={1} ... />
20
+ * <WoongCanvasLayer zIndex={2} ... />
21
+ * </KonvaMarkerProvider>
22
+ * ```
23
+ *
24
+ * @version 2.2.1
25
+ * @since 2.0.0
26
+ * @author 박건웅
27
+ */
28
+ /**
29
+ * WoongCanvasLayer 컴포넌트 인스턴스 인터페이스
30
+ *
31
+ * Context에서 관리하는 각 WoongCanvasLayer 인스턴스가 구현해야 하는 메서드들입니다.
32
+ *
33
+ * @template T 마커/폴리곤 데이터의 추가 속성 타입
11
34
  */
12
35
  export interface ComponentInstance<T> {
36
+ /** 레이어 순서 (높을수록 우선순위 높음) */
13
37
  zIndex: number;
38
+ /** 특정 좌표에서 히트 테스트 수행 */
14
39
  hitTest: (offset: Offset) => boolean;
40
+ /** 클릭 이벤트 핸들러 */
15
41
  onClick?: (payload: KonvaCanvasData<T>, selectedIds: Set<string>) => void;
42
+ /** 마우스 오버 이벤트 핸들러 */
16
43
  onMouseOver?: (payload: KonvaCanvasData<T>) => void;
44
+ /** 마우스 아웃 이벤트 핸들러 */
17
45
  onMouseOut?: (payload: KonvaCanvasData<T>) => void;
46
+ /** 특정 좌표에서 데이터 찾기 */
18
47
  findData: (offset: Offset) => KonvaCanvasData<T> | null;
48
+ /** 호버 상태 설정 */
19
49
  setHovered: (data: KonvaCanvasData<T> | null) => void;
50
+ /** 로컬 클릭 처리 */
20
51
  handleLocalClick: (data: KonvaCanvasData<T>) => void;
52
+ /** 선택된 항목 ID 목록 반환 */
21
53
  getSelectedIds: () => Set<string>;
54
+ /** 상호작용 비활성화 여부 체크 */
22
55
  isInteractionDisabled: () => boolean;
23
56
  }
57
+ /**
58
+ * KonvaMarkerContext의 값 타입
59
+ */
24
60
  interface KonvaMarkerContextValue {
61
+ /** 컴포넌트 인스턴스 등록 */
25
62
  registerComponent: <T>(instance: ComponentInstance<T>) => void;
63
+ /** 컴포넌트 인스턴스 등록 해제 */
26
64
  unregisterComponent: <T>(instance: ComponentInstance<T>) => void;
27
65
  }
66
+ /**
67
+ * 다중 WoongCanvasLayer 관리를 위한 Context Provider
68
+ *
69
+ * 여러 개의 WoongCanvasLayer가 동시에 사용될 때 이벤트 우선순위를 관리하고
70
+ * 전역 클릭/호버 이벤트를 조정합니다.
71
+ *
72
+ * @param children - Provider로 감쌀 React 컴포넌트들
73
+ * @returns Context Provider 컴포넌트
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * <KonvaMarkerProvider>
78
+ * <WoongCanvasLayer zIndex={1} data={markers1} ... />
79
+ * <WoongCanvasLayer zIndex={2} data={markers2} ... />
80
+ * </KonvaMarkerProvider>
81
+ * ```
82
+ */
28
83
  export declare const KonvaMarkerProvider: React.FC<{
29
84
  children: React.ReactNode;
30
85
  }>;
86
+ /**
87
+ * KonvaMarkerContext를 사용하기 위한 Hook
88
+ *
89
+ * @returns Context 값 또는 null (Provider 외부에서 사용 시)
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * const context = useKonvaMarkerContext();
94
+ * if (context) {
95
+ * context.registerComponent(instance);
96
+ * }
97
+ * ```
98
+ */
31
99
  export declare const useKonvaMarkerContext: () => KonvaMarkerContextValue | null;
32
100
  export {};
@@ -9,18 +9,50 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
9
9
 
10
10
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
11
11
 
12
+ /** 다중 레이어 관리를 위한 React Context */
13
+
12
14
  var KonvaMarkerContext = React.createContext(null);
15
+ /**
16
+ * 다중 WoongCanvasLayer 관리를 위한 Context Provider
17
+ *
18
+ * 여러 개의 WoongCanvasLayer가 동시에 사용될 때 이벤트 우선순위를 관리하고
19
+ * 전역 클릭/호버 이벤트를 조정합니다.
20
+ *
21
+ * @param children - Provider로 감쌀 React 컴포넌트들
22
+ * @returns Context Provider 컴포넌트
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <KonvaMarkerProvider>
27
+ * <WoongCanvasLayer zIndex={1} data={markers1} ... />
28
+ * <WoongCanvasLayer zIndex={2} data={markers2} ... />
29
+ * </KonvaMarkerProvider>
30
+ * ```
31
+ */
32
+
13
33
  var KonvaMarkerProvider = function (_a) {
14
34
  var children = _a.children;
15
- var controller = MintMapProvider.useMintMapController(); // Refs
35
+ var controller = MintMapProvider.useMintMapController(); // === Refs ===
36
+
37
+ /** 등록된 모든 컴포넌트 인스턴스들 (zIndex 내림차순 정렬) */
16
38
 
17
39
  var componentsRef = React.useRef([]);
40
+ /** 현재 호버된 컴포넌트 인스턴스 */
41
+
18
42
  var currentHoveredRef = React.useRef(null);
43
+ /** 현재 호버된 데이터 */
44
+
19
45
  var currentHoveredDataRef = React.useRef(null);
20
- var draggingRef = React.useRef(false);
46
+ /** 드래그/줌 여부 (마우스 이동 이벤트 무시용) */
47
+
48
+ var draggingRef = React.useRef(false); // === 컴포넌트 관리 함수들 ===
49
+
21
50
  /**
22
- * 컴포넌트 등록 (zIndex 내림차순 정렬)
23
- * 높은 zIndex가 먼저 처리됨
51
+ * 컴포넌트 인스턴스 등록
52
+ *
53
+ * zIndex 내림차순으로 정렬하여 높은 우선순위의 컴포넌트가 먼저 이벤트를 처리하도록 합니다.
54
+ *
55
+ * @param instance - 등록할 컴포넌트 인스턴스
24
56
  */
25
57
 
26
58
  var registerComponent = React.useCallback(function (instance) {
@@ -30,7 +62,12 @@ var KonvaMarkerProvider = function (_a) {
30
62
  });
31
63
  }, []);
32
64
  /**
33
- * 컴포넌트 등록 해제
65
+ * 컴포넌트 인스턴스 등록 해제
66
+ *
67
+ * 컴포넌트가 언마운트될 때 호출되어 Context에서 제거합니다.
68
+ * 현재 호버 중인 컴포넌트라면 호버 상태도 초기화합니다.
69
+ *
70
+ * @param instance - 등록 해제할 컴포넌트 인스턴스
34
71
  */
35
72
 
36
73
  var unregisterComponent = React.useCallback(function (instance) {
@@ -43,9 +80,15 @@ var KonvaMarkerProvider = function (_a) {
43
80
  componentsRef.current = componentsRef.current.filter(function (c) {
44
81
  return c !== instance;
45
82
  });
46
- }, []);
83
+ }, []); // === 전역 이벤트 핸들러들 ===
84
+
47
85
  /**
48
- * 전역 클릭 핸들러 (zIndex 우선순위)
86
+ * 전역 클릭 이벤트 핸들러
87
+ *
88
+ * zIndex 우선순위에 따라 등록된 컴포넌트들을 순회하며 클릭된 데이터를 찾습니다.
89
+ * 첫 번째로 히트된 컴포넌트의 이벤트만 처리합니다.
90
+ *
91
+ * @param event - 지도 클릭 이벤트 파라미터
49
92
  */
50
93
 
51
94
  var handleGlobalClick = React.useCallback(function (event) {
@@ -55,7 +98,7 @@ var KonvaMarkerProvider = function (_a) {
55
98
  var clickedOffset = controller.positionToOffset(event.param.position); // zIndex 순서대로 순회 (높은 것부터)
56
99
 
57
100
  for (var _i = 0, _b = componentsRef.current; _i < _b.length; _i++) {
58
- var component = _b[_i]; // 🚫 상호작용이 비활성화된 컴포넌트는 스킵
101
+ var component = _b[_i]; // 상호작용이 비활성화된 컴포넌트는 스킵
59
102
 
60
103
  if (component.isInteractionDisabled()) continue;
61
104
  var data = component.findData(clickedOffset);
@@ -72,7 +115,12 @@ var KonvaMarkerProvider = function (_a) {
72
115
  }
73
116
  }, [controller]);
74
117
  /**
75
- * 전역 마우스 이동 핸들러 (zIndex 우선순위)
118
+ * 전역 마우스 이동 이벤트 핸들러
119
+ *
120
+ * zIndex 우선순위에 따라 호버된 데이터를 찾고, 호버 상태가 변경되면
121
+ * 이전 호버를 해제하고 새로운 호버를 설정합니다.
122
+ *
123
+ * @param event - 지도 마우스 이동 이벤트 파라미터
76
124
  */
77
125
 
78
126
  var handleGlobalMouseMove = React.useCallback(function (event) {
@@ -85,7 +133,7 @@ var KonvaMarkerProvider = function (_a) {
85
133
  var newHoveredData = null;
86
134
 
87
135
  for (var _i = 0, _b = componentsRef.current; _i < _b.length; _i++) {
88
- var component = _b[_i]; // 🚫 상호작용이 비활성화된 컴포넌트는 스킵
136
+ var component = _b[_i]; // 상호작용이 비활성화된 컴포넌트는 스킵
89
137
 
90
138
  if (component.isInteractionDisabled()) continue;
91
139
  var data = component.findData(mouseOffset);
@@ -122,19 +170,24 @@ var KonvaMarkerProvider = function (_a) {
122
170
  }
123
171
  }, [controller]);
124
172
  /**
125
- * 줌/드래그 시작 (마우스 이동 이벤트 무시)
173
+ * 줌/드래그 시작 이벤트 핸들러
174
+ *
175
+ * 지도가 줌이나 드래그를 시작할 때 마우스 이동 이벤트를 무시하도록 설정합니다.
176
+ * 이는 성능 최적화와 불필요한 호버 이벤트 방지를 위한 것입니다.
126
177
  */
127
178
 
128
179
  var handleZoomStart = React.useCallback(function () {
129
180
  draggingRef.current = true;
130
181
  }, []);
131
182
  /**
132
- * 지도 idle (마우스 이동 이벤트 재개)
183
+ * 지도 idle 이벤트 핸들러
184
+ *
185
+ * 지도가 idle 상태가 되면 마우스 이동 이벤트를 다시 활성화합니다.
133
186
  */
134
187
 
135
188
  var handleIdle = React.useCallback(function () {
136
189
  draggingRef.current = false;
137
- }, []); // 이벤트 리스너 등록
190
+ }, []); // === 이벤트 리스너 등록 ===
138
191
 
139
192
  React.useEffect(function () {
140
193
  controller.addEventListener('CLICK', handleGlobalClick);
@@ -147,7 +200,7 @@ var KonvaMarkerProvider = function (_a) {
147
200
  controller.removeEventListener('ZOOMSTART', handleZoomStart);
148
201
  controller.removeEventListener('IDLE', handleIdle);
149
202
  };
150
- }, [controller, handleGlobalClick, handleGlobalMouseMove, handleZoomStart, handleIdle]); // Context value 메모이제이션
203
+ }, [controller, handleGlobalClick, handleGlobalMouseMove, handleZoomStart, handleIdle]); // === Context value 메모이제이션 ===
151
204
 
152
205
  var contextValue = React.useMemo(function () {
153
206
  return {
@@ -159,6 +212,20 @@ var KonvaMarkerProvider = function (_a) {
159
212
  value: contextValue
160
213
  }, children);
161
214
  };
215
+ /**
216
+ * KonvaMarkerContext를 사용하기 위한 Hook
217
+ *
218
+ * @returns Context 값 또는 null (Provider 외부에서 사용 시)
219
+ *
220
+ * @example
221
+ * ```tsx
222
+ * const context = useKonvaMarkerContext();
223
+ * if (context) {
224
+ * context.registerComponent(instance);
225
+ * }
226
+ * ```
227
+ */
228
+
162
229
  var useKonvaMarkerContext = function () {
163
230
  var context = React.useContext(KonvaMarkerContext);
164
231
  return context;
@@ -1,4 +1,15 @@
1
+ /**
2
+ * @fileoverview WoongCanvasLayer의 공유 유틸리티 모듈
3
+ *
4
+ * 이 파일은 WoongCanvasLayer에서 사용하는 모든 공통 타입, 유틸리티 함수,
5
+ * 성능 최적화 클래스, Context Provider를 외부로 노출합니다.
6
+ *
7
+ * @version 2.2.1
8
+ * @since 2.0.0
9
+ * @author 박건웅
10
+ */
1
11
  export * from './types';
2
12
  export * from './utils';
3
13
  export * from './context';
4
14
  export * from './performance';
15
+ export * from './renderer';
@@ -1,3 +1,18 @@
1
+ /**
2
+ * @fileoverview WoongCanvasLayer 성능 최적화를 위한 상수 및 클래스
3
+ *
4
+ * 이 파일은 30,000개 이상의 마커/폴리곤을 60fps로 렌더링하기 위한
5
+ * 성능 최적화 상수와 최적화된 자료구조들을 제공합니다.
6
+ *
7
+ * ## 주요 구성 요소
8
+ * - **성능 최적화 상수**: 그리드 셀 크기, 캐시 크기, 컬링 여유 공간
9
+ * - **LRUCache**: 좌표 변환 결과 캐싱을 위한 LRU 캐시 구현
10
+ * - **SpatialHashGrid**: O(1) 수준의 빠른 Hit Test를 위한 공간 해시 그리드
11
+ *
12
+ * @version 2.2.1
13
+ * @since 2.0.0
14
+ * @author 박건웅
15
+ */
1
16
  /**
2
17
  * 공간 인덱스 그리드 셀 크기 (px)
3
18
  *
@@ -40,12 +55,29 @@ export declare const DEFAULT_CULLING_MARGIN = 100;
40
55
  export declare const DEFAULT_MAX_CACHE_SIZE = 30000;
41
56
  /**
42
57
  * LRU (Least Recently Used) Cache
43
- * 메모리 제한을 위한 캐시 구현 (최적화 버전)
44
58
  *
45
- * 개선 사항:
46
- * 1. get() 성능 향상: 접근 빈도 추적 없이 단순 조회만 수행 (delete+set 제거)
47
- * 2. set() 버그 수정: 기존 키 업데이트 시 maxSize 체크 로직 개선
48
- * 3. 메모리 효율: 단순 FIFO 캐시로 동작하여 오버헤드 최소화
59
+ * 메모리 제한을 위한 캐시 구현으로, 좌표 변환 결과를 캐싱하여
60
+ * 성능을 최적화합니다. WoongCanvasLayer의 특성에 맞게 최적화되었습니다.
61
+ *
62
+ * ## 주요 특징
63
+ * - **빠른 조회**: O(1) 해시 조회로 성능 최적화
64
+ * - **메모리 제한**: 최대 크기 초과 시 자동 eviction
65
+ * - **FIFO 방식**: 삽입 순서 기반 eviction (접근 빈도 추적 없음)
66
+ *
67
+ * ## 개선 사항
68
+ * 1. **get() 성능 향상**: 접근 빈도 추적 없이 단순 조회만 수행
69
+ * 2. **set() 버그 수정**: 기존 키 업데이트 시 maxSize 체크 로직 개선
70
+ * 3. **메모리 효율**: 단순 FIFO 캐시로 동작하여 오버헤드 최소화
71
+ *
72
+ * @template K 캐시 키 타입
73
+ * @template V 캐시 값 타입
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const cache = new LRUCache<string, Offset>(1000);
78
+ * cache.set('marker-1', { x: 100, y: 200 });
79
+ * const offset = cache.get('marker-1'); // { x: 100, y: 200 }
80
+ * ```
49
81
  */
50
82
  export declare class LRUCache<K, V> {
51
83
  private cache;
@@ -81,16 +113,33 @@ export declare class LRUCache<K, V> {
81
113
  }
82
114
  /**
83
115
  * Spatial Hash Grid (공간 해시 그리드)
84
- * 공간 인덱싱을 위한 그리드 기반 자료구조 (개선 버전)
85
116
  *
86
- * 개선 사항:
87
- * 1. 중복 삽입 방지: 같은 항목을 여러 insert 해도 안전
88
- * 2. 메모리 누수 방지: 기존 항목 자동 제거
89
- * 3. 성능 최적화: 불필요한 배열 생성 최소화
117
+ * 공간 인덱싱을 위한 그리드 기반 자료구조로, 2D 공간을 격자로 나누어
118
+ * 특정 영역에 있는 객체들을 빠르게 찾을 있게 해줍니다.
119
+ *
120
+ * ## 주요 특징
121
+ * - **O(1) 조회**: 클릭 위치 주변의 객체들만 체크하여 성능 최적화
122
+ * - **메모리 효율**: 격자 기반으로 필요한 영역만 인덱싱
123
+ * - **중복 방지**: 같은 항목을 여러 번 삽입해도 안전
124
+ *
125
+ * ## 성능 비교
126
+ * - **일반 검색**: 30,000개 항목 전체 체크 → O(n)
127
+ * - **Spatial Hash**: 클릭 위치 주변 ~10개만 체크 → O(1) + O(10)
128
+ * - **성능 향상**: 약 3,000배 빠름! 🚀
129
+ *
130
+ * ## 개선 사항
131
+ * 1. **중복 삽입 방지**: 같은 항목을 여러 번 insert 해도 안전
132
+ * 2. **메모리 누수 방지**: 기존 항목 자동 제거
133
+ * 3. **성능 최적화**: 불필요한 배열 생성 최소화
134
+ *
135
+ * @template T 그리드에 저장할 객체 타입
90
136
  *
91
- * 사용 사례:
92
- * - 빠른 Hit Test (마우스 클릭 시 어떤 마커/폴리곤인지 찾기)
93
- * - 30,000개 항목 클릭 위치 주변 ~10개만 체크 (3,000배 빠름)
137
+ * @example
138
+ * ```typescript
139
+ * const grid = new SpatialHashGrid<Marker>(50);
140
+ * grid.insert(marker, { x: 100, y: 200, width: 30, height: 40 });
141
+ * const nearby = grid.query(105, 205, 10); // (105, 205) 주변 10px 반경
142
+ * ```
94
143
  */
95
144
  export declare class SpatialHashGrid<T> {
96
145
  private cellSize;