@mint-ui/map 1.2.0-test.11 → 1.2.0-test.13

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.
@@ -22,7 +22,7 @@ export interface Paths {
22
22
  * Konva 캔버스 마커/폴리곤의 기본 필수 속성
23
23
  * (렌더링에 필요한 최소 정보)
24
24
  */
25
- export interface KonvaCanvasMarkerOption {
25
+ export interface KonvaCanvasOption {
26
26
  id: string;
27
27
  position: Position;
28
28
  boxWidth?: number;
@@ -35,97 +35,247 @@ export interface KonvaCanvasMarkerOption {
35
35
  * @template T 서버에서 받은 원본 데이터 타입 (예: Marker, Polygon)
36
36
  * @example
37
37
  * // API에서 받은 Marker 타입을 그대로 유지하면서 캔버스 렌더링 정보 추가
38
- * type MarkerWithCanvas = KonvaCanvasMarkerData<Marker>
38
+ * type MarkerWithCanvas = KonvaCanvasData<Marker>
39
39
  * // { raId, lat, lng, buildingName, totalArea } + { id, position, boxWidth, ... }
40
40
  */
41
- export declare type KonvaCanvasMarkerData<T = {}> = T & KonvaCanvasMarkerOption;
41
+ export declare type KonvaCanvasData<T = {}> = T & KonvaCanvasOption;
42
42
  /**
43
- * 렌더링 유틸리티 함수들
43
+ * 🛠️ 렌더링 유틸리티 함수들
44
+ *
45
+ * WoongCanvasLayer가 제공하는 헬퍼 함수 모음입니다.
46
+ * 커스텀 렌더링 함수 내에서 좌표 변환 시 사용하세요.
47
+ *
48
+ * ## 주요 기능
49
+ * - **자동 캐싱**: 좌표 변환 결과를 LRU 캐시에 저장 (성능 최적화)
50
+ * - **지도 좌표 → 화면 좌표**: 위경도를 픽셀 좌표로 자동 변환
51
+ * - **null 안전성**: 변환 실패 시 null 반환 (안전한 예외 처리)
52
+ *
53
+ * @template T 마커/폴리곤 데이터의 추가 속성 타입
54
+ *
55
+ * @example
56
+ * // 마커 렌더링 예시
57
+ * const renderBase = ({ ctx, items, utils }) => {
58
+ * for (const item of items) {
59
+ * const offset = utils.getOrComputeMarkerOffset(item);
60
+ * if (!offset) continue; // 변환 실패 시 스킵
61
+ *
62
+ * ctx.fillRect(offset.x, offset.y, 50, 50);
63
+ * }
64
+ * };
65
+ *
66
+ * @example
67
+ * // 폴리곤 렌더링 예시
68
+ * const renderBase = ({ ctx, items, utils }) => {
69
+ * for (const item of items) {
70
+ * const offsets = utils.getOrComputePolygonOffsets(item);
71
+ * if (!offsets) continue;
72
+ *
73
+ * for (const multiPolygon of offsets) {
74
+ * for (const polygon of multiPolygon) {
75
+ * ctx.beginPath();
76
+ * ctx.moveTo(polygon[0][0], polygon[0][1]);
77
+ * for (let i = 1; i < polygon.length; i++) {
78
+ * ctx.lineTo(polygon[i][0], polygon[i][1]);
79
+ * }
80
+ * ctx.closePath();
81
+ * ctx.fill();
82
+ * }
83
+ * }
84
+ * }
85
+ * };
44
86
  */
45
87
  export interface RenderUtils<T> {
46
- getOrComputePolygonOffsets: (polygonData: KonvaCanvasMarkerData<T>) => number[][][][] | null;
47
- getOrComputeMarkerOffset: (markerData: KonvaCanvasMarkerData<T>) => Offset | null;
88
+ /**
89
+ * 폴리곤의 위경도 좌표를 화면 픽셀 좌표로 변환합니다.
90
+ *
91
+ * - **자동 캐싱**: 동일한 폴리곤은 캐시에서 즉시 반환 (성능 최적화)
92
+ * - **MultiPolygon 지원**: GeoJSON MultiPolygon 형식 지원
93
+ * - **Donut Polygon 지원**: 구멍이 있는 폴리곤 지원
94
+ *
95
+ * @param polygonData 폴리곤 데이터 (paths 필드 필수)
96
+ * @returns 변환된 픽셀 좌표 배열 (4차원 배열) 또는 null (변환 실패 시)
97
+ *
98
+ * @example
99
+ * const offsets = utils.getOrComputePolygonOffsets(polygonItem);
100
+ * if (!offsets) return; // 변환 실패
101
+ *
102
+ * // offsets 구조: [MultiPolygon][Polygon][Point][x/y]
103
+ * for (const multiPolygon of offsets) {
104
+ * for (const polygon of multiPolygon) {
105
+ * ctx.beginPath();
106
+ * ctx.moveTo(polygon[0][0], polygon[0][1]);
107
+ * for (let i = 1; i < polygon.length; i++) {
108
+ * ctx.lineTo(polygon[i][0], polygon[i][1]);
109
+ * }
110
+ * ctx.closePath();
111
+ * ctx.fill();
112
+ * }
113
+ * }
114
+ */
115
+ getOrComputePolygonOffsets: (polygonData: KonvaCanvasData<T>) => number[][][][] | null;
116
+ /**
117
+ * 마커의 위경도 좌표를 화면 픽셀 좌표로 변환합니다.
118
+ *
119
+ * - **자동 캐싱**: 동일한 마커는 캐시에서 즉시 반환 (성능 최적화)
120
+ * - **중심점 기준**: 반환된 좌표는 마커의 중심점 (x, y)
121
+ *
122
+ * @param markerData 마커 데이터 (position 필드 필수)
123
+ * @returns 변환된 픽셀 좌표 { x, y } 또는 null (변환 실패 시)
124
+ *
125
+ * @example
126
+ * const offset = utils.getOrComputeMarkerOffset(markerItem);
127
+ * if (!offset) return; // 변환 실패
128
+ *
129
+ * // offset.x, offset.y는 화면 픽셀 좌표
130
+ * const boxWidth = markerItem.boxWidth || 60;
131
+ * const boxHeight = markerItem.boxHeight || 75;
132
+ *
133
+ * // 중앙 정렬, 하단 기준으로 그리기
134
+ * ctx.fillRect(
135
+ * offset.x - boxWidth / 2,
136
+ * offset.y - boxHeight,
137
+ * boxWidth,
138
+ * boxHeight
139
+ * );
140
+ */
141
+ getOrComputeMarkerOffset: (markerData: KonvaCanvasData<T>) => Offset | null;
48
142
  }
49
143
  /**
50
144
  * 커스텀 렌더링 함수 파라미터 - Base Layer
145
+ *
146
+ * @template T 데이터 타입
147
+ * @template C 설정(Config) 타입 (선택)
51
148
  */
52
- export interface RenderBaseParams<T> {
149
+ export interface RenderBaseParams<T, C = any> {
53
150
  /** Canvas 2D 렌더링 컨텍스트 (순수 Canvas API) */
54
151
  ctx: CanvasRenderingContext2D;
55
152
  /** 렌더링할 마커 데이터 배열 */
56
- items: KonvaCanvasMarkerData<T>[];
153
+ items: KonvaCanvasData<T>[];
57
154
  /** 현재 선택된 마커 ID Set */
58
155
  selectedIds: Set<string>;
59
156
  /** 렌더링 유틸리티 함수들 */
60
157
  utils: RenderUtils<T>;
158
+ /** 렌더링 설정 (색상, 표시 여부, 모양 등) */
159
+ config?: C;
61
160
  }
62
161
  /**
63
162
  * 커스텀 렌더링 함수 타입 - Base Layer
64
163
  *
65
164
  * 🔥 순수 Canvas API 사용 (Konva 지식 불필요!)
66
165
  *
166
+ * @template T 데이터 타입
167
+ * @template C 설정(Config) 타입 - 렌더링 옵션 (색상, 표시 여부, 모양 등)
168
+ *
67
169
  * @example
68
- * const renderBase = ({ ctx, items, selectedIds, utils }) => {
170
+ * // 기본 사용 (config 없이)
171
+ * const renderBase: CustomRenderBase<Marker> = ({ ctx, items, selectedIds, utils }) => {
69
172
  * for (const item of items) {
70
173
  * if (selectedIds.has(item.id)) continue;
71
174
  * const pos = utils.getOrComputeMarkerOffset(item);
72
- * ctx.fillRect(pos.x, pos.y, 50, 50); // 순수 Canvas API!
175
+ * ctx.fillRect(pos.x, pos.y, 50, 50);
176
+ * }
177
+ * };
178
+ *
179
+ * @example
180
+ * // config 사용
181
+ * interface MarkerRenderConfig {
182
+ * showLabel: boolean;
183
+ * color: string;
184
+ * shape: 'circle' | 'square';
185
+ * }
186
+ *
187
+ * const renderBase: CustomRenderBase<Marker, MarkerRenderConfig> = ({ ctx, items, config, utils }) => {
188
+ * for (const item of items) {
189
+ * const pos = utils.getOrComputeMarkerOffset(item);
190
+ * ctx.fillStyle = config?.color || 'blue';
191
+ * if (config?.shape === 'circle') {
192
+ * ctx.arc(pos.x, pos.y, 10, 0, Math.PI * 2);
193
+ * } else {
194
+ * ctx.fillRect(pos.x, pos.y, 20, 20);
195
+ * }
196
+ * ctx.fill();
73
197
  * }
74
198
  * };
75
199
  */
76
- export declare type CustomRenderBase<T> = (params: RenderBaseParams<T>) => void;
200
+ export declare type CustomRenderBase<T, C = any> = (params: RenderBaseParams<T, C>) => void;
77
201
  /**
78
202
  * 커스텀 렌더링 함수 파라미터 - Animation Layer
203
+ *
204
+ * @template T 데이터 타입
205
+ * @template C 설정(Config) 타입 (선택)
79
206
  */
80
- export interface RenderAnimationParams<T> {
207
+ export interface RenderAnimationParams<T, C = any> {
81
208
  /** Konva Layer 인스턴스 */
82
209
  layer: Konva.Layer;
83
210
  /** 현재 선택된 마커 ID Set */
84
211
  selectedIds: Set<string>;
85
212
  /** 전체 마커 데이터 배열 */
86
- items: KonvaCanvasMarkerData<T>[];
213
+ items: KonvaCanvasData<T>[];
87
214
  /** 렌더링 유틸리티 함수들 */
88
215
  utils: RenderUtils<T>;
216
+ /** 렌더링 설정 (애니메이션 속도, 효과 등) */
217
+ config?: C;
89
218
  }
90
219
  /**
91
220
  * 커스텀 렌더링 함수 타입 - Animation Layer (선택)
92
221
  *
222
+ * @template T 데이터 타입
223
+ * @template C 설정(Config) 타입 - 애니메이션 옵션
224
+ *
93
225
  * @example
94
- * const renderAnimation = ({ layer, selectedIds, items, utils }) => {
95
- * for (const id of selectedIds) {
96
- * const item = items.find(i => i.id === id);
97
- * // Konva 애니메이션 구현
98
- * }
226
+ * // config 사용
227
+ * interface AnimationConfig {
228
+ * speed: number;
229
+ * bounceHeight: number;
230
+ * }
231
+ *
232
+ * const renderAnimation: CustomRenderAnimation<Marker, AnimationConfig> = ({ layer, selectedIds, items, config, utils }) => {
233
+ * const bounceHeight = config?.bounceHeight || 15;
234
+ * // Konva 애니메이션 구현
99
235
  * };
100
236
  */
101
- export declare type CustomRenderAnimation<T> = (params: RenderAnimationParams<T>) => void;
237
+ export declare type CustomRenderAnimation<T, C = any> = (params: RenderAnimationParams<T, C>) => void;
102
238
  /**
103
239
  * 커스텀 렌더링 함수 파라미터 - Event Layer
240
+ *
241
+ * @template T 데이터 타입
242
+ * @template C 설정(Config) 타입 (선택)
104
243
  */
105
- export interface RenderEventParams<T> {
244
+ export interface RenderEventParams<T, C = any> {
106
245
  /** Canvas 2D 렌더링 컨텍스트 (순수 Canvas API) */
107
246
  ctx: CanvasRenderingContext2D;
108
247
  /** 현재 hover된 마커 데이터 */
109
- hoveredItem: KonvaCanvasMarkerData<T> | null;
248
+ hoveredItem: KonvaCanvasData<T> | null;
110
249
  /** 렌더링 유틸리티 함수들 */
111
250
  utils: RenderUtils<T>;
112
251
  /** 현재 선택된 마커 데이터 배열 (선택 강조용) */
113
- selectedItems?: KonvaCanvasMarkerData<T>[];
252
+ selectedItems?: KonvaCanvasData<T>[];
114
253
  /** 외부에서 전달된 단일 선택 아이템 (특별한 효과용) */
115
- selectedItem?: KonvaCanvasMarkerData<T> | null;
254
+ selectedItem?: KonvaCanvasData<T> | null;
255
+ /** 렌더링 설정 (hover 색상, 선택 효과 등) */
256
+ config?: C;
116
257
  }
117
258
  /**
118
259
  * 커스텀 렌더링 함수 타입 - Event Layer
119
260
  *
120
261
  * 🔥 순수 Canvas API 사용 (Konva 지식 불필요!)
121
262
  *
263
+ * @template T 데이터 타입
264
+ * @template C 설정(Config) 타입 - 이벤트 렌더링 옵션
265
+ *
122
266
  * @example
123
- * const renderEvent = ({ ctx, hoveredItem, utils, selectedItems }) => {
267
+ * // config 사용
268
+ * interface EventRenderConfig {
269
+ * hoverColor: string;
270
+ * selectedColor: string;
271
+ * }
272
+ *
273
+ * const renderEvent: CustomRenderEvent<Marker, EventRenderConfig> = ({ ctx, hoveredItem, config, utils }) => {
124
274
  * if (hoveredItem) {
125
275
  * const pos = utils.getOrComputeMarkerOffset(hoveredItem);
126
- * ctx.fillStyle = 'red';
127
- * ctx.fillRect(pos.x, pos.y, 50, 50); // 순수 Canvas API!
276
+ * ctx.fillStyle = config?.hoverColor || 'red';
277
+ * ctx.fillRect(pos.x, pos.y, 50, 50);
128
278
  * }
129
279
  * };
130
280
  */
131
- export declare type CustomRenderEvent<T> = (params: RenderEventParams<T>) => void;
281
+ export declare type CustomRenderEvent<T, C = any> = (params: RenderEventParams<T, C>) => void;
@@ -1,14 +1,14 @@
1
1
  import { Offset } from "../../../../types";
2
2
  import { MintMapController } from "../../../MintMapController";
3
- import { KonvaCanvasMarkerData } from "./types";
3
+ import { KonvaCanvasData } from "./types";
4
4
  /**
5
5
  * 폴리곤 offset 계산
6
6
  */
7
- export declare const computePolygonOffsets: (polygonData: KonvaCanvasMarkerData<any>, controller: MintMapController) => number[][][][] | null;
7
+ export declare const computePolygonOffsets: (polygonData: KonvaCanvasData<any>, controller: MintMapController) => number[][][][] | null;
8
8
  /**
9
9
  * 마커 offset 계산
10
10
  */
11
- export declare const computeMarkerOffset: (markerData: KonvaCanvasMarkerData<any>, controller: MintMapController) => Offset | null;
11
+ export declare const computeMarkerOffset: (markerData: KonvaCanvasData<any>, controller: MintMapController) => Offset | null;
12
12
  /**
13
13
  * Point-in-Polygon 알고리즘
14
14
  */
@@ -24,9 +24,25 @@ export declare const isPointInPolygon: (point: Offset, polygon: number[][]) => b
24
24
  * - 도넛 폴리곤 A: isDonutPolygon=true
25
25
  * - 내부 폴리곤 B: isDonutPolygon=false (별도 데이터)
26
26
  */
27
- export declare const isPointInPolygonData: (clickedOffset: Offset, polygonData: KonvaCanvasMarkerData<any>, getPolygonOffsets: (data: KonvaCanvasMarkerData<any>) => number[][][][] | null) => boolean;
27
+ export declare const isPointInPolygonData: (clickedOffset: Offset, polygonData: KonvaCanvasData<any>, getPolygonOffsets: (data: KonvaCanvasData<any>) => number[][][][] | null) => boolean;
28
28
  /**
29
29
  * 마커 히트 테스트
30
30
  */
31
- export declare const isPointInMarkerData: (clickedOffset: Offset, markerData: KonvaCanvasMarkerData<any>, getMarkerOffset: (data: KonvaCanvasMarkerData<any>) => Offset | null) => boolean;
31
+ export declare const isPointInMarkerData: (clickedOffset: Offset, markerData: KonvaCanvasData<any>, getMarkerOffset: (data: KonvaCanvasData<any>) => Offset | null) => boolean;
32
32
  export declare const hexToRgba: (hexColor: string, alpha?: number) => string;
33
+ /**
34
+ * 텍스트 박스의 너비를 계산합니다.
35
+ *
36
+ * @param {Object} params - 파라미터 객체
37
+ * @param {string} params.text - 측정할 텍스트
38
+ * @param {string} params.fontConfig - 폰트 설정 (예: 'bold 16px Arial')
39
+ * @param {number} params.padding - 텍스트 박스에 적용할 패딩 값
40
+ * @param {number} params.minWidth - 최소 너비
41
+ * @returns {number} 계산된 텍스트 박스의 너비
42
+ */
43
+ export declare const calculateTextBoxWidth: ({ text, fontConfig, padding, minWidth, }: {
44
+ text: string;
45
+ fontConfig: string;
46
+ padding: number;
47
+ minWidth: number;
48
+ }) => number;
@@ -173,7 +173,31 @@ var hexToRgba = function (hexColor, alpha) {
173
173
 
174
174
  throw new Error('Invalid hex color format');
175
175
  };
176
+ var tempCanvas = document.createElement('canvas');
177
+ var tempCtx = tempCanvas.getContext('2d');
178
+ /**
179
+ * 텍스트 박스의 너비를 계산합니다.
180
+ *
181
+ * @param {Object} params - 파라미터 객체
182
+ * @param {string} params.text - 측정할 텍스트
183
+ * @param {string} params.fontConfig - 폰트 설정 (예: 'bold 16px Arial')
184
+ * @param {number} params.padding - 텍스트 박스에 적용할 패딩 값
185
+ * @param {number} params.minWidth - 최소 너비
186
+ * @returns {number} 계산된 텍스트 박스의 너비
187
+ */
188
+
189
+ var calculateTextBoxWidth = function (_a) {
190
+ var text = _a.text,
191
+ fontConfig = _a.fontConfig,
192
+ padding = _a.padding,
193
+ minWidth = _a.minWidth;
194
+ if (!tempCtx) return 0;
195
+ tempCtx.font = fontConfig;
196
+ var textWidth = tempCtx.measureText(text).width;
197
+ return Math.max(minWidth, textWidth + padding);
198
+ };
176
199
 
200
+ exports.calculateTextBoxWidth = calculateTextBoxWidth;
177
201
  exports.computeMarkerOffset = computeMarkerOffset;
178
202
  exports.computePolygonOffsets = computePolygonOffsets;
179
203
  exports.hexToRgba = hexToRgba;
@@ -22,6 +22,7 @@ require('../core/advanced/canvas/CanvasMarkerClaude.js');
22
22
  require('../core/advanced/MapLoadingComponents.js');
23
23
  require('../core/advanced/woongCanvas/WoongCanvasLayer.js');
24
24
  require('../core/advanced/woongCanvas/shared/types.js');
25
+ require('../core/advanced/woongCanvas/shared/utils.js');
25
26
  require('../core/advanced/woongCanvas/shared/context.js');
26
27
  require('../core/advanced/woongCanvas/shared/performance.js');
27
28
  require('../core/wrapper/MapControlWrapper.js');
@@ -23,6 +23,7 @@ require('../core/advanced/canvas/CanvasMarkerClaude.js');
23
23
  require('../core/advanced/MapLoadingComponents.js');
24
24
  require('../core/advanced/woongCanvas/WoongCanvasLayer.js');
25
25
  require('../core/advanced/woongCanvas/shared/types.js');
26
+ require('../core/advanced/woongCanvas/shared/utils.js');
26
27
  require('../core/advanced/woongCanvas/shared/context.js');
27
28
  require('../core/advanced/woongCanvas/shared/performance.js');
28
29
  require('../core/wrapper/MapControlWrapper.js');
@@ -22,6 +22,7 @@ require('../core/advanced/canvas/CanvasMarkerClaude.js');
22
22
  require('../core/advanced/MapLoadingComponents.js');
23
23
  require('../core/advanced/woongCanvas/WoongCanvasLayer.js');
24
24
  require('../core/advanced/woongCanvas/shared/types.js');
25
+ require('../core/advanced/woongCanvas/shared/utils.js');
25
26
  require('../core/advanced/woongCanvas/shared/context.js');
26
27
  require('../core/advanced/woongCanvas/shared/performance.js');
27
28
  require('../core/wrapper/MapControlWrapper.js');