@canvas-tile-engine/react 0.1.0 → 0.2.0

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.d.mts CHANGED
@@ -1,15 +1,15 @@
1
1
  import * as react from 'react';
2
- import { DrawObject, ImageItem, Coords, CanvasTileEngineConfig, CanvasTileEngine as CanvasTileEngine$1, EventHandlers, LayerHandle, onClickCallback, onRightClickCallback, onHoverCallback, onMouseDownCallback, onMouseUpCallback, onMouseLeaveCallback, onDrawCallback, onZoomCallback } from '@canvas-tile-engine/core';
2
+ import { Rect, Circle, ImageItem, Line, Text, Path, Coords, CanvasTileEngineConfig, CanvasTileEngine as CanvasTileEngine$1, EventHandlers, LayerHandle, onClickCallback, onRightClickCallback, onHoverCallback, onMouseDownCallback, onMouseUpCallback, onMouseLeaveCallback, onDrawCallback, onZoomCallback } from '@canvas-tile-engine/core';
3
3
  export { CanvasTileEngineConfig, CanvasTileEngine as CanvasTileEngineCore, Circle, Coords, DrawObject, EventHandlers, ImageItem, Line, Path, Rect, Text, gridToSize, onClickCallback, onDrawCallback, onHoverCallback, onMouseDownCallback, onMouseLeaveCallback, onMouseUpCallback } from '@canvas-tile-engine/core';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
 
6
6
  interface RectProps {
7
- items: DrawObject | DrawObject[];
7
+ items: Rect | Rect[];
8
8
  layer?: number;
9
9
  }
10
10
 
11
11
  interface CircleProps {
12
- items: DrawObject | DrawObject[];
12
+ items: Circle | Circle[];
13
13
  layer?: number;
14
14
  }
15
15
 
@@ -26,13 +26,7 @@ interface GridLinesProps {
26
26
  }
27
27
 
