@canvas-tile-engine/react 0.1.0 → 0.3.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/README.md CHANGED
@@ -1,17 +1,22 @@
1
1
  # @canvas-tile-engine/react
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@canvas-tile-engine/react)](https://www.npmjs.com/package/@canvas-tile-engine/react)
4
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@canvas-tile-engine/react)](https://bundlephobia.com/package/@canvas-tile-engine/react)
5
+ [![license](https://img.shields.io/npm/l/@canvas-tile-engine/react)](../../LICENSE)
6
+
3
7
  React bindings for Canvas Tile Engine — build interactive 2D grid-based maps with declarative components.
4
8
 
5
9
  ## Install
6
10
 
7
11
  ```bash
8
- npm install @canvas-tile-engine/react
12
+ npm install @canvas-tile-engine/react @canvas-tile-engine/renderer-canvas
9
13
  ```
10
14
 
11
15
  ## Quick Start
12
16
 
13
17
  ```tsx
14
18
  import { CanvasTileEngine, useCanvasTileEngine } from "@canvas-tile-engine/react";
19
+ import { RendererCanvas } from "@canvas-tile-engine/renderer-canvas";
15
20
 
16
21
  const config = {
17
22
  scale: 50,
@@ -27,6 +32,7 @@ function App() {
27
32
  <CanvasTileEngine
28
33
  engine={engine}
29
34
  config={config}
35
+ renderer={new RendererCanvas()}
30
36
  center={{ x: 0, y: 0 }}
31
37
  onClick={(coords) => console.log("Clicked:", coords.snapped)}
32
38
  >
@@ -37,9 +43,22 @@ function App() {
37
43
  }
38
44
  ```
39
45
 
46
+ ## Architecture
47
+
48
+ The React package wraps `@canvas-tile-engine/core` with declarative components. You inject a renderer via the `renderer` prop:
49
+
50
+ ```tsx
51
+ // Canvas2D
52
+ import { RendererCanvas } from "@canvas-tile-engine/renderer-canvas";
53
+ <CanvasTileEngine engine={engine} config={config} renderer={new RendererCanvas()} />
54
+
55
+ // Custom renderer
56
+ <CanvasTileEngine engine={engine} config={config} renderer={new MyCustomRenderer()} />
57
+ ```
58
+
40
59
  ## Documentation
41
60
 
42
- Full API reference and examples: [https://www.canvastileengine.dev/docs/react/installation](https://www.canvastileengine.dev/docs/react/installation)
61
+ Full API reference and examples: [canvastileengine.dev](https://canvastileengine.dev/docs/react/installation)
43
62
 
44
63
  ## License
45
64
 
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, DrawHandle, IRenderer, 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
  }
@@ -86,7 +68,7 @@ interface StaticImageProps {
86
68
 
87
69
  interface DrawFunctionProps {
88
70
  /** The draw function to execute */
89
- children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;
71
+ children: (ctx: unknown, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;
90
72
  layer?: number;
91
73
  }
92
74
 
@@ -143,57 +125,34 @@ interface EngineHandle {
143
125
  }): void;
144
126
  /** Dynamically update event handlers at runtime */
145
127
  setEventHandlers(handlers: Partial<EventHandlers>): void;
128
+ /** Register a custom draw function */
129
+ addDrawFunction(fn: (ctx: unknown, coords: Coords, config: Required<CanvasTileEngineConfig>) => void, layer?: number): DrawHandle;
146
130
  /** Draw rectangles */
147
- drawRect(items: DrawObject | DrawObject[], layer?: number): LayerHandle;
131
+ drawRect(items: Rect | Rect[], layer?: number): DrawHandle;
148
132
  /** Draw static rectangles (cached) */
149
- drawStaticRect(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;
133
+ drawStaticRect(items: Rect[], cacheKey: string, layer?: number): DrawHandle;
150
134
  /** Draw circles */
151
- drawCircle(items: DrawObject | DrawObject[], layer?: number): LayerHandle;
135
+ drawCircle(items: Circle | Circle[], layer?: number): DrawHandle;
152
136
  /** Draw static circles (cached) */
153
- drawStaticCircle(items: DrawObject[], cacheKey: string, layer?: number): LayerHandle;
137
+ drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): DrawHandle;
154
138
  /** Draw lines */
155
- drawLine(items: {
156
- from: Coords;
157
- to: Coords;
158
- } | {
159
- from: Coords;
160
- to: Coords;
161
- }[], style?: {
139
+ drawLine(items: Line | Line[], style?: {
162
140
  strokeStyle?: string;
163
141
  lineWidth?: number;
164
- }, layer?: number): LayerHandle;
142
+ }, layer?: number): DrawHandle;
165
143
  /** 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;
144
+ drawText(items: Text | Text[], layer?: number): DrawHandle;
178
145
  /** Draw paths/polylines */
179
146
  drawPath(items: Coords[] | Coords[][], style?: {
180
147
  strokeStyle?: string;
181
148
  lineWidth?: number;
182
- }, layer?: number): LayerHandle;
149
+ }, layer?: number): DrawHandle;
183
150
  /** Draw images */
184
- drawImage(items: (Omit<DrawObject, "style"> & {
185
- img: HTMLImageElement;
186
- }) | (Omit<DrawObject, "style"> & {
187
- img: HTMLImageElement;
188
- })[], layer?: number): LayerHandle;
151
+ drawImage(items: ImageItem | ImageItem[], layer?: number): DrawHandle;
189
152
  /** Draw static images (cached) */
190
- drawStaticImage(items: (Omit<DrawObject, "style"> & {
191
- img: HTMLImageElement;
192
- })[], cacheKey: string, layer?: number): LayerHandle;
153
+ drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): DrawHandle;
193
154
  /** Draw grid lines */
194
- drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;
195
- /** Add custom draw function */
196
- addDrawFunction(fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void, layer?: number): LayerHandle;
155
+ drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): DrawHandle;
197
156
  /** Clear a specific layer */
198
157
  clearLayer(layer: number): void;
199
158
  /** Clear all layers */
@@ -201,9 +160,20 @@ interface EngineHandle {
201
160
  /** Clear static cache */
202
161
  clearStaticCache(cacheKey?: string): void;
203
162
  /** Remove a previously registered draw callback */
204
- removeLayerHandle(handle: LayerHandle): void;
163
+ removeDrawHandle(handle: DrawHandle): 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.
@@ -241,6 +211,15 @@ declare function useCanvasTileEngine(): EngineHandle;
241
211
  interface CanvasTileEngineProps {
242
212
  /** Engine handle from useCanvasTileEngine hook (required) */
243
213
  engine: EngineHandle;
214
+ /**
215
+ * Renderer instance to use.
216
+ * @example
217
+ * ```tsx
218
+ * import { RendererCanvas } from "@canvas-tile-engine/renderer-canvas";
219
+ * <CanvasTileEngine config={config} engine={engine} renderer={new RendererCanvas()} />
220
+ * ```
221
+ */
222
+ renderer: IRenderer;
244
223
  /** Engine configuration */
245
224
  config: CanvasTileEngineConfig;
246
225
  /** Initial center coordinates */
@@ -251,25 +230,128 @@ interface CanvasTileEngineProps {
251
230
  style?: React.CSSProperties;
252
231
  /** Draw components (Rect, Circle, Image, GridLines, etc.) */
253
232
  children?: React.ReactNode;
254
- /** Callback when center coordinates change */
233
+ /**
234
+ * Callback when center coordinates change (pan or zoom).
235
+ * @param coords - Center world coordinates: `{ x, y }`
236
+ * @example
237
+ * ```tsx
238
+ * onCoordsChange={(coords) => {
239
+ * console.log(`Center: ${coords.x}, ${coords.y}`);
240
+ * }}
241
+ * ```
242
+ */
255
243
  onCoordsChange?: (coords: Coords) => void;
256
- /** Callback when a tile is clicked */
244
+ /**
245
+ * Callback when a tile is clicked (mouse or touch tap).
246
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
247
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
248
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
249
+ * @example
250
+ * ```tsx
251
+ * onClick={(coords) => {
252
+ * console.log(`Clicked tile: ${coords.snapped.x}, ${coords.snapped.y}`);
253
+ * }}
254
+ * ```
255
+ */
257
256
  onClick?: onClickCallback;
258
- /** Callback when a tile is right-clicked */
257
+ /**
258
+ * Callback when a tile is right-clicked.
259
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
260
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
261
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
262
+ * @example
263
+ * ```tsx
264
+ * onRightClick={(coords) => {
265
+ * showContextMenu(coords.snapped.x, coords.snapped.y);
266
+ * }}
267
+ * ```
268
+ */
259
269
  onRightClick?: onRightClickCallback;
260
- /** Callback when hovering over tiles */
270
+ /**
271
+ * Callback when hovering over tiles.
272
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
273
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
274
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
275
+ * @example
276
+ * ```tsx
277
+ * onHover={(coords) => {
278
+ * setHoveredTile({ x: coords.snapped.x, y: coords.snapped.y });
279
+ * }}
280
+ * ```
281
+ */
261
282
  onHover?: onHoverCallback;
262
- /** Callback on mouse down */
283
+ /**
284
+ * Callback on mouse/touch down.
285
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
286
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
287
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
288
+ * @example
289
+ * ```tsx
290
+ * onMouseDown={(coords) => {
291
+ * startPainting(coords.snapped.x, coords.snapped.y);
292
+ * }}
293
+ * ```
294
+ */
263
295
  onMouseDown?: onMouseDownCallback;
264
- /** Callback on mouse up */
296
+ /**
297
+ * Callback on mouse/touch up.
298
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
299
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
300
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
301
+ * @example
302
+ * ```tsx
303
+ * onMouseUp={() => {
304
+ * stopPainting();
305
+ * }}
306
+ * ```
307
+ */
265
308
  onMouseUp?: onMouseUpCallback;
266
- /** Callback on mouse leave */
309
+ /**
310
+ * Callback when mouse/touch leaves the canvas.
311
+ * @param coords - World coordinates: `raw` (exact), `snapped` (floored to tile)
312
+ * @param mouse - Canvas-relative position: `raw` (exact), `snapped` (tile-aligned)
313
+ * @param client - Viewport position: `raw` (exact), `snapped` (tile-aligned)
314
+ * @example
315
+ * ```tsx
316
+ * onMouseLeave={() => {
317
+ * clearHoveredTile();
318
+ * }}
319
+ * ```
320
+ */
267
321
  onMouseLeave?: onMouseLeaveCallback;
268
- /** Callback after each draw frame */
322
+ /**
323
+ * Callback after each draw frame. Use for custom canvas drawing.
324
+ * @param ctx - The canvas 2D rendering context
325
+ * @param info - Frame info: `scale`, `width`, `height`, `coords` (center)
326
+ * @example
327
+ * ```tsx
328
+ * onDraw={(ctx, info) => {
329
+ * ctx.fillStyle = "red";
330
+ * ctx.fillText(`Scale: ${info.scale}`, 10, 20);
331
+ * }}
332
+ * ```
333
+ */
269
334
  onDraw?: onDrawCallback;
270
- /** Callback on canvas resize */
335
+ /**
336
+ * Callback on canvas resize.
337
+ * @example
338
+ * ```tsx
339
+ * onResize={() => {
340
+ * console.log("Canvas resized");
341
+ * }}
342
+ * ```
343
+ */
271
344
  onResize?: () => void;
272
- /** Callback when zoom level changes */
345
+ /**
346
+ * Callback when zoom level changes (wheel or pinch).
347
+ * @param scale - The new scale value
348
+ * @example
349
+ * ```tsx
350
+ * onZoom={(scale) => {
351
+ * console.log(`Zoom level: ${scale}`);
352
+ * }}
353
+ * ```
354
+ */
273
355
  onZoom?: onZoomCallback;
274
356
  }
275
357
 
@@ -308,7 +390,7 @@ interface CanvasTileEngineProps {
308
390
  * }
309
391
  * ```
310
392
  */
311
- declare function CanvasTileEngineBase({ engine, config, center, className, style, children, onCoordsChange, onClick, onRightClick, onHover, onMouseDown, onMouseUp, onMouseLeave, onDraw, onResize, onZoom, }: CanvasTileEngineProps): react_jsx_runtime.JSX.Element;
393
+ declare function CanvasTileEngineBase({ engine, renderer, config, center, className, style, children, onCoordsChange, onClick, onRightClick, onHover, onMouseDown, onMouseUp, onMouseLeave, onDraw, onResize, onZoom, }: CanvasTileEngineProps): react_jsx_runtime.JSX.Element;
312
394
  declare const CanvasTileEngine: typeof CanvasTileEngineBase & {
313
395
  Rect: react.NamedExoticComponent<RectProps>;
314
396
  Circle: react.NamedExoticComponent<CircleProps>;