@canvas-tile-engine/react 0.2.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,5 +1,5 @@
1
1
  import * as react from 'react';
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';
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
 
@@ -68,7 +68,7 @@ interface StaticImageProps {
68
68
 
69
69
  interface DrawFunctionProps {
70
70
  /** The draw function to execute */
71
- children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;
71
+ children: (ctx: unknown, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;
72
72
  layer?: number;
73
73
  }
74
74
 
@@ -125,34 +125,34 @@ interface EngineHandle {
125
125
  }): void;
126
126
  /** Dynamically update event handlers at runtime */
127
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;
128
130
  /** Draw rectangles */
129
- drawRect(items: Rect | Rect[], layer?: number): LayerHandle;
131
+ drawRect(items: Rect | Rect[], layer?: number): DrawHandle;
130
132
  /** Draw static rectangles (cached) */
131
- drawStaticRect(items: Rect[], cacheKey: string, layer?: number): LayerHandle;
133
+ drawStaticRect(items: Rect[], cacheKey: string, layer?: number): DrawHandle;
132
134
  /** Draw circles */
133
- drawCircle(items: Circle | Circle[], layer?: number): LayerHandle;
135
+ drawCircle(items: Circle | Circle[], layer?: number): DrawHandle;
134
136
  /** Draw static circles (cached) */
135
- drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): LayerHandle;
137
+ drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): DrawHandle;
136
138
  /** Draw lines */
137
139
  drawLine(items: Line | Line[], style?: {
138
140
  strokeStyle?: string;
139
141
  lineWidth?: number;
140
- }, layer?: number): LayerHandle;
142
+ }, layer?: number): DrawHandle;
141
143
  /** Draw text */
142
- drawText(items: Text | Text[], layer?: number): LayerHandle;
144
+ drawText(items: Text | Text[], layer?: number): DrawHandle;
143
145
  /** Draw paths/polylines */
144
146
  drawPath(items: Coords[] | Coords[][], style?: {
145
147
  strokeStyle?: string;
146
148
  lineWidth?: number;
147
- }, layer?: number): LayerHandle;
149
+ }, layer?: number): DrawHandle;
148
150
  /** Draw images */
149
- drawImage(items: ImageItem | ImageItem[], layer?: number): LayerHandle;
151
+ drawImage(items: ImageItem | ImageItem[], layer?: number): DrawHandle;
150
152
  /** Draw static images (cached) */
151
- drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): LayerHandle;
153
+ drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): DrawHandle;
152
154
  /** Draw grid lines */
153
- drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;
154
- /** Add custom draw function */
155
- addDrawFunction(fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void, layer?: number): LayerHandle;
155
+ drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): DrawHandle;
156
156
  /** Clear a specific layer */
157
157
  clearLayer(layer: number): void;
158
158
  /** Clear all layers */