28
28
  interface LineProps {
29
- items: {
30
- from: Coords;
31
- to: Coords;
32
- } | {
33
- from: Coords;
34
- to: Coords;
35
- }[];
29
+ items: Line | Line[];
36
30
  style?: {
37
31
  strokeStyle?: string;
38
32
  lineWidth?: number;
@@ -41,24 +35,12 @@ interface LineProps {
41
35
  }
42
36
 
43
37
  interface TextProps {
44
- items: {
45
- coords: Coords;
46
- text: string;
47
- } | {
48
- coords: Coords;
49
- text: string;
50
- }[];
51
- style?: {
52
- fillStyle?: string;
53
- font?: string;
54
- textAlign?: CanvasTextAlign;
55
- textBaseline?: CanvasTextBaseline;
56
- };
38
+ items: Text | Text[];
57
39
  layer?: number;
58
40
  }
59
41
 
60
42
  interface PathProps {
61
- items: Coords[] | Coords[][];
43
+ items: Path | Path[];
62
44
  style?: {
63
45
  strokeStyle?: string;
64
46
  lineWidth?: number;
@@ -67,13 +49,13 @@ interface PathProps {
67
49
  }
68
50
 
69
51
  interface StaticRectProps {
70
- items: DrawObject[];
52
+ items: Rect[];
71
53
  cacheKey: string;
72
54
  layer?: number;
73
55
  }
74
56
 
75
57
  interface StaticCircleProps {
76
- items: DrawObject[];
58
+ items: Circle[];
77
59
  cacheKey: string;
78
60
  layer?: number;
79
61
  }
@@ -144,52 +126,29 @@ interface EngineHandle {
144
126
  /** Dynamically update event handlers at runtime */
145
127
  setEventHandlers(handlers: Partial<EventHandlers>): void;
146
128
  /** Draw rectangles */
147
- drawRect(items: DrawObject | DrawObject[], layer?: number): LayerHandle;
129
+ drawRect(items: Rect | Rect[], layer?: number): LayerHandle;
148
130
  /** Draw static rectangles (cached) */
149
- drawStaticRect(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;
131
+ drawStaticRect(items: Rect[], cacheKey: string, layer?: number): LayerHandle;
150
132
  /** Draw circles */
151
- drawCircle(items: DrawObject | DrawObject[], layer?: number): LayerHandle;
133
+ drawCircle(items: Circle | Circle[], layer?: number): LayerHandle;
152
134
  /** Draw static circles (cached) */
153
- drawStaticCircle(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;
135
+ drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): LayerHandle;
154
136
  /** Draw lines */
155
- drawLine(items: {
156
- from: Coords;
157
- to: Coords;
158
- } | {
159
- from: Coords;
160
- to: Coords;
161
- }[], style?: {
137
+ drawLine(items: Line | Line[], style?: {
162
138
  strokeStyle?: string;
163
139
  lineWidth?: number;
164
140
  }, layer?: number): LayerHandle;
165
141
  /** Draw text */
166
- drawText(items: {
167
- coords: Coords;
168
- text: string;
169
- } | {
170
- coords: Coords;
171
- text: string;
172
- }[], style?: {
173
- fillStyle?: string;
174
- font?: string;
175
- textAlign?: CanvasTextAlign;
176
- textBaseline?: CanvasTextBaseline;
177
- }, layer?: number): LayerHandle;
142
+ drawText(items: Text | Text[], layer?: number): LayerHandle;
178
143
  /** Draw paths/polylines */
179
144
  drawPath(items: Coords[] | Coords[][], style?: {
180
145
  strokeStyle?: string;
181
146
  lineWidth?: number;
182
147
  }, layer?: number): LayerHandle;
183
148
  /** Draw images */
184
- drawImage(items: (Omit<DrawObject, "style"> & {
185
- img: HTMLImageElement;
186
- }) | (Omit<DrawObject, "style"> & {
187
- img: HTMLImageElement;
188
- })[], layer?: number): LayerHandle;
149
+ drawImage(items: ImageItem | ImageItem[], layer?: number): LayerHandle;
189
150
  /** Draw static images (cached) */
190
- drawStaticImage(items: (Omit<DrawObject, "style"> & {
191
- img: HTMLImageElement;
192
- })[], cacheKey: string, layer?: number): LayerHandle;
151
+ drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): LayerHandle;
193
152
  /** Draw grid lines */
194
153
  drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;
195
154
  /** Add custom draw function */
@@ -204,6 +163,17 @@ interface EngineHandle {
204
163
  removeLayerHandle(handle: LayerHandle): void;
205
164
  /** Image loader instance (undefined until engine mounts) */
206
165
  readonly images: CanvasTileEngine$1["images"] | undefined;
166
+ /**
167
+ * Load an image using the engine's image loader.
168
+ * Returns a rejected promise if engine is not ready.
169
+ * @param src - Image URL to load
170
+ * @param retry - Number of retries on failure (default: 1)
171
+ * @example
172
+ * ```tsx
173
+ * const img = await engine.loadImage("/sprites/player.png");
174
+ * ```
175
+ */
176
+ loadImage(src: string, retry?: number): Promise<HTMLImageElement>;
207
177
  }
208
178
  /**
209
179
  * React hook that creates an engine handle for use with CanvasTileEngine component.
@@ -251,25 +221,128 @@ interface CanvasTileEngineProps {
251
221
  style?: React.CSSProperties;
252
222
  /** Draw components (Rect, Circle, Image, GridLines, etc.) */
253
223
  children?: React.ReactNode;
254
- /** Callback when center coordinates change */
224
+ /**
225
+ * Callback when center coordinates change (pan or zoom).
226
+ * @param coords - Center world coordinates: `{ x, y }`
227
+ * @example
228
+ * ```tsx
229
+ * onCoordsChange={(coords) => {
230
+ * console.log(`Center: ${coords.x}, ${coords.y}`);
231
+ * }}
232
+ * ```
233
+ */
255
234
  onCoordsChange?: (coords: Coords) => void;
256
- /** Callback when a tile is clicked */
235
+ /**
236
+ * Callback when a tile is clicked (mouse or touch tap).
237
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
238
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
239
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
240
+ * @example
241
+ * ```tsx
242
+ * onClick={(coords) => {
243
+ * console.log(`Clicked tile: ${coords.snapped.x}, ${coords.snapped.y}`);
244
+ * }}
245
+ * ```
246
+ */
257
247
  onClick?: onClickCallback;
258
- /** Callback when a tile is right-clicked */
248
+ /**
249
+ * Callback when a tile is right-clicked.
250
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
251
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
252
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
253
+ * @example
254
+ * ```tsx
255
+ * onRightClick={(coords) => {
256
+ * showContextMenu(coords.snapped.x, coords.snapped.y);
257
+ * }}
258
+ * ```
259
+ */
259
260
  onRightClick?: onRightClickCallback;
260
- /** Callback when hovering over tiles */
261
+ /**
262
+ * Callback when hovering over tiles.
263
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
264
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
265
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
266
+ * @example
267
+ * ```tsx
268
+ * onHover={(coords) => {
269
+ * setHoveredTile({ x: coords.snapped.x, y: coords.snapped.y });
270
+ * }}
271
+ * ```
272
+ */
261
273
  onHover?: onHoverCallback;
262
- /** Callback on mouse down */
274
+ /**
275
+ * Callback on mouse/touch down.
276
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
277
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
278
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
279
+ * @example
280
+ * ```tsx
281
+ * onMouseDown={(coords) => {
282
+ * startPainting(coords.snapped.x, coords.snapped.y);
283
+ * }}
284
+ * ```
285
+ */
263
286
  onMouseDown?: onMouseDownCallback;
264
- /** Callback on mouse up */
287
+ /**
288
+ * Callback on mouse/touch up.
289
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
290
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
291
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
292
+ * @example
293
+ * ```tsx
294
+ * onMouseUp={() => {
295
+ * stopPainting();
296
+ * }}
297
+ * ```
298
+ */
265
299
  onMouseUp?: onMouseUpCallback;
266
- /** Callback on mouse leave */
300
+ /**
301
+ * Callback when mouse/touch leaves the canvas.
302
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
303
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
304
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
305
+ * @example
306
+ * ```tsx
307
+ * onMouseLeave={() => {
308
+ * clearHoveredTile();
309
+ * }}
310
+ * ```
311
+ */
267
312
  onMouseLeave?: onMouseLeaveCallback;
268
- /** Callback after each draw frame */
313
+ /**
314
+ * Callback after each draw frame. Use for custom canvas drawing.
315
+ * @param ctx - The canvas 2D rendering context
316
+ * @param info - Frame info: `scale`, `width`, `height`, `coords` (center)
317
+ * @example
318
+ * ```tsx
319
+ * onDraw={(ctx, info) => {
320
+ * ctx.fillStyle = "red";
321
+ * ctx.fillText(`Scale: ${info.scale}`, 10, 20);
322
+ * }}
323
+ * ```
324
+ */
269
325
  onDraw?: onDrawCallback;
270
- /** Callback on canvas resize */
326
+ /**
327
+ * Callback on canvas resize.
328
+ * @example
329
+ * ```tsx
330
+ * onResize={() => {
331
+ * console.log("Canvas resized");
332
+ * }}
333
+ * ```
334
+ */
271
335
  onResize?: () => void;
272
- /** Callback when zoom level changes */
336
+ /**
337
+ * Callback when zoom level changes (wheel or pinch).
338
+ * @param scale - The new scale value
339
+ * @example
340
+ * ```tsx
341
+ * onZoom={(scale) => {
342
+ * console.log(`Zoom level: ${scale}`);
343
+ * }}
344
+ * ```
345
+ */
273
346
  onZoom?: onZoomCallback;
274
347
  }
275
348
 
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import * as react from 'react';
2
- import { DrawObject, ImageItem, Coords, CanvasTileEngineConfig, CanvasTileEngine as CanvasTileEngine$1, EventHandlers, LayerHandle, onClickCallback, onRightClickCallback, onHoverCallback, onMouseDownCallback, onMouseUpCallback, onMouseLeaveCallback, onDrawCallback, onZoomCallback } from '@canvas-tile-engine/core';
2
+ import { Rect, Circle, ImageItem, Line, Text, Path, Coords, CanvasTileEngineConfig, CanvasTileEngine as CanvasTileEngine$1, EventHandlers, LayerHandle, onClickCallback, onRightClickCallback, onHoverCallback, onMouseDownCallback, onMouseUpCallback, onMouseLeaveCallback, onDrawCallback, onZoomCallback } from '@canvas-tile-engine/core';
3
3
  export { CanvasTileEngineConfig, CanvasTileEngine as CanvasTileEngineCore, Circle, Coords, DrawObject, EventHandlers, ImageItem, Line, Path, Rect, Text, gridToSize, onClickCallback, onDrawCallback, onHoverCallback, onMouseDownCallback, onMouseLeaveCallback, onMouseUpCallback } from '@canvas-tile-engine/core';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
 
6
6
  interface RectProps {
7
- items: DrawObject | DrawObject[];
7
+ items: Rect | Rect[];
8
8
  layer?: number;
9
9
  }
10
10
 
11
11
  interface CircleProps {
12
- items: DrawObject | DrawObject[];
12
+ items: Circle | Circle[];
13
13
  layer?: number;
14
14
  }
15
15
 
@@ -26,13 +26,7 @@ interface GridLinesProps {
26
26
  }
27
27
 
28
28
  interface LineProps {
29
- items: {
30
- from: Coords;
31
- to: Coords;
32
- } | {
33
- from: Coords;
34
- to: Coords;
35
- }[];
29
+ items: Line | Line[];
36
30
  style?: {
37
31
  strokeStyle?: string;
38
32
  lineWidth?: number;
@@ -41,24 +35,12 @@ interface LineProps {
41
35
  }
42
36
 
43
37
  interface TextProps {
44
- items: {
45
- coords: Coords;
46
- text: string;
47
- } | {
48
- coords: Coords;
49
- text: string;
50
- }[];
51
- style?: {
52
- fillStyle?: string;
53
- font?: string;
54
- textAlign?: CanvasTextAlign;
55
- textBaseline?: CanvasTextBaseline;
56
- };
38
+ items: Text | Text[];
57
39
  layer?: number;
58
40
  }
59
41
 
60
42
  interface PathProps {
61
- items: Coords[] | Coords[][];
43
+ items: Path | Path[];
62
44
  style?: {
63
45
  strokeStyle?: string;
64
46
  lineWidth?: number;
@@ -67,13 +49,13 @@ interface PathProps {
67
49
  }
68
50
 
69
51
  interface StaticRectProps {
70
- items: DrawObject[];
52
+ items: Rect[];
71
53
  cacheKey: string;
72
54
  layer?: number;
73
55
  }
74
56
 
75
57
  interface StaticCircleProps {
76
- items: DrawObject[];
58
+ items: Circle[];
77
59
  cacheKey: string;
78
60
  layer?: number;
79
61
  }
@@ -144,52 +126,29 @@ interface EngineHandle {
144
126
  /** Dynamically update event handlers at runtime */
145
127
  setEventHandlers(handlers: Partial<EventHandlers>): void;
146
128
  /** Draw rectangles */
147
- drawRect(items: DrawObject | DrawObject[], layer?: number): LayerHandle;
129
+ drawRect(items: Rect | Rect[], layer?: number): LayerHandle;
148
130
  /** Draw static rectangles (cached) */
149
- drawStaticRect(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;
131
+ drawStaticRect(items: Rect[], cacheKey: string, layer?: number): LayerHandle;
150
132
  /** Draw circles */
151
- drawCircle(items: DrawObject | DrawObject[], layer?: number): LayerHandle;
133
+ drawCircle(items: Circle | Circle[], layer?: number): LayerHandle;
152
134
  /** Draw static circles (cached) */
153
- drawStaticCircle(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;
135
+ drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): LayerHandle;
154
136
  /** Draw lines */
155
- drawLine(items: {
156
- from: Coords;
157
- to: Coords;
158
- } | {
159
- from: Coords;
160
- to: Coords;
161
- }[], style?: {
137
+ drawLine(items: Line | Line[], style?: {
162
138
  strokeStyle?: string;
163
139
  lineWidth?: number;
164
140
  }, layer?: number): LayerHandle;
165
141
  /** Draw text */
166
- drawText(items: {
167
- coords: Coords;
168
- text: string;
169
- } | {
170
- coords: Coords;
171
- text: string;
172
- }[], style?: {
173
- fillStyle?: string;
174
- font?: string;
175
- textAlign?: CanvasTextAlign;
176
- textBaseline?: CanvasTextBaseline;
177
- }, layer?: number): LayerHandle;
142
+ drawText(items: Text | Text[], layer?: number): LayerHandle;
178
143
  /** Draw paths/polylines */
179
144
  drawPath(items: Coords[] | Coords[][], style?: {
180
145
  strokeStyle?: string;
181
146
  lineWidth?: number;
182
147
  }, layer?: number): LayerHandle;
183
148
  /** Draw images */
184
- drawImage(items: (Omit<DrawObject, "style"> & {
185
- img: HTMLImageElement;
186
- }) | (Omit<DrawObject, "style"> & {
187
- img: HTMLImageElement;
188
- })[], layer?: number): LayerHandle;
149
+ drawImage(items: ImageItem | ImageItem[], layer?: number): LayerHandle;
189
150
  /** Draw static images (cached) */
190
- drawStaticImage(items: (Omit<DrawObject, "style"> & {
191
- img: HTMLImageElement;
192
- })[], cacheKey: string, layer?: number): LayerHandle;
151
+ drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): LayerHandle;
193
152
  /** Draw grid lines */
194
153
  drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;
195
154
  /** Add custom draw function */
@@ -204,6 +163,17 @@ interface EngineHandle {
204
163
  removeLayerHandle(handle: LayerHandle): void;
205
164
  /** Image loader instance (undefined until engine mounts) */
206
165
  readonly images: CanvasTileEngine$1["images"] | undefined;
166
+ /**
167
+ * Load an image using the engine's image loader.
168
+ * Returns a rejected promise if engine is not ready.
169
+ * @param src - Image URL to load
170
+ * @param retry - Number of retries on failure (default: 1)
171
+ * @example
172
+ * ```tsx
173
+ * const img = await engine.loadImage("/sprites/player.png");
174
+ * ```
175
+ */
176
+ loadImage(src: string, retry?: number): Promise<HTMLImageElement>;
207
177
  }
208
178
  /**
209
179
  * React hook that creates an engine handle for use with CanvasTileEngine component.
@@ -251,25 +221,128 @@ interface CanvasTileEngineProps {
251
221
  style?: React.CSSProperties;
252
222
  /** Draw components (Rect, Circle, Image, GridLines, etc.) */
253
223
  children?: React.ReactNode;
254
- /** Callback when center coordinates change */
224
+ /**
225
+ * Callback when center coordinates change (pan or zoom).
226
+ * @param coords - Center world coordinates: `{ x, y }`
227
+ * @example
228
+ * ```tsx
229
+ * onCoordsChange={(coords) => {
230
+ * console.log(`Center: ${coords.x}, ${coords.y}`);
231
+ * }}
232
+ * ```
233
+ */
255
234
  onCoordsChange?: (coords: Coords) => void;
256
- /** Callback when a tile is clicked */
235
+ /**
236
+ * Callback when a tile is clicked (mouse or touch tap).
237
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
238
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
239
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
240
+ * @example
241
+ * ```tsx
242
+ * onClick={(coords) => {
243
+ * console.log(`Clicked tile: ${coords.snapped.x}, ${coords.snapped.y}`);
244
+ * }}
245
+ * ```
246
+ */
257
247
  onClick?: onClickCallback;
258
- /** Callback when a tile is right-clicked */
248
+ /**
249
+ * Callback when a tile is right-clicked.
250
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
251
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
252
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
253
+ * @example
254
+ * ```tsx
255
+ * onRightClick={(coords) => {
256
+ * showContextMenu(coords.snapped.x, coords.snapped.y);
257
+ * }}
258
+ * ```
259
+ */
259
260
  onRightClick?: onRightClickCallback;
260
- /** Callback when hovering over tiles */
261
+ /**
262
+ * Callback when hovering over tiles.
263
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
264
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
265
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
266
+ * @example
267
+ * ```tsx
268
+ * onHover={(coords) => {
269
+ * setHoveredTile({ x: coords.snapped.x, y: coords.snapped.y });
270
+ * }}
271
+ * ```
272
+ */
261
273
  onHover?: onHoverCallback;
262
- /** Callback on mouse down */
274
+ /**
275
+ * Callback on mouse/touch down.
276
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
277
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
278
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
279
+ * @example
280
+ * ```tsx
281
+ * onMouseDown={(coords) => {
282
+ * startPainting(coords.snapped.x, coords.snapped.y);
283
+ * }}
284
+ * ```
285
+ */
263
286
  onMouseDown?: onMouseDownCallback;
264
- /** Callback on mouse up */
287
+ /**
288
+ * Callback on mouse/touch up.
289
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
290
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
291
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
292
+ * @example
293
+ * ```tsx
294
+ * onMouseUp={() => {
295
+ * stopPainting();
296
+ * }}
297
+ * ```
298
+ */
265
299
  onMouseUp?: onMouseUpCallback;
266
- /** Callback on mouse leave */
300
+ /**
301
+ * Callback when mouse/touch leaves the canvas.
302
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
303
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
304
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
305
+ * @example
306
+ * ```tsx
307
+ * onMouseLeave={() => {
308
+ * clearHoveredTile();
309
+ * }}
310
+ * ```
311
+ */
267
312
  onMouseLeave?: onMouseLeaveCallback;
268
- /** Callback after each draw frame */
313
+ /**
314
+ * Callback after each draw frame. Use for custom canvas drawing.
315
+ * @param ctx - The canvas 2D rendering context
316
+ * @param info - Frame info: `scale`, `width`, `height`, `coords` (center)
317
+ * @example
318
+ * ```tsx
319
+ * onDraw={(ctx, info) => {
320
+ * ctx.fillStyle = "red";
321
+ * ctx.fillText(`Scale: ${info.scale}`, 10, 20);
322
+ * }}
323
+ * ```
324
+ */
269
325
  onDraw?: onDrawCallback;
270
- /** Callback on canvas resize */
326
+ /**
327
+ * Callback on canvas resize.
328
+ * @example
329
+ * ```tsx
330
+ * onResize={() => {
331
+ * console.log("Canvas resized");
332
+ * }}
333
+ * ```
334
+ */
271
335
  onResize?: () => void;
272
- /** Callback when zoom level changes */
336
+ /**
337
+ * Callback when zoom level changes (wheel or pinch).
338
+ * @param scale - The new scale value
339
+ * @example
340
+ * ```tsx
341
+ * onZoom={(scale) => {
342
+ * console.log(`Zoom level: ${scale}`);
343
+ * }}
344
+ * ```
345
+ */
273
346
  onZoom?: onZoomCallback;
274
347
  }
275
348
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var k=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var ie=(r,o)=>{for(var t in o)k(r,t,{get:o[t],enumerable:!0})},se=(r,o,t,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of oe(o))!ae.call(r,n)&&n!==t&&k(r,n,{get:()=>o[n],enumerable:!(a=te(o,n))||a.enumerable});return r};var ce=r=>se(k({},"__esModule",{value:!0}),r);var me={};ie(me,{CanvasTileEngine:()=>j,CanvasTileEngineCore:()=>O.CanvasTileEngine,gridToSize:()=>O.gridToSize,useCanvasTileEngine:()=>z,useEngineContext:()=>c});module.exports=ce(me);var f=require("react"),re=require("@canvas-tile-engine/core");var R=require("react"),S=(0,R.createContext)(null);function c(){let r=(0,R.useContext)(S);if(!r)throw new Error("useEngineContext must be used within a CanvasTileEngine component");return r}var L=require("react");var Y=(0,L.memo)(function({items:o,layer:t=1}){let{engine:a,requestRender:n}=c();return(0,L.useEffect)(()=>{let s=a.drawRect(o,t);return n(),()=>{s&&a.removeLayerHandle(s)}},[a,o,t,n]),null});var h=require("react");var X=(0,h.memo)(function({items:o,layer:t=1}){let{engine:a,requestRender:n}=c();return(0,h.useEffect)(()=>{let s=a.drawCircle(o,t);return n(),()=>{s&&a.removeLayerHandle(s)}},[a,o,t,n]),null});var P=require("react");var W=(0,P.memo)(function({items:o,layer:t=1}){let{engine:a,requestRender:n}=c();return(0,P.useEffect)(()=>{let s=a.drawImage(o,t);return n(),()=>{s&&a.removeLayerHandle(s)}},[a,o,t,n]),null});var I=require("react");var U=(0,I.memo)(function({cellSize:o,lineWidth:t=1,strokeStyle:a="black",layer:n=0}){let{engine:s,requestRender:e}=c();return(0,I.useEffect)(()=>{let i=s.drawGridLines(o,t,a,n);return e(),()=>{i&&s.removeLayerHandle(i)}},[s,o,t,a,n,e]),null});var T=require("react");var N=(0,T.memo)(function({items:o,style:t,layer:a=1}){let{engine:n,requestRender:s}=c();return(0,T.useEffect)(()=>{let e=n.drawLine(o,t,a);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,o,t,a,s]),null});var H=require("react");var Z=(0,H.memo)(function({items:o,style:t,layer:a=2}){let{engine:n,requestRender:s}=c();return(0,H.useEffect)(()=>{let e=n.drawText(o,t,a);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,o,t,a,s]),null});var D=require("react");var J=(0,D.memo)(function({items:o,style:t,layer:a=1}){let{engine:n,requestRender:s}=c();return(0,D.useEffect)(()=>{let e=n.drawPath(o,t,a);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,o,t,a,s]),null});var x=require("react");var Q=(0,x.memo)(function({items:o,cacheKey:t,layer:a=1}){let{engine:n,requestRender:s}=c(),e=(0,x.useRef)(t);return(0,x.useEffect)(()=>{if(o.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let i=n.drawStaticRect(o,t,a);return s(),()=>{i&&n.removeLayerHandle(i)}},[n,o,t,a,s]),(0,x.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var y=require("react");var $=(0,y.memo)(function({items:o,cacheKey:t,layer:a=1}){let{engine:n,requestRender:s}=c(),e=(0,y.useRef)(t);return(0,y.useEffect)(()=>{if(o.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let i=n.drawStaticCircle(o,t,a);return s(),()=>{i&&n.removeLayerHandle(i)}},[n,o,t,a,s]),(0,y.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var v=require("react");var K=(0,v.memo)(function({items:o,cacheKey:t,layer:a=1}){let{engine:n,requestRender:s}=c(),e=(0,v.useRef)(t);return(0,v.useEffect)(()=>{if(o.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let i=n.drawStaticImage(o,t,a);return s(),()=>{i&&n.removeLayerHandle(i)}},[n,o,t,a,s]),(0,v.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var b=require("react");var ee=(0,b.memo)(function({children:o,layer:t=1}){let{engine:a,requestRender:n}=c(),s=(0,b.useRef)(o);return(0,b.useEffect)(()=>{s.current=o}),(0,b.useEffect)(()=>{let e=a.addDrawFunction((i,l,p)=>{s.current(i,l,p)},t);return n(),()=>{e&&a.removeLayerHandle(e)}},[a,t,n]),null});var w=require("react/jsx-runtime");function le({engine:r,config:o,center:t={x:0,y:0},className:a,style:n,children:s,onCoordsChange:e,onClick:i,onRightClick:l,onHover:p,onMouseDown:q,onMouseUp:M,onMouseLeave:F,onDraw:A,onResize:G,onZoom:V}){let d=(0,f.useRef)({onCoordsChange:e,onClick:i,onRightClick:l,onHover:p,onMouseDown:q,onMouseUp:M,onMouseLeave:F,onDraw:A,onResize:G,onZoom:V});(0,f.useEffect)(()=>{d.current={onCoordsChange:e,onClick:i,onRightClick:l,onHover:p,onMouseDown:q,onMouseUp:M,onMouseLeave:F,onDraw:A,onResize:G,onZoom:V}});let E=(0,f.useRef)(null),B=(0,f.useCallback)(()=>{E.current===null&&(E.current=requestAnimationFrame(()=>{E.current=null,r.render()}))},[r]);(0,f.useEffect)(()=>()=>{E.current!==null&&cancelAnimationFrame(E.current)},[]);let ne=(0,f.useMemo)(()=>({engine:r,requestRender:B}),[r,B]);return(0,f.useEffect)(()=>{let _=r._containerRef.current;if(!_)return;let m=new re.CanvasTileEngine(_,o,t);return m.onCoordsChange=u=>d.current.onCoordsChange?.(u),m.onClick=(...u)=>d.current.onClick?.(...u),m.onRightClick=(...u)=>d.current.onRightClick?.(...u),m.onHover=(...u)=>d.current.onHover?.(...u),m.onMouseDown=(...u)=>d.current.onMouseDown?.(...u),m.onMouseUp=(...u)=>d.current.onMouseUp?.(...u),m.onMouseLeave=(...u)=>d.current.onMouseLeave?.(...u),m.onDraw=(...u)=>d.current.onDraw?.(...u),m.onResize=()=>d.current.onResize?.(),m.onZoom=u=>d.current.onZoom?.(u),r._setInstance(m),m.render(),()=>{m.destroy(),r._setInstance(null)}},[r]),(0,w.jsxs)(S.Provider,{value:ne,children:[(0,w.jsx)("div",{ref:r._containerRef,className:a,style:{...n},children:(0,w.jsx)("canvas",{})}),r.isReady&&s]})}var j=Object.assign(le,{Rect:Y,Circle:X,Image:W,GridLines:U,Line:N,Text:Z,Path:J,StaticRect:Q,StaticCircle:$,StaticImage:K,DrawFunction:ee});var C=require("react"),g={layer:-1,id:Symbol("dummy")},ue={size:{width:0,height:0,minWidth:100,minHeight:100,maxWidth:1/0,maxHeight:1/0},responsive:!1,scale:1,minScale:.5,maxScale:2,backgroundColor:"#ffffff",gridAligned:!1,renderer:"canvas",eventHandlers:{drag:!0,zoom:!0,hover:!1,click:!1,rightClick:!1,resize:!1},bounds:{minX:-1/0,maxX:1/0,minY:-1/0,maxY:1/0},coordinates:{enabled:!1,shownScaleRange:{min:0,max:1/0}},cursor:{default:"default",move:"move"},debug:{enabled:!1,hud:{enabled:!1,topLeftCoordinates:!1,coordinates:!1,scale:!1,tilesInView:!1,fps:!1},eventHandlers:{click:!1,hover:!1,drag:!1,zoom:!1,resize:!1}}};function z(){let r=(0,C.useRef)(null),o=(0,C.useRef)(null),[,t]=(0,C.useState)(!1),a=(0,C.useRef)(!1),n=(0,C.useCallback)(e=>{r.current=e,a.current=e!==null,t(e!==null)},[]);return(0,C.useMemo)(()=>({_containerRef:o,_setInstance:n,get isReady(){return a.current},get instance(){return r.current},get images(){return r.current?.images},render(){r.current?.render()},getCenterCoords(){return r.current?.getCenterCoords()??{x:0,y:0}},getVisibleBounds(){return r.current?.getVisibleBounds()??{minX:0,maxX:0,minY:0,maxY:0}},updateCoords(e){r.current?.updateCoords(e)},goCoords(e,i,l,p){r.current?.goCoords(e,i,l,p)},resize(e,i,l,p){r.current?.resize(e,i,l,p)},getSize(){return r.current?.getSize()??{width:0,height:0}},getScale(){return r.current?.getScale()??1},setScale(e){r.current?.setScale(e)},zoomIn(e){r.current?.zoomIn(e)},zoomOut(e){r.current?.zoomOut(e)},getConfig(){return r.current?.getConfig()??ue},setBounds(e){r.current?.setBounds(e)},setEventHandlers(e){r.current?.setEventHandlers(e)},drawRect(e,i){return r.current?.drawRect(e,i)??g},drawStaticRect(e,i,l){return r.current?.drawStaticRect(e,i,l)??g},drawCircle(e,i){return r.current?.drawCircle(e,i)??g},drawStaticCircle(e,i,l){return r.current?.drawStaticCircle(e,i,l)??g},drawLine(e,i,l){return r.current?.drawLine(e,i,l)??g},drawText(e,i,l){return r.current?.drawText(e,i,l)??g},drawPath(e,i,l){return r.current?.drawPath(e,i,l)??g},drawImage(e,i){return r.current?.drawImage(e,i)??g},drawStaticImage(e,i,l){return r.current?.drawStaticImage(e,i,l)??g},drawGridLines(e,i,l,p){return r.current?.drawGridLines(e,i,l,p)??g},addDrawFunction(e,i){return r.current?.addDrawFunction(e,i)??g},clearLayer(e){r.current?.clearLayer(e)},clearAll(){r.current?.clearAll()},clearStaticCache(e){r.current?.clearStaticCache(e)},removeLayerHandle(e){r.current?.removeLayerHandle(e)}}),[n])}var O=require("@canvas-tile-engine/core");0&&(module.exports={CanvasTileEngine,CanvasTileEngineCore,gridToSize,useCanvasTileEngine,useEngineContext});
1
+ "use strict";var z=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ie=Object.prototype.hasOwnProperty;var ae=(r,o)=>{for(var t in o)z(r,t,{get:o[t],enumerable:!0})},se=(r,o,t,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of oe(o))!ie.call(r,n)&&n!==t&&z(r,n,{get:()=>o[n],enumerable:!(i=te(o,n))||i.enumerable});return r};var ce=r=>se(z({},"__esModule",{value:!0}),r);var me={};ae(me,{CanvasTileEngine:()=>q,CanvasTileEngineCore:()=>D.CanvasTileEngine,gridToSize:()=>D.gridToSize,useCanvasTileEngine:()=>F,useEngineContext:()=>c});module.exports=ce(me);var f=require("react"),re=require("@canvas-tile-engine/core");var T=require("react"),L=(0,T.createContext)(null);function c(){let r=(0,T.useContext)(L);if(!r)throw new Error("useEngineContext must be used within a CanvasTileEngine component");return r}var w=require("react");var B=(0,w.memo)(function({items:o,layer:t=1}){let{engine:i,requestRender:n}=c();return(0,w.useEffect)(()=>{let s=i.drawRect(o,t);return n(),()=>{s&&i.removeLayerHandle(s)}},[i,o,t,n]),null});var P=require("react");var O=(0,P.memo)(function({items:o,layer:t=1}){let{engine:i,requestRender:n}=c();return(0,P.useEffect)(()=>{let s=i.drawCircle(o,t);return n(),()=>{s&&i.removeLayerHandle(s)}},[i,o,t,n]),null});var h=require("react");var U=(0,h.memo)(function({items:o,layer:t=1}){let{engine:i,requestRender:n}=c();return(0,h.useEffect)(()=>{let s=i.drawImage(o,t);return n(),()=>{s&&i.removeLayerHandle(s)}},[i,o,t,n]),null});var S=require("react");var j=(0,S.memo)(function({cellSize:o,lineWidth:t=1,strokeStyle:i="black",layer:n=0}){let{engine:s,requestRender:e}=c();return(0,S.useEffect)(()=>{let a=s.drawGridLines(o,t,i,n);return e(),()=>{a&&s.removeLayerHandle(a)}},[s,o,t,i,n,e]),null});var I=require("react");var N=(0,I.memo)(function({items:o,style:t,layer:i=1}){let{engine:n,requestRender:s}=c();return(0,I.useEffect)(()=>{let e=n.drawLine(o,t,i);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,o,t,i,s]),null});var H=require("react");var Z=(0,H.memo)(function({items:o,layer:t=2}){let{engine:i,requestRender:n}=c();return(0,H.useEffect)(()=>{let s=i.drawText(o,t);return n(),()=>{s&&i.removeLayerHandle(s)}},[i,o,t,n]),null});var k=require("react");var J=(0,k.memo)(function({items:o,style:t,layer:i=1}){let{engine:n,requestRender:s}=c();return(0,k.useEffect)(()=>{let e=n.drawPath(o,t,i);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,o,t,i,s]),null});var y=require("react");var Q=(0,y.memo)(function({items:o,cacheKey:t,layer:i=1}){let{engine:n,requestRender:s}=c(),e=(0,y.useRef)(t);return(0,y.useEffect)(()=>{if(o.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let a=n.drawStaticRect(o,t,i);return s(),()=>{a&&n.removeLayerHandle(a)}},[n,o,t,i,s]),(0,y.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var x=require("react");var $=(0,x.memo)(function({items:o,cacheKey:t,layer:i=1}){let{engine:n,requestRender:s}=c(),e=(0,x.useRef)(t);return(0,x.useEffect)(()=>{if(o.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let a=n.drawStaticCircle(o,t,i);return s(),()=>{a&&n.removeLayerHandle(a)}},[n,o,t,i,s]),(0,x.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var v=require("react");var K=(0,v.memo)(function({items:o,cacheKey:t,layer:i=1}){let{engine:n,requestRender:s}=c(),e=(0,v.useRef)(t);return(0,v.useEffect)(()=>{if(o.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let a=n.drawStaticImage(o,t,i);return s(),()=>{a&&n.removeLayerHandle(a)}},[n,o,t,i,s]),(0,v.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var b=require("react");var ee=(0,b.memo)(function({children:o,layer:t=1}){let{engine:i,requestRender:n}=c(),s=(0,b.useRef)(o);return(0,b.useEffect)(()=>{s.current=o}),(0,b.useEffect)(()=>{let e=i.addDrawFunction((a,u,g)=>{s.current(a,u,g)},t);return n(),()=>{e&&i.removeLayerHandle(e)}},[i,t,n]),null});var R=require("react/jsx-runtime");function ue({engine:r,config:o,center:t={x:0,y:0},className:i,style:n,children:s,onCoordsChange:e,onClick:a,onRightClick:u,onHover:g,onMouseDown:M,onMouseUp:G,onMouseLeave:V,onDraw:_,onResize:Y,onZoom:A}){let d=(0,f.useRef)({onCoordsChange:e,onClick:a,onRightClick:u,onHover:g,onMouseDown:M,onMouseUp:G,onMouseLeave:V,onDraw:_,onResize:Y,onZoom:A});(0,f.useEffect)(()=>{d.current={onCoordsChange:e,onClick:a,onRightClick:u,onHover:g,onMouseDown:M,onMouseUp:G,onMouseLeave:V,onDraw:_,onResize:Y,onZoom:A}});let E=(0,f.useRef)(null),W=(0,f.useCallback)(()=>{E.current===null&&(E.current=requestAnimationFrame(()=>{E.current=null,r.render()}))},[r]);(0,f.useEffect)(()=>()=>{E.current!==null&&cancelAnimationFrame(E.current)},[]);let ne=(0,f.useMemo)(()=>({engine:r,requestRender:W}),[r,W]);return(0,f.useEffect)(()=>{let X=r._containerRef.current;if(!X)return;let m=new re.CanvasTileEngine(X,o,t);return m.onCoordsChange=l=>d.current.onCoordsChange?.(l),m.onClick=(...l)=>d.current.onClick?.(...l),m.onRightClick=(...l)=>d.current.onRightClick?.(...l),m.onHover=(...l)=>d.current.onHover?.(...l),m.onMouseDown=(...l)=>d.current.onMouseDown?.(...l),m.onMouseUp=(...l)=>d.current.onMouseUp?.(...l),m.onMouseLeave=(...l)=>d.current.onMouseLeave?.(...l),m.onDraw=(...l)=>d.current.onDraw?.(...l),m.onResize=()=>d.current.onResize?.(),m.onZoom=l=>d.current.onZoom?.(l),r._setInstance(m),m.render(),()=>{m.destroy(),r._setInstance(null)}},[r]),(0,R.jsxs)(L.Provider,{value:ne,children:[(0,R.jsx)("div",{ref:r._containerRef,className:i,style:{...n},children:(0,R.jsx)("canvas",{})}),r.isReady&&s]})}var q=Object.assign(ue,{Rect:B,Circle:O,Image:U,GridLines:j,Line:N,Text:Z,Path:J,StaticRect:Q,StaticCircle:$,StaticImage:K,DrawFunction:ee});var C=require("react"),p={layer:-1,id:Symbol("dummy")},le={size:{width:0,height:0,minWidth:100,minHeight:100,maxWidth:1/0,maxHeight:1/0},responsive:!1,scale:1,minScale:.5,maxScale:2,backgroundColor:"#ffffff",gridAligned:!1,renderer:"canvas",eventHandlers:{drag:!0,zoom:!0,hover:!1,click:!1,rightClick:!1,resize:!1},bounds:{minX:-1/0,maxX:1/0,minY:-1/0,maxY:1/0},coordinates:{enabled:!1,shownScaleRange:{min:0,max:1/0}},cursor:{default:"default",move:"move"},debug:{enabled:!1,hud:{enabled:!1,topLeftCoordinates:!1,coordinates:!1,scale:!1,tilesInView:!1,fps:!1},eventHandlers:{click:!1,hover:!1,drag:!1,zoom:!1,resize:!1}}};function F(){let r=(0,C.useRef)(null),o=(0,C.useRef)(null),[,t]=(0,C.useState)(!1),i=(0,C.useRef)(!1),n=(0,C.useCallback)(e=>{r.current=e,i.current=e!==null,t(e!==null)},[]);return(0,C.useMemo)(()=>({_containerRef:o,_setInstance:n,get isReady(){return i.current},get instance(){return r.current},get images(){return r.current?.images},render(){r.current?.render()},getCenterCoords(){return r.current?.getCenterCoords()??{x:0,y:0}},getVisibleBounds(){return r.current?.getVisibleBounds()??{minX:0,maxX:0,minY:0,maxY:0}},updateCoords(e){r.current?.updateCoords(e)},goCoords(e,a,u,g){r.current?.goCoords(e,a,u,g)},resize(e,a,u,g){r.current?.resize(e,a,u,g)},getSize(){return r.current?.getSize()??{width:0,height:0}},getScale(){return r.current?.getScale()??1},setScale(e){r.current?.setScale(e)},zoomIn(e){r.current?.zoomIn(e)},zoomOut(e){r.current?.zoomOut(e)},getConfig(){return r.current?.getConfig()??le},setBounds(e){r.current?.setBounds(e)},setEventHandlers(e){r.current?.setEventHandlers(e)},drawRect(e,a){return r.current?.drawRect(e,a)??p},drawStaticRect(e,a,u){return r.current?.drawStaticRect(e,a,u)??p},drawCircle(e,a){return r.current?.drawCircle(e,a)??p},drawStaticCircle(e,a,u){return r.current?.drawStaticCircle(e,a,u)??p},drawLine(e,a,u){return r.current?.drawLine(e,a,u)??p},drawText(e,a){return r.current?.drawText(e,a)??p},drawPath(e,a,u){return r.current?.drawPath(e,a,u)??p},drawImage(e,a){return r.current?.drawImage(e,a)??p},drawStaticImage(e,a,u){return r.current?.drawStaticImage(e,a,u)??p},drawGridLines(e,a,u,g){return r.current?.drawGridLines(e,a,u,g)??p},addDrawFunction(e,a){return r.current?.addDrawFunction(e,a)??p},clearLayer(e){r.current?.clearLayer(e)},clearAll(){r.current?.clearAll()},clearStaticCache(e){r.current?.clearStaticCache(e)},removeLayerHandle(e){r.current?.removeLayerHandle(e)},loadImage(e,a){return r.current?r.current.images.load(e,a):Promise.reject(new Error("Engine not ready. Wait for isReady before loading images."))}}),[n])}var D=require("@canvas-tile-engine/core");0&&(module.exports={CanvasTileEngine,CanvasTileEngineCore,gridToSize,useCanvasTileEngine,useEngineContext});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/CanvasTileEngine.tsx","../src/context/EngineContext.tsx","../src/components/draw/Rect.tsx","../src/components/draw/Circle.tsx","../src/components/draw/Image.tsx","../src/components/draw/GridLines.tsx","../src/components/draw/Line.tsx","../src/components/draw/Text.tsx","../src/components/draw/Path.tsx","../src/components/draw/StaticRect.tsx","../src/components/draw/StaticCircle.tsx","../src/components/draw/StaticImage.tsx","../src/components/draw/DrawFunction.tsx","../src/hooks/useCanvasTileEngine.ts"],"sourcesContent":["// Main component\nexport { CanvasTileEngine } from \"./components\";\n\n// Draw components\nexport {\n type RectProps,\n type CircleProps,\n type ImageProps,\n type GridLinesProps,\n type LineProps,\n type TextProps,\n type PathProps,\n type StaticRectProps,\n type StaticCircleProps,\n type StaticImageProps,\n type DrawFunctionProps,\n} from \"./components\";\n\n// Hooks\nexport { useCanvasTileEngine } from \"./hooks\";\n\n// Context\nexport { useEngineContext, type EngineContextValue } from \"./context\";\n\n// Types\nexport type {\n CanvasTileEngineProps,\n CanvasTileEngineConfig,\n Coords,\n DrawObject,\n EventHandlers,\n onClickCallback,\n onHoverCallback,\n onMouseDownCallback,\n onMouseUpCallback,\n onMouseLeaveCallback,\n onDrawCallback,\n Rect,\n Line,\n Circle,\n Text,\n Path,\n ImageItem,\n} from \"./types\";\nexport type { EngineHandle } from \"./hooks/useCanvasTileEngine\";\n\n// Re-export core class and utilities\nexport { CanvasTileEngine as CanvasTileEngineCore, gridToSize } from \"@canvas-tile-engine/core\";\n","import { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { CanvasTileEngine as CanvasTileEngineCore } from \"@canvas-tile-engine/core\";\nimport { EngineContext, type EngineContextValue } from \"../context/EngineContext\";\nimport type { CanvasTileEngineProps } from \"../types\";\n\n// Import draw components for compound pattern\nimport { Rect } from \"./draw/Rect\";\nimport { Circle } from \"./draw/Circle\";\nimport { Image } from \"./draw/Image\";\nimport { GridLines } from \"./draw/GridLines\";\nimport { Line } from \"./draw/Line\";\nimport { Text } from \"./draw/Text\";\nimport { Path } from \"./draw/Path\";\nimport { StaticRect } from \"./draw/StaticRect\";\nimport { StaticCircle } from \"./draw/StaticCircle\";\nimport { StaticImage } from \"./draw/StaticImage\";\nimport { DrawFunction } from \"./draw/DrawFunction\";\n\n/**\n * React component that renders a CanvasTileEngine.\n * Supports both imperative API (via engine handle) and declarative API (via children).\n *\n * @example Declarative API with compound components\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * return (\n * <CanvasTileEngine engine={engine} config={config}>\n * <CanvasTileEngine.GridLines cellSize={50} layer={0} />\n * <CanvasTileEngine.Image items={imageItems} layer={1} />\n * <CanvasTileEngine.Circle items={markers} layer={2} />\n * </CanvasTileEngine>\n * );\n * }\n * ```\n *\n * @example Imperative API\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (engine.isReady) {\n * engine.drawGridLines(50);\n * engine.render();\n * }\n * }, [engine.isReady]);\n *\n * return <CanvasTileEngine engine={engine} config={config} />;\n * }\n * ```\n */\nfunction CanvasTileEngineBase({\n engine,\n config,\n center = { x: 0, y: 0 },\n className,\n style,\n children,\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n}: CanvasTileEngineProps) {\n // Stable callback refs\n const callbacksRef = useRef({\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n });\n\n // Update callback refs\n useEffect(() => {\n callbacksRef.current = {\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n };\n });\n\n // Debounced render - multiple draw components calling requestRender\n // in the same frame will trigger only one render\n const rafIdRef = useRef<number | null>(null);\n const requestRender = useCallback(() => {\n if (rafIdRef.current !== null) return;\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n engine.render();\n });\n }, [engine]);\n\n // Cleanup RAF on unmount\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n };\n }, []);\n\n // Context value\n const contextValue = useMemo<EngineContextValue>(\n () => ({\n engine,\n requestRender,\n }),\n [engine, requestRender]\n );\n\n // Initialize engine when component mounts\n // Note: config and center are intentionally not in deps - we only want to create the engine once\n // Callbacks are accessed via callbacksRef which is always up-to-date\n useEffect(() => {\n const container = engine._containerRef.current;\n\n if (!container) {\n return;\n }\n\n // Create engine instance\n const instance = new CanvasTileEngineCore(container, config, center);\n\n // Set up callbacks using stable refs\n instance.onCoordsChange = (coords) => callbacksRef.current.onCoordsChange?.(coords);\n instance.onClick = (...args) => callbacksRef.current.onClick?.(...args);\n instance.onRightClick = (...args) => callbacksRef.current.onRightClick?.(...args);\n instance.onHover = (...args) => callbacksRef.current.onHover?.(...args);\n instance.onMouseDown = (...args) => callbacksRef.current.onMouseDown?.(...args);\n instance.onMouseUp = (...args) => callbacksRef.current.onMouseUp?.(...args);\n instance.onMouseLeave = (...args) => callbacksRef.current.onMouseLeave?.(...args);\n instance.onDraw = (...args) => callbacksRef.current.onDraw?.(...args);\n instance.onResize = () => callbacksRef.current.onResize?.();\n instance.onZoom = (scale) => callbacksRef.current.onZoom?.(scale);\n\n // Attach to handle\n engine._setInstance(instance);\n\n // Initial render\n instance.render();\n\n // Cleanup on unmount\n return () => {\n instance.destroy();\n engine._setInstance(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine]);\n\n return (\n <EngineContext.Provider value={contextValue}>\n <div\n ref={engine._containerRef}\n className={className}\n style={{\n ...style,\n }}\n >\n <canvas />\n </div>\n {/* Render children only when engine is ready */}\n {engine.isReady && children}\n </EngineContext.Provider>\n );\n}\n\n// Compound component pattern - attach draw components as static properties\nexport const CanvasTileEngine = Object.assign(CanvasTileEngineBase, {\n Rect,\n Circle,\n Image,\n GridLines,\n Line,\n Text,\n Path,\n StaticRect,\n StaticCircle,\n StaticImage,\n DrawFunction,\n});\n","import { createContext, useContext } from \"react\";\nimport type { EngineHandle } from \"../hooks/useCanvasTileEngine\";\n\nexport interface EngineContextValue {\n engine: EngineHandle;\n /** Request a re-render of the canvas */\n requestRender: () => void;\n}\n\nexport const EngineContext = createContext<EngineContextValue | null>(null);\n\n/**\n * Hook to access the engine context from child components.\n * Must be used within a CanvasTileEngine component.\n */\nexport function useEngineContext(): EngineContextValue {\n const context = useContext(EngineContext);\n\n if (!context) {\n throw new Error(\"useEngineContext must be used within a CanvasTileEngine component\");\n }\n\n return context;\n}\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface RectProps {\n items: DrawObject | DrawObject[];\n layer?: number;\n}\n\n/**\n * Draws rectangles on the canvas.\n */\nexport const Rect = memo(function Rect({ items, layer = 1 }: RectProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawRect(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface CircleProps {\n items: DrawObject | DrawObject[];\n layer?: number;\n}\n\n/**\n * Draws circles on the canvas.\n */\nexport const Circle = memo(function Circle({ items, layer = 1 }: CircleProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawCircle(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface ImageProps {\n items: ImageItem | ImageItem[];\n layer?: number;\n}\n\n/**\n * Draws images on the canvas.\n */\nexport const Image = memo(function Image({ items, layer = 1 }: ImageProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawImage(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\n\nexport interface GridLinesProps {\n cellSize: number;\n lineWidth?: number;\n strokeStyle?: string;\n layer?: number;\n}\n\n/**\n * Draws grid lines on the canvas.\n * Multiple GridLines can share the same layer (additive drawing).\n */\nexport const GridLines = memo(function GridLines({ cellSize, lineWidth = 1, strokeStyle = \"black\", layer = 0 }: GridLinesProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawGridLines(cellSize, lineWidth, strokeStyle, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, cellSize, lineWidth, strokeStyle, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Coords } from \"@canvas-tile-engine/core\";\n\nexport interface LineProps {\n items: { from: Coords; to: Coords } | { from: Coords; to: Coords }[];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws lines on the canvas.\n */\nexport const Line = memo(function Line({ items, style, layer = 1 }: LineProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawLine(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Coords } from \"@canvas-tile-engine/core\";\n\nexport interface TextProps {\n items: { coords: Coords; text: string } | { coords: Coords; text: string }[];\n style?: {\n fillStyle?: string;\n font?: string;\n textAlign?: CanvasTextAlign;\n textBaseline?: CanvasTextBaseline;\n };\n layer?: number;\n}\n\n/**\n * Draws text on the canvas.\n */\nexport const Text = memo(function Text({ items, style, layer = 2 }: TextProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawText(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Coords } from \"@canvas-tile-engine/core\";\n\nexport interface PathProps {\n items: Coords[] | Coords[][];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws paths/polylines on the canvas.\n */\nexport const Path = memo(function Path({ items, style, layer = 1 }: PathProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawPath(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface StaticRectProps {\n items: DrawObject[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static rectangles with caching for performance.\n * Ideal for large datasets that don't change frequently.\n */\nexport const StaticRect = memo(function StaticRect({ items, cacheKey, layer = 1 }: StaticRectProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n // Clear previous cache if cacheKey changed\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticRect(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface StaticCircleProps {\n items: DrawObject[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static circles with caching for performance.\n */\nexport const StaticCircle = memo(function StaticCircle({ items, cacheKey, layer = 1 }: StaticCircleProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticCircle(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface StaticImageProps {\n items: ImageItem[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static images with caching for performance.\n * Ideal for terrain tiles or static decorations.\n */\nexport const StaticImage = memo(function StaticImage({ items, cacheKey, layer = 1 }: StaticImageProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticImage(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { CanvasTileEngineConfig, Coords } from \"@canvas-tile-engine/core\";\n\nexport interface DrawFunctionProps {\n /** The draw function to execute */\n children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;\n layer?: number;\n}\n\n/**\n * Custom draw function component.\n * Allows arbitrary canvas drawing within the engine's render cycle.\n * Multiple DrawFunction components can share the same layer (additive drawing).\n *\n * @example\n * ```tsx\n * <DrawFunction layer={3}>\n * {(ctx, coords, config) => {\n * ctx.fillStyle = \"red\";\n * ctx.fillRect(config.size.width / 2 - 5, config.size.height / 2 - 5, 10, 10);\n * }}\n * </DrawFunction>\n * ```\n */\nexport const DrawFunction = memo(function DrawFunction({ children, layer = 1 }: DrawFunctionProps) {\n const { engine, requestRender } = useEngineContext();\n const fnRef = useRef(children);\n\n // Keep function ref updated\n useEffect(() => {\n fnRef.current = children;\n });\n\n useEffect(() => {\n const handle = engine.addDrawFunction((ctx, coords, config) => {\n fnRef.current(ctx, coords, config);\n }, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, layer, requestRender]);\n\n return null;\n});\n","import { useRef, useCallback, useState, useMemo } from \"react\";\nimport type {\n CanvasTileEngine as CanvasTileEngineCore,\n CanvasTileEngineConfig,\n Coords,\n DrawObject,\n EventHandlers,\n LayerHandle,\n} from \"@canvas-tile-engine/core\";\n\n/** Dummy handle returned when engine is not ready */\nconst DUMMY_LAYER_HANDLE: LayerHandle = { layer: -1, id: Symbol(\"dummy\") };\n\n/** Default config when engine is not ready */\nconst DEFAULT_CONFIG: Required<CanvasTileEngineConfig> = {\n size: { width: 0, height: 0, minWidth: 100, minHeight: 100, maxWidth: Infinity, maxHeight: Infinity },\n responsive: false,\n scale: 1,\n minScale: 0.5,\n maxScale: 2,\n backgroundColor: \"#ffffff\",\n gridAligned: false,\n renderer: \"canvas\",\n eventHandlers: {\n drag: true,\n zoom: true,\n hover: false,\n click: false,\n rightClick: false,\n resize: false,\n },\n bounds: {\n minX: -Infinity,\n maxX: Infinity,\n minY: -Infinity,\n maxY: Infinity,\n },\n coordinates: {\n enabled: false,\n shownScaleRange: { min: 0, max: Infinity },\n },\n cursor: {\n default: \"default\",\n move: \"move\",\n },\n debug: {\n enabled: false,\n hud: {\n enabled: false,\n topLeftCoordinates: false,\n coordinates: false,\n scale: false,\n tilesInView: false,\n fps: false,\n },\n eventHandlers: {\n click: false,\n hover: false,\n drag: false,\n zoom: false,\n resize: false,\n },\n },\n};\n\n/**\n * Engine handle returned by useCanvasTileEngine hook.\n * Provides access to engine methods with proper typing.\n *\n * All methods return default/dummy values when engine is not ready,\n * allowing safe usage without null checks.\n */\nexport interface EngineHandle {\n /** @internal - Used by CanvasTileEngine component */\n readonly _containerRef: React.RefObject<HTMLDivElement>;\n /** @internal - Used by CanvasTileEngine component */\n _setInstance: (engine: CanvasTileEngineCore | null) => void;\n\n /** Whether the engine is ready (mounted and initialized) */\n readonly isReady: boolean;\n\n /** The underlying engine instance (null until component mounts) */\n readonly instance: CanvasTileEngineCore | null;\n\n /** Render a frame */\n render(): void;\n\n /** Get current center coordinates */\n getCenterCoords(): Coords;\n\n /** Get visible world coordinate bounds of the viewport */\n getVisibleBounds(): { minX: number; maxX: number; minY: number; maxY: number };\n\n /** Update center coordinates */\n updateCoords(center: Coords): void;\n\n /** Animate to target coordinates */\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Resize the canvas */\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Get current canvas size */\n getSize(): { width: number; height: number };\n\n /** Get current canvas scale */\n getScale(): number;\n\n /** Set the canvas scale directly, clamped to min/max bounds. */\n setScale(newScale: number): void;\n\n /** Zoom in by a factor (default: 1.5) */\n zoomIn(factor?: number): void;\n\n /** Zoom out by a factor (default: 1.5) */\n zoomOut(factor?: number): void;\n\n /** Get current config */\n getConfig(): Required<CanvasTileEngineConfig>;\n\n /** Set map boundaries */\n setBounds(bounds: { minX: number; maxX: number; minY: number; maxY: number }): void;\n\n /** Dynamically update event handlers at runtime */\n setEventHandlers(handlers: Partial<EventHandlers>): void;\n\n /** Draw rectangles */\n drawRect(items: DrawObject | DrawObject[], layer?: number): LayerHandle;\n\n /** Draw static rectangles (cached) */\n drawStaticRect(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw circles */\n drawCircle(items: DrawObject | DrawObject[], layer?: number): LayerHandle;\n\n /** Draw static circles (cached) */\n drawStaticCircle(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw lines */\n drawLine(\n items: { from: Coords; to: Coords } | { from: Coords; to: Coords }[],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): LayerHandle;\n\n /** Draw text */\n drawText(\n items: { coords: Coords; text: string } | { coords: Coords; text: string }[],\n style?: { fillStyle?: string; font?: string; textAlign?: CanvasTextAlign; textBaseline?: CanvasTextBaseline },\n layer?: number\n ): LayerHandle;\n\n /** Draw paths/polylines */\n drawPath(\n items: Coords[] | Coords[][],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): LayerHandle;\n\n /** Draw images */\n drawImage(\n items:\n | (Omit<DrawObject, \"style\"> & { img: HTMLImageElement })\n | (Omit<DrawObject, \"style\"> & { img: HTMLImageElement })[],\n layer?: number\n ): LayerHandle;\n\n /** Draw static images (cached) */\n drawStaticImage(\n items: (Omit<DrawObject, \"style\"> & { img: HTMLImageElement })[],\n cacheKey: string,\n layer?: number\n ): LayerHandle;\n\n /** Draw grid lines */\n drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;\n\n /** Add custom draw function */\n addDrawFunction(\n fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void,\n layer?: number\n ): LayerHandle;\n\n /** Clear a specific layer */\n clearLayer(layer: number): void;\n\n /** Clear all layers */\n clearAll(): void;\n\n /** Clear static cache */\n clearStaticCache(cacheKey?: string): void;\n\n /** Remove a previously registered draw callback */\n removeLayerHandle(handle: LayerHandle): void;\n\n /** Image loader instance (undefined until engine mounts) */\n readonly images: CanvasTileEngineCore[\"images\"] | undefined;\n}\n\n/**\n * React hook that creates an engine handle for use with CanvasTileEngine component.\n *\n * @returns Engine handle to pass to CanvasTileEngine component\n *\n * @example\n * ```tsx\n * function App() {\n * const mainMap = useCanvasTileEngine();\n * const miniMap = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (mainMap.isReady && miniMap.isReady) {\n * // Both engines are ready, draw items\n * mainMap.drawGridLines(50);\n * mainMap.render();\n * }\n * }, [mainMap.isReady, miniMap.isReady]);\n *\n * return (\n * <>\n * <CanvasTileEngine engine={mainMap} config={...} />\n * <CanvasTileEngine engine={miniMap} config={...} />\n * </>\n * );\n * }\n * ```\n */\nexport function useCanvasTileEngine(): EngineHandle {\n const instanceRef = useRef<CanvasTileEngineCore | null>(null);\n const containerRef = useRef<HTMLDivElement>(null!);\n // _isReady state is only used to trigger re-renders, actual value is read from isReadyRef\n const [, setIsReady] = useState(false);\n // Keep isReady in a ref so the handle getter can read it without recreating handle\n const isReadyRef = useRef(false);\n\n const setInstance = useCallback((engine: CanvasTileEngineCore | null) => {\n instanceRef.current = engine;\n isReadyRef.current = engine !== null;\n setIsReady(engine !== null);\n }, []);\n\n // Create stable handle object using useMemo\n // Note: isReady is NOT in deps - we read from isReadyRef to keep handle stable\n const handle = useMemo<EngineHandle>(\n () => ({\n _containerRef: containerRef,\n _setInstance: setInstance,\n\n get isReady() {\n return isReadyRef.current;\n },\n\n get instance() {\n return instanceRef.current;\n },\n\n get images() {\n return instanceRef.current?.images;\n },\n\n render() {\n instanceRef.current?.render();\n },\n\n getCenterCoords() {\n return instanceRef.current?.getCenterCoords() ?? { x: 0, y: 0 };\n },\n\n getVisibleBounds() {\n return instanceRef.current?.getVisibleBounds() ?? { minX: 0, maxX: 0, minY: 0, maxY: 0 };\n },\n\n updateCoords(center: Coords) {\n instanceRef.current?.updateCoords(center);\n },\n\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.goCoords(x, y, durationMs, onComplete);\n },\n\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.resize(width, height, durationMs, onComplete);\n },\n\n getSize() {\n return instanceRef.current?.getSize() ?? { width: 0, height: 0 };\n },\n\n getScale() {\n return instanceRef.current?.getScale() ?? 1;\n },\n\n setScale(newScale: number) {\n instanceRef.current?.setScale(newScale);\n },\n\n zoomIn(factor?: number) {\n instanceRef.current?.zoomIn(factor);\n },\n\n zoomOut(factor?: number) {\n instanceRef.current?.zoomOut(factor);\n },\n\n getConfig() {\n return instanceRef.current?.getConfig() ?? DEFAULT_CONFIG;\n },\n\n setBounds(bounds) {\n instanceRef.current?.setBounds(bounds);\n },\n\n setEventHandlers(handlers) {\n instanceRef.current?.setEventHandlers(handlers);\n },\n\n drawRect(items, layer) {\n return instanceRef.current?.drawRect(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticRect(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticRect(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawCircle(items, layer) {\n return instanceRef.current?.drawCircle(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticCircle(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticCircle(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawLine(items, style, layer) {\n return instanceRef.current?.drawLine(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawText(items, style, layer) {\n return instanceRef.current?.drawText(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawPath(items, style, layer) {\n return instanceRef.current?.drawPath(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawImage(items, layer) {\n return instanceRef.current?.drawImage(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticImage(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticImage(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawGridLines(cellSize, lineWidth, strokeStyle, layer) {\n return (\n instanceRef.current?.drawGridLines(cellSize, lineWidth, strokeStyle, layer) ?? DUMMY_LAYER_HANDLE\n );\n },\n\n addDrawFunction(fn, layer) {\n return instanceRef.current?.addDrawFunction(fn, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n clearLayer(layer) {\n instanceRef.current?.clearLayer(layer);\n },\n\n clearAll() {\n instanceRef.current?.clearAll();\n },\n\n clearStaticCache(cacheKey) {\n instanceRef.current?.clearStaticCache(cacheKey);\n },\n\n removeLayerHandle(handle) {\n instanceRef.current?.removeLayerHandle(handle);\n },\n }),\n [setInstance]\n );\n\n return handle;\n}\n"],"mappings":"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","names":["index_exports","__export","CanvasTileEngine","useCanvasTileEngine","useEngineContext","__toCommonJS","import_react","import_core","import_react","EngineContext","useEngineContext","context","import_react","Rect","items","layer","engine","requestRender","useEngineContext","handle","import_react","Circle","items","layer","engine","requestRender","useEngineContext","handle","import_react","Image","items","layer","engine","requestRender","useEngineContext","handle","import_react","GridLines","cellSize","lineWidth","strokeStyle","layer","engine","requestRender","useEngineContext","handle","import_react","Line","items","style","layer","engine","requestRender","useEngineContext","handle","import_react","Text","items","style","layer","engine","requestRender","useEngineContext","handle","import_react","Path","items","style","layer","engine","requestRender","useEngineContext","handle","import_react","StaticRect","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","handle","import_react","StaticCircle","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","handle","import_react","StaticImage","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","handle","import_react","DrawFunction","children","layer","engine","requestRender","useEngineContext","fnRef","handle","ctx","coords","config","import_jsx_runtime","CanvasTileEngineBase","engine","config","center","className","style","children","onCoordsChange","onClick","onRightClick","onHover","onMouseDown","onMouseUp","onMouseLeave","onDraw","onResize","onZoom","callbacksRef","rafIdRef","requestRender","contextValue","container","instance","CanvasTileEngineCore","coords","args","scale","EngineContext","CanvasTileEngine","Rect","Circle","Image","GridLines","Line","Text","Path","StaticRect","StaticCircle","StaticImage","DrawFunction","import_react","DUMMY_LAYER_HANDLE","DEFAULT_CONFIG","useCanvasTileEngine","instanceRef","containerRef","setIsReady","isReadyRef","setInstance","engine","center","x","y","durationMs","onComplete","width","height","newScale","factor","bounds","handlers","items","layer","cacheKey","style","cellSize","lineWidth","strokeStyle","fn","handle","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/CanvasTileEngine.tsx","../src/context/EngineContext.tsx","../src/components/draw/Rect.tsx","../src/components/draw/Circle.tsx","../src/components/draw/Image.tsx","../src/components/draw/GridLines.tsx","../src/components/draw/Line.tsx","../src/components/draw/Text.tsx","../src/components/draw/Path.tsx","../src/components/draw/StaticRect.tsx","../src/components/draw/StaticCircle.tsx","../src/components/draw/StaticImage.tsx","../src/components/draw/DrawFunction.tsx","../src/hooks/useCanvasTileEngine.ts"],"sourcesContent":["// Main component\nexport { CanvasTileEngine } from \"./components\";\n\n// Draw components\nexport {\n type RectProps,\n type CircleProps,\n type ImageProps,\n type GridLinesProps,\n type LineProps,\n type TextProps,\n type PathProps,\n type StaticRectProps,\n type StaticCircleProps,\n type StaticImageProps,\n type DrawFunctionProps,\n} from \"./components\";\n\n// Hooks\nexport { useCanvasTileEngine } from \"./hooks\";\n\n// Context\nexport { useEngineContext, type EngineContextValue } from \"./context\";\n\n// Types\nexport type {\n CanvasTileEngineProps,\n CanvasTileEngineConfig,\n Coords,\n DrawObject,\n EventHandlers,\n onClickCallback,\n onHoverCallback,\n onMouseDownCallback,\n onMouseUpCallback,\n onMouseLeaveCallback,\n onDrawCallback,\n Rect,\n Line,\n Circle,\n Text,\n Path,\n ImageItem,\n} from \"./types\";\nexport type { EngineHandle } from \"./hooks/useCanvasTileEngine\";\n\n// Re-export core class and utilities\nexport { CanvasTileEngine as CanvasTileEngineCore, gridToSize } from \"@canvas-tile-engine/core\";\n","import { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { CanvasTileEngine as CanvasTileEngineCore } from \"@canvas-tile-engine/core\";\nimport { EngineContext, type EngineContextValue } from \"../context/EngineContext\";\nimport type { CanvasTileEngineProps } from \"../types\";\n\n// Import draw components for compound pattern\nimport { Rect } from \"./draw/Rect\";\nimport { Circle } from \"./draw/Circle\";\nimport { Image } from \"./draw/Image\";\nimport { GridLines } from \"./draw/GridLines\";\nimport { Line } from \"./draw/Line\";\nimport { Text } from \"./draw/Text\";\nimport { Path } from \"./draw/Path\";\nimport { StaticRect } from \"./draw/StaticRect\";\nimport { StaticCircle } from \"./draw/StaticCircle\";\nimport { StaticImage } from \"./draw/StaticImage\";\nimport { DrawFunction } from \"./draw/DrawFunction\";\n\n/**\n * React component that renders a CanvasTileEngine.\n * Supports both imperative API (via engine handle) and declarative API (via children).\n *\n * @example Declarative API with compound components\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * return (\n * <CanvasTileEngine engine={engine} config={config}>\n * <CanvasTileEngine.GridLines cellSize={50} layer={0} />\n * <CanvasTileEngine.Image items={imageItems} layer={1} />\n * <CanvasTileEngine.Circle items={markers} layer={2} />\n * </CanvasTileEngine>\n * );\n * }\n * ```\n *\n * @example Imperative API\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (engine.isReady) {\n * engine.drawGridLines(50);\n * engine.render();\n * }\n * }, [engine.isReady]);\n *\n * return <CanvasTileEngine engine={engine} config={config} />;\n * }\n * ```\n */\nfunction CanvasTileEngineBase({\n engine,\n config,\n center = { x: 0, y: 0 },\n className,\n style,\n children,\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n}: CanvasTileEngineProps) {\n // Stable callback refs\n const callbacksRef = useRef({\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n });\n\n // Update callback refs\n useEffect(() => {\n callbacksRef.current = {\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n };\n });\n\n // Debounced render - multiple draw components calling requestRender\n // in the same frame will trigger only one render\n const rafIdRef = useRef<number | null>(null);\n const requestRender = useCallback(() => {\n if (rafIdRef.current !== null) return;\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n engine.render();\n });\n }, [engine]);\n\n // Cleanup RAF on unmount\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n };\n }, []);\n\n // Context value\n const contextValue = useMemo<EngineContextValue>(\n () => ({\n engine,\n requestRender,\n }),\n [engine, requestRender]\n );\n\n // Initialize engine when component mounts\n // Note: config and center are intentionally not in deps - we only want to create the engine once\n // Callbacks are accessed via callbacksRef which is always up-to-date\n useEffect(() => {\n const container = engine._containerRef.current;\n\n if (!container) {\n return;\n }\n\n // Create engine instance\n const instance = new CanvasTileEngineCore(container, config, center);\n\n // Set up callbacks using stable refs\n instance.onCoordsChange = (coords) => callbacksRef.current.onCoordsChange?.(coords);\n instance.onClick = (...args) => callbacksRef.current.onClick?.(...args);\n instance.onRightClick = (...args) => callbacksRef.current.onRightClick?.(...args);\n instance.onHover = (...args) => callbacksRef.current.onHover?.(...args);\n instance.onMouseDown = (...args) => callbacksRef.current.onMouseDown?.(...args);\n instance.onMouseUp = (...args) => callbacksRef.current.onMouseUp?.(...args);\n instance.onMouseLeave = (...args) => callbacksRef.current.onMouseLeave?.(...args);\n instance.onDraw = (...args) => callbacksRef.current.onDraw?.(...args);\n instance.onResize = () => callbacksRef.current.onResize?.();\n instance.onZoom = (scale) => callbacksRef.current.onZoom?.(scale);\n\n // Attach to handle\n engine._setInstance(instance);\n\n // Initial render\n instance.render();\n\n // Cleanup on unmount\n return () => {\n instance.destroy();\n engine._setInstance(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine]);\n\n return (\n <EngineContext.Provider value={contextValue}>\n <div\n ref={engine._containerRef}\n className={className}\n style={{\n ...style,\n }}\n >\n <canvas />\n </div>\n {/* Render children only when engine is ready */}\n {engine.isReady && children}\n </EngineContext.Provider>\n );\n}\n\n// Compound component pattern - attach draw components as static properties\nexport const CanvasTileEngine = Object.assign(CanvasTileEngineBase, {\n Rect,\n Circle,\n Image,\n GridLines,\n Line,\n Text,\n Path,\n StaticRect,\n StaticCircle,\n StaticImage,\n DrawFunction,\n});\n","import { createContext, useContext } from \"react\";\nimport type { EngineHandle } from \"../hooks/useCanvasTileEngine\";\n\nexport interface EngineContextValue {\n engine: EngineHandle;\n /** Request a re-render of the canvas */\n requestRender: () => void;\n}\n\nexport const EngineContext = createContext<EngineContextValue | null>(null);\n\n/**\n * Hook to access the engine context from child components.\n * Must be used within a CanvasTileEngine component.\n */\nexport function useEngineContext(): EngineContextValue {\n const context = useContext(EngineContext);\n\n if (!context) {\n throw new Error(\"useEngineContext must be used within a CanvasTileEngine component\");\n }\n\n return context;\n}\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Rect as RectType } from \"@canvas-tile-engine/core\";\n\nexport interface RectProps {\n items: RectType | RectType[];\n layer?: number;\n}\n\n/**\n * Draws rectangles on the canvas.\n */\nexport const Rect = memo(function Rect({ items, layer = 1 }: RectProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawRect(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Circle as CircleType } from \"@canvas-tile-engine/core\";\n\nexport interface CircleProps {\n items: CircleType | CircleType[];\n layer?: number;\n}\n\n/**\n * Draws circles on the canvas.\n */\nexport const Circle = memo(function Circle({ items, layer = 1 }: CircleProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawCircle(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface ImageProps {\n items: ImageItem | ImageItem[];\n layer?: number;\n}\n\n/**\n * Draws images on the canvas.\n */\nexport const Image = memo(function Image({ items, layer = 1 }: ImageProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawImage(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\n\nexport interface GridLinesProps {\n cellSize: number;\n lineWidth?: number;\n strokeStyle?: string;\n layer?: number;\n}\n\n/**\n * Draws grid lines on the canvas.\n * Multiple GridLines can share the same layer (additive drawing).\n */\nexport const GridLines = memo(function GridLines({ cellSize, lineWidth = 1, strokeStyle = \"black\", layer = 0 }: GridLinesProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawGridLines(cellSize, lineWidth, strokeStyle, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, cellSize, lineWidth, strokeStyle, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Line as LineType } from \"@canvas-tile-engine/core\";\n\nexport interface LineProps {\n items: LineType | LineType[];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws lines on the canvas.\n */\nexport const Line = memo(function Line({ items, style, layer = 1 }: LineProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawLine(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Text as TextType } from \"@canvas-tile-engine/core\";\n\nexport interface TextProps {\n items: TextType | TextType[];\n layer?: number;\n}\n\n/**\n * Draws text on the canvas.\n * @example\n * ```tsx\n * <Text\n * items={{\n * x: 0,\n * y: 0,\n * text: \"Hello\",\n * size: 1,\n * style: { fillStyle: \"black\", fontFamily: \"Arial\" }\n * }}\n * />\n * ```\n */\nexport const Text = memo(function Text({ items, layer = 2 }: TextProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawText(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Path as PathType } from \"@canvas-tile-engine/core\";\n\nexport interface PathProps {\n items: PathType | PathType[];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws paths/polylines on the canvas.\n */\nexport const Path = memo(function Path({ items, style, layer = 1 }: PathProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawPath(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Rect as RectType } from \"@canvas-tile-engine/core\";\n\nexport interface StaticRectProps {\n items: RectType[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static rectangles with caching for performance.\n * Ideal for large datasets that don't change frequently.\n */\nexport const StaticRect = memo(function StaticRect({ items, cacheKey, layer = 1 }: StaticRectProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n // Clear previous cache if cacheKey changed\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticRect(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Circle as CircleType } from \"@canvas-tile-engine/core\";\n\nexport interface StaticCircleProps {\n items: CircleType[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static circles with caching for performance.\n */\nexport const StaticCircle = memo(function StaticCircle({ items, cacheKey, layer = 1 }: StaticCircleProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticCircle(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface StaticImageProps {\n items: ImageItem[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static images with caching for performance.\n * Ideal for terrain tiles or static decorations.\n */\nexport const StaticImage = memo(function StaticImage({ items, cacheKey, layer = 1 }: StaticImageProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticImage(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { CanvasTileEngineConfig, Coords } from \"@canvas-tile-engine/core\";\n\nexport interface DrawFunctionProps {\n /** The draw function to execute */\n children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;\n layer?: number;\n}\n\n/**\n * Custom draw function component.\n * Allows arbitrary canvas drawing within the engine's render cycle.\n * Multiple DrawFunction components can share the same layer (additive drawing).\n *\n * @example\n * ```tsx\n * <DrawFunction layer={3}>\n * {(ctx, coords, config) => {\n * ctx.fillStyle = \"red\";\n * ctx.fillRect(config.size.width / 2 - 5, config.size.height / 2 - 5, 10, 10);\n * }}\n * </DrawFunction>\n * ```\n */\nexport const DrawFunction = memo(function DrawFunction({ children, layer = 1 }: DrawFunctionProps) {\n const { engine, requestRender } = useEngineContext();\n const fnRef = useRef(children);\n\n // Keep function ref updated\n useEffect(() => {\n fnRef.current = children;\n });\n\n useEffect(() => {\n const handle = engine.addDrawFunction((ctx, coords, config) => {\n fnRef.current(ctx, coords, config);\n }, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, layer, requestRender]);\n\n return null;\n});\n","import { useRef, useCallback, useState, useMemo } from \"react\";\nimport type {\n CanvasTileEngine as CanvasTileEngineCore,\n CanvasTileEngineConfig,\n Coords,\n EventHandlers,\n LayerHandle,\n ImageItem,\n Text,\n Circle,\n Line,\n Rect,\n} from \"@canvas-tile-engine/core\";\n\n/** Dummy handle returned when engine is not ready */\nconst DUMMY_LAYER_HANDLE: LayerHandle = { layer: -1, id: Symbol(\"dummy\") };\n\n/** Default config when engine is not ready */\nconst DEFAULT_CONFIG: Required<CanvasTileEngineConfig> = {\n size: { width: 0, height: 0, minWidth: 100, minHeight: 100, maxWidth: Infinity, maxHeight: Infinity },\n responsive: false,\n scale: 1,\n minScale: 0.5,\n maxScale: 2,\n backgroundColor: \"#ffffff\",\n gridAligned: false,\n renderer: \"canvas\",\n eventHandlers: {\n drag: true,\n zoom: true,\n hover: false,\n click: false,\n rightClick: false,\n resize: false,\n },\n bounds: {\n minX: -Infinity,\n maxX: Infinity,\n minY: -Infinity,\n maxY: Infinity,\n },\n coordinates: {\n enabled: false,\n shownScaleRange: { min: 0, max: Infinity },\n },\n cursor: {\n default: \"default\",\n move: \"move\",\n },\n debug: {\n enabled: false,\n hud: {\n enabled: false,\n topLeftCoordinates: false,\n coordinates: false,\n scale: false,\n tilesInView: false,\n fps: false,\n },\n eventHandlers: {\n click: false,\n hover: false,\n drag: false,\n zoom: false,\n resize: false,\n },\n },\n};\n\n/**\n * Engine handle returned by useCanvasTileEngine hook.\n * Provides access to engine methods with proper typing.\n *\n * All methods return default/dummy values when engine is not ready,\n * allowing safe usage without null checks.\n */\nexport interface EngineHandle {\n /** @internal - Used by CanvasTileEngine component */\n readonly _containerRef: React.RefObject<HTMLDivElement>;\n /** @internal - Used by CanvasTileEngine component */\n _setInstance: (engine: CanvasTileEngineCore | null) => void;\n\n /** Whether the engine is ready (mounted and initialized) */\n readonly isReady: boolean;\n\n /** The underlying engine instance (null until component mounts) */\n readonly instance: CanvasTileEngineCore | null;\n\n /** Render a frame */\n render(): void;\n\n /** Get current center coordinates */\n getCenterCoords(): Coords;\n\n /** Get visible world coordinate bounds of the viewport */\n getVisibleBounds(): { minX: number; maxX: number; minY: number; maxY: number };\n\n /** Update center coordinates */\n updateCoords(center: Coords): void;\n\n /** Animate to target coordinates */\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Resize the canvas */\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Get current canvas size */\n getSize(): { width: number; height: number };\n\n /** Get current canvas scale */\n getScale(): number;\n\n /** Set the canvas scale directly, clamped to min/max bounds. */\n setScale(newScale: number): void;\n\n /** Zoom in by a factor (default: 1.5) */\n zoomIn(factor?: number): void;\n\n /** Zoom out by a factor (default: 1.5) */\n zoomOut(factor?: number): void;\n\n /** Get current config */\n getConfig(): Required<CanvasTileEngineConfig>;\n\n /** Set map boundaries */\n setBounds(bounds: { minX: number; maxX: number; minY: number; maxY: number }): void;\n\n /** Dynamically update event handlers at runtime */\n setEventHandlers(handlers: Partial<EventHandlers>): void;\n\n /** Draw rectangles */\n drawRect(items: Rect | Rect[], layer?: number): LayerHandle;\n\n /** Draw static rectangles (cached) */\n drawStaticRect(items: Rect[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw circles */\n drawCircle(items: Circle | Circle[], layer?: number): LayerHandle;\n\n /** Draw static circles (cached) */\n drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw lines */\n drawLine(items: Line | Line[], style?: { strokeStyle?: string; lineWidth?: number }, layer?: number): LayerHandle;\n\n /** Draw text */\n drawText(items: Text | Text[], layer?: number): LayerHandle;\n\n /** Draw paths/polylines */\n drawPath(\n items: Coords[] | Coords[][],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): LayerHandle;\n\n /** Draw images */\n drawImage(items: ImageItem | ImageItem[], layer?: number): LayerHandle;\n\n /** Draw static images (cached) */\n drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw grid lines */\n drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;\n\n /** Add custom draw function */\n addDrawFunction(\n fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void,\n layer?: number\n ): LayerHandle;\n\n /** Clear a specific layer */\n clearLayer(layer: number): void;\n\n /** Clear all layers */\n clearAll(): void;\n\n /** Clear static cache */\n clearStaticCache(cacheKey?: string): void;\n\n /** Remove a previously registered draw callback */\n removeLayerHandle(handle: LayerHandle): void;\n\n /** Image loader instance (undefined until engine mounts) */\n readonly images: CanvasTileEngineCore[\"images\"] | undefined;\n\n /**\n * Load an image using the engine's image loader.\n * Returns a rejected promise if engine is not ready.\n * @param src - Image URL to load\n * @param retry - Number of retries on failure (default: 1)\n * @example\n * ```tsx\n * const img = await engine.loadImage(\"/sprites/player.png\");\n * ```\n */\n loadImage(src: string, retry?: number): Promise<HTMLImageElement>;\n}\n\n/**\n * React hook that creates an engine handle for use with CanvasTileEngine component.\n *\n * @returns Engine handle to pass to CanvasTileEngine component\n *\n * @example\n * ```tsx\n * function App() {\n * const mainMap = useCanvasTileEngine();\n * const miniMap = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (mainMap.isReady && miniMap.isReady) {\n * // Both engines are ready, draw items\n * mainMap.drawGridLines(50);\n * mainMap.render();\n * }\n * }, [mainMap.isReady, miniMap.isReady]);\n *\n * return (\n * <>\n * <CanvasTileEngine engine={mainMap} config={...} />\n * <CanvasTileEngine engine={miniMap} config={...} />\n * </>\n * );\n * }\n * ```\n */\nexport function useCanvasTileEngine(): EngineHandle {\n const instanceRef = useRef<CanvasTileEngineCore | null>(null);\n const containerRef = useRef<HTMLDivElement>(null!);\n // _isReady state is only used to trigger re-renders, actual value is read from isReadyRef\n const [, setIsReady] = useState(false);\n // Keep isReady in a ref so the handle getter can read it without recreating handle\n const isReadyRef = useRef(false);\n\n const setInstance = useCallback((engine: CanvasTileEngineCore | null) => {\n instanceRef.current = engine;\n isReadyRef.current = engine !== null;\n setIsReady(engine !== null);\n }, []);\n\n // Create stable handle object using useMemo\n // Note: isReady is NOT in deps - we read from isReadyRef to keep handle stable\n const handle = useMemo<EngineHandle>(\n () => ({\n _containerRef: containerRef,\n _setInstance: setInstance,\n\n get isReady() {\n return isReadyRef.current;\n },\n\n get instance() {\n return instanceRef.current;\n },\n\n get images() {\n return instanceRef.current?.images;\n },\n\n render() {\n instanceRef.current?.render();\n },\n\n getCenterCoords() {\n return instanceRef.current?.getCenterCoords() ?? { x: 0, y: 0 };\n },\n\n getVisibleBounds() {\n return instanceRef.current?.getVisibleBounds() ?? { minX: 0, maxX: 0, minY: 0, maxY: 0 };\n },\n\n updateCoords(center: Coords) {\n instanceRef.current?.updateCoords(center);\n },\n\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.goCoords(x, y, durationMs, onComplete);\n },\n\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.resize(width, height, durationMs, onComplete);\n },\n\n getSize() {\n return instanceRef.current?.getSize() ?? { width: 0, height: 0 };\n },\n\n getScale() {\n return instanceRef.current?.getScale() ?? 1;\n },\n\n setScale(newScale: number) {\n instanceRef.current?.setScale(newScale);\n },\n\n zoomIn(factor?: number) {\n instanceRef.current?.zoomIn(factor);\n },\n\n zoomOut(factor?: number) {\n instanceRef.current?.zoomOut(factor);\n },\n\n getConfig() {\n return instanceRef.current?.getConfig() ?? DEFAULT_CONFIG;\n },\n\n setBounds(bounds) {\n instanceRef.current?.setBounds(bounds);\n },\n\n setEventHandlers(handlers) {\n instanceRef.current?.setEventHandlers(handlers);\n },\n\n drawRect(items, layer) {\n return instanceRef.current?.drawRect(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticRect(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticRect(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawCircle(items, layer) {\n return instanceRef.current?.drawCircle(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticCircle(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticCircle(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawLine(items, style, layer) {\n return instanceRef.current?.drawLine(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawText(items, layer) {\n return instanceRef.current?.drawText(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawPath(items, style, layer) {\n return instanceRef.current?.drawPath(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawImage(items, layer) {\n return instanceRef.current?.drawImage(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticImage(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticImage(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawGridLines(cellSize, lineWidth, strokeStyle, layer) {\n return (\n instanceRef.current?.drawGridLines(cellSize, lineWidth, strokeStyle, layer) ?? DUMMY_LAYER_HANDLE\n );\n },\n\n addDrawFunction(fn, layer) {\n return instanceRef.current?.addDrawFunction(fn, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n clearLayer(layer) {\n instanceRef.current?.clearLayer(layer);\n },\n\n clearAll() {\n instanceRef.current?.clearAll();\n },\n\n clearStaticCache(cacheKey) {\n instanceRef.current?.clearStaticCache(cacheKey);\n },\n\n removeLayerHandle(handle) {\n instanceRef.current?.removeLayerHandle(handle);\n },\n\n loadImage(src: string, retry?: number) {\n if (!instanceRef.current) {\n return Promise.reject(new Error(\"Engine not ready. Wait for isReady before loading images.\"));\n }\n return instanceRef.current.images.load(src, retry);\n },\n }),\n [setInstance]\n );\n\n return handle;\n}\n"],"mappings":"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","names":["index_exports","__export","CanvasTileEngine","useCanvasTileEngine","useEngineContext","__toCommonJS","import_react","import_core","import_react","EngineContext","useEngineContext","context","import_react","Rect","items","layer","engine","requestRender","useEngineContext","handle","import_react","Circle","items","layer","engine","requestRender","useEngineContext","handle","import_react","Image","items","layer","engine","requestRender","useEngineContext","handle","import_react","GridLines","cellSize","lineWidth","strokeStyle","layer","engine","requestRender","useEngineContext","handle","import_react","Line","items","style","layer","engine","requestRender","useEngineContext","handle","import_react","Text","items","layer","engine","requestRender","useEngineContext","handle","import_react","Path","items","style","layer","engine","requestRender","useEngineContext","handle","import_react","StaticRect","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","handle","import_react","StaticCircle","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","handle","import_react","StaticImage","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","handle","import_react","DrawFunction","children","layer","engine","requestRender","useEngineContext","fnRef","handle","ctx","coords","config","import_jsx_runtime","CanvasTileEngineBase","engine","config","center","className","style","children","onCoordsChange","onClick","onRightClick","onHover","onMouseDown","onMouseUp","onMouseLeave","onDraw","onResize","onZoom","callbacksRef","rafIdRef","requestRender","contextValue","container","instance","CanvasTileEngineCore","coords","args","scale","EngineContext","CanvasTileEngine","Rect","Circle","Image","GridLines","Line","Text","Path","StaticRect","StaticCircle","StaticImage","DrawFunction","import_react","DUMMY_LAYER_HANDLE","DEFAULT_CONFIG","useCanvasTileEngine","instanceRef","containerRef","setIsReady","isReadyRef","setInstance","engine","center","x","y","durationMs","onComplete","width","height","newScale","factor","bounds","handlers","items","layer","cacheKey","style","cellSize","lineWidth","strokeStyle","fn","handle","src","retry","import_core"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{useEffect as x,useRef as B,useCallback as xe,useMemo as ye}from"react";import{CanvasTileEngine as ve}from"@canvas-tile-engine/core";import{createContext as U,useContext as N}from"react";var C=U(null);function c(){let r=N(C);if(!r)throw new Error("useEngineContext must be used within a CanvasTileEngine component");return r}import{useEffect as Z,memo as J}from"react";var P=J(function({items:i,layer:t=1}){let{engine:a,requestRender:n}=c();return Z(()=>{let s=a.drawRect(i,t);return n(),()=>{s&&a.removeLayerHandle(s)}},[a,i,t,n]),null});import{useEffect as Q,memo as $}from"react";var I=$(function({items:i,layer:t=1}){let{engine:a,requestRender:n}=c();return Q(()=>{let s=a.drawCircle(i,t);return n(),()=>{s&&a.removeLayerHandle(s)}},[a,i,t,n]),null});import{useEffect as K,memo as ee}from"react";var T=ee(function({items:i,layer:t=1}){let{engine:a,requestRender:n}=c();return K(()=>{let s=a.drawImage(i,t);return n(),()=>{s&&a.removeLayerHandle(s)}},[a,i,t,n]),null});import{useEffect as re,memo as ne}from"react";var H=ne(function({cellSize:i,lineWidth:t=1,strokeStyle:a="black",layer:n=0}){let{engine:s,requestRender:e}=c();return re(()=>{let o=s.drawGridLines(i,t,a,n);return e(),()=>{o&&s.removeLayerHandle(o)}},[s,i,t,a,n,e]),null});import{useEffect as te,memo as oe}from"react";var D=oe(function({items:i,style:t,layer:a=1}){let{engine:n,requestRender:s}=c();return te(()=>{let e=n.drawLine(i,t,a);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,i,t,a,s]),null});import{useEffect as ae,memo as ie}from"react";var O=ie(function({items:i,style:t,layer:a=2}){let{engine:n,requestRender:s}=c();return ae(()=>{let e=n.drawText(i,t,a);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,i,t,a,s]),null});import{useEffect as se,memo as ce}from"react";var k=ce(function({items:i,style:t,layer:a=1}){let{engine:n,requestRender:s}=c();return se(()=>{let e=n.drawPath(i,t,a);return s(),()=>{e&&n.removeLayerHandle(e)}},[n,i,t,a,s]),null});import{useEffect as j,useRef as le,memo as ue}from"react";var z=ue(function({items:i,cacheKey:t,layer:a=1}){let{engine:n,requestRender:s}=c(),e=le(t);return j(()=>{if(i.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let o=n.drawStaticRect(i,t,a);return s(),()=>{o&&n.removeLayerHandle(o)}},[n,i,t,a,s]),j(()=>()=>{n.clearStaticCache(t)},[n,t]),null});import{useEffect as q,useRef as me,memo as de}from"react";var M=de(function({items:i,cacheKey:t,layer:a=1}){let{engine:n,requestRender:s}=c(),e=me(t);return q(()=>{if(i.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let o=n.drawStaticCircle(i,t,a);return s(),()=>{o&&n.removeLayerHandle(o)}},[n,i,t,a,s]),q(()=>()=>{n.clearStaticCache(t)},[n,t]),null});import{useEffect as F,useRef as fe,memo as ge}from"react";var A=ge(function({items:i,cacheKey:t,layer:a=1}){let{engine:n,requestRender:s}=c(),e=fe(t);return F(()=>{if(i.length===0)return;e.current!==t&&(n.clearStaticCache(e.current),e.current=t);let o=n.drawStaticImage(i,t,a);return s(),()=>{o&&n.removeLayerHandle(o)}},[n,i,t,a,s]),F(()=>()=>{n.clearStaticCache(t)},[n,t]),null});import{useEffect as G,useRef as pe,memo as Ce}from"react";var V=Ce(function({children:i,layer:t=1}){let{engine:a,requestRender:n}=c(),s=pe(i);return G(()=>{s.current=i}),G(()=>{let e=a.addDrawFunction((o,l,g)=>{s.current(o,l,g)},t);return n(),()=>{e&&a.removeLayerHandle(e)}},[a,t,n]),null});import{jsx as _,jsxs as Ee}from"react/jsx-runtime";function be({engine:r,config:i,center:t={x:0,y:0},className:a,style:n,children:s,onCoordsChange:e,onClick:o,onRightClick:l,onHover:g,onMouseDown:v,onMouseUp:b,onMouseLeave:E,onDraw:w,onResize:R,onZoom:S}){let d=B({onCoordsChange:e,onClick:o,onRightClick:l,onHover:g,onMouseDown:v,onMouseUp:b,onMouseLeave:E,onDraw:w,onResize:R,onZoom:S});x(()=>{d.current={onCoordsChange:e,onClick:o,onRightClick:l,onHover:g,onMouseDown:v,onMouseUp:b,onMouseLeave:E,onDraw:w,onResize:R,onZoom:S}});let p=B(null),L=xe(()=>{p.current===null&&(p.current=requestAnimationFrame(()=>{p.current=null,r.render()}))},[r]);x(()=>()=>{p.current!==null&&cancelAnimationFrame(p.current)},[]);let W=ye(()=>({engine:r,requestRender:L}),[r,L]);return x(()=>{let h=r._containerRef.current;if(!h)return;let m=new ve(h,i,t);return m.onCoordsChange=u=>d.current.onCoordsChange?.(u),m.onClick=(...u)=>d.current.onClick?.(...u),m.onRightClick=(...u)=>d.current.onRightClick?.(...u),m.onHover=(...u)=>d.current.onHover?.(...u),m.onMouseDown=(...u)=>d.current.onMouseDown?.(...u),m.onMouseUp=(...u)=>d.current.onMouseUp?.(...u),m.onMouseLeave=(...u)=>d.current.onMouseLeave?.(...u),m.onDraw=(...u)=>d.current.onDraw?.(...u),m.onResize=()=>d.current.onResize?.(),m.onZoom=u=>d.current.onZoom?.(u),r._setInstance(m),m.render(),()=>{m.destroy(),r._setInstance(null)}},[r]),Ee(C.Provider,{value:W,children:[_("div",{ref:r._containerRef,className:a,style:{...n},children:_("canvas",{})}),r.isReady&&s]})}var Y=Object.assign(be,{Rect:P,Circle:I,Image:T,GridLines:H,Line:D,Text:O,Path:k,StaticRect:z,StaticCircle:M,StaticImage:A,DrawFunction:V});import{useRef as y,useCallback as we,useState as Re,useMemo as Se}from"react";var f={layer:-1,id:Symbol("dummy")},Le={size:{width:0,height:0,minWidth:100,minHeight:100,maxWidth:1/0,maxHeight:1/0},responsive:!1,scale:1,minScale:.5,maxScale:2,backgroundColor:"#ffffff",gridAligned:!1,renderer:"canvas",eventHandlers:{drag:!0,zoom:!0,hover:!1,click:!1,rightClick:!1,resize:!1},bounds:{minX:-1/0,maxX:1/0,minY:-1/0,maxY:1/0},coordinates:{enabled:!1,shownScaleRange:{min:0,max:1/0}},cursor:{default:"default",move:"move"},debug:{enabled:!1,hud:{enabled:!1,topLeftCoordinates:!1,coordinates:!1,scale:!1,tilesInView:!1,fps:!1},eventHandlers:{click:!1,hover:!1,drag:!1,zoom:!1,resize:!1}}};function X(){let r=y(null),i=y(null),[,t]=Re(!1),a=y(!1),n=we(e=>{r.current=e,a.current=e!==null,t(e!==null)},[]);return Se(()=>({_containerRef:i,_setInstance:n,get isReady(){return a.current},get instance(){return r.current},get images(){return r.current?.images},render(){r.current?.render()},getCenterCoords(){return r.current?.getCenterCoords()??{x:0,y:0}},getVisibleBounds(){return r.current?.getVisibleBounds()??{minX:0,maxX:0,minY:0,maxY:0}},updateCoords(e){r.current?.updateCoords(e)},goCoords(e,o,l,g){r.current?.goCoords(e,o,l,g)},resize(e,o,l,g){r.current?.resize(e,o,l,g)},getSize(){return r.current?.getSize()??{width:0,height:0}},getScale(){return r.current?.getScale()??1},setScale(e){r.current?.setScale(e)},zoomIn(e){r.current?.zoomIn(e)},zoomOut(e){r.current?.zoomOut(e)},getConfig(){return r.current?.getConfig()??Le},setBounds(e){r.current?.setBounds(e)},setEventHandlers(e){r.current?.setEventHandlers(e)},drawRect(e,o){return r.current?.drawRect(e,o)??f},drawStaticRect(e,o,l){return r.current?.drawStaticRect(e,o,l)??f},drawCircle(e,o){return r.current?.drawCircle(e,o)??f},drawStaticCircle(e,o,l){return r.current?.drawStaticCircle(e,o,l)??f},drawLine(e,o,l){return r.current?.drawLine(e,o,l)??f},drawText(e,o,l){return r.current?.drawText(e,o,l)??f},drawPath(e,o,l){return r.current?.drawPath(e,o,l)??f},drawImage(e,o){return r.current?.drawImage(e,o)??f},drawStaticImage(e,o,l){return r.current?.drawStaticImage(e,o,l)??f},drawGridLines(e,o,l,g){return r.current?.drawGridLines(e,o,l,g)??f},addDrawFunction(e,o){return r.current?.addDrawFunction(e,o)??f},clearLayer(e){r.current?.clearLayer(e)},clearAll(){r.current?.clearAll()},clearStaticCache(e){r.current?.clearStaticCache(e)},removeLayerHandle(e){r.current?.removeLayerHandle(e)}}),[n])}import{CanvasTileEngine as qr,gridToSize as Mr}from"@canvas-tile-engine/core";export{Y as CanvasTileEngine,qr as CanvasTileEngineCore,Mr as gridToSize,X as useCanvasTileEngine,c as useEngineContext};
1
+ import{useEffect as y,useRef as W,useCallback as ye,useMemo as xe}from"react";import{CanvasTileEngine as ve}from"@canvas-tile-engine/core";import{createContext as j,useContext as N}from"react";var C=j(null);function c(){let r=N(C);if(!r)throw new Error("useEngineContext must be used within a CanvasTileEngine component");return r}import{useEffect as Z,memo as J}from"react";var h=J(function({items:a,layer:n=1}){let{engine:i,requestRender:t}=c();return Z(()=>{let s=i.drawRect(a,n);return t(),()=>{s&&i.removeLayerHandle(s)}},[i,a,n,t]),null});import{useEffect as Q,memo as $}from"react";var S=$(function({items:a,layer:n=1}){let{engine:i,requestRender:t}=c();return Q(()=>{let s=i.drawCircle(a,n);return t(),()=>{s&&i.removeLayerHandle(s)}},[i,a,n,t]),null});import{useEffect as K,memo as ee}from"react";var I=ee(function({items:a,layer:n=1}){let{engine:i,requestRender:t}=c();return K(()=>{let s=i.drawImage(a,n);return t(),()=>{s&&i.removeLayerHandle(s)}},[i,a,n,t]),null});import{useEffect as re,memo as ne}from"react";var H=ne(function({cellSize:a,lineWidth:n=1,strokeStyle:i="black",layer:t=0}){let{engine:s,requestRender:e}=c();return re(()=>{let o=s.drawGridLines(a,n,i,t);return e(),()=>{o&&s.removeLayerHandle(o)}},[s,a,n,i,t,e]),null});import{useEffect as te,memo as oe}from"react";var k=oe(function({items:a,style:n,layer:i=1}){let{engine:t,requestRender:s}=c();return te(()=>{let e=t.drawLine(a,n,i);return s(),()=>{e&&t.removeLayerHandle(e)}},[t,a,n,i,s]),null});import{useEffect as ie,memo as ae}from"react";var D=ae(function({items:a,layer:n=2}){let{engine:i,requestRender:t}=c();return ie(()=>{let s=i.drawText(a,n);return t(),()=>{s&&i.removeLayerHandle(s)}},[i,a,n,t]),null});import{useEffect as se,memo as ce}from"react";var z=ce(function({items:a,style:n,layer:i=1}){let{engine:t,requestRender:s}=c();return se(()=>{let e=t.drawPath(a,n,i);return s(),()=>{e&&t.removeLayerHandle(e)}},[t,a,n,i,s]),null});import{useEffect as q,useRef as ue,memo as le}from"react";var F=le(function({items:a,cacheKey:n,layer:i=1}){let{engine:t,requestRender:s}=c(),e=ue(n);return q(()=>{if(a.length===0)return;e.current!==n&&(t.clearStaticCache(e.current),e.current=n);let o=t.drawStaticRect(a,n,i);return s(),()=>{o&&t.removeLayerHandle(o)}},[t,a,n,i,s]),q(()=>()=>{t.clearStaticCache(n)},[t,n]),null});import{useEffect as M,useRef as me,memo as de}from"react";var G=de(function({items:a,cacheKey:n,layer:i=1}){let{engine:t,requestRender:s}=c(),e=me(n);return M(()=>{if(a.length===0)return;e.current!==n&&(t.clearStaticCache(e.current),e.current=n);let o=t.drawStaticCircle(a,n,i);return s(),()=>{o&&t.removeLayerHandle(o)}},[t,a,n,i,s]),M(()=>()=>{t.clearStaticCache(n)},[t,n]),null});import{useEffect as V,useRef as fe,memo as pe}from"react";var _=pe(function({items:a,cacheKey:n,layer:i=1}){let{engine:t,requestRender:s}=c(),e=fe(n);return V(()=>{if(a.length===0)return;e.current!==n&&(t.clearStaticCache(e.current),e.current=n);let o=t.drawStaticImage(a,n,i);return s(),()=>{o&&t.removeLayerHandle(o)}},[t,a,n,i,s]),V(()=>()=>{t.clearStaticCache(n)},[t,n]),null});import{useEffect as Y,useRef as ge,memo as Ce}from"react";var A=Ce(function({children:a,layer:n=1}){let{engine:i,requestRender:t}=c(),s=ge(a);return Y(()=>{s.current=a}),Y(()=>{let e=i.addDrawFunction((o,u,p)=>{s.current(o,u,p)},n);return t(),()=>{e&&i.removeLayerHandle(e)}},[i,n,t]),null});import{jsx as X,jsxs as Ee}from"react/jsx-runtime";function be({engine:r,config:a,center:n={x:0,y:0},className:i,style:t,children:s,onCoordsChange:e,onClick:o,onRightClick:u,onHover:p,onMouseDown:v,onMouseUp:b,onMouseLeave:E,onDraw:R,onResize:T,onZoom:L}){let d=W({onCoordsChange:e,onClick:o,onRightClick:u,onHover:p,onMouseDown:v,onMouseUp:b,onMouseLeave:E,onDraw:R,onResize:T,onZoom:L});y(()=>{d.current={onCoordsChange:e,onClick:o,onRightClick:u,onHover:p,onMouseDown:v,onMouseUp:b,onMouseLeave:E,onDraw:R,onResize:T,onZoom:L}});let g=W(null),w=ye(()=>{g.current===null&&(g.current=requestAnimationFrame(()=>{g.current=null,r.render()}))},[r]);y(()=>()=>{g.current!==null&&cancelAnimationFrame(g.current)},[]);let U=xe(()=>({engine:r,requestRender:w}),[r,w]);return y(()=>{let P=r._containerRef.current;if(!P)return;let m=new ve(P,a,n);return m.onCoordsChange=l=>d.current.onCoordsChange?.(l),m.onClick=(...l)=>d.current.onClick?.(...l),m.onRightClick=(...l)=>d.current.onRightClick?.(...l),m.onHover=(...l)=>d.current.onHover?.(...l),m.onMouseDown=(...l)=>d.current.onMouseDown?.(...l),m.onMouseUp=(...l)=>d.current.onMouseUp?.(...l),m.onMouseLeave=(...l)=>d.current.onMouseLeave?.(...l),m.onDraw=(...l)=>d.current.onDraw?.(...l),m.onResize=()=>d.current.onResize?.(),m.onZoom=l=>d.current.onZoom?.(l),r._setInstance(m),m.render(),()=>{m.destroy(),r._setInstance(null)}},[r]),Ee(C.Provider,{value:U,children:[X("div",{ref:r._containerRef,className:i,style:{...t},children:X("canvas",{})}),r.isReady&&s]})}var B=Object.assign(be,{Rect:h,Circle:S,Image:I,GridLines:H,Line:k,Text:D,Path:z,StaticRect:F,StaticCircle:G,StaticImage:_,DrawFunction:A});import{useRef as x,useCallback as Re,useState as Te,useMemo as Le}from"react";var f={layer:-1,id:Symbol("dummy")},we={size:{width:0,height:0,minWidth:100,minHeight:100,maxWidth:1/0,maxHeight:1/0},responsive:!1,scale:1,minScale:.5,maxScale:2,backgroundColor:"#ffffff",gridAligned:!1,renderer:"canvas",eventHandlers:{drag:!0,zoom:!0,hover:!1,click:!1,rightClick:!1,resize:!1},bounds:{minX:-1/0,maxX:1/0,minY:-1/0,maxY:1/0},coordinates:{enabled:!1,shownScaleRange:{min:0,max:1/0}},cursor:{default:"default",move:"move"},debug:{enabled:!1,hud:{enabled:!1,topLeftCoordinates:!1,coordinates:!1,scale:!1,tilesInView:!1,fps:!1},eventHandlers:{click:!1,hover:!1,drag:!1,zoom:!1,resize:!1}}};function O(){let r=x(null),a=x(null),[,n]=Te(!1),i=x(!1),t=Re(e=>{r.current=e,i.current=e!==null,n(e!==null)},[]);return Le(()=>({_containerRef:a,_setInstance:t,get isReady(){return i.current},get instance(){return r.current},get images(){return r.current?.images},render(){r.current?.render()},getCenterCoords(){return r.current?.getCenterCoords()??{x:0,y:0}},getVisibleBounds(){return r.current?.getVisibleBounds()??{minX:0,maxX:0,minY:0,maxY:0}},updateCoords(e){r.current?.updateCoords(e)},goCoords(e,o,u,p){r.current?.goCoords(e,o,u,p)},resize(e,o,u,p){r.current?.resize(e,o,u,p)},getSize(){return r.current?.getSize()??{width:0,height:0}},getScale(){return r.current?.getScale()??1},setScale(e){r.current?.setScale(e)},zoomIn(e){r.current?.zoomIn(e)},zoomOut(e){r.current?.zoomOut(e)},getConfig(){return r.current?.getConfig()??we},setBounds(e){r.current?.setBounds(e)},setEventHandlers(e){r.current?.setEventHandlers(e)},drawRect(e,o){return r.current?.drawRect(e,o)??f},drawStaticRect(e,o,u){return r.current?.drawStaticRect(e,o,u)??f},drawCircle(e,o){return r.current?.drawCircle(e,o)??f},drawStaticCircle(e,o,u){return r.current?.drawStaticCircle(e,o,u)??f},drawLine(e,o,u){return r.current?.drawLine(e,o,u)??f},drawText(e,o){return r.current?.drawText(e,o)??f},drawPath(e,o,u){return r.current?.drawPath(e,o,u)??f},drawImage(e,o){return r.current?.drawImage(e,o)??f},drawStaticImage(e,o,u){return r.current?.drawStaticImage(e,o,u)??f},drawGridLines(e,o,u,p){return r.current?.drawGridLines(e,o,u,p)??f},addDrawFunction(e,o){return r.current?.addDrawFunction(e,o)??f},clearLayer(e){r.current?.clearLayer(e)},clearAll(){r.current?.clearAll()},clearStaticCache(e){r.current?.clearStaticCache(e)},removeLayerHandle(e){r.current?.removeLayerHandle(e)},loadImage(e,o){return r.current?r.current.images.load(e,o):Promise.reject(new Error("Engine not ready. Wait for isReady before loading images."))}}),[t])}import{CanvasTileEngine as Mr,gridToSize as Gr}from"@canvas-tile-engine/core";export{B as CanvasTileEngine,Mr as CanvasTileEngineCore,Gr as gridToSize,O as useCanvasTileEngine,c as useEngineContext};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/CanvasTileEngine.tsx","../src/context/EngineContext.tsx","../src/components/draw/Rect.tsx","../src/components/draw/Circle.tsx","../src/components/draw/Image.tsx","../src/components/draw/GridLines.tsx","../src/components/draw/Line.tsx","../src/components/draw/Text.tsx","../src/components/draw/Path.tsx","../src/components/draw/StaticRect.tsx","../src/components/draw/StaticCircle.tsx","../src/components/draw/StaticImage.tsx","../src/components/draw/DrawFunction.tsx","../src/hooks/useCanvasTileEngine.ts","../src/index.ts"],"sourcesContent":["import { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { CanvasTileEngine as CanvasTileEngineCore } from \"@canvas-tile-engine/core\";\nimport { EngineContext, type EngineContextValue } from \"../context/EngineContext\";\nimport type { CanvasTileEngineProps } from \"../types\";\n\n// Import draw components for compound pattern\nimport { Rect } from \"./draw/Rect\";\nimport { Circle } from \"./draw/Circle\";\nimport { Image } from \"./draw/Image\";\nimport { GridLines } from \"./draw/GridLines\";\nimport { Line } from \"./draw/Line\";\nimport { Text } from \"./draw/Text\";\nimport { Path } from \"./draw/Path\";\nimport { StaticRect } from \"./draw/StaticRect\";\nimport { StaticCircle } from \"./draw/StaticCircle\";\nimport { StaticImage } from \"./draw/StaticImage\";\nimport { DrawFunction } from \"./draw/DrawFunction\";\n\n/**\n * React component that renders a CanvasTileEngine.\n * Supports both imperative API (via engine handle) and declarative API (via children).\n *\n * @example Declarative API with compound components\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * return (\n * <CanvasTileEngine engine={engine} config={config}>\n * <CanvasTileEngine.GridLines cellSize={50} layer={0} />\n * <CanvasTileEngine.Image items={imageItems} layer={1} />\n * <CanvasTileEngine.Circle items={markers} layer={2} />\n * </CanvasTileEngine>\n * );\n * }\n * ```\n *\n * @example Imperative API\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (engine.isReady) {\n * engine.drawGridLines(50);\n * engine.render();\n * }\n * }, [engine.isReady]);\n *\n * return <CanvasTileEngine engine={engine} config={config} />;\n * }\n * ```\n */\nfunction CanvasTileEngineBase({\n engine,\n config,\n center = { x: 0, y: 0 },\n className,\n style,\n children,\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n}: CanvasTileEngineProps) {\n // Stable callback refs\n const callbacksRef = useRef({\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n });\n\n // Update callback refs\n useEffect(() => {\n callbacksRef.current = {\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n };\n });\n\n // Debounced render - multiple draw components calling requestRender\n // in the same frame will trigger only one render\n const rafIdRef = useRef<number | null>(null);\n const requestRender = useCallback(() => {\n if (rafIdRef.current !== null) return;\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n engine.render();\n });\n }, [engine]);\n\n // Cleanup RAF on unmount\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n };\n }, []);\n\n // Context value\n const contextValue = useMemo<EngineContextValue>(\n () => ({\n engine,\n requestRender,\n }),\n [engine, requestRender]\n );\n\n // Initialize engine when component mounts\n // Note: config and center are intentionally not in deps - we only want to create the engine once\n // Callbacks are accessed via callbacksRef which is always up-to-date\n useEffect(() => {\n const container = engine._containerRef.current;\n\n if (!container) {\n return;\n }\n\n // Create engine instance\n const instance = new CanvasTileEngineCore(container, config, center);\n\n // Set up callbacks using stable refs\n instance.onCoordsChange = (coords) => callbacksRef.current.onCoordsChange?.(coords);\n instance.onClick = (...args) => callbacksRef.current.onClick?.(...args);\n instance.onRightClick = (...args) => callbacksRef.current.onRightClick?.(...args);\n instance.onHover = (...args) => callbacksRef.current.onHover?.(...args);\n instance.onMouseDown = (...args) => callbacksRef.current.onMouseDown?.(...args);\n instance.onMouseUp = (...args) => callbacksRef.current.onMouseUp?.(...args);\n instance.onMouseLeave = (...args) => callbacksRef.current.onMouseLeave?.(...args);\n instance.onDraw = (...args) => callbacksRef.current.onDraw?.(...args);\n instance.onResize = () => callbacksRef.current.onResize?.();\n instance.onZoom = (scale) => callbacksRef.current.onZoom?.(scale);\n\n // Attach to handle\n engine._setInstance(instance);\n\n // Initial render\n instance.render();\n\n // Cleanup on unmount\n return () => {\n instance.destroy();\n engine._setInstance(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine]);\n\n return (\n <EngineContext.Provider value={contextValue}>\n <div\n ref={engine._containerRef}\n className={className}\n style={{\n ...style,\n }}\n >\n <canvas />\n </div>\n {/* Render children only when engine is ready */}\n {engine.isReady && children}\n </EngineContext.Provider>\n );\n}\n\n// Compound component pattern - attach draw components as static properties\nexport const CanvasTileEngine = Object.assign(CanvasTileEngineBase, {\n Rect,\n Circle,\n Image,\n GridLines,\n Line,\n Text,\n Path,\n StaticRect,\n StaticCircle,\n StaticImage,\n DrawFunction,\n});\n","import { createContext, useContext } from \"react\";\nimport type { EngineHandle } from \"../hooks/useCanvasTileEngine\";\n\nexport interface EngineContextValue {\n engine: EngineHandle;\n /** Request a re-render of the canvas */\n requestRender: () => void;\n}\n\nexport const EngineContext = createContext<EngineContextValue | null>(null);\n\n/**\n * Hook to access the engine context from child components.\n * Must be used within a CanvasTileEngine component.\n */\nexport function useEngineContext(): EngineContextValue {\n const context = useContext(EngineContext);\n\n if (!context) {\n throw new Error(\"useEngineContext must be used within a CanvasTileEngine component\");\n }\n\n return context;\n}\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface RectProps {\n items: DrawObject | DrawObject[];\n layer?: number;\n}\n\n/**\n * Draws rectangles on the canvas.\n */\nexport const Rect = memo(function Rect({ items, layer = 1 }: RectProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawRect(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface CircleProps {\n items: DrawObject | DrawObject[];\n layer?: number;\n}\n\n/**\n * Draws circles on the canvas.\n */\nexport const Circle = memo(function Circle({ items, layer = 1 }: CircleProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawCircle(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface ImageProps {\n items: ImageItem | ImageItem[];\n layer?: number;\n}\n\n/**\n * Draws images on the canvas.\n */\nexport const Image = memo(function Image({ items, layer = 1 }: ImageProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawImage(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\n\nexport interface GridLinesProps {\n cellSize: number;\n lineWidth?: number;\n strokeStyle?: string;\n layer?: number;\n}\n\n/**\n * Draws grid lines on the canvas.\n * Multiple GridLines can share the same layer (additive drawing).\n */\nexport const GridLines = memo(function GridLines({ cellSize, lineWidth = 1, strokeStyle = \"black\", layer = 0 }: GridLinesProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawGridLines(cellSize, lineWidth, strokeStyle, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, cellSize, lineWidth, strokeStyle, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Coords } from \"@canvas-tile-engine/core\";\n\nexport interface LineProps {\n items: { from: Coords; to: Coords } | { from: Coords; to: Coords }[];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws lines on the canvas.\n */\nexport const Line = memo(function Line({ items, style, layer = 1 }: LineProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawLine(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Coords } from \"@canvas-tile-engine/core\";\n\nexport interface TextProps {\n items: { coords: Coords; text: string } | { coords: Coords; text: string }[];\n style?: {\n fillStyle?: string;\n font?: string;\n textAlign?: CanvasTextAlign;\n textBaseline?: CanvasTextBaseline;\n };\n layer?: number;\n}\n\n/**\n * Draws text on the canvas.\n */\nexport const Text = memo(function Text({ items, style, layer = 2 }: TextProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawText(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Coords } from \"@canvas-tile-engine/core\";\n\nexport interface PathProps {\n items: Coords[] | Coords[][];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws paths/polylines on the canvas.\n */\nexport const Path = memo(function Path({ items, style, layer = 1 }: PathProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawPath(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface StaticRectProps {\n items: DrawObject[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static rectangles with caching for performance.\n * Ideal for large datasets that don't change frequently.\n */\nexport const StaticRect = memo(function StaticRect({ items, cacheKey, layer = 1 }: StaticRectProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n // Clear previous cache if cacheKey changed\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticRect(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { DrawObject } from \"@canvas-tile-engine/core\";\n\nexport interface StaticCircleProps {\n items: DrawObject[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static circles with caching for performance.\n */\nexport const StaticCircle = memo(function StaticCircle({ items, cacheKey, layer = 1 }: StaticCircleProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticCircle(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface StaticImageProps {\n items: ImageItem[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static images with caching for performance.\n * Ideal for terrain tiles or static decorations.\n */\nexport const StaticImage = memo(function StaticImage({ items, cacheKey, layer = 1 }: StaticImageProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticImage(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { CanvasTileEngineConfig, Coords } from \"@canvas-tile-engine/core\";\n\nexport interface DrawFunctionProps {\n /** The draw function to execute */\n children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;\n layer?: number;\n}\n\n/**\n * Custom draw function component.\n * Allows arbitrary canvas drawing within the engine's render cycle.\n * Multiple DrawFunction components can share the same layer (additive drawing).\n *\n * @example\n * ```tsx\n * <DrawFunction layer={3}>\n * {(ctx, coords, config) => {\n * ctx.fillStyle = \"red\";\n * ctx.fillRect(config.size.width / 2 - 5, config.size.height / 2 - 5, 10, 10);\n * }}\n * </DrawFunction>\n * ```\n */\nexport const DrawFunction = memo(function DrawFunction({ children, layer = 1 }: DrawFunctionProps) {\n const { engine, requestRender } = useEngineContext();\n const fnRef = useRef(children);\n\n // Keep function ref updated\n useEffect(() => {\n fnRef.current = children;\n });\n\n useEffect(() => {\n const handle = engine.addDrawFunction((ctx, coords, config) => {\n fnRef.current(ctx, coords, config);\n }, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, layer, requestRender]);\n\n return null;\n});\n","import { useRef, useCallback, useState, useMemo } from \"react\";\nimport type {\n CanvasTileEngine as CanvasTileEngineCore,\n CanvasTileEngineConfig,\n Coords,\n DrawObject,\n EventHandlers,\n LayerHandle,\n} from \"@canvas-tile-engine/core\";\n\n/** Dummy handle returned when engine is not ready */\nconst DUMMY_LAYER_HANDLE: LayerHandle = { layer: -1, id: Symbol(\"dummy\") };\n\n/** Default config when engine is not ready */\nconst DEFAULT_CONFIG: Required<CanvasTileEngineConfig> = {\n size: { width: 0, height: 0, minWidth: 100, minHeight: 100, maxWidth: Infinity, maxHeight: Infinity },\n responsive: false,\n scale: 1,\n minScale: 0.5,\n maxScale: 2,\n backgroundColor: \"#ffffff\",\n gridAligned: false,\n renderer: \"canvas\",\n eventHandlers: {\n drag: true,\n zoom: true,\n hover: false,\n click: false,\n rightClick: false,\n resize: false,\n },\n bounds: {\n minX: -Infinity,\n maxX: Infinity,\n minY: -Infinity,\n maxY: Infinity,\n },\n coordinates: {\n enabled: false,\n shownScaleRange: { min: 0, max: Infinity },\n },\n cursor: {\n default: \"default\",\n move: \"move\",\n },\n debug: {\n enabled: false,\n hud: {\n enabled: false,\n topLeftCoordinates: false,\n coordinates: false,\n scale: false,\n tilesInView: false,\n fps: false,\n },\n eventHandlers: {\n click: false,\n hover: false,\n drag: false,\n zoom: false,\n resize: false,\n },\n },\n};\n\n/**\n * Engine handle returned by useCanvasTileEngine hook.\n * Provides access to engine methods with proper typing.\n *\n * All methods return default/dummy values when engine is not ready,\n * allowing safe usage without null checks.\n */\nexport interface EngineHandle {\n /** @internal - Used by CanvasTileEngine component */\n readonly _containerRef: React.RefObject<HTMLDivElement>;\n /** @internal - Used by CanvasTileEngine component */\n _setInstance: (engine: CanvasTileEngineCore | null) => void;\n\n /** Whether the engine is ready (mounted and initialized) */\n readonly isReady: boolean;\n\n /** The underlying engine instance (null until component mounts) */\n readonly instance: CanvasTileEngineCore | null;\n\n /** Render a frame */\n render(): void;\n\n /** Get current center coordinates */\n getCenterCoords(): Coords;\n\n /** Get visible world coordinate bounds of the viewport */\n getVisibleBounds(): { minX: number; maxX: number; minY: number; maxY: number };\n\n /** Update center coordinates */\n updateCoords(center: Coords): void;\n\n /** Animate to target coordinates */\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Resize the canvas */\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Get current canvas size */\n getSize(): { width: number; height: number };\n\n /** Get current canvas scale */\n getScale(): number;\n\n /** Set the canvas scale directly, clamped to min/max bounds. */\n setScale(newScale: number): void;\n\n /** Zoom in by a factor (default: 1.5) */\n zoomIn(factor?: number): void;\n\n /** Zoom out by a factor (default: 1.5) */\n zoomOut(factor?: number): void;\n\n /** Get current config */\n getConfig(): Required<CanvasTileEngineConfig>;\n\n /** Set map boundaries */\n setBounds(bounds: { minX: number; maxX: number; minY: number; maxY: number }): void;\n\n /** Dynamically update event handlers at runtime */\n setEventHandlers(handlers: Partial<EventHandlers>): void;\n\n /** Draw rectangles */\n drawRect(items: DrawObject | DrawObject[], layer?: number): LayerHandle;\n\n /** Draw static rectangles (cached) */\n drawStaticRect(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw circles */\n drawCircle(items: DrawObject | DrawObject[], layer?: number): LayerHandle;\n\n /** Draw static circles (cached) */\n drawStaticCircle(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw lines */\n drawLine(\n items: { from: Coords; to: Coords } | { from: Coords; to: Coords }[],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): LayerHandle;\n\n /** Draw text */\n drawText(\n items: { coords: Coords; text: string } | { coords: Coords; text: string }[],\n style?: { fillStyle?: string; font?: string; textAlign?: CanvasTextAlign; textBaseline?: CanvasTextBaseline },\n layer?: number\n ): LayerHandle;\n\n /** Draw paths/polylines */\n drawPath(\n items: Coords[] | Coords[][],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): LayerHandle;\n\n /** Draw images */\n drawImage(\n items:\n | (Omit<DrawObject, \"style\"> & { img: HTMLImageElement })\n | (Omit<DrawObject, \"style\"> & { img: HTMLImageElement })[],\n layer?: number\n ): LayerHandle;\n\n /** Draw static images (cached) */\n drawStaticImage(\n items: (Omit<DrawObject, \"style\"> & { img: HTMLImageElement })[],\n cacheKey: string,\n layer?: number\n ): LayerHandle;\n\n /** Draw grid lines */\n drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;\n\n /** Add custom draw function */\n addDrawFunction(\n fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void,\n layer?: number\n ): LayerHandle;\n\n /** Clear a specific layer */\n clearLayer(layer: number): void;\n\n /** Clear all layers */\n clearAll(): void;\n\n /** Clear static cache */\n clearStaticCache(cacheKey?: string): void;\n\n /** Remove a previously registered draw callback */\n removeLayerHandle(handle: LayerHandle): void;\n\n /** Image loader instance (undefined until engine mounts) */\n readonly images: CanvasTileEngineCore[\"images\"] | undefined;\n}\n\n/**\n * React hook that creates an engine handle for use with CanvasTileEngine component.\n *\n * @returns Engine handle to pass to CanvasTileEngine component\n *\n * @example\n * ```tsx\n * function App() {\n * const mainMap = useCanvasTileEngine();\n * const miniMap = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (mainMap.isReady && miniMap.isReady) {\n * // Both engines are ready, draw items\n * mainMap.drawGridLines(50);\n * mainMap.render();\n * }\n * }, [mainMap.isReady, miniMap.isReady]);\n *\n * return (\n * <>\n * <CanvasTileEngine engine={mainMap} config={...} />\n * <CanvasTileEngine engine={miniMap} config={...} />\n * </>\n * );\n * }\n * ```\n */\nexport function useCanvasTileEngine(): EngineHandle {\n const instanceRef = useRef<CanvasTileEngineCore | null>(null);\n const containerRef = useRef<HTMLDivElement>(null!);\n // _isReady state is only used to trigger re-renders, actual value is read from isReadyRef\n const [, setIsReady] = useState(false);\n // Keep isReady in a ref so the handle getter can read it without recreating handle\n const isReadyRef = useRef(false);\n\n const setInstance = useCallback((engine: CanvasTileEngineCore | null) => {\n instanceRef.current = engine;\n isReadyRef.current = engine !== null;\n setIsReady(engine !== null);\n }, []);\n\n // Create stable handle object using useMemo\n // Note: isReady is NOT in deps - we read from isReadyRef to keep handle stable\n const handle = useMemo<EngineHandle>(\n () => ({\n _containerRef: containerRef,\n _setInstance: setInstance,\n\n get isReady() {\n return isReadyRef.current;\n },\n\n get instance() {\n return instanceRef.current;\n },\n\n get images() {\n return instanceRef.current?.images;\n },\n\n render() {\n instanceRef.current?.render();\n },\n\n getCenterCoords() {\n return instanceRef.current?.getCenterCoords() ?? { x: 0, y: 0 };\n },\n\n getVisibleBounds() {\n return instanceRef.current?.getVisibleBounds() ?? { minX: 0, maxX: 0, minY: 0, maxY: 0 };\n },\n\n updateCoords(center: Coords) {\n instanceRef.current?.updateCoords(center);\n },\n\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.goCoords(x, y, durationMs, onComplete);\n },\n\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.resize(width, height, durationMs, onComplete);\n },\n\n getSize() {\n return instanceRef.current?.getSize() ?? { width: 0, height: 0 };\n },\n\n getScale() {\n return instanceRef.current?.getScale() ?? 1;\n },\n\n setScale(newScale: number) {\n instanceRef.current?.setScale(newScale);\n },\n\n zoomIn(factor?: number) {\n instanceRef.current?.zoomIn(factor);\n },\n\n zoomOut(factor?: number) {\n instanceRef.current?.zoomOut(factor);\n },\n\n getConfig() {\n return instanceRef.current?.getConfig() ?? DEFAULT_CONFIG;\n },\n\n setBounds(bounds) {\n instanceRef.current?.setBounds(bounds);\n },\n\n setEventHandlers(handlers) {\n instanceRef.current?.setEventHandlers(handlers);\n },\n\n drawRect(items, layer) {\n return instanceRef.current?.drawRect(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticRect(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticRect(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawCircle(items, layer) {\n return instanceRef.current?.drawCircle(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticCircle(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticCircle(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawLine(items, style, layer) {\n return instanceRef.current?.drawLine(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawText(items, style, layer) {\n return instanceRef.current?.drawText(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawPath(items, style, layer) {\n return instanceRef.current?.drawPath(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawImage(items, layer) {\n return instanceRef.current?.drawImage(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticImage(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticImage(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawGridLines(cellSize, lineWidth, strokeStyle, layer) {\n return (\n instanceRef.current?.drawGridLines(cellSize, lineWidth, strokeStyle, layer) ?? DUMMY_LAYER_HANDLE\n );\n },\n\n addDrawFunction(fn, layer) {\n return instanceRef.current?.addDrawFunction(fn, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n clearLayer(layer) {\n instanceRef.current?.clearLayer(layer);\n },\n\n clearAll() {\n instanceRef.current?.clearAll();\n },\n\n clearStaticCache(cacheKey) {\n instanceRef.current?.clearStaticCache(cacheKey);\n },\n\n removeLayerHandle(handle) {\n instanceRef.current?.removeLayerHandle(handle);\n },\n }),\n [setInstance]\n );\n\n return handle;\n}\n","// Main component\nexport { CanvasTileEngine } from \"./components\";\n\n// Draw components\nexport {\n type RectProps,\n type CircleProps,\n type ImageProps,\n type GridLinesProps,\n type LineProps,\n type TextProps,\n type PathProps,\n type StaticRectProps,\n type StaticCircleProps,\n type StaticImageProps,\n type DrawFunctionProps,\n} from \"./components\";\n\n// Hooks\nexport { useCanvasTileEngine } from \"./hooks\";\n\n// Context\nexport { useEngineContext, type EngineContextValue } from \"./context\";\n\n// Types\nexport type {\n CanvasTileEngineProps,\n CanvasTileEngineConfig,\n Coords,\n DrawObject,\n EventHandlers,\n onClickCallback,\n onHoverCallback,\n onMouseDownCallback,\n onMouseUpCallback,\n onMouseLeaveCallback,\n onDrawCallback,\n Rect,\n Line,\n Circle,\n Text,\n Path,\n ImageItem,\n} from \"./types\";\nexport type { EngineHandle } from \"./hooks/useCanvasTileEngine\";\n\n// Re-export core class and utilities\nexport { CanvasTileEngine as CanvasTileEngineCore, gridToSize } from \"@canvas-tile-engine/core\";\n"],"mappings":"AAAA,OAAS,aAAAA,EAAW,UAAAC,EAAQ,eAAAC,GAAa,WAAAC,OAAe,QACxD,OAAS,oBAAoBC,OAA4B,2BCDzD,OAAS,iBAAAC,EAAe,cAAAC,MAAkB,QASnC,IAAMC,EAAgBF,EAAyC,IAAI,EAMnE,SAASG,GAAuC,CACnD,IAAMC,EAAUH,EAAWC,CAAa,EAExC,GAAI,CAACE,EACD,MAAM,IAAI,MAAM,mEAAmE,EAGvF,OAAOA,CACX,CCvBA,OAAS,aAAAC,EAAW,QAAAC,MAAY,QAYzB,IAAMC,EAAOC,EAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CACpE,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,EAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,SAASF,EAAOC,CAAK,EAC3C,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,EC1BD,OAAS,aAAAI,EAAW,QAAAC,MAAY,QAYzB,IAAMC,EAASC,EAAK,SAAgB,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAgB,CAC1E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,EAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,WAAWF,EAAOC,CAAK,EAC7C,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,EC1BD,OAAS,aAAAI,EAAW,QAAAC,OAAY,QAYzB,IAAMC,EAAQC,GAAK,SAAe,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAe,CACvE,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,EAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,UAAUF,EAAOC,CAAK,EAC5C,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,EC1BD,OAAS,aAAAI,GAAW,QAAAC,OAAY,QAczB,IAAMC,EAAYC,GAAK,SAAmB,CAAE,SAAAC,EAAU,UAAAC,EAAY,EAAG,YAAAC,EAAc,QAAS,MAAAC,EAAQ,CAAE,EAAmB,CAC5H,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,GAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,cAAcJ,EAAUC,EAAWC,EAAaC,CAAK,EAC3E,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQJ,EAAUC,EAAWC,EAAaC,EAAOE,CAAa,CAAC,EAE5D,IACX,CAAC,EC5BD,OAAS,aAAAI,GAAW,QAAAC,OAAY,QAazB,IAAMC,EAAOC,GAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CAC3E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,GAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,SAASH,EAAOC,EAAOC,CAAK,EAClD,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQH,EAAOC,EAAOC,EAAOE,CAAa,CAAC,EAExC,IACX,CAAC,EC3BD,OAAS,aAAAI,GAAW,QAAAC,OAAY,QAkBzB,IAAMC,EAAOC,GAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CAC3E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,GAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,SAASH,EAAOC,EAAOC,CAAK,EAClD,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQH,EAAOC,EAAOC,EAAOE,CAAa,CAAC,EAExC,IACX,CAAC,EChCD,OAAS,aAAAI,GAAW,QAAAC,OAAY,QAazB,IAAMC,EAAOC,GAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CAC3E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,OAAAC,GAAU,IAAM,CACZ,IAAMC,EAASJ,EAAO,SAASH,EAAOC,EAAOC,CAAK,EAClD,OAAAE,EAAc,EACP,IAAM,CACLG,GACAJ,EAAO,kBAAkBI,CAAM,CAEvC,CACJ,EAAG,CAACJ,EAAQH,EAAOC,EAAOC,EAAOE,CAAa,CAAC,EAExC,IACX,CAAC,EC3BD,OAAS,aAAAI,EAAW,UAAAC,GAAQ,QAAAC,OAAY,QAcjC,IAAMC,EAAaC,GAAK,SAAoB,CAAE,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAoB,CAChG,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,EAAkBC,GAAeN,CAAQ,EAE/C,OAAAO,EAAU,IAAM,CACZ,GAAIR,EAAM,SAAW,EACjB,OAIAM,EAAgB,UAAYL,IAC5BE,EAAO,iBAAiBG,EAAgB,OAAO,EAC/CA,EAAgB,QAAUL,GAG9B,IAAMQ,EAASN,EAAO,eAAeH,EAAOC,EAAUC,CAAK,EAC3D,OAAAE,EAAc,EAEP,IAAM,CACLK,GACAN,EAAO,kBAAkBM,CAAM,CAEvC,CACJ,EAAG,CAACN,EAAQH,EAAOC,EAAUC,EAAOE,CAAa,CAAC,EAGlDI,EAAU,IACC,IAAM,CACTL,EAAO,iBAAiBF,CAAQ,CACpC,EACD,CAACE,EAAQF,CAAQ,CAAC,EAEd,IACX,CAAC,EC/CD,OAAS,aAAAS,EAAW,UAAAC,GAAQ,QAAAC,OAAY,QAajC,IAAMC,EAAeC,GAAK,SAAsB,CAAE,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAsB,CACtG,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,EAAkBC,GAAeN,CAAQ,EAE/C,OAAAO,EAAU,IAAM,CACZ,GAAIR,EAAM,SAAW,EACjB,OAGAM,EAAgB,UAAYL,IAC5BE,EAAO,iBAAiBG,EAAgB,OAAO,EAC/CA,EAAgB,QAAUL,GAG9B,IAAMQ,EAASN,EAAO,iBAAiBH,EAAOC,EAAUC,CAAK,EAC7D,OAAAE,EAAc,EAEP,IAAM,CACLK,GACAN,EAAO,kBAAkBM,CAAM,CAEvC,CACJ,EAAG,CAACN,EAAQH,EAAOC,EAAUC,EAAOE,CAAa,CAAC,EAElDI,EAAU,IACC,IAAM,CACTL,EAAO,iBAAiBF,CAAQ,CACpC,EACD,CAACE,EAAQF,CAAQ,CAAC,EAEd,IACX,CAAC,EC5CD,OAAS,aAAAS,EAAW,UAAAC,GAAQ,QAAAC,OAAY,QAcjC,IAAMC,EAAcC,GAAK,SAAqB,CAAE,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAqB,CACnG,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,EAAkBC,GAAeN,CAAQ,EAE/C,OAAAO,EAAU,IAAM,CACZ,GAAIR,EAAM,SAAW,EACjB,OAGAM,EAAgB,UAAYL,IAC5BE,EAAO,iBAAiBG,EAAgB,OAAO,EAC/CA,EAAgB,QAAUL,GAG9B,IAAMQ,EAASN,EAAO,gBAAgBH,EAAOC,EAAUC,CAAK,EAC5D,OAAAE,EAAc,EAEP,IAAM,CACLK,GACAN,EAAO,kBAAkBM,CAAM,CAEvC,CACJ,EAAG,CAACN,EAAQH,EAAOC,EAAUC,EAAOE,CAAa,CAAC,EAElDI,EAAU,IACC,IAAM,CACTL,EAAO,iBAAiBF,CAAQ,CACpC,EACD,CAACE,EAAQF,CAAQ,CAAC,EAEd,IACX,CAAC,EC7CD,OAAS,aAAAS,EAAW,UAAAC,GAAQ,QAAAC,OAAY,QAyBjC,IAAMC,EAAeC,GAAK,SAAsB,CAAE,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAsB,CAC/F,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,EAAQC,GAAON,CAAQ,EAG7B,OAAAO,EAAU,IAAM,CACZF,EAAM,QAAUL,CACpB,CAAC,EAEDO,EAAU,IAAM,CACZ,IAAMC,EAASN,EAAO,gBAAgB,CAACO,EAAKC,EAAQC,IAAW,CAC3DN,EAAM,QAAQI,EAAKC,EAAQC,CAAM,CACrC,EAAGV,CAAK,EACR,OAAAE,EAAc,EAEP,IAAM,CACLK,GACAN,EAAO,kBAAkBM,CAAM,CAEvC,CACJ,EAAG,CAACN,EAAQD,EAAOE,CAAa,CAAC,EAE1B,IACX,CAAC,EZ0HO,OAQQ,OAAAS,EARR,QAAAC,OAAA,oBArHR,SAASC,GAAqB,CAC1B,OAAAC,EACA,OAAAC,EACA,OAAAC,EAAS,CAAE,EAAG,EAAG,EAAG,CAAE,EACtB,UAAAC,EACA,MAAAC,EACA,SAAAC,EACA,eAAAC,EACA,QAAAC,EACA,aAAAC,EACA,QAAAC,EACA,YAAAC,EACA,UAAAC,EACA,aAAAC,EACA,OAAAC,EACA,SAAAC,EACA,OAAAC,CACJ,EAA0B,CAEtB,IAAMC,EAAeC,EAAO,CACxB,eAAAX,EACA,QAAAC,EACA,aAAAC,EACA,QAAAC,EACA,YAAAC,EACA,UAAAC,EACA,aAAAC,EACA,OAAAC,EACA,SAAAC,EACA,OAAAC,CACJ,CAAC,EAGDG,EAAU,IAAM,CACZF,EAAa,QAAU,CACnB,eAAAV,EACA,QAAAC,EACA,aAAAC,EACA,QAAAC,EACA,YAAAC,EACA,UAAAC,EACA,aAAAC,EACA,OAAAC,EACA,SAAAC,EACA,OAAAC,CACJ,CACJ,CAAC,EAID,IAAMI,EAAWF,EAAsB,IAAI,EACrCG,EAAgBC,GAAY,IAAM,CAChCF,EAAS,UAAY,OACzBA,EAAS,QAAU,sBAAsB,IAAM,CAC3CA,EAAS,QAAU,KACnBnB,EAAO,OAAO,CAClB,CAAC,EACL,EAAG,CAACA,CAAM,CAAC,EAGXkB,EAAU,IACC,IAAM,CACLC,EAAS,UAAY,MACrB,qBAAqBA,EAAS,OAAO,CAE7C,EACD,CAAC,CAAC,EAGL,IAAMG,EAAeC,GACjB,KAAO,CACH,OAAAvB,EACA,cAAAoB,CACJ,GACA,CAACpB,EAAQoB,CAAa,CAC1B,EAKA,OAAAF,EAAU,IAAM,CACZ,IAAMM,EAAYxB,EAAO,cAAc,QAEvC,GAAI,CAACwB,EACD,OAIJ,IAAMC,EAAW,IAAIC,GAAqBF,EAAWvB,EAAQC,CAAM,EAGnE,OAAAuB,EAAS,eAAkBE,GAAWX,EAAa,QAAQ,iBAAiBW,CAAM,EAClFF,EAAS,QAAU,IAAIG,IAASZ,EAAa,QAAQ,UAAU,GAAGY,CAAI,EACtEH,EAAS,aAAe,IAAIG,IAASZ,EAAa,QAAQ,eAAe,GAAGY,CAAI,EAChFH,EAAS,QAAU,IAAIG,IAASZ,EAAa,QAAQ,UAAU,GAAGY,CAAI,EACtEH,EAAS,YAAc,IAAIG,IAASZ,EAAa,QAAQ,cAAc,GAAGY,CAAI,EAC9EH,EAAS,UAAY,IAAIG,IAASZ,EAAa,QAAQ,YAAY,GAAGY,CAAI,EAC1EH,EAAS,aAAe,IAAIG,IAASZ,EAAa,QAAQ,eAAe,GAAGY,CAAI,EAChFH,EAAS,OAAS,IAAIG,IAASZ,EAAa,QAAQ,SAAS,GAAGY,CAAI,EACpEH,EAAS,SAAW,IAAMT,EAAa,QAAQ,WAAW,EAC1DS,EAAS,OAAUI,GAAUb,EAAa,QAAQ,SAASa,CAAK,EAGhE7B,EAAO,aAAayB,CAAQ,EAG5BA,EAAS,OAAO,EAGT,IAAM,CACTA,EAAS,QAAQ,EACjBzB,EAAO,aAAa,IAAI,CAC5B,CAEJ,EAAG,CAACA,CAAM,CAAC,EAGPF,GAACgC,EAAc,SAAd,CAAuB,MAAOR,EAC3B,UAAAzB,EAAC,OACG,IAAKG,EAAO,cACZ,UAAWG,EACX,MAAO,CACH,GAAGC,CACP,EAEA,SAAAP,EAAC,WAAO,EACZ,EAECG,EAAO,SAAWK,GACvB,CAER,CAGO,IAAM0B,EAAmB,OAAO,OAAOhC,GAAsB,CAChE,KAAAiC,EACA,OAAAC,EACA,MAAAC,EACA,UAAAC,EACA,KAAAC,EACA,KAAAC,EACA,KAAAC,EACA,WAAAC,EACA,aAAAC,EACA,YAAAC,EACA,aAAAC,CACJ,CAAC,EavMD,OAAS,UAAAC,EAAQ,eAAAC,GAAa,YAAAC,GAAU,WAAAC,OAAe,QAWvD,IAAMC,EAAkC,CAAE,MAAO,GAAI,GAAI,OAAO,OAAO,CAAE,EAGnEC,GAAmD,CACrD,KAAM,CAAE,MAAO,EAAG,OAAQ,EAAG,SAAU,IAAK,UAAW,IAAK,SAAU,IAAU,UAAW,GAAS,EACpG,WAAY,GACZ,MAAO,EACP,SAAU,GACV,SAAU,EACV,gBAAiB,UACjB,YAAa,GACb,SAAU,SACV,cAAe,CACX,KAAM,GACN,KAAM,GACN,MAAO,GACP,MAAO,GACP,WAAY,GACZ,OAAQ,EACZ,EACA,OAAQ,CACJ,KAAM,KACN,KAAM,IACN,KAAM,KACN,KAAM,GACV,EACA,YAAa,CACT,QAAS,GACT,gBAAiB,CAAE,IAAK,EAAG,IAAK,GAAS,CAC7C,EACA,OAAQ,CACJ,QAAS,UACT,KAAM,MACV,EACA,MAAO,CACH,QAAS,GACT,IAAK,CACD,QAAS,GACT,mBAAoB,GACpB,YAAa,GACb,MAAO,GACP,YAAa,GACb,IAAK,EACT,EACA,cAAe,CACX,MAAO,GACP,MAAO,GACP,KAAM,GACN,KAAM,GACN,OAAQ,EACZ,CACJ,CACJ,EAoKO,SAASC,GAAoC,CAChD,IAAMC,EAAcP,EAAoC,IAAI,EACtDQ,EAAeR,EAAuB,IAAK,EAE3C,CAAC,CAAES,CAAU,EAAIP,GAAS,EAAK,EAE/BQ,EAAaV,EAAO,EAAK,EAEzBW,EAAcV,GAAaW,GAAwC,CACrEL,EAAY,QAAUK,EACtBF,EAAW,QAAUE,IAAW,KAChCH,EAAWG,IAAW,IAAI,CAC9B,EAAG,CAAC,CAAC,EA8IL,OA1IeT,GACX,KAAO,CACH,cAAeK,EACf,aAAcG,EAEd,IAAI,SAAU,CACV,OAAOD,EAAW,OACtB,EAEA,IAAI,UAAW,CACX,OAAOH,EAAY,OACvB,EAEA,IAAI,QAAS,CACT,OAAOA,EAAY,SAAS,MAChC,EAEA,QAAS,CACLA,EAAY,SAAS,OAAO,CAChC,EAEA,iBAAkB,CACd,OAAOA,EAAY,SAAS,gBAAgB,GAAK,CAAE,EAAG,EAAG,EAAG,CAAE,CAClE,EAEA,kBAAmB,CACf,OAAOA,EAAY,SAAS,iBAAiB,GAAK,CAAE,KAAM,EAAG,KAAM,EAAG,KAAM,EAAG,KAAM,CAAE,CAC3F,EAEA,aAAaM,EAAgB,CACzBN,EAAY,SAAS,aAAaM,CAAM,CAC5C,EAEA,SAASC,EAAWC,EAAWC,EAAqBC,EAAyB,CACzEV,EAAY,SAAS,SAASO,EAAGC,EAAGC,EAAYC,CAAU,CAC9D,EAEA,OAAOC,EAAeC,EAAgBH,EAAqBC,EAAyB,CAChFV,EAAY,SAAS,OAAOW,EAAOC,EAAQH,EAAYC,CAAU,CACrE,EAEA,SAAU,CACN,OAAOV,EAAY,SAAS,QAAQ,GAAK,CAAE,MAAO,EAAG,OAAQ,CAAE,CACnE,EAEA,UAAW,CACP,OAAOA,EAAY,SAAS,SAAS,GAAK,CAC9C,EAEA,SAASa,EAAkB,CACvBb,EAAY,SAAS,SAASa,CAAQ,CAC1C,EAEA,OAAOC,EAAiB,CACpBd,EAAY,SAAS,OAAOc,CAAM,CACtC,EAEA,QAAQA,EAAiB,CACrBd,EAAY,SAAS,QAAQc,CAAM,CACvC,EAEA,WAAY,CACR,OAAOd,EAAY,SAAS,UAAU,GAAKF,EAC/C,EAEA,UAAUiB,EAAQ,CACdf,EAAY,SAAS,UAAUe,CAAM,CACzC,EAEA,iBAAiBC,EAAU,CACvBhB,EAAY,SAAS,iBAAiBgB,CAAQ,CAClD,EAEA,SAASC,EAAOC,EAAO,CACnB,OAAOlB,EAAY,SAAS,SAASiB,EAAOC,CAAK,GAAKrB,CAC1D,EAEA,eAAeoB,EAAOE,EAAUD,EAAO,CACnC,OAAOlB,EAAY,SAAS,eAAeiB,EAAOE,EAAUD,CAAK,GAAKrB,CAC1E,EAEA,WAAWoB,EAAOC,EAAO,CACrB,OAAOlB,EAAY,SAAS,WAAWiB,EAAOC,CAAK,GAAKrB,CAC5D,EAEA,iBAAiBoB,EAAOE,EAAUD,EAAO,CACrC,OAAOlB,EAAY,SAAS,iBAAiBiB,EAAOE,EAAUD,CAAK,GAAKrB,CAC5E,EAEA,SAASoB,EAAOG,EAAOF,EAAO,CAC1B,OAAOlB,EAAY,SAAS,SAASiB,EAAOG,EAAOF,CAAK,GAAKrB,CACjE,EAEA,SAASoB,EAAOG,EAAOF,EAAO,CAC1B,OAAOlB,EAAY,SAAS,SAASiB,EAAOG,EAAOF,CAAK,GAAKrB,CACjE,EAEA,SAASoB,EAAOG,EAAOF,EAAO,CAC1B,OAAOlB,EAAY,SAAS,SAASiB,EAAOG,EAAOF,CAAK,GAAKrB,CACjE,EAEA,UAAUoB,EAAOC,EAAO,CACpB,OAAOlB,EAAY,SAAS,UAAUiB,EAAOC,CAAK,GAAKrB,CAC3D,EAEA,gBAAgBoB,EAAOE,EAAUD,EAAO,CACpC,OAAOlB,EAAY,SAAS,gBAAgBiB,EAAOE,EAAUD,CAAK,GAAKrB,CAC3E,EAEA,cAAcwB,EAAUC,EAAWC,EAAaL,EAAO,CACnD,OACIlB,EAAY,SAAS,cAAcqB,EAAUC,EAAWC,EAAaL,CAAK,GAAKrB,CAEvF,EAEA,gBAAgB2B,EAAIN,EAAO,CACvB,OAAOlB,EAAY,SAAS,gBAAgBwB,EAAIN,CAAK,GAAKrB,CAC9D,EAEA,WAAWqB,EAAO,CACdlB,EAAY,SAAS,WAAWkB,CAAK,CACzC,EAEA,UAAW,CACPlB,EAAY,SAAS,SAAS,CAClC,EAEA,iBAAiBmB,EAAU,CACvBnB,EAAY,SAAS,iBAAiBmB,CAAQ,CAClD,EAEA,kBAAkBM,EAAQ,CACtBzB,EAAY,SAAS,kBAAkByB,CAAM,CACjD,CACJ,GACA,CAACrB,CAAW,CAChB,CAGJ,CC/UA,OAA6B,oBAApBsB,GAA0C,cAAAC,OAAkB","names":["useEffect","useRef","useCallback","useMemo","CanvasTileEngineCore","createContext","useContext","EngineContext","useEngineContext","context","useEffect","memo","Rect","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Circle","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Image","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","GridLines","memo","cellSize","lineWidth","strokeStyle","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Line","memo","items","style","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Text","memo","items","style","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Path","memo","items","style","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","useRef","memo","StaticRect","memo","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","useRef","useEffect","handle","useEffect","useRef","memo","StaticCircle","memo","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","useRef","useEffect","handle","useEffect","useRef","memo","StaticImage","memo","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","useRef","useEffect","handle","useEffect","useRef","memo","DrawFunction","memo","children","layer","engine","requestRender","useEngineContext","fnRef","useRef","useEffect","handle","ctx","coords","config","jsx","jsxs","CanvasTileEngineBase","engine","config","center","className","style","children","onCoordsChange","onClick","onRightClick","onHover","onMouseDown","onMouseUp","onMouseLeave","onDraw","onResize","onZoom","callbacksRef","useRef","useEffect","rafIdRef","requestRender","useCallback","contextValue","useMemo","container","instance","CanvasTileEngineCore","coords","args","scale","EngineContext","CanvasTileEngine","Rect","Circle","Image","GridLines","Line","Text","Path","StaticRect","StaticCircle","StaticImage","DrawFunction","useRef","useCallback","useState","useMemo","DUMMY_LAYER_HANDLE","DEFAULT_CONFIG","useCanvasTileEngine","instanceRef","containerRef","setIsReady","isReadyRef","setInstance","engine","center","x","y","durationMs","onComplete","width","height","newScale","factor","bounds","handlers","items","layer","cacheKey","style","cellSize","lineWidth","strokeStyle","fn","handle","CanvasTileEngine","gridToSize"]}
1
+ {"version":3,"sources":["../src/components/CanvasTileEngine.tsx","../src/context/EngineContext.tsx","../src/components/draw/Rect.tsx","../src/components/draw/Circle.tsx","../src/components/draw/Image.tsx","../src/components/draw/GridLines.tsx","../src/components/draw/Line.tsx","../src/components/draw/Text.tsx","../src/components/draw/Path.tsx","../src/components/draw/StaticRect.tsx","../src/components/draw/StaticCircle.tsx","../src/components/draw/StaticImage.tsx","../src/components/draw/DrawFunction.tsx","../src/hooks/useCanvasTileEngine.ts","../src/index.ts"],"sourcesContent":["import { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { CanvasTileEngine as CanvasTileEngineCore } from \"@canvas-tile-engine/core\";\nimport { EngineContext, type EngineContextValue } from \"../context/EngineContext\";\nimport type { CanvasTileEngineProps } from \"../types\";\n\n// Import draw components for compound pattern\nimport { Rect } from \"./draw/Rect\";\nimport { Circle } from \"./draw/Circle\";\nimport { Image } from \"./draw/Image\";\nimport { GridLines } from \"./draw/GridLines\";\nimport { Line } from \"./draw/Line\";\nimport { Text } from \"./draw/Text\";\nimport { Path } from \"./draw/Path\";\nimport { StaticRect } from \"./draw/StaticRect\";\nimport { StaticCircle } from \"./draw/StaticCircle\";\nimport { StaticImage } from \"./draw/StaticImage\";\nimport { DrawFunction } from \"./draw/DrawFunction\";\n\n/**\n * React component that renders a CanvasTileEngine.\n * Supports both imperative API (via engine handle) and declarative API (via children).\n *\n * @example Declarative API with compound components\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * return (\n * <CanvasTileEngine engine={engine} config={config}>\n * <CanvasTileEngine.GridLines cellSize={50} layer={0} />\n * <CanvasTileEngine.Image items={imageItems} layer={1} />\n * <CanvasTileEngine.Circle items={markers} layer={2} />\n * </CanvasTileEngine>\n * );\n * }\n * ```\n *\n * @example Imperative API\n * ```tsx\n * function App() {\n * const engine = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (engine.isReady) {\n * engine.drawGridLines(50);\n * engine.render();\n * }\n * }, [engine.isReady]);\n *\n * return <CanvasTileEngine engine={engine} config={config} />;\n * }\n * ```\n */\nfunction CanvasTileEngineBase({\n engine,\n config,\n center = { x: 0, y: 0 },\n className,\n style,\n children,\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n}: CanvasTileEngineProps) {\n // Stable callback refs\n const callbacksRef = useRef({\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n });\n\n // Update callback refs\n useEffect(() => {\n callbacksRef.current = {\n onCoordsChange,\n onClick,\n onRightClick,\n onHover,\n onMouseDown,\n onMouseUp,\n onMouseLeave,\n onDraw,\n onResize,\n onZoom,\n };\n });\n\n // Debounced render - multiple draw components calling requestRender\n // in the same frame will trigger only one render\n const rafIdRef = useRef<number | null>(null);\n const requestRender = useCallback(() => {\n if (rafIdRef.current !== null) return;\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n engine.render();\n });\n }, [engine]);\n\n // Cleanup RAF on unmount\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n };\n }, []);\n\n // Context value\n const contextValue = useMemo<EngineContextValue>(\n () => ({\n engine,\n requestRender,\n }),\n [engine, requestRender]\n );\n\n // Initialize engine when component mounts\n // Note: config and center are intentionally not in deps - we only want to create the engine once\n // Callbacks are accessed via callbacksRef which is always up-to-date\n useEffect(() => {\n const container = engine._containerRef.current;\n\n if (!container) {\n return;\n }\n\n // Create engine instance\n const instance = new CanvasTileEngineCore(container, config, center);\n\n // Set up callbacks using stable refs\n instance.onCoordsChange = (coords) => callbacksRef.current.onCoordsChange?.(coords);\n instance.onClick = (...args) => callbacksRef.current.onClick?.(...args);\n instance.onRightClick = (...args) => callbacksRef.current.onRightClick?.(...args);\n instance.onHover = (...args) => callbacksRef.current.onHover?.(...args);\n instance.onMouseDown = (...args) => callbacksRef.current.onMouseDown?.(...args);\n instance.onMouseUp = (...args) => callbacksRef.current.onMouseUp?.(...args);\n instance.onMouseLeave = (...args) => callbacksRef.current.onMouseLeave?.(...args);\n instance.onDraw = (...args) => callbacksRef.current.onDraw?.(...args);\n instance.onResize = () => callbacksRef.current.onResize?.();\n instance.onZoom = (scale) => callbacksRef.current.onZoom?.(scale);\n\n // Attach to handle\n engine._setInstance(instance);\n\n // Initial render\n instance.render();\n\n // Cleanup on unmount\n return () => {\n instance.destroy();\n engine._setInstance(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine]);\n\n return (\n <EngineContext.Provider value={contextValue}>\n <div\n ref={engine._containerRef}\n className={className}\n style={{\n ...style,\n }}\n >\n <canvas />\n </div>\n {/* Render children only when engine is ready */}\n {engine.isReady && children}\n </EngineContext.Provider>\n );\n}\n\n// Compound component pattern - attach draw components as static properties\nexport const CanvasTileEngine = Object.assign(CanvasTileEngineBase, {\n Rect,\n Circle,\n Image,\n GridLines,\n Line,\n Text,\n Path,\n StaticRect,\n StaticCircle,\n StaticImage,\n DrawFunction,\n});\n","import { createContext, useContext } from \"react\";\nimport type { EngineHandle } from \"../hooks/useCanvasTileEngine\";\n\nexport interface EngineContextValue {\n engine: EngineHandle;\n /** Request a re-render of the canvas */\n requestRender: () => void;\n}\n\nexport const EngineContext = createContext<EngineContextValue | null>(null);\n\n/**\n * Hook to access the engine context from child components.\n * Must be used within a CanvasTileEngine component.\n */\nexport function useEngineContext(): EngineContextValue {\n const context = useContext(EngineContext);\n\n if (!context) {\n throw new Error(\"useEngineContext must be used within a CanvasTileEngine component\");\n }\n\n return context;\n}\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Rect as RectType } from \"@canvas-tile-engine/core\";\n\nexport interface RectProps {\n items: RectType | RectType[];\n layer?: number;\n}\n\n/**\n * Draws rectangles on the canvas.\n */\nexport const Rect = memo(function Rect({ items, layer = 1 }: RectProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawRect(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Circle as CircleType } from \"@canvas-tile-engine/core\";\n\nexport interface CircleProps {\n items: CircleType | CircleType[];\n layer?: number;\n}\n\n/**\n * Draws circles on the canvas.\n */\nexport const Circle = memo(function Circle({ items, layer = 1 }: CircleProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawCircle(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface ImageProps {\n items: ImageItem | ImageItem[];\n layer?: number;\n}\n\n/**\n * Draws images on the canvas.\n */\nexport const Image = memo(function Image({ items, layer = 1 }: ImageProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawImage(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\n\nexport interface GridLinesProps {\n cellSize: number;\n lineWidth?: number;\n strokeStyle?: string;\n layer?: number;\n}\n\n/**\n * Draws grid lines on the canvas.\n * Multiple GridLines can share the same layer (additive drawing).\n */\nexport const GridLines = memo(function GridLines({ cellSize, lineWidth = 1, strokeStyle = \"black\", layer = 0 }: GridLinesProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawGridLines(cellSize, lineWidth, strokeStyle, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, cellSize, lineWidth, strokeStyle, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Line as LineType } from \"@canvas-tile-engine/core\";\n\nexport interface LineProps {\n items: LineType | LineType[];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws lines on the canvas.\n */\nexport const Line = memo(function Line({ items, style, layer = 1 }: LineProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawLine(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Text as TextType } from \"@canvas-tile-engine/core\";\n\nexport interface TextProps {\n items: TextType | TextType[];\n layer?: number;\n}\n\n/**\n * Draws text on the canvas.\n * @example\n * ```tsx\n * <Text\n * items={{\n * x: 0,\n * y: 0,\n * text: \"Hello\",\n * size: 1,\n * style: { fillStyle: \"black\", fontFamily: \"Arial\" }\n * }}\n * />\n * ```\n */\nexport const Text = memo(function Text({ items, layer = 2 }: TextProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawText(items, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Path as PathType } from \"@canvas-tile-engine/core\";\n\nexport interface PathProps {\n items: PathType | PathType[];\n style?: { strokeStyle?: string; lineWidth?: number };\n layer?: number;\n}\n\n/**\n * Draws paths/polylines on the canvas.\n */\nexport const Path = memo(function Path({ items, style, layer = 1 }: PathProps) {\n const { engine, requestRender } = useEngineContext();\n\n useEffect(() => {\n const handle = engine.drawPath(items, style, layer);\n requestRender();\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, style, layer, requestRender]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Rect as RectType } from \"@canvas-tile-engine/core\";\n\nexport interface StaticRectProps {\n items: RectType[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static rectangles with caching for performance.\n * Ideal for large datasets that don't change frequently.\n */\nexport const StaticRect = memo(function StaticRect({ items, cacheKey, layer = 1 }: StaticRectProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n // Clear previous cache if cacheKey changed\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticRect(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { Circle as CircleType } from \"@canvas-tile-engine/core\";\n\nexport interface StaticCircleProps {\n items: CircleType[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static circles with caching for performance.\n */\nexport const StaticCircle = memo(function StaticCircle({ items, cacheKey, layer = 1 }: StaticCircleProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticCircle(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport { ImageItem } from \"@canvas-tile-engine/core\";\n\nexport interface StaticImageProps {\n items: ImageItem[];\n cacheKey: string;\n layer?: number;\n}\n\n/**\n * Draws static images with caching for performance.\n * Ideal for terrain tiles or static decorations.\n */\nexport const StaticImage = memo(function StaticImage({ items, cacheKey, layer = 1 }: StaticImageProps) {\n const { engine, requestRender } = useEngineContext();\n const prevCacheKeyRef = useRef<string>(cacheKey);\n\n useEffect(() => {\n if (items.length === 0) {\n return;\n }\n\n if (prevCacheKeyRef.current !== cacheKey) {\n engine.clearStaticCache(prevCacheKeyRef.current);\n prevCacheKeyRef.current = cacheKey;\n }\n\n const handle = engine.drawStaticImage(items, cacheKey, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, items, cacheKey, layer, requestRender]);\n\n useEffect(() => {\n return () => {\n engine.clearStaticCache(cacheKey);\n };\n }, [engine, cacheKey]);\n\n return null;\n});\n","import { useEffect, useRef, memo } from \"react\";\nimport { useEngineContext } from \"../../context/EngineContext\";\nimport type { CanvasTileEngineConfig, Coords } from \"@canvas-tile-engine/core\";\n\nexport interface DrawFunctionProps {\n /** The draw function to execute */\n children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;\n layer?: number;\n}\n\n/**\n * Custom draw function component.\n * Allows arbitrary canvas drawing within the engine's render cycle.\n * Multiple DrawFunction components can share the same layer (additive drawing).\n *\n * @example\n * ```tsx\n * <DrawFunction layer={3}>\n * {(ctx, coords, config) => {\n * ctx.fillStyle = \"red\";\n * ctx.fillRect(config.size.width / 2 - 5, config.size.height / 2 - 5, 10, 10);\n * }}\n * </DrawFunction>\n * ```\n */\nexport const DrawFunction = memo(function DrawFunction({ children, layer = 1 }: DrawFunctionProps) {\n const { engine, requestRender } = useEngineContext();\n const fnRef = useRef(children);\n\n // Keep function ref updated\n useEffect(() => {\n fnRef.current = children;\n });\n\n useEffect(() => {\n const handle = engine.addDrawFunction((ctx, coords, config) => {\n fnRef.current(ctx, coords, config);\n }, layer);\n requestRender();\n\n return () => {\n if (handle) {\n engine.removeLayerHandle(handle);\n }\n };\n }, [engine, layer, requestRender]);\n\n return null;\n});\n","import { useRef, useCallback, useState, useMemo } from \"react\";\nimport type {\n CanvasTileEngine as CanvasTileEngineCore,\n CanvasTileEngineConfig,\n Coords,\n EventHandlers,\n LayerHandle,\n ImageItem,\n Text,\n Circle,\n Line,\n Rect,\n} from \"@canvas-tile-engine/core\";\n\n/** Dummy handle returned when engine is not ready */\nconst DUMMY_LAYER_HANDLE: LayerHandle = { layer: -1, id: Symbol(\"dummy\") };\n\n/** Default config when engine is not ready */\nconst DEFAULT_CONFIG: Required<CanvasTileEngineConfig> = {\n size: { width: 0, height: 0, minWidth: 100, minHeight: 100, maxWidth: Infinity, maxHeight: Infinity },\n responsive: false,\n scale: 1,\n minScale: 0.5,\n maxScale: 2,\n backgroundColor: \"#ffffff\",\n gridAligned: false,\n renderer: \"canvas\",\n eventHandlers: {\n drag: true,\n zoom: true,\n hover: false,\n click: false,\n rightClick: false,\n resize: false,\n },\n bounds: {\n minX: -Infinity,\n maxX: Infinity,\n minY: -Infinity,\n maxY: Infinity,\n },\n coordinates: {\n enabled: false,\n shownScaleRange: { min: 0, max: Infinity },\n },\n cursor: {\n default: \"default\",\n move: \"move\",\n },\n debug: {\n enabled: false,\n hud: {\n enabled: false,\n topLeftCoordinates: false,\n coordinates: false,\n scale: false,\n tilesInView: false,\n fps: false,\n },\n eventHandlers: {\n click: false,\n hover: false,\n drag: false,\n zoom: false,\n resize: false,\n },\n },\n};\n\n/**\n * Engine handle returned by useCanvasTileEngine hook.\n * Provides access to engine methods with proper typing.\n *\n * All methods return default/dummy values when engine is not ready,\n * allowing safe usage without null checks.\n */\nexport interface EngineHandle {\n /** @internal - Used by CanvasTileEngine component */\n readonly _containerRef: React.RefObject<HTMLDivElement>;\n /** @internal - Used by CanvasTileEngine component */\n _setInstance: (engine: CanvasTileEngineCore | null) => void;\n\n /** Whether the engine is ready (mounted and initialized) */\n readonly isReady: boolean;\n\n /** The underlying engine instance (null until component mounts) */\n readonly instance: CanvasTileEngineCore | null;\n\n /** Render a frame */\n render(): void;\n\n /** Get current center coordinates */\n getCenterCoords(): Coords;\n\n /** Get visible world coordinate bounds of the viewport */\n getVisibleBounds(): { minX: number; maxX: number; minY: number; maxY: number };\n\n /** Update center coordinates */\n updateCoords(center: Coords): void;\n\n /** Animate to target coordinates */\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Resize the canvas */\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void): void;\n\n /** Get current canvas size */\n getSize(): { width: number; height: number };\n\n /** Get current canvas scale */\n getScale(): number;\n\n /** Set the canvas scale directly, clamped to min/max bounds. */\n setScale(newScale: number): void;\n\n /** Zoom in by a factor (default: 1.5) */\n zoomIn(factor?: number): void;\n\n /** Zoom out by a factor (default: 1.5) */\n zoomOut(factor?: number): void;\n\n /** Get current config */\n getConfig(): Required<CanvasTileEngineConfig>;\n\n /** Set map boundaries */\n setBounds(bounds: { minX: number; maxX: number; minY: number; maxY: number }): void;\n\n /** Dynamically update event handlers at runtime */\n setEventHandlers(handlers: Partial<EventHandlers>): void;\n\n /** Draw rectangles */\n drawRect(items: Rect | Rect[], layer?: number): LayerHandle;\n\n /** Draw static rectangles (cached) */\n drawStaticRect(items: Rect[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw circles */\n drawCircle(items: Circle | Circle[], layer?: number): LayerHandle;\n\n /** Draw static circles (cached) */\n drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw lines */\n drawLine(items: Line | Line[], style?: { strokeStyle?: string; lineWidth?: number }, layer?: number): LayerHandle;\n\n /** Draw text */\n drawText(items: Text | Text[], layer?: number): LayerHandle;\n\n /** Draw paths/polylines */\n drawPath(\n items: Coords[] | Coords[][],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): LayerHandle;\n\n /** Draw images */\n drawImage(items: ImageItem | ImageItem[], layer?: number): LayerHandle;\n\n /** Draw static images (cached) */\n drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): LayerHandle;\n\n /** Draw grid lines */\n drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;\n\n /** Add custom draw function */\n addDrawFunction(\n fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void,\n layer?: number\n ): LayerHandle;\n\n /** Clear a specific layer */\n clearLayer(layer: number): void;\n\n /** Clear all layers */\n clearAll(): void;\n\n /** Clear static cache */\n clearStaticCache(cacheKey?: string): void;\n\n /** Remove a previously registered draw callback */\n removeLayerHandle(handle: LayerHandle): void;\n\n /** Image loader instance (undefined until engine mounts) */\n readonly images: CanvasTileEngineCore[\"images\"] | undefined;\n\n /**\n * Load an image using the engine's image loader.\n * Returns a rejected promise if engine is not ready.\n * @param src - Image URL to load\n * @param retry - Number of retries on failure (default: 1)\n * @example\n * ```tsx\n * const img = await engine.loadImage(\"/sprites/player.png\");\n * ```\n */\n loadImage(src: string, retry?: number): Promise<HTMLImageElement>;\n}\n\n/**\n * React hook that creates an engine handle for use with CanvasTileEngine component.\n *\n * @returns Engine handle to pass to CanvasTileEngine component\n *\n * @example\n * ```tsx\n * function App() {\n * const mainMap = useCanvasTileEngine();\n * const miniMap = useCanvasTileEngine();\n *\n * useEffect(() => {\n * if (mainMap.isReady && miniMap.isReady) {\n * // Both engines are ready, draw items\n * mainMap.drawGridLines(50);\n * mainMap.render();\n * }\n * }, [mainMap.isReady, miniMap.isReady]);\n *\n * return (\n * <>\n * <CanvasTileEngine engine={mainMap} config={...} />\n * <CanvasTileEngine engine={miniMap} config={...} />\n * </>\n * );\n * }\n * ```\n */\nexport function useCanvasTileEngine(): EngineHandle {\n const instanceRef = useRef<CanvasTileEngineCore | null>(null);\n const containerRef = useRef<HTMLDivElement>(null!);\n // _isReady state is only used to trigger re-renders, actual value is read from isReadyRef\n const [, setIsReady] = useState(false);\n // Keep isReady in a ref so the handle getter can read it without recreating handle\n const isReadyRef = useRef(false);\n\n const setInstance = useCallback((engine: CanvasTileEngineCore | null) => {\n instanceRef.current = engine;\n isReadyRef.current = engine !== null;\n setIsReady(engine !== null);\n }, []);\n\n // Create stable handle object using useMemo\n // Note: isReady is NOT in deps - we read from isReadyRef to keep handle stable\n const handle = useMemo<EngineHandle>(\n () => ({\n _containerRef: containerRef,\n _setInstance: setInstance,\n\n get isReady() {\n return isReadyRef.current;\n },\n\n get instance() {\n return instanceRef.current;\n },\n\n get images() {\n return instanceRef.current?.images;\n },\n\n render() {\n instanceRef.current?.render();\n },\n\n getCenterCoords() {\n return instanceRef.current?.getCenterCoords() ?? { x: 0, y: 0 };\n },\n\n getVisibleBounds() {\n return instanceRef.current?.getVisibleBounds() ?? { minX: 0, maxX: 0, minY: 0, maxY: 0 };\n },\n\n updateCoords(center: Coords) {\n instanceRef.current?.updateCoords(center);\n },\n\n goCoords(x: number, y: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.goCoords(x, y, durationMs, onComplete);\n },\n\n resize(width: number, height: number, durationMs?: number, onComplete?: () => void) {\n instanceRef.current?.resize(width, height, durationMs, onComplete);\n },\n\n getSize() {\n return instanceRef.current?.getSize() ?? { width: 0, height: 0 };\n },\n\n getScale() {\n return instanceRef.current?.getScale() ?? 1;\n },\n\n setScale(newScale: number) {\n instanceRef.current?.setScale(newScale);\n },\n\n zoomIn(factor?: number) {\n instanceRef.current?.zoomIn(factor);\n },\n\n zoomOut(factor?: number) {\n instanceRef.current?.zoomOut(factor);\n },\n\n getConfig() {\n return instanceRef.current?.getConfig() ?? DEFAULT_CONFIG;\n },\n\n setBounds(bounds) {\n instanceRef.current?.setBounds(bounds);\n },\n\n setEventHandlers(handlers) {\n instanceRef.current?.setEventHandlers(handlers);\n },\n\n drawRect(items, layer) {\n return instanceRef.current?.drawRect(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticRect(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticRect(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawCircle(items, layer) {\n return instanceRef.current?.drawCircle(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticCircle(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticCircle(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawLine(items, style, layer) {\n return instanceRef.current?.drawLine(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawText(items, layer) {\n return instanceRef.current?.drawText(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawPath(items, style, layer) {\n return instanceRef.current?.drawPath(items, style, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawImage(items, layer) {\n return instanceRef.current?.drawImage(items, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawStaticImage(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticImage(items, cacheKey, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n drawGridLines(cellSize, lineWidth, strokeStyle, layer) {\n return (\n instanceRef.current?.drawGridLines(cellSize, lineWidth, strokeStyle, layer) ?? DUMMY_LAYER_HANDLE\n );\n },\n\n addDrawFunction(fn, layer) {\n return instanceRef.current?.addDrawFunction(fn, layer) ?? DUMMY_LAYER_HANDLE;\n },\n\n clearLayer(layer) {\n instanceRef.current?.clearLayer(layer);\n },\n\n clearAll() {\n instanceRef.current?.clearAll();\n },\n\n clearStaticCache(cacheKey) {\n instanceRef.current?.clearStaticCache(cacheKey);\n },\n\n removeLayerHandle(handle) {\n instanceRef.current?.removeLayerHandle(handle);\n },\n\n loadImage(src: string, retry?: number) {\n if (!instanceRef.current) {\n return Promise.reject(new Error(\"Engine not ready. Wait for isReady before loading images.\"));\n }\n return instanceRef.current.images.load(src, retry);\n },\n }),\n [setInstance]\n );\n\n return handle;\n}\n","// Main component\nexport { CanvasTileEngine } from \"./components\";\n\n// Draw components\nexport {\n type RectProps,\n type CircleProps,\n type ImageProps,\n type GridLinesProps,\n type LineProps,\n type TextProps,\n type PathProps,\n type StaticRectProps,\n type StaticCircleProps,\n type StaticImageProps,\n type DrawFunctionProps,\n} from \"./components\";\n\n// Hooks\nexport { useCanvasTileEngine } from \"./hooks\";\n\n// Context\nexport { useEngineContext, type EngineContextValue } from \"./context\";\n\n// Types\nexport type {\n CanvasTileEngineProps,\n CanvasTileEngineConfig,\n Coords,\n DrawObject,\n EventHandlers,\n onClickCallback,\n onHoverCallback,\n onMouseDownCallback,\n onMouseUpCallback,\n onMouseLeaveCallback,\n onDrawCallback,\n Rect,\n Line,\n Circle,\n Text,\n Path,\n ImageItem,\n} from \"./types\";\nexport type { EngineHandle } from \"./hooks/useCanvasTileEngine\";\n\n// Re-export core class and utilities\nexport { CanvasTileEngine as CanvasTileEngineCore, gridToSize } from \"@canvas-tile-engine/core\";\n"],"mappings":"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","names":["useEffect","useRef","useCallback","useMemo","CanvasTileEngineCore","createContext","useContext","EngineContext","useEngineContext","context","useEffect","memo","Rect","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Circle","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Image","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","GridLines","memo","cellSize","lineWidth","strokeStyle","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Line","memo","items","style","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Text","memo","items","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","memo","Path","memo","items","style","layer","engine","requestRender","useEngineContext","useEffect","handle","useEffect","useRef","memo","StaticRect","memo","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","useRef","useEffect","handle","useEffect","useRef","memo","StaticCircle","memo","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","useRef","useEffect","handle","useEffect","useRef","memo","StaticImage","memo","items","cacheKey","layer","engine","requestRender","useEngineContext","prevCacheKeyRef","useRef","useEffect","handle","useEffect","useRef","memo","DrawFunction","memo","children","layer","engine","requestRender","useEngineContext","fnRef","useRef","useEffect","handle","ctx","coords","config","jsx","jsxs","CanvasTileEngineBase","engine","config","center","className","style","children","onCoordsChange","onClick","onRightClick","onHover","onMouseDown","onMouseUp","onMouseLeave","onDraw","onResize","onZoom","callbacksRef","useRef","useEffect","rafIdRef","requestRender","useCallback","contextValue","useMemo","container","instance","CanvasTileEngineCore","coords","args","scale","EngineContext","CanvasTileEngine","Rect","Circle","Image","GridLines","Line","Text","Path","StaticRect","StaticCircle","StaticImage","DrawFunction","useRef","useCallback","useState","useMemo","DUMMY_LAYER_HANDLE","DEFAULT_CONFIG","useCanvasTileEngine","instanceRef","containerRef","setIsReady","isReadyRef","setInstance","engine","center","x","y","durationMs","onComplete","width","height","newScale","factor","bounds","handlers","items","layer","cacheKey","style","cellSize","lineWidth","strokeStyle","fn","handle","src","retry","CanvasTileEngine","gridToSize"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canvas-tile-engine/react",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "React bindings for Canvas Tile Engine - build interactive 2D grid-based maps with declarative components",
5
5
  "author": "Enes Yüksel",
6
6
  "license": "MIT",
@@ -42,10 +42,10 @@
42
42
  "peerDependencies": {
43
43
  "react": ">=18.0.0",
44
44
  "react-dom": ">=18.0.0",
45
- "@canvas-tile-engine/core": ">=0.1.0"
45
+ "@canvas-tile-engine/core": ">=0.2.0"
46
46
  },
47
47
  "dependencies": {
48
- "@canvas-tile-engine/core": "0.1.0"
48
+ "@canvas-tile-engine/core": "0.2.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/react": "^18.3.0",