@mint-ui/map 1.2.0-test.10 → 1.2.0-test.12

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.
Files changed (23) hide show
  1. package/dist/components/mint-map/core/MintMapController.d.ts +1 -0
  2. package/dist/components/mint-map/core/MintMapCore.js +1 -2
  3. package/dist/components/mint-map/core/advanced/woongCanvas/WoongCanvasLayer.d.ts +162 -0
  4. package/dist/components/mint-map/core/advanced/woongCanvas/{WoongKonvaMarker.js → WoongCanvasLayer.js} +136 -82
  5. package/dist/components/mint-map/core/advanced/woongCanvas/index.d.ts +2 -2
  6. package/dist/components/mint-map/core/advanced/woongCanvas/shared/renderer.d.ts +59 -0
  7. package/dist/components/mint-map/core/advanced/woongCanvas/shared/renderer.js +226 -0
  8. package/dist/components/mint-map/core/advanced/woongCanvas/shared/types.d.ts +95 -1
  9. package/dist/components/mint-map/core/advanced/woongCanvas/shared/utils.d.ts +17 -0
  10. package/dist/components/mint-map/core/advanced/woongCanvas/shared/utils.js +42 -0
  11. package/dist/components/mint-map/core/wrapper/MapMarkerWrapper.js +22 -1
  12. package/dist/components/mint-map/google/GoogleMintMapController.d.ts +1 -0
  13. package/dist/components/mint-map/google/GoogleMintMapController.js +6 -1
  14. package/dist/components/mint-map/kakao/KakaoMintMapController.d.ts +1 -0
  15. package/dist/components/mint-map/kakao/KakaoMintMapController.js +6 -1
  16. package/dist/components/mint-map/naver/NaverMintMapController.d.ts +3 -0
  17. package/dist/components/mint-map/naver/NaverMintMapController.js +39 -4
  18. package/dist/index.es.js +458 -83
  19. package/dist/index.js +4 -2
  20. package/dist/index.umd.js +460 -83
  21. package/package.json +1 -1
  22. package/dist/components/mint-map/core/advanced/woongCanvas/ClusterMarker.d.ts +0 -11
  23. package/dist/components/mint-map/core/advanced/woongCanvas/WoongKonvaMarker.d.ts +0 -54