@@ -160,7 +160,7 @@ interface EngineHandle {
160
160
  /** Clear static cache */
161
161
  clearStaticCache(cacheKey?: string): void;
162
162
  /** Remove a previously registered draw callback */
163
- removeLayerHandle(handle: LayerHandle): void;
163
+ removeDrawHandle(handle: DrawHandle): void;
164
164
  /** Image loader instance (undefined until engine mounts) */
165
165
  readonly images: CanvasTileEngine$1["images"] | undefined;
166
166
  /**
@@ -211,6 +211,15 @@ declare function useCanvasTileEngine(): EngineHandle;
211
211
  interface CanvasTileEngineProps {
212
212
  /** Engine handle from useCanvasTileEngine hook (required) */
213
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;
214
223
  /** Engine configuration */
215
224
  config: CanvasTileEngineConfig;
216
225
  /** Initial center coordinates */
@@ -381,7 +390,7 @@ interface CanvasTileEngineProps {
381
390
  * }
382
391
  * ```
383
392
  */
384
- 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;
385
394
  declare const CanvasTileEngine: typeof CanvasTileEngineBase & {
386
395
  Rect: react.NamedExoticComponent<RectProps>;
387
396
  Circle: react.NamedExoticComponent<CircleProps>;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
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';
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
 
@@ -68,7 +68,7 @@ interface StaticImageProps {
68
68
 
69
69
  interface DrawFunctionProps {
70
70
  /** The draw function to execute */
71
- children: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;
71
+ children: (ctx: unknown, coords: Coords, config: Required<CanvasTileEngineConfig>) => void;
72
72
  layer?: number;
73
73
  }
74
74
 
@@ -125,34 +125,34 @@ interface EngineHandle {
125
125
  }): void;
126
126
  /** Dynamically update event handlers at runtime */
127
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;
128
130
  /** Draw rectangles */
129
- drawRect(items: Rect | Rect[], layer?: number): LayerHandle;
131
+ drawRect(items: Rect | Rect[], layer?: number): DrawHandle;
130
132
  /** Draw static rectangles (cached) */
131
- drawStaticRect(items: Rect[], cacheKey: string, layer?: number): LayerHandle;
133
+ drawStaticRect(items: Rect[], cacheKey: string, layer?: number): DrawHandle;
132
134
  /** Draw circles */
133
- drawCircle(items: Circle | Circle[], layer?: number): LayerHandle;
135
+ drawCircle(items: Circle | Circle[], layer?: number): DrawHandle;
134
136
  /** Draw static circles (cached) */
135
- drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): LayerHandle;
137
+ drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): DrawHandle;
136
138
  /** Draw lines */
137
139
  drawLine(items: Line | Line[], style?: {
138
140
  strokeStyle?: string;
139
141
  lineWidth?: number;
140
- }, layer?: number): LayerHandle;
142
+ }, layer?: number): DrawHandle;
141
143
  /** Draw text */
142
- drawText(items: Text | Text[], layer?: number): LayerHandle;
144
+ drawText(items: Text | Text[], layer?: number): DrawHandle;
143
145
  /** Draw paths/polylines */
144
146
  drawPath(items: Coords[] | Coords[][], style?: {
145
147
  strokeStyle?: string;
146
148
  lineWidth?: number;
147
- }, layer?: number): LayerHandle;
149
+ }, layer?: number): DrawHandle;
148
150
  /** Draw images */
149
- drawImage(items: ImageItem | ImageItem[], layer?: number): LayerHandle;
151
+ drawImage(items: ImageItem | ImageItem[], layer?: number): DrawHandle;
150
152
  /** Draw static images (cached) */
151
- drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): LayerHandle;
153
+ drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): DrawHandle;
152
154
  /** Draw grid lines */
153
- drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): LayerHandle;
154
- /** Add custom draw function */
155
- addDrawFunction(fn: (ctx: CanvasRenderingContext2D, coords: Coords, config: Required<CanvasTileEngineConfig>) => void, layer?: number): LayerHandle;
155
+ drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): DrawHandle;
156
156
  /** Clear a specific layer */
157
157
  clearLayer(layer: number): void;
158
158
  /** Clear all layers */
@@ -160,7 +160,7 @@ interface EngineHandle {
160
160
  /** Clear static cache */
161
161
  clearStaticCache(cacheKey?: string): void;
162
162
  /** Remove a previously registered draw callback */
163
- removeLayerHandle(handle: LayerHandle): void;
163
+ removeDrawHandle(handle: DrawHandle): void;
164
164
  /** Image loader instance (undefined until engine mounts) */
165
165
  readonly images: CanvasTileEngine$1["images"] | undefined;
166
166
  /**
@@ -211,6 +211,15 @@ declare function useCanvasTileEngine(): EngineHandle;
211
211
  interface CanvasTileEngineProps {
212
212
  /** Engine handle from useCanvasTileEngine hook (required) */
213
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;
214
223
  /** Engine configuration */
215
224
  config: CanvasTileEngineConfig;
216
225
  /** Initial center coordinates */
@@ -381,7 +390,7 @@ interface CanvasTileEngineProps {
381
390
  * }
382
391
  * ```
383
392
  */
384
- 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;
385
394
  declare const CanvasTileEngine: typeof CanvasTileEngineBase & {
386
395
  Rect: react.NamedExoticComponent<RectProps>;
387
396
  Circle: react.NamedExoticComponent<CircleProps>;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
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});
1
+ "use strict";var z=Object.defineProperty;var oe=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var se=(r,o)=>{for(var t in o)z(r,t,{get:o[t],enumerable:!0})},ce=(r,o,t,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of ie(o))!ae.call(r,n)&&n!==t&&z(r,n,{get:()=>o[n],enumerable:!(i=oe(o,n))||i.enumerable});return r};var ue=r=>ce(z({},"__esModule",{value:!0}),r);var de={};se(de,{CanvasTileEngine:()=>q,CanvasTileEngineCore:()=>k.CanvasTileEngine,gridToSize:()=>k.gridToSize,useCanvasTileEngine:()=>F,useEngineContext:()=>c});module.exports=ue(de);var f=require("react"),ne=require("@canvas-tile-engine/core");var R=require("react"),T=(0,R.createContext)(null);function c(){let r=(0,R.useContext)(T);if(!r)throw new Error("useEngineContext must be used within a CanvasTileEngine component");return r}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.drawRect(o,t);return n(),()=>{s&&i.removeDrawHandle(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.drawCircle(o,t);return n(),()=>{s&&i.removeDrawHandle(s)}},[i,o,t,n]),null});var I=require("react");var j=(0,I.memo)(function({items:o,layer:t=1}){let{engine:i,requestRender:n}=c();return(0,I.useEffect)(()=>{let s=i.drawImage(o,t);return n(),()=>{s&&i.removeDrawHandle(s)}},[i,o,t,n]),null});var S=require("react");var N=(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.removeDrawHandle(a)}},[s,o,t,i,n,e]),null});var D=require("react");var Z=(0,D.memo)(function({items:o,style:t,layer:i=1}){let{engine:n,requestRender:s}=c();return(0,D.useEffect)(()=>{let e=n.drawLine(o,t,i);return s(),()=>{e&&n.removeDrawHandle(e)}},[n,o,t,i,s]),null});var H=require("react");var J=(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.removeDrawHandle(s)}},[i,o,t,n]),null});var L=require("react");var Q=(0,L.memo)(function({items:o,style:t,layer:i=1}){let{engine:n,requestRender:s}=c();return(0,L.useEffect)(()=>{let e=n.drawPath(o,t,i);return s(),()=>{e&&n.removeDrawHandle(e)}},[n,o,t,i,s]),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.drawStaticRect(o,t,i);return s(),()=>{a&&n.removeDrawHandle(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.drawStaticCircle(o,t,i);return s(),()=>{a&&n.removeDrawHandle(a)}},[n,o,t,i,s]),(0,v.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var y=require("react");var ee=(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.drawStaticImage(o,t,i);return s(),()=>{a&&n.removeDrawHandle(a)}},[n,o,t,i,s]),(0,y.useEffect)(()=>()=>{n.clearStaticCache(t)},[n,t]),null});var w=require("react");var re=(0,w.memo)(function({children:o,layer:t=1}){let{engine:i,requestRender:n}=c(),s=(0,w.useRef)(o);return(0,w.useEffect)(()=>{s.current=o}),(0,w.useEffect)(()=>{let e=i.addDrawFunction((a,u,g)=>{s.current(a,u,g)},t);return n(),()=>{e&&i.removeDrawHandle(e)}},[i,t,n]),null});var E=require("react/jsx-runtime");function le({engine:r,renderer:o,config:t,center:i={x:0,y:0},className:n,style:s,children:e,onCoordsChange:a,onClick:u,onRightClick:g,onHover:M,onMouseDown:G,onMouseUp:V,onMouseLeave:_,onDraw:A,onResize:W,onZoom:Y}){let d=(0,f.useRef)({onCoordsChange:a,onClick:u,onRightClick:g,onHover:M,onMouseDown:G,onMouseUp:V,onMouseLeave:_,onDraw:A,onResize:W,onZoom:Y});(0,f.useEffect)(()=>{d.current={onCoordsChange:a,onClick:u,onRightClick:g,onHover:M,onMouseDown:G,onMouseUp:V,onMouseLeave:_,onDraw:A,onResize:W,onZoom:Y}});let b=(0,f.useRef)(null),X=(0,f.useCallback)(()=>{b.current===null&&(b.current=requestAnimationFrame(()=>{b.current=null,r.render()}))},[r]);(0,f.useEffect)(()=>()=>{b.current!==null&&cancelAnimationFrame(b.current)},[]);let te=(0,f.useMemo)(()=>({engine:r,requestRender:X}),[r,X]);return(0,f.useEffect)(()=>{let B=r._containerRef.current;if(!B)return;let m=new ne.CanvasTileEngine(B,t,o,i);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,E.jsxs)(T.Provider,{value:te,children:[(0,E.jsx)("div",{ref:r._containerRef,className:n,style:{...s},children:(0,E.jsx)("canvas",{})}),r.isReady&&e]})}var q=Object.assign(le,{Rect:O,Circle:U,Image:j,GridLines:N,Line:Z,Text:J,Path:Q,StaticRect:$,StaticCircle:K,StaticImage:ee,DrawFunction:re});var C=require("react"),p={layer:-1,id:Symbol("dummy")},me={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()??me},setBounds(e){r.current?.setBounds(e)},setEventHandlers(e){r.current?.setEventHandlers(e)},addDrawFunction(e,a){return r.current?.addDrawFunction(e,a)??p},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},clearLayer(e){r.current?.clearLayer(e)},clearAll(){r.current?.clearAll()},clearStaticCache(e){r.current?.clearStaticCache(e)},removeDrawHandle(e){r.current?.removeDrawHandle(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 k=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 { 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"]}
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 renderer,\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, renderer, 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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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: unknown, 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.removeDrawHandle(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 DrawHandle,\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_DRAW_HANDLE: DrawHandle = { 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 /** Register a custom draw function */\n addDrawFunction(\n fn: (ctx: unknown, coords: Coords, config: Required<CanvasTileEngineConfig>) => void,\n layer?: number\n ): DrawHandle;\n\n /** Draw rectangles */\n drawRect(items: Rect | Rect[], layer?: number): DrawHandle;\n\n /** Draw static rectangles (cached) */\n drawStaticRect(items: Rect[], cacheKey: string, layer?: number): DrawHandle;\n\n /** Draw circles */\n drawCircle(items: Circle | Circle[], layer?: number): DrawHandle;\n\n /** Draw static circles (cached) */\n drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): DrawHandle;\n\n /** Draw lines */\n drawLine(items: Line | Line[], style?: { strokeStyle?: string; lineWidth?: number }, layer?: number): DrawHandle;\n\n /** Draw text */\n drawText(items: Text | Text[], layer?: number): DrawHandle;\n\n /** Draw paths/polylines */\n drawPath(\n items: Coords[] | Coords[][],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): DrawHandle;\n\n /** Draw images */\n drawImage(items: ImageItem | ImageItem[], layer?: number): DrawHandle;\n\n /** Draw static images (cached) */\n drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): DrawHandle;\n\n /** Draw grid lines */\n drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): DrawHandle;\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 removeDrawHandle(handle: DrawHandle): 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 addDrawFunction(fn, layer) {\n return instanceRef.current?.addDrawFunction(fn, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawRect(items, layer) {\n return instanceRef.current?.drawRect(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawStaticRect(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticRect(items, cacheKey, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawCircle(items, layer) {\n return instanceRef.current?.drawCircle(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawStaticCircle(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticCircle(items, cacheKey, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawLine(items, style, layer) {\n return instanceRef.current?.drawLine(items, style, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawText(items, layer) {\n return instanceRef.current?.drawText(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawPath(items, style, layer) {\n return instanceRef.current?.drawPath(items, style, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawImage(items, layer) {\n return instanceRef.current?.drawImage(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawStaticImage(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticImage(items, cacheKey, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawGridLines(cellSize, lineWidth, strokeStyle, layer) {\n return instanceRef.current?.drawGridLines(cellSize, lineWidth, strokeStyle, layer) ?? DUMMY_DRAW_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 removeDrawHandle(handle) {\n instanceRef.current?.removeDrawHandle(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) as Promise<HTMLImageElement>;\n },\n }),\n [setInstance]\n );\n\n return handle;\n}\n"],"mappings":"mbAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,sBAAAE,EAAA,gGAAAC,EAAA,qBAAAC,IAAA,eAAAC,GAAAL,ICAA,IAAAM,EAAwD,iBACxDC,GAAyD,oCCDzD,IAAAC,EAA0C,iBAS7BC,KAAgB,iBAAyC,IAAI,EAMnE,SAASC,GAAuC,CACnD,IAAMC,KAAU,cAAWF,CAAa,EAExC,GAAI,CAACE,EACD,MAAM,IAAI,MAAM,mEAAmE,EAGvF,OAAOA,CACX,CCvBA,IAAAC,EAAgC,iBAYzB,IAAMC,KAAO,QAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CACpE,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,SAASF,EAAOC,CAAK,EAC3C,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,EC1BD,IAAAG,EAAgC,iBAYzB,IAAMC,KAAS,QAAK,SAAgB,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAgB,CAC1E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,WAAWF,EAAOC,CAAK,EAC7C,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,EC1BD,IAAAG,EAAgC,iBAYzB,IAAMC,KAAQ,QAAK,SAAe,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAe,CACvE,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,UAAUF,EAAOC,CAAK,EAC5C,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,EC1BD,IAAAG,EAAgC,iBAczB,IAAMC,KAAY,QAAK,SAAmB,CAAE,SAAAC,EAAU,UAAAC,EAAY,EAAG,YAAAC,EAAc,QAAS,MAAAC,EAAQ,CAAE,EAAmB,CAC5H,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,cAAcJ,EAAUC,EAAWC,EAAaC,CAAK,EAC3E,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQJ,EAAUC,EAAWC,EAAaC,EAAOE,CAAa,CAAC,EAE5D,IACX,CAAC,EC5BD,IAAAG,EAAgC,iBAazB,IAAMC,KAAO,QAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CAC3E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,SAASH,EAAOC,EAAOC,CAAK,EAClD,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQH,EAAOC,EAAOC,EAAOE,CAAa,CAAC,EAExC,IACX,CAAC,EC3BD,IAAAG,EAAgC,iBAwBzB,IAAMC,KAAO,QAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CACpE,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,SAASF,EAAOC,CAAK,EAC3C,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQF,EAAOC,EAAOE,CAAa,CAAC,EAEjC,IACX,CAAC,ECtCD,IAAAG,EAAgC,iBAazB,IAAMC,KAAO,QAAK,SAAc,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAQ,CAAE,EAAc,CAC3E,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAEnD,sBAAU,IAAM,CACZ,IAAMC,EAASH,EAAO,SAASH,EAAOC,EAAOC,CAAK,EAClD,OAAAE,EAAc,EACP,IAAM,CACLE,GACAH,EAAO,iBAAiBG,CAAM,CAEtC,CACJ,EAAG,CAACH,EAAQH,EAAOC,EAAOC,EAAOE,CAAa,CAAC,EAExC,IACX,CAAC,EC3BD,IAAAG,EAAwC,iBAcjC,IAAMC,KAAa,QAAK,SAAoB,CAAE,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAoB,CAChG,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,KAAkB,UAAeL,CAAQ,EAE/C,sBAAU,IAAM,CACZ,GAAID,EAAM,SAAW,EACjB,OAIAM,EAAgB,UAAYL,IAC5BE,EAAO,iBAAiBG,EAAgB,OAAO,EAC/CA,EAAgB,QAAUL,GAG9B,IAAMM,EAASJ,EAAO,eAAeH,EAAOC,EAAUC,CAAK,EAC3D,OAAAE,EAAc,EAEP,IAAM,CACLG,GACAJ,EAAO,iBAAiBI,CAAM,CAEtC,CACJ,EAAG,CAACJ,EAAQH,EAAOC,EAAUC,EAAOE,CAAa,CAAC,KAGlD,aAAU,IACC,IAAM,CACTD,EAAO,iBAAiBF,CAAQ,CACpC,EACD,CAACE,EAAQF,CAAQ,CAAC,EAEd,IACX,CAAC,EC/CD,IAAAO,EAAwC,iBAajC,IAAMC,KAAe,QAAK,SAAsB,CAAE,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAsB,CACtG,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,KAAkB,UAAeL,CAAQ,EAE/C,sBAAU,IAAM,CACZ,GAAID,EAAM,SAAW,EACjB,OAGAM,EAAgB,UAAYL,IAC5BE,EAAO,iBAAiBG,EAAgB,OAAO,EAC/CA,EAAgB,QAAUL,GAG9B,IAAMM,EAASJ,EAAO,iBAAiBH,EAAOC,EAAUC,CAAK,EAC7D,OAAAE,EAAc,EAEP,IAAM,CACLG,GACAJ,EAAO,iBAAiBI,CAAM,CAEtC,CACJ,EAAG,CAACJ,EAAQH,EAAOC,EAAUC,EAAOE,CAAa,CAAC,KAElD,aAAU,IACC,IAAM,CACTD,EAAO,iBAAiBF,CAAQ,CACpC,EACD,CAACE,EAAQF,CAAQ,CAAC,EAEd,IACX,CAAC,EC5CD,IAAAO,EAAwC,iBAcjC,IAAMC,MAAc,QAAK,SAAqB,CAAE,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAqB,CACnG,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,KAAkB,UAAeL,CAAQ,EAE/C,sBAAU,IAAM,CACZ,GAAID,EAAM,SAAW,EACjB,OAGAM,EAAgB,UAAYL,IAC5BE,EAAO,iBAAiBG,EAAgB,OAAO,EAC/CA,EAAgB,QAAUL,GAG9B,IAAMM,EAASJ,EAAO,gBAAgBH,EAAOC,EAAUC,CAAK,EAC5D,OAAAE,EAAc,EAEP,IAAM,CACLG,GACAJ,EAAO,iBAAiBI,CAAM,CAEtC,CACJ,EAAG,CAACJ,EAAQH,EAAOC,EAAUC,EAAOE,CAAa,CAAC,KAElD,aAAU,IACC,IAAM,CACTD,EAAO,iBAAiBF,CAAQ,CACpC,EACD,CAACE,EAAQF,CAAQ,CAAC,EAEd,IACX,CAAC,EC7CD,IAAAO,EAAwC,iBAyBjC,IAAMC,MAAe,QAAK,SAAsB,CAAE,SAAAC,EAAU,MAAAC,EAAQ,CAAE,EAAsB,CAC/F,GAAM,CAAE,OAAAC,EAAQ,cAAAC,CAAc,EAAIC,EAAiB,EAC7CC,KAAQ,UAAOL,CAAQ,EAG7B,sBAAU,IAAM,CACZK,EAAM,QAAUL,CACpB,CAAC,KAED,aAAU,IAAM,CACZ,IAAMM,EAASJ,EAAO,gBAAgB,CAACK,EAAKC,EAAQC,IAAW,CAC3DJ,EAAM,QAAQE,EAAKC,EAAQC,CAAM,CACrC,EAAGR,CAAK,EACR,OAAAE,EAAc,EAEP,IAAM,CACLG,GACAJ,EAAO,iBAAiBI,CAAM,CAEtC,CACJ,EAAG,CAACJ,EAAQD,EAAOE,CAAa,CAAC,EAE1B,IACX,CAAC,EZ2HO,IAAAO,EAAA,6BAtHR,SAASC,GAAqB,CAC1B,OAAAC,EACA,SAAAC,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,KAAe,UAAO,CACxB,eAAAV,EACA,QAAAC,EACA,aAAAC,EACA,QAAAC,EACA,YAAAC,EACA,UAAAC,EACA,aAAAC,EACA,OAAAC,EACA,SAAAC,EACA,OAAAC,CACJ,CAAC,KAGD,aAAU,IAAM,CACZC,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,IAAME,KAAW,UAAsB,IAAI,EACrCC,KAAgB,eAAY,IAAM,CAChCD,EAAS,UAAY,OACzBA,EAAS,QAAU,sBAAsB,IAAM,CAC3CA,EAAS,QAAU,KACnBlB,EAAO,OAAO,CAClB,CAAC,EACL,EAAG,CAACA,CAAM,CAAC,KAGX,aAAU,IACC,IAAM,CACLkB,EAAS,UAAY,MACrB,qBAAqBA,EAAS,OAAO,CAE7C,EACD,CAAC,CAAC,EAGL,IAAME,MAAe,WACjB,KAAO,CACH,OAAApB,EACA,cAAAmB,CACJ,GACA,CAACnB,EAAQmB,CAAa,CAC1B,EAKA,sBAAU,IAAM,CACZ,IAAME,EAAYrB,EAAO,cAAc,QAEvC,GAAI,CAACqB,EACD,OAIJ,IAAMC,EAAW,IAAI,GAAAC,iBAAqBF,EAAWnB,EAAQD,EAAUE,CAAM,EAG7E,OAAAmB,EAAS,eAAkBE,GAAWP,EAAa,QAAQ,iBAAiBO,CAAM,EAClFF,EAAS,QAAU,IAAIG,IAASR,EAAa,QAAQ,UAAU,GAAGQ,CAAI,EACtEH,EAAS,aAAe,IAAIG,IAASR,EAAa,QAAQ,eAAe,GAAGQ,CAAI,EAChFH,EAAS,QAAU,IAAIG,IAASR,EAAa,QAAQ,UAAU,GAAGQ,CAAI,EACtEH,EAAS,YAAc,IAAIG,IAASR,EAAa,QAAQ,cAAc,GAAGQ,CAAI,EAC9EH,EAAS,UAAY,IAAIG,IAASR,EAAa,QAAQ,YAAY,GAAGQ,CAAI,EAC1EH,EAAS,aAAe,IAAIG,IAASR,EAAa,QAAQ,eAAe,GAAGQ,CAAI,EAChFH,EAAS,OAAS,IAAIG,IAASR,EAAa,QAAQ,SAAS,GAAGQ,CAAI,EACpEH,EAAS,SAAW,IAAML,EAAa,QAAQ,WAAW,EAC1DK,EAAS,OAAUI,GAAUT,EAAa,QAAQ,SAASS,CAAK,EAGhE1B,EAAO,aAAasB,CAAQ,EAG5BA,EAAS,OAAO,EAGT,IAAM,CACTA,EAAS,QAAQ,EACjBtB,EAAO,aAAa,IAAI,CAC5B,CAEJ,EAAG,CAACA,CAAM,CAAC,KAGP,QAAC2B,EAAc,SAAd,CAAuB,MAAOP,GAC3B,oBAAC,OACG,IAAKpB,EAAO,cACZ,UAAWI,EACX,MAAO,CACH,GAAGC,CACP,EAEA,mBAAC,WAAO,EACZ,EAECL,EAAO,SAAWM,GACvB,CAER,CAGO,IAAMsB,EAAmB,OAAO,OAAO7B,GAAsB,CAChE,KAAA8B,EACA,OAAAC,EACA,MAAAC,EACA,UAAAC,EACA,KAAAC,EACA,KAAAC,EACA,KAAAC,EACA,WAAAC,EACA,aAAAC,EACA,YAAAC,GACA,aAAAC,EACJ,CAAC,EaxMD,IAAAC,EAAuD,iBAejDC,EAAgC,CAAE,MAAO,GAAI,GAAI,OAAO,OAAO,CAAE,EAGjEC,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,EA+JO,SAASC,GAAoC,CAChD,IAAMC,KAAc,UAAoC,IAAI,EACtDC,KAAe,UAAuB,IAAK,EAE3C,CAAC,CAAEC,CAAU,KAAI,YAAS,EAAK,EAE/BC,KAAa,UAAO,EAAK,EAEzBC,KAAc,eAAaC,GAAwC,CACrEL,EAAY,QAAUK,EACtBF,EAAW,QAAUE,IAAW,KAChCH,EAAWG,IAAW,IAAI,CAC9B,EAAG,CAAC,CAAC,EAmJL,SA/Ie,WACX,KAAO,CACH,cAAeJ,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,gBAAgBC,EAAIC,EAAO,CACvB,OAAOlB,EAAY,SAAS,gBAAgBiB,EAAIC,CAAK,GAAKrB,CAC9D,EAEA,SAASsB,EAAOD,EAAO,CACnB,OAAOlB,EAAY,SAAS,SAASmB,EAAOD,CAAK,GAAKrB,CAC1D,EAEA,eAAesB,EAAOC,EAAUF,EAAO,CACnC,OAAOlB,EAAY,SAAS,eAAemB,EAAOC,EAAUF,CAAK,GAAKrB,CAC1E,EAEA,WAAWsB,EAAOD,EAAO,CACrB,OAAOlB,EAAY,SAAS,WAAWmB,EAAOD,CAAK,GAAKrB,CAC5D,EAEA,iBAAiBsB,EAAOC,EAAUF,EAAO,CACrC,OAAOlB,EAAY,SAAS,iBAAiBmB,EAAOC,EAAUF,CAAK,GAAKrB,CAC5E,EAEA,SAASsB,EAAOE,EAAOH,EAAO,CAC1B,OAAOlB,EAAY,SAAS,SAASmB,EAAOE,EAAOH,CAAK,GAAKrB,CACjE,EAEA,SAASsB,EAAOD,EAAO,CACnB,OAAOlB,EAAY,SAAS,SAASmB,EAAOD,CAAK,GAAKrB,CAC1D,EAEA,SAASsB,EAAOE,EAAOH,EAAO,CAC1B,OAAOlB,EAAY,SAAS,SAASmB,EAAOE,EAAOH,CAAK,GAAKrB,CACjE,EAEA,UAAUsB,EAAOD,EAAO,CACpB,OAAOlB,EAAY,SAAS,UAAUmB,EAAOD,CAAK,GAAKrB,CAC3D,EAEA,gBAAgBsB,EAAOC,EAAUF,EAAO,CACpC,OAAOlB,EAAY,SAAS,gBAAgBmB,EAAOC,EAAUF,CAAK,GAAKrB,CAC3E,EAEA,cAAcyB,EAAUC,EAAWC,EAAaN,EAAO,CACnD,OAAOlB,EAAY,SAAS,cAAcsB,EAAUC,EAAWC,EAAaN,CAAK,GAAKrB,CAC1F,EAEA,WAAWqB,EAAO,CACdlB,EAAY,SAAS,WAAWkB,CAAK,CACzC,EAEA,UAAW,CACPlB,EAAY,SAAS,SAAS,CAClC,EAEA,iBAAiBoB,EAAU,CACvBpB,EAAY,SAAS,iBAAiBoB,CAAQ,CAClD,EAEA,iBAAiBK,EAAQ,CACrBzB,EAAY,SAAS,iBAAiByB,CAAM,CAChD,EAEA,UAAUC,EAAaC,EAAgB,CACnC,OAAK3B,EAAY,QAGVA,EAAY,QAAQ,OAAO,KAAK0B,EAAKC,CAAK,EAFtC,QAAQ,OAAO,IAAI,MAAM,2DAA2D,CAAC,CAGpG,CACJ,GACA,CAACvB,CAAW,CAChB,CAGJ,CdnVA,IAAAwB,EAAqE","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","renderer","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_DRAW_HANDLE","DEFAULT_CONFIG","useCanvasTileEngine","instanceRef","containerRef","setIsReady","isReadyRef","setInstance","engine","center","x","y","durationMs","onComplete","width","height","newScale","factor","bounds","handlers","fn","layer","items","cacheKey","style","cellSize","lineWidth","strokeStyle","handle","src","retry","import_core"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
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};
1
+ import{useEffect as x,useRef as X,useCallback as ve,useMemo as ye}from"react";import{CanvasTileEngine as we}from"@canvas-tile-engine/core";import{createContext as N,useContext as Z}from"react";var C=N(null);function c(){let r=Z(C);if(!r)throw new Error("useEngineContext must be used within a CanvasTileEngine component");return r}import{useEffect as J,memo as Q}from"react";var S=Q(function({items:a,layer:n=1}){let{engine:i,requestRender:t}=c();return J(()=>{let s=i.drawRect(a,n);return t(),()=>{s&&i.removeDrawHandle(s)}},[i,a,n,t]),null});import{useEffect as $,memo as K}from"react";var D=K(function({items:a,layer:n=1}){let{engine:i,requestRender:t}=c();return $(()=>{let s=i.drawCircle(a,n);return t(),()=>{s&&i.removeDrawHandle(s)}},[i,a,n,t]),null});import{useEffect as ee,memo as re}from"react";var H=re(function({items:a,layer:n=1}){let{engine:i,requestRender:t}=c();return ee(()=>{let s=i.drawImage(a,n);return t(),()=>{s&&i.removeDrawHandle(s)}},[i,a,n,t]),null});import{useEffect as ne,memo as te}from"react";var L=te(function({cellSize:a,lineWidth:n=1,strokeStyle:i="black",layer:t=0}){let{engine:s,requestRender:e}=c();return ne(()=>{let o=s.drawGridLines(a,n,i,t);return e(),()=>{o&&s.removeDrawHandle(o)}},[s,a,n,i,t,e]),null});import{useEffect as oe,memo as ie}from"react";var k=ie(function({items:a,style:n,layer:i=1}){let{engine:t,requestRender:s}=c();return oe(()=>{let e=t.drawLine(a,n,i);return s(),()=>{e&&t.removeDrawHandle(e)}},[t,a,n,i,s]),null});import{useEffect as ae,memo as se}from"react";var z=se(function({items:a,layer:n=2}){let{engine:i,requestRender:t}=c();return ae(()=>{let s=i.drawText(a,n);return t(),()=>{s&&i.removeDrawHandle(s)}},[i,a,n,t]),null});import{useEffect as ce,memo as ue}from"react";var q=ue(function({items:a,style:n,layer:i=1}){let{engine:t,requestRender:s}=c();return ce(()=>{let e=t.drawPath(a,n,i);return s(),()=>{e&&t.removeDrawHandle(e)}},[t,a,n,i,s]),null});import{useEffect as F,useRef as le,memo as me}from"react";var M=me(function({items:a,cacheKey:n,layer:i=1}){let{engine:t,requestRender:s}=c(),e=le(n);return F(()=>{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.removeDrawHandle(o)}},[t,a,n,i,s]),F(()=>()=>{t.clearStaticCache(n)},[t,n]),null});import{useEffect as G,useRef as de,memo as fe}from"react";var V=fe(function({items:a,cacheKey:n,layer:i=1}){let{engine:t,requestRender:s}=c(),e=de(n);return G(()=>{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.removeDrawHandle(o)}},[t,a,n,i,s]),G(()=>()=>{t.clearStaticCache(n)},[t,n]),null});import{useEffect as _,useRef as pe,memo as ge}from"react";var A=ge(function({items:a,cacheKey:n,layer:i=1}){let{engine:t,requestRender:s}=c(),e=pe(n);return _(()=>{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.removeDrawHandle(o)}},[t,a,n,i,s]),_(()=>()=>{t.clearStaticCache(n)},[t,n]),null});import{useEffect as W,useRef as Ce,memo as xe}from"react";var Y=xe(function({children:a,layer:n=1}){let{engine:i,requestRender:t}=c(),s=Ce(a);return W(()=>{s.current=a}),W(()=>{let e=i.addDrawFunction((o,u,p)=>{s.current(o,u,p)},n);return t(),()=>{e&&i.removeDrawHandle(e)}},[i,n,t]),null});import{jsx as B,jsxs as Ee}from"react/jsx-runtime";function be({engine:r,renderer:a,config:n,center:i={x:0,y:0},className:t,style:s,children:e,onCoordsChange:o,onClick:u,onRightClick:p,onHover:y,onMouseDown:w,onMouseUp:b,onMouseLeave:E,onDraw:R,onResize:T,onZoom:P}){let d=X({onCoordsChange:o,onClick:u,onRightClick:p,onHover:y,onMouseDown:w,onMouseUp:b,onMouseLeave:E,onDraw:R,onResize:T,onZoom:P});x(()=>{d.current={onCoordsChange:o,onClick:u,onRightClick:p,onHover:y,onMouseDown:w,onMouseUp:b,onMouseLeave:E,onDraw:R,onResize:T,onZoom:P}});let g=X(null),h=ve(()=>{g.current===null&&(g.current=requestAnimationFrame(()=>{g.current=null,r.render()}))},[r]);x(()=>()=>{g.current!==null&&cancelAnimationFrame(g.current)},[]);let j=ye(()=>({engine:r,requestRender:h}),[r,h]);return x(()=>{let I=r._containerRef.current;if(!I)return;let m=new we(I,n,a,i);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:j,children:[B("div",{ref:r._containerRef,className:t,style:{...s},children:B("canvas",{})}),r.isReady&&e]})}var O=Object.assign(be,{Rect:S,Circle:D,Image:H,GridLines:L,Line:k,Text:z,Path:q,StaticRect:M,StaticCircle:V,StaticImage:A,DrawFunction:Y});import{useRef as v,useCallback as Re,useState as Te,useMemo as Pe}from"react";var f={layer:-1,id:Symbol("dummy")},he={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 U(){let r=v(null),a=v(null),[,n]=Te(!1),i=v(!1),t=Re(e=>{r.current=e,i.current=e!==null,n(e!==null)},[]);return Pe(()=>({_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()??he},setBounds(e){r.current?.setBounds(e)},setEventHandlers(e){r.current?.setEventHandlers(e)},addDrawFunction(e,o){return r.current?.addDrawFunction(e,o)??f},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},clearLayer(e){r.current?.clearLayer(e)},clearAll(){r.current?.clearAll()},clearStaticCache(e){r.current?.clearStaticCache(e)},removeDrawHandle(e){r.current?.removeDrawHandle(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 Gr,gridToSize as Vr}from"@canvas-tile-engine/core";export{O as CanvasTileEngine,Gr as CanvasTileEngineCore,Vr as gridToSize,U 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 { 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"]}
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 renderer,\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, renderer, 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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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.removeDrawHandle(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: unknown, 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.removeDrawHandle(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 DrawHandle,\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_DRAW_HANDLE: DrawHandle = { 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 /** Register a custom draw function */\n addDrawFunction(\n fn: (ctx: unknown, coords: Coords, config: Required<CanvasTileEngineConfig>) => void,\n layer?: number\n ): DrawHandle;\n\n /** Draw rectangles */\n drawRect(items: Rect | Rect[], layer?: number): DrawHandle;\n\n /** Draw static rectangles (cached) */\n drawStaticRect(items: Rect[], cacheKey: string, layer?: number): DrawHandle;\n\n /** Draw circles */\n drawCircle(items: Circle | Circle[], layer?: number): DrawHandle;\n\n /** Draw static circles (cached) */\n drawStaticCircle(items: Circle[], cacheKey: string, layer?: number): DrawHandle;\n\n /** Draw lines */\n drawLine(items: Line | Line[], style?: { strokeStyle?: string; lineWidth?: number }, layer?: number): DrawHandle;\n\n /** Draw text */\n drawText(items: Text | Text[], layer?: number): DrawHandle;\n\n /** Draw paths/polylines */\n drawPath(\n items: Coords[] | Coords[][],\n style?: { strokeStyle?: string; lineWidth?: number },\n layer?: number\n ): DrawHandle;\n\n /** Draw images */\n drawImage(items: ImageItem | ImageItem[], layer?: number): DrawHandle;\n\n /** Draw static images (cached) */\n drawStaticImage(items: ImageItem[], cacheKey: string, layer?: number): DrawHandle;\n\n /** Draw grid lines */\n drawGridLines(cellSize: number, lineWidth?: number, strokeStyle?: string, layer?: number): DrawHandle;\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 removeDrawHandle(handle: DrawHandle): 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 addDrawFunction(fn, layer) {\n return instanceRef.current?.addDrawFunction(fn, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawRect(items, layer) {\n return instanceRef.current?.drawRect(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawStaticRect(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticRect(items, cacheKey, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawCircle(items, layer) {\n return instanceRef.current?.drawCircle(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawStaticCircle(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticCircle(items, cacheKey, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawLine(items, style, layer) {\n return instanceRef.current?.drawLine(items, style, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawText(items, layer) {\n return instanceRef.current?.drawText(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawPath(items, style, layer) {\n return instanceRef.current?.drawPath(items, style, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawImage(items, layer) {\n return instanceRef.current?.drawImage(items, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawStaticImage(items, cacheKey, layer) {\n return instanceRef.current?.drawStaticImage(items, cacheKey, layer) ?? DUMMY_DRAW_HANDLE;\n },\n\n drawGridLines(cellSize, lineWidth, strokeStyle, layer) {\n return instanceRef.current?.drawGridLines(cellSize, lineWidth, strokeStyle, layer) ?? DUMMY_DRAW_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 removeDrawHandle(handle) {\n instanceRef.current?.removeDrawHandle(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) as Promise<HTMLImageElement>;\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","renderer","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_DRAW_HANDLE","DEFAULT_CONFIG","useCanvasTileEngine","instanceRef","containerRef","setIsReady","isReadyRef","setInstance","engine","center","x","y","durationMs","onComplete","width","height","newScale","factor","bounds","handlers","fn","layer","items","cacheKey","style","cellSize","lineWidth","strokeStyle","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.2.0",
3
+ "version": "0.3.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.2.0"
45
+ "@canvas-tile-engine/core": ">=0.3.0"
46
46
  },
47
47
  "dependencies": {
48
- "@canvas-tile-engine/core": "0.2.0"
48
+ "@canvas-tile-engine/core": "0.3.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/react": "^18.3.0",