@@ -24,6 +24,7 @@ export declare abstract class MintMapController {
24
24
  abstract updateMarker(marker: Marker, options: MarkerOptions): void;
25
25
  abstract clearDrawable(drawable: Drawable): boolean;
26
26
  abstract markerToTheTop(marker: Marker): void;
27
+ abstract restoreMarkerZIndex(marker: Marker): void;
27
28
  abstract isMapDragged(): boolean;
28
29
  abstract setMapDragged(value: boolean): void;
29
30
  abstract setMarkerZIndex(marker: Marker, zIndex: number): void;
@@ -9,8 +9,7 @@ var MapTypes = require('../types/MapTypes.js');
9
9
  var MintMapProvider = require('./provider/MintMapProvider.js');
10
10
  var MintMapCore_module = require('./MintMapCore.module.scss.js');
11
11
  require('./advanced/woongCanvas/shared/types.js');
12
- require('../types/MapDrawables.js');
13
- require('../types/MapEventTypes.js');
12
+ require('./advanced/woongCanvas/shared/utils.js');
14
13
  var context = require('./advanced/woongCanvas/shared/context.js');
15
14
  require('./advanced/woongCanvas/shared/performance.js');
16
15
 
@@ -0,0 +1,162 @@
1
+ import React from "react";
2
+ import { MarkerOptions } from "../../../types";
3
+ import { KonvaCanvasMarkerData, CanvasDataType, CustomRenderBase, CustomRenderAnimation, CustomRenderEvent } from "./shared";
4
+ export { KonvaMarkerProvider, LRUCache, SpatialHashGrid, CanvasDataType } from "./shared";
5
+ export type { KonvaCanvasMarkerOption, Paths, KonvaCanvasMarkerData, CustomRenderBase, CustomRenderAnimation, CustomRenderEvent, RenderUtils, RenderBaseParams, RenderAnimationParams, RenderEventParams } from "./shared";
6
+ /**
7
+ * 공통 Props (MARKER와 POLYGON 모두 사용)
8
+ */
9
+ interface WoongCanvasLayerBaseProps<T> extends Pick<MarkerOptions, 'zIndex' | 'anchor' | 'visible'> {
10
+ /** 렌더링할 데이터 배열 (마커 또는 폴리곤) */
11
+ data: KonvaCanvasMarkerData<T>[];
12
+ /** 마커 클릭 시 호출되는 콜백 (선택) */
13
+ onClick?: (payload: KonvaCanvasMarkerData<T>, selectedIds: Set<string>) => void;
14
+ /** 마커에 마우스 오버 시 호출되는 콜백 (선택) */
15
+ onMouseOver?: (payload: KonvaCanvasMarkerData<T>) => void;
16
+ /** 마커에서 마우스 아웃 시 호출되는 콜백 (선택) */
17
+ onMouseOut?: (payload: KonvaCanvasMarkerData<T>) => void;
18
+ /** 다중 선택 활성화 여부 (기본: false) */
19
+ enableMultiSelect?: boolean;
20
+ /** hover 시 마커를 최상단으로 표시 (기본: false) */
21
+ topOnHover?: boolean;
22
+ /** 뷰포트 컬링 활성화 여부 (기본: true) */
23
+ enableViewportCulling?: boolean;
24
+ /** 뷰포트 컬링 여유 공간 (기본: 100px) */
25
+ cullingMargin?: number;
26
+ /** LRU 캐시 최대 크기 (기본: 10000) */
27
+ maxCacheSize?: number;
28
+ /** 외부에서 제어하는 선택된 항목 배열 (선택) */
29
+ selectedItems?: KonvaCanvasMarkerData<T>[];
30
+ /** 외부에서 전달된 단일 선택 아이템 (특별한 효과용) */
31
+ selectedItem?: KonvaCanvasMarkerData<T> | null;
32
+ /** 상호작용 비활성화 (hover, click 등 모든 이벤트 차단) */
33
+ disableInteraction?: boolean;
34
+ }
35
+ /**
36
+ * MARKER 타입 Props - 커스텀 렌더링 필수
37
+ */
38
+ interface WoongCanvasLayerPropsForMarker<T> extends WoongCanvasLayerBaseProps<T> {
39
+ /** 데이터 타입 */
40
+ dataType: CanvasDataType.MARKER;
41
+ /** Base Layer 렌더링 함수 (필수) */
42
+ renderBase: CustomRenderBase<T>;
43
+ /** Animation Layer 렌더링 함수 (선택, 애니메이션용) */
44
+ renderAnimation?: CustomRenderAnimation<T>;
45
+ /** Event Layer 렌더링 함수 (선택) */
46
+ renderEvent?: CustomRenderEvent<T>;
47
+ }
48
+ /**
49
+ * POLYGON 타입 Props - 스타일 속성으로 내부 처리
50
+ */
51
+ interface WoongCanvasLayerPropsForPolygon<T> extends WoongCanvasLayerBaseProps<T> {
52
+ /** 데이터 타입 */
53
+ dataType: CanvasDataType.POLYGON;
54
+ /** 기본 폴리곤 채우기 색상 (필수) */
55
+ baseFillColor: string;
56
+ /** 기본 폴리곤 테두리 색상 (필수) */
57
+ baseStrokeColor: string;
58
+ /** 기본 폴리곤 테두리 두께 (필수) */
59
+ baseLineWidth: number;
60
+ /** 선택된 폴리곤 채우기 색상 (필수) */
61
+ selectedFillColor: string;
62
+ /** 선택된 폴리곤 테두리 색상 (필수) */
63
+ selectedStrokeColor: string;
64
+ /** 선택된 폴리곤 테두리 두께 (필수) */
65
+ selectedLineWidth: number;
66
+ /** 마지막 선택된 폴리곤 채우기 색상 (선택, 기본값: selectedFillColor) */
67
+ activeFillColor?: string;
68
+ /** 마지막 선택된 폴리곤 테두리 색상 (선택, 기본값: selectedStrokeColor) */
69
+ activeStrokeColor?: string;
70
+ /** 마지막 선택된 폴리곤 테두리 두께 (선택, 기본값: selectedLineWidth) */
71
+ activeLineWidth?: number;
72
+ /** Hover 시 폴리곤 채우기 색상 (선택, 기본값: selectedFillColor) */
73
+ hoveredFillColor?: string;
74
+ /** Hover 시 폴리곤 테두리 색상 (선택, 기본값: selectedStrokeColor) */
75
+ hoveredStrokeColor?: string;
76
+ /** Hover 시 폴리곤 테두리 두께 (선택, 기본값: selectedLineWidth) */
77
+ hoveredLineWidth?: number;
78
+ }
79
+ /**
80
+ * 최종 Props 타입 - Discriminated Union
81
+ */
82
+ export declare type WoongCanvasLayerProps<T> = WoongCanvasLayerPropsForMarker<T> | WoongCanvasLayerPropsForPolygon<T>;
83
+ /**
84
+ * 🚀 WoongCanvasLayer - Konva 기반 초고성능 마커/폴리곤 렌더링 컴포넌트
85
+ *
86
+ * ## 📌 주요 특징
87
+ * - **30,000개 이상의 폴리곤/마커를 60fps로 렌더링**
88
+ * - **Multi-Layer 아키텍처**: Base/Animation/Event 레이어 분리
89
+ * - **Spatial Hash Grid**: O(1) 수준의 빠른 Hit Test
90
+ * - **LRU 캐시**: 좌표 변환 결과 캐싱으로 성능 최적화
91
+ * - **Viewport Culling**: 화면에 보이는 영역만 렌더링
92
+ * - **Discriminated Union Props**: 타입 안전한 MARKER/POLYGON 모드
93
+ *
94
+ * ## 🎯 사용 방법
95
+ *
96
+ * ### 1️⃣ POLYGON 모드 (자동 렌더링)
97
+ * ```tsx
98
+ * <WoongCanvasLayer
99
+ * dataType={CanvasDataType.POLYGON}
100
+ * data={polygons}
101
+ * baseFillColor="rgba(255, 100, 100, 0.5)"
102
+ * baseStrokeColor="rgba(200, 50, 50, 0.8)"
103
+ * baseLineWidth={2}
104
+ * selectedFillColor="rgba(255, 193, 7, 0.7)"
105
+ * selectedStrokeColor="rgba(255, 152, 0, 1)"
106
+ * selectedLineWidth={4}
107
+ * hoveredFillColor="rgba(100, 150, 255, 0.8)" // optional
108
+ * hoveredStrokeColor="rgba(0, 100, 200, 1)" // optional
109
+ * hoveredLineWidth={3} // optional
110
+ * enableMultiSelect={true}
111
+ * onClick={handleClick}
112
+ * />
113
+ * ```
114
+ *
115
+ * ### 2️⃣ MARKER 모드 (커스텀 렌더링)
116
+ * ```tsx
117
+ * <WoongCanvasLayer
118
+ * dataType={CanvasDataType.MARKER}
119
+ * data={markers}
120
+ * renderBase={renderMarkerBase} // required
121
+ * renderAnimation={renderMarkerAnimation} // optional
122
+ * renderEvent={renderMarkerEvent} // optional
123
+ * topOnHover={true}
124
+ * onClick={handleClick}
125
+ * />
126
+ * ```
127
+ *
128
+ * ## 📊 데이터 형식
129
+ * ```typescript
130
+ * const data: KonvaCanvasMarkerData<T>[] = [
131
+ * {
132
+ * id: 'unique-id',
133
+ * position: new Position(lat, lng),
134
+ * // POLYGON: paths 필수
135
+ * paths: [[[lat, lng], [lat, lng], ...]],
136
+ * // MARKER: boxWidth/boxHeight 권장 (Hit Test 정확도)
137
+ * boxWidth: 60,
138
+ * boxHeight: 75,
139
+ * // 커스텀 데이터
140
+ * ...customData
141
+ * }
142
+ * ];
143
+ * ```
144
+ *
145
+ * ## ⚡ 성능 최적화 팁
146
+ * 1. **동적 boxWidth 계산**: `measureText()`로 실제 너비 계산 후 전달
147
+ * 2. **enableViewportCulling**: 대량 데이터 시 필수 (기본 true)
148
+ * 3. **selectedItems 외부 관리**: 상태를 외부에서 관리하여 리렌더링 최소화
149
+ * 4. **React.memo 최적화**: 컴포넌트가 자동으로 불필요한 리렌더링 방지
150
+ *
151
+ * @template T 마커/폴리곤 데이터의 추가 속성 타입
152
+ *
153
+ * @example
154
+ * // 동적 boxWidth 계산 예시
155
+ * const tempCtx = document.createElement('canvas').getContext('2d');
156
+ * tempCtx.font = 'bold 15px Arial';
157
+ * const boxWidth = Math.max(60, tempCtx.measureText(text).width + 20);
158
+ *
159
+ * @see {@link https://github.com/your-repo/docs/WoongCanvasLayer.md} 전체 문서
160
+ */
161
+ declare const WoongCanvasLayer: <T>(props: WoongCanvasLayerProps<T>) => React.ReactPortal;
162
+ export default WoongCanvasLayer;
@@ -14,6 +14,7 @@ var types = require('./shared/types.js');
14
14
  var utils = require('./shared/utils.js');
15
15
  var context = require('./shared/context.js');
16
16
  var performance = require('./shared/performance.js');
17
+ var renderer = require('./shared/renderer.js');
17
18
 
18
19
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
19
20
 
@@ -23,42 +24,27 @@ var Konva__default = /*#__PURE__*/_interopDefaultLegacy(Konva);
23
24
  // 메인 컴포넌트
24
25
  // ============================================================================
25
26
 
26
- /**
27
- * Konva 기반 고성능 마커/폴리곤 렌더링 컴포넌트
28
- *
29
- * 특징:
30
- * - Base/Event 레이어 분리로 성능 최적화
31
- * - LRU 캐시로 좌표 변환 결과 캐싱
32
- * - Spatial Hash Grid로 빠른 Hit Test
33
- * - Viewport Culling으로 보이는 영역만 렌더링
34
- *
35
- * @template T 마커 데이터의 추가 속성 타입
36
- */
37
-
38
- var WoongKonvaMarkerComponent = function (_a) {
39
- var markers = _a.markers,
40
- dataType = _a.dataType,
41
- onClick = _a.onClick,
42
- onMouseOver = _a.onMouseOver,
43
- onMouseOut = _a.onMouseOut,
44
- renderBase = _a.renderBase,
45
- renderAnimation = _a.renderAnimation,
46
- renderEvent = _a.renderEvent,
47
- _b = _a.enableMultiSelect,
48
- enableMultiSelect = _b === void 0 ? false : _b,
49
- _c = _a.topOnHover,
50
- topOnHover = _c === void 0 ? false : _c,
51
- _d = _a.enableViewportCulling,
52
- enableViewportCulling = _d === void 0 ? true : _d,
53
- _e = _a.cullingMargin,
54
- cullingMargin = _e === void 0 ? performance.DEFAULT_CULLING_MARGIN : _e,
55
- _f = _a.maxCacheSize,
56
- maxCacheSize = _f === void 0 ? performance.DEFAULT_MAX_CACHE_SIZE : _f,
57
- externalSelectedItems = _a.selectedItems,
58
- externalSelectedItem = _a.selectedItem,
59
- _g = _a.disableInteraction,
60
- disableInteraction = _g === void 0 ? false : _g,
61
- options = tslib.__rest(_a, ["markers", "dataType", "onClick", "onMouseOver", "onMouseOut", "renderBase", "renderAnimation", "renderEvent", "enableMultiSelect", "topOnHover", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction"]); // --------------------------------------------------------------------------
27
+ var WoongCanvasLayerComponent = function (props) {
28
+ var data = props.data,
29
+ dataType = props.dataType,
30
+ onClick = props.onClick,
31
+ onMouseOver = props.onMouseOver,
32
+ onMouseOut = props.onMouseOut,
33
+ _a = props.enableMultiSelect,
34
+ enableMultiSelect = _a === void 0 ? false : _a,
35
+ _b = props.topOnHover,
36
+ topOnHover = _b === void 0 ? false : _b,
37
+ _c = props.enableViewportCulling,
38
+ enableViewportCulling = _c === void 0 ? true : _c,
39
+ _d = props.cullingMargin,
40
+ cullingMargin = _d === void 0 ? performance.DEFAULT_CULLING_MARGIN : _d,
41
+ _e = props.maxCacheSize,
42
+ maxCacheSize = _e === void 0 ? performance.DEFAULT_MAX_CACHE_SIZE : _e,
43
+ externalSelectedItems = props.selectedItems,
44
+ externalSelectedItem = props.selectedItem,
45
+ _f = props.disableInteraction,
46
+ disableInteraction = _f === void 0 ? false : _f,
47
+ options = tslib.__rest(props, ["data", "dataType", "onClick", "onMouseOver", "onMouseOut", "enableMultiSelect", "topOnHover", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction"]); // --------------------------------------------------------------------------
62
48
  // Hooks & Context
63
49
  // --------------------------------------------------------------------------
64
50
 
@@ -83,9 +69,9 @@ var WoongKonvaMarkerComponent = function (_a) {
83
69
  // Data Refs - 선택 및 Hover 상태 관리
84
70
  // --------------------------------------------------------------------------
85
71
 
86
- /** markers prop을 ref로 추적 (stale closure 방지, useEffect에서 동기화) */
72
+ /** data prop을 ref로 추적 (stale closure 방지, useEffect에서 동기화) */
87
73
 
88
- var markersRef = React.useRef(markers); // --------------------------------------------------------------------------
74
+ var markersRef = React.useRef(data); // --------------------------------------------------------------------------
89
75
  // State Refs - 선택 및 Hover 상태 관리
90
76
  // --------------------------------------------------------------------------
91
77
 
@@ -257,6 +243,7 @@ var WoongKonvaMarkerComponent = function (_a) {
257
243
  };
258
244
  /**
259
245
  * 마커 좌표 변환 결과를 캐시하고 반환
246
+ *
260
247
  * @param markerData 마커 데이터
261
248
  * @returns 변환된 좌표 또는 null
262
249
  */
@@ -336,7 +323,7 @@ var WoongKonvaMarkerComponent = function (_a) {
336
323
  }
337
324
  }
338
325
  }; // --------------------------------------------------------------------------
339
- // 렌더링 함수
326
+ // 렌더링 함수 결정 (dataType에 따라)
340
327
  // --------------------------------------------------------------------------
341
328
 
342
329
  /**
@@ -351,6 +338,18 @@ var WoongKonvaMarkerComponent = function (_a) {
351
338
  /** Base Layer에서 사용할 빈 Set (재사용) */
352
339
 
353
340
  React.useRef(new Set());
341
+ /**
342
+ * 실제 사용할 렌더링 함수 결정
343
+ * - MARKER: 외부에서 전달받은 renderBase 사용 (필수)
344
+ * - POLYGON: renderer.ts의 팩토리 함수로 생성 (props 기반)
345
+ */
346
+
347
+ var renderBase = dataType === types.CanvasDataType.MARKER ? props.renderBase : renderer.renderPolygonBase(props.baseFillColor, props.baseStrokeColor, props.baseLineWidth);
348
+ var renderAnimation = dataType === types.CanvasDataType.MARKER ? props.renderAnimation : undefined;
349
+ var renderEvent = dataType === types.CanvasDataType.MARKER ? props.renderEvent : function () {
350
+ var polygonProps = props;
351
+ return renderer.renderPolygonEvent(polygonProps.selectedFillColor, polygonProps.selectedStrokeColor, polygonProps.selectedLineWidth, polygonProps.activeFillColor, polygonProps.activeStrokeColor, polygonProps.activeLineWidth, polygonProps.hoveredFillColor, polygonProps.hoveredStrokeColor, polygonProps.hoveredLineWidth);
352
+ }();
354
353
  /**
355
354
  * Base 레이어 렌더링 (뷰포트 컬링 적용, 선택된 마커 제외)
356
355
  *
@@ -715,11 +714,11 @@ var WoongKonvaMarkerComponent = function (_a) {
715
714
 
716
715
  try {
717
716
  var clickedOffset = controller.positionToOffset(event.param.position);
718
- var data = findData(clickedOffset);
717
+ var data_1 = findData(clickedOffset);
719
718
 
720
- if (data) {
721
- handleLocalClick(data);
722
- onClick(data, selectedIdsRef.current);
719
+ if (data_1) {
720
+ handleLocalClick(data_1);
721
+ onClick(data_1, selectedIdsRef.current);
723
722
  }
724
723
  } catch (error) {
725
724
  console.error('[WoongKonvaMarker] handleClick error:', error);
@@ -996,13 +995,13 @@ var WoongKonvaMarkerComponent = function (_a) {
996
995
 
997
996
  doRenderEvent();
998
997
  }, [externalSelectedItem]); // --------------------------------------------------------------------------
999
- // Lifecycle: 마커 데이터 변경 시 렌더링
998
+ // Lifecycle: 데이터 변경 시 렌더링
1000
999
  // --------------------------------------------------------------------------
1001
1000
 
1002
1001
  React.useEffect(function () {
1003
1002
  if (!stageRef.current) return; // markersRef 동기화
1004
1003
 
1005
- markersRef.current = markers; // 데이터 변경 시 즉시 transform 제거 및 캐시 정리 (겹침 방지)
1004
+ markersRef.current = data; // 데이터 변경 시 즉시 transform 제거 및 캐시 정리 (겹침 방지)
1006
1005
 
1007
1006
  if (containerRef.current) {
1008
1007
  containerRef.current.style.transform = '';
@@ -1019,18 +1018,18 @@ var WoongKonvaMarkerComponent = function (_a) {
1019
1018
  /**
1020
1019
  * 선택 상태 동기화 (최적화 버전)
1021
1020
  *
1022
- * markers가 변경되면 selectedItemsMapRef도 업데이트 필요
1021
+ * data가 변경되면 selectedItemsMapRef도 업데이트 필요
1023
1022
  * (참조가 바뀌므로 기존 Map의 데이터는 stale 상태)
1024
1023
  *
1025
- * 🔥 중요: 화면 밖 마커도 선택 상태 유지!
1026
- * - 현재 markers에 있으면 최신 데이터로 업데이트
1024
+ * 🔥 중요: 화면 밖 데이터도 선택 상태 유지!
1025
+ * - 현재 data에 있으면 최신 데이터로 업데이트
1027
1026
  * - 없으면 기존 selectedItemsMapRef의 데이터 유지
1028
1027
  *
1029
- * 최적화: markers를 Map으로 먼저 변환하여 find() 순회 제거
1030
- * - O(전체 마커 수 + 선택된 개수) - 매우 효율적
1028
+ * 최적화: data를 Map으로 먼저 변환하여 find() 순회 제거
1029
+ * - O(전체 데이터 수 + 선택된 개수) - 매우 효율적
1031
1030
  */
1032
1031
 
1033
- var markersMap = new Map(markers.map(function (m) {
1032
+ var markersMap = new Map(data.map(function (m) {
1034
1033
  return [m.id, m];
1035
1034
  }));
1036
1035
  var newSelectedItemsMap = new Map();
@@ -1053,40 +1052,107 @@ var WoongKonvaMarkerComponent = function (_a) {
1053
1052
  selectedItemsMapRef.current = newSelectedItemsMap; // 즉시 렌더링
1054
1053
 
1055
1054
  renderAllImmediate();
1056
- }, [markers]);
1055
+ }, [data]);
1057
1056
  return reactDom.createPortal(React__default["default"].createElement("div", {
1058
1057
  ref: containerRef,
1059
- style: tslib.__assign({
1058
+ style: {
1060
1059
  position: 'absolute',
1061
1060
  width: '100%',
1062
1061
  height: '100%'
1063
- }, disableInteraction && {
1064
- pointerEvents: 'none'
1065
- })
1062
+ }
1066
1063
  }), divElement);
1067
1064
  };
1068
1065
  /**
1069
- * 🔥 React.memo 최적화: 마커 배열과 selectedItems 변경 체크
1066
+ * 🚀 WoongCanvasLayer - Konva 기반 초고성능 마커/폴리곤 렌더링 컴포넌트
1067
+ *
1068
+ * ## 📌 주요 특징
1069
+ * - **30,000개 이상의 폴리곤/마커를 60fps로 렌더링**
1070
+ * - **Multi-Layer 아키텍처**: Base/Animation/Event 레이어 분리
1071
+ * - **Spatial Hash Grid**: O(1) 수준의 빠른 Hit Test
1072
+ * - **LRU 캐시**: 좌표 변환 결과 캐싱으로 성능 최적화
1073
+ * - **Viewport Culling**: 화면에 보이는 영역만 렌더링
1074
+ * - **Discriminated Union Props**: 타입 안전한 MARKER/POLYGON 모드
1075
+ *
1076
+ * ## 🎯 사용 방법
1077
+ *
1078
+ * ### 1️⃣ POLYGON 모드 (자동 렌더링)
1079
+ * ```tsx
1080
+ * <WoongCanvasLayer
1081
+ * dataType={CanvasDataType.POLYGON}
1082
+ * data={polygons}
1083
+ * baseFillColor="rgba(255, 100, 100, 0.5)"
1084
+ * baseStrokeColor="rgba(200, 50, 50, 0.8)"
1085
+ * baseLineWidth={2}
1086
+ * selectedFillColor="rgba(255, 193, 7, 0.7)"
1087
+ * selectedStrokeColor="rgba(255, 152, 0, 1)"
1088
+ * selectedLineWidth={4}
1089
+ * hoveredFillColor="rgba(100, 150, 255, 0.8)" // optional
1090
+ * hoveredStrokeColor="rgba(0, 100, 200, 1)" // optional
1091
+ * hoveredLineWidth={3} // optional
1092
+ * enableMultiSelect={true}
1093
+ * onClick={handleClick}
1094
+ * />
1095
+ * ```
1070
1096
  *
1071
- * 비교 전략:
1072
- * 1. markers 배열 비교
1073
- * 2. selectedItems 배열 비교 (외부 제어)
1097
+ * ### 2️⃣ MARKER 모드 (커스텀 렌더링)
1098
+ * ```tsx
1099
+ * <WoongCanvasLayer
1100
+ * dataType={CanvasDataType.MARKER}
1101
+ * data={markers}
1102
+ * renderBase={renderMarkerBase} // required
1103
+ * renderAnimation={renderMarkerAnimation} // optional
1104
+ * renderEvent={renderMarkerEvent} // optional
1105
+ * topOnHover={true}
1106
+ * onClick={handleClick}
1107
+ * />
1108
+ * ```
1074
1109
  *
1075
- * 주의: JSON.stringify() 사용 금지! (매우 느림)
1110
+ * ## 📊 데이터 형식
1111
+ * ```typescript
1112
+ * const data: KonvaCanvasMarkerData<T>[] = [
1113
+ * {
1114
+ * id: 'unique-id',
1115
+ * position: new Position(lat, lng),
1116
+ * // POLYGON: paths 필수
1117
+ * paths: [[[lat, lng], [lat, lng], ...]],
1118
+ * // MARKER: boxWidth/boxHeight 권장 (Hit Test 정확도)
1119
+ * boxWidth: 60,
1120
+ * boxHeight: 75,
1121
+ * // 커스텀 데이터
1122
+ * ...customData
1123
+ * }
1124
+ * ];
1125
+ * ```
1126
+ *
1127
+ * ## ⚡ 성능 최적화 팁
1128
+ * 1. **동적 boxWidth 계산**: `measureText()`로 실제 너비 계산 후 전달
1129
+ * 2. **enableViewportCulling**: 대량 데이터 시 필수 (기본 true)
1130
+ * 3. **selectedItems 외부 관리**: 상태를 외부에서 관리하여 리렌더링 최소화
1131
+ * 4. **React.memo 최적화**: 컴포넌트가 자동으로 불필요한 리렌더링 방지
1132
+ *
1133
+ * @template T 마커/폴리곤 데이터의 추가 속성 타입
1134
+ *
1135
+ * @example
1136
+ * // 동적 boxWidth 계산 예시
1137
+ * const tempCtx = document.createElement('canvas').getContext('2d');
1138
+ * tempCtx.font = 'bold 15px Arial';
1139
+ * const boxWidth = Math.max(60, tempCtx.measureText(text).width + 20);
1140
+ *
1141
+ * @see {@link https://github.com/your-repo/docs/WoongCanvasLayer.md} 전체 문서
1076
1142
  */
1077
1143
 
1078
1144
 
1079
- var WoongKonvaMarker = React__default["default"].memo(WoongKonvaMarkerComponent, function (prevProps, nextProps) {
1080
- // 1. markers 비교
1081
- var prevMarkers = prevProps.markers;
1082
- var nextMarkers = nextProps.markers; // 참조가 같으면 스킵
1145
+ var WoongCanvasLayer = React__default["default"].memo(WoongCanvasLayerComponent, function (prevProps, nextProps) {
1146
+ // 1. data 비교
1147
+ var prevData = prevProps.data;
1148
+ var nextData = nextProps.data; // 참조가 같으면 스킵
1083
1149
 
1084
- if (prevMarkers !== nextMarkers) {
1150
+ if (prevData !== nextData) {
1085
1151
  // 길이가 다르면 변경됨
1086
- if (prevMarkers.length !== nextMarkers.length) return false; // 각 마커의 ID 비교
1152
+ if (prevData.length !== nextData.length) return false; // 각 데이터의 ID 비교
1087
1153
 
1088
- for (var i = 0; i < prevMarkers.length; i++) {
1089
- if (prevMarkers[i].id !== nextMarkers[i].id) {
1154
+ for (var i = 0; i < prevData.length; i++) {
1155
+ if (prevData[i].id !== nextData[i].id) {
1090
1156
  return false; // 변경됨 → 리렌더링
1091
1157
  }
1092
1158
  }
@@ -1101,18 +1167,6 @@ var WoongKonvaMarker = React__default["default"].memo(WoongKonvaMarkerComponent,
1101
1167
  return false; // 변경됨 → 리렌더링
1102
1168
  }
1103
1169
 
1104
- if (prevProps.onClick !== nextProps.onClick) {
1105
- return false; // 변경됨 → 리렌더링
1106
- }
1107
-
1108
- if (prevProps.onMouseOver !== nextProps.onMouseOver) {
1109
- return false; // 변경됨 → 리렌더링
1110
- }
1111
-
1112
- if (prevProps.onMouseOut !== nextProps.onMouseOut) {
1113
- return false; // 변경됨 → 리렌더링
1114
- }
1115
-
1116
1170
  if (prevProps.disableInteraction !== nextProps.disableInteraction) {
1117
1171
  return false; // 변경됨 → 리렌더링
1118
1172
  }
@@ -1127,4 +1181,4 @@ Object.defineProperty(exports, 'CanvasDataType', {
1127
1181
  exports.KonvaMarkerProvider = context.KonvaMarkerProvider;
1128
1182
  exports.LRUCache = performance.LRUCache;
1129
1183
  exports.SpatialHashGrid = performance.SpatialHashGrid;
1130
- exports["default"] = WoongKonvaMarker;
1184
+ exports["default"] = WoongCanvasLayer;
@@ -1,3 +1,3 @@
1
- export { default as WoongKonvaMarker } from "./WoongKonvaMarker";
2
- export * from "./WoongKonvaMarker";
1
+ export { default as WoongCanvasLayer } from "./WoongCanvasLayer";
2
+ export * from "./WoongCanvasLayer";
3
3
  export * from "./shared";
@@ -0,0 +1,59 @@
1
+ /**
2
+ * 폴리곤 렌더링 유틸리티
3
+ *
4
+ * 이 파일은 폴리곤 렌더링을 위한 헬퍼 함수와 팩토리 함수를 제공합니다.
5
+ */
6
+ import { CustomRenderBase, CustomRenderEvent, KonvaCanvasMarkerData } from "./types";
7
+ /**
8
+ * 폴리곤 그리기 헬퍼 함수 (도넛 폴리곤 지원)
9
+ */
10
+ export declare const drawPolygon: ({ ctx, polygonOffsets, isDonutPolygon, fillColor, strokeColor, lineWidth }: {
11
+ ctx: CanvasRenderingContext2D;
12
+ polygonOffsets: number[][][][];
13
+ isDonutPolygon: boolean;
14
+ fillColor: string;
15
+ strokeColor: string;
16
+ lineWidth: number;
17
+ }) => void;
18
+ /**
19
+ * 폴리곤 Base 렌더링 함수
20
+ *
21
+ * @param baseFillColor 기본 폴리곤 채우기 색상
22
+ * @param baseStrokeColor 기본 폴리곤 테두리 색상
23
+ * @param baseLineWidth 기본 폴리곤 테두리 두께
24
+ * @returns Base Layer 렌더링 함수
25
+ *
26
+ * @example
27
+ * const renderBase = renderPolygonBase(
28
+ * 'rgba(255, 100, 100, 0.5)',
29
+ * 'rgba(200, 50, 50, 0.8)',
30
+ * 2
31
+ * );
32
+ */
33
+ export declare const renderPolygonBase: <T = any>(baseFillColor: string, baseStrokeColor: string, baseLineWidth: number) => CustomRenderBase<KonvaCanvasMarkerData<T>>;
34
+ /**
35
+ * 폴리곤 Event 렌더링 함수
36
+ *
37
+ * @param selectedFillColor 선택된 폴리곤 채우기 색상
38
+ * @param selectedStrokeColor 선택된 폴리곤 테두리 색상
39
+ * @param selectedLineWidth 선택된 폴리곤 테두리 두께
40
+ * @param activeFillColor 마지막 선택된 폴리곤 채우기 색상 (선택, 기본값: selectedFillColor)
41
+ * @param activeStrokeColor 마지막 선택된 폴리곤 테두리 색상 (선택, 기본값: selectedStrokeColor)
42
+ * @param activeLineWidth 마지막 선택된 폴리곤 테두리 두께 (선택, 기본값: selectedLineWidth)
43
+ * @param hoveredFillColor Hover 시 폴리곤 채우기 색상 (선택, 기본값: selectedFillColor)
44
+ * @param hoveredStrokeColor Hover 시 폴리곤 테두리 색상 (선택, 기본값: selectedStrokeColor)
45
+ * @param hoveredLineWidth Hover 시 폴리곤 테두리 두께 (선택, 기본값: selectedLineWidth)
46
+ * @returns Event Layer 렌더링 함수
47
+ *
48
+ * @example
49
+ * const renderEvent = renderPolygonEvent(
50
+ * 'rgba(255, 193, 7, 0.7)',
51
+ * 'rgba(255, 152, 0, 1)',
52
+ * 4,
53
+ * 'rgba(255, 0, 0, 0.8)',
54
+ * undefined,
55
+ * undefined,
56
+ * 'rgba(100, 150, 255, 0.8)'
57
+ * );
58
+ */
59
+ export declare const renderPolygonEvent: <T = any>(selectedFillColor: string, selectedStrokeColor: string, selectedLineWidth: number, activeFillColor?: string, activeStrokeColor?: string, activeLineWidth?: number, hoveredFillColor?: string, hoveredStrokeColor?: string, hoveredLineWidth?: number) => CustomRenderEvent<KonvaCanvasMarkerData<T>>;