@canvas-tile-engine/core 0.0.1 → 0.0.3
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/LICENSE +21 -0
- package/dist/index.d.mts +44 -9
- package/dist/index.d.ts +44 -9
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +54 -54
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ENES YÜKSEL
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
DEALINGS IN THE SOFTWARE.
|
package/dist/index.d.mts
CHANGED
|
@@ -44,6 +44,8 @@ type CanvasTileEngineConfig = {
|
|
|
44
44
|
maxScale?: number;
|
|
45
45
|
minScale?: number;
|
|
46
46
|
backgroundColor?: string;
|
|
47
|
+
/** When true, center coordinates are snapped to cell centers (x.5, y.5) for pixel-perfect grid alignment */
|
|
48
|
+
gridAligned?: boolean;
|
|
47
49
|
size: {
|
|
48
50
|
width: number;
|
|
49
51
|
height: number;
|
|
@@ -91,6 +93,7 @@ type CanvasTileEngineConfig = {
|
|
|
91
93
|
};
|
|
92
94
|
type EventHandlers = {
|
|
93
95
|
click?: boolean;
|
|
96
|
+
rightClick?: boolean;
|
|
94
97
|
hover?: boolean;
|
|
95
98
|
drag?: boolean;
|
|
96
99
|
zoom?: boolean;
|
|
@@ -106,7 +109,7 @@ type onDrawCallback = (ctx: CanvasRenderingContext2D, info: {
|
|
|
106
109
|
height: number;
|
|
107
110
|
coords: Coords;
|
|
108
111
|
}) => void;
|
|
109
|
-
type
|
|
112
|
+
type MouseEventCallback = (coords: {
|
|
110
113
|
raw: Coords;
|
|
111
114
|
snapped: Coords;
|
|
112
115
|
}, mouse: {
|
|
@@ -116,7 +119,13 @@ type onClickCallback = (coords: {
|
|
|
116
119
|
raw: Coords;
|
|
117
120
|
snapped: Coords;
|
|
118
121
|
}) => void;
|
|
119
|
-
type
|
|
122
|
+
type onClickCallback = MouseEventCallback;
|
|
123
|
+
type onHoverCallback = MouseEventCallback;
|
|
124
|
+
type onMouseDownCallback = MouseEventCallback;
|
|
125
|
+
type onMouseUpCallback = MouseEventCallback;
|
|
126
|
+
type onMouseLeaveCallback = MouseEventCallback;
|
|
127
|
+
type onRightClickCallback = MouseEventCallback;
|
|
128
|
+
type onZoomCallback = (scale: number) => void;
|
|
120
129
|
type DrawObject = {
|
|
121
130
|
x: number;
|
|
122
131
|
y: number;
|
|
@@ -177,24 +186,31 @@ declare class CanvasTileEngine {
|
|
|
177
186
|
private _onClick?;
|
|
178
187
|
get onClick(): onClickCallback | undefined;
|
|
179
188
|
set onClick(cb: onClickCallback | undefined);
|
|
189
|
+
private _onRightClick?;
|
|
190
|
+
get onRightClick(): onRightClickCallback | undefined;
|
|
191
|
+
set onRightClick(cb: onRightClickCallback | undefined);
|
|
180
192
|
private _onHover?;
|
|
181
193
|
get onHover(): onHoverCallback | undefined;
|
|
182
194
|
set onHover(cb: onHoverCallback | undefined);
|
|
183
195
|
private _onMouseDown?;
|
|
184
|
-
get onMouseDown():
|
|
185
|
-
set onMouseDown(cb:
|
|
196
|
+
get onMouseDown(): onMouseDownCallback | undefined;
|
|
197
|
+
set onMouseDown(cb: onMouseDownCallback | undefined);
|
|
186
198
|
private _onMouseUp?;
|
|
187
|
-
get onMouseUp():
|
|
188
|
-
set onMouseUp(cb:
|
|
199
|
+
get onMouseUp(): onMouseUpCallback | undefined;
|
|
200
|
+
set onMouseUp(cb: onMouseUpCallback | undefined);
|
|
189
201
|
private _onMouseLeave?;
|
|
190
|
-
get onMouseLeave():
|
|
191
|
-
set onMouseLeave(cb:
|
|
202
|
+
get onMouseLeave(): onMouseLeaveCallback | undefined;
|
|
203
|
+
set onMouseLeave(cb: onMouseLeaveCallback | undefined);
|
|
192
204
|
private _onDraw?;
|
|
193
205
|
get onDraw(): onDrawCallback | undefined;
|
|
194
206
|
set onDraw(cb: onDrawCallback | undefined);
|
|
195
207
|
private _onResize?;
|
|
196
208
|
get onResize(): (() => void) | undefined;
|
|
197
209
|
set onResize(cb: (() => void) | undefined);
|
|
210
|
+
private _onZoom?;
|
|
211
|
+
/** Callback: zoom level changes (wheel or pinch) */
|
|
212
|
+
get onZoom(): ((scale: number) => void) | undefined;
|
|
213
|
+
set onZoom(cb: ((scale: number) => void) | undefined);
|
|
198
214
|
/**
|
|
199
215
|
* @param canvas Target canvas element.
|
|
200
216
|
* @param config Initial engine configuration.
|
|
@@ -240,6 +256,25 @@ declare class CanvasTileEngine {
|
|
|
240
256
|
getConfig(): Required<CanvasTileEngineConfig>;
|
|
241
257
|
/** Center coordinates of the map. */
|
|
242
258
|
getCenterCoords(): Coords;
|
|
259
|
+
/**
|
|
260
|
+
* Get the visible world coordinate bounds of the viewport.
|
|
261
|
+
* Returns floored/ceiled values representing which cells are visible.
|
|
262
|
+
* @returns Visible bounds with min/max coordinates.
|
|
263
|
+
* @example
|
|
264
|
+
* ```ts
|
|
265
|
+
* const bounds = engine.getVisibleBounds();
|
|
266
|
+
* // { minX: 0, maxX: 10, minY: 0, maxY: 10 }
|
|
267
|
+
*
|
|
268
|
+
* // Use for random placement within visible area
|
|
269
|
+
* const x = bounds.minX + Math.floor(Math.random() * (bounds.maxX - bounds.minX));
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
getVisibleBounds(): {
|
|
273
|
+
minX: number;
|
|
274
|
+
maxX: number;
|
|
275
|
+
minY: number;
|
|
276
|
+
maxY: number;
|
|
277
|
+
};
|
|
243
278
|
/** Set center coordinates from outside (adjusts the camera accordingly). */
|
|
244
279
|
updateCoords(newCenter: Coords): void;
|
|
245
280
|
/**
|
|
@@ -511,4 +546,4 @@ declare const VISIBILITY_BUFFER: {
|
|
|
511
546
|
readonly TILE_BUFFER: 1;
|
|
512
547
|
};
|
|
513
548
|
|
|
514
|
-
export { COORDINATE_OVERLAY, CanvasTileEngine, type CanvasTileEngineConfig, type Circle, type Coords, DEBUG_HUD, DEFAULT_VALUES, type DrawObject, type EventHandlers, type ImageItem, type LayerHandle, type Line, type Path, RENDER_DEFAULTS, type Rect, SCALE_LIMITS, SIZE_LIMITS, type Text, VISIBILITY_BUFFER, type onClickCallback, type onDrawCallback, type onHoverCallback };
|
|
549
|
+
export { COORDINATE_OVERLAY, CanvasTileEngine, type CanvasTileEngineConfig, type Circle, type Coords, DEBUG_HUD, DEFAULT_VALUES, type DrawObject, type EventHandlers, type ImageItem, type LayerHandle, type Line, type Path, RENDER_DEFAULTS, type Rect, SCALE_LIMITS, SIZE_LIMITS, type Text, VISIBILITY_BUFFER, type onClickCallback, type onDrawCallback, type onHoverCallback, type onMouseDownCallback, type onMouseLeaveCallback, type onMouseUpCallback, type onRightClickCallback, type onZoomCallback };
|
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ type CanvasTileEngineConfig = {
|
|
|
44
44
|
maxScale?: number;
|
|
45
45
|
minScale?: number;
|
|
46
46
|
backgroundColor?: string;
|
|
47
|
+
/** When true, center coordinates are snapped to cell centers (x.5, y.5) for pixel-perfect grid alignment */
|
|
48
|
+
gridAligned?: boolean;
|
|
47
49
|
size: {
|
|
48
50
|
width: number;
|
|
49
51
|
height: number;
|
|
@@ -91,6 +93,7 @@ type CanvasTileEngineConfig = {
|
|
|
91
93
|
};
|
|
92
94
|
type EventHandlers = {
|
|
93
95
|
click?: boolean;
|
|
96
|
+
rightClick?: boolean;
|
|
94
97
|
hover?: boolean;
|
|
95
98
|
drag?: boolean;
|
|
96
99
|
zoom?: boolean;
|
|
@@ -106,7 +109,7 @@ type onDrawCallback = (ctx: CanvasRenderingContext2D, info: {
|
|
|
106
109
|
height: number;
|
|
107
110
|
coords: Coords;
|
|
108
111
|
}) => void;
|
|
109
|
-
type
|
|
112
|
+
type MouseEventCallback = (coords: {
|
|
110
113
|
raw: Coords;
|
|
111
114
|
snapped: Coords;
|
|
112
115
|
}, mouse: {
|
|
@@ -116,7 +119,13 @@ type onClickCallback = (coords: {
|
|
|
116
119
|
raw: Coords;
|
|
117
120
|
snapped: Coords;
|
|
118
121
|
}) => void;
|
|
119
|
-
type
|
|
122
|
+
type onClickCallback = MouseEventCallback;
|
|
123
|
+
type onHoverCallback = MouseEventCallback;
|
|
124
|
+
type onMouseDownCallback = MouseEventCallback;
|
|
125
|
+
type onMouseUpCallback = MouseEventCallback;
|
|
126
|
+
type onMouseLeaveCallback = MouseEventCallback;
|
|
127
|
+
type onRightClickCallback = MouseEventCallback;
|
|
128
|
+
type onZoomCallback = (scale: number) => void;
|
|
120
129
|
type DrawObject = {
|
|
121
130
|
x: number;
|
|
122
131
|
y: number;
|
|
@@ -177,24 +186,31 @@ declare class CanvasTileEngine {
|
|
|
177
186
|
private _onClick?;
|
|
178
187
|
get onClick(): onClickCallback | undefined;
|
|
179
188
|
set onClick(cb: onClickCallback | undefined);
|
|
189
|
+
private _onRightClick?;
|
|
190
|
+
get onRightClick(): onRightClickCallback | undefined;
|
|
191
|
+
set onRightClick(cb: onRightClickCallback | undefined);
|
|
180
192
|
private _onHover?;
|
|
181
193
|
get onHover(): onHoverCallback | undefined;
|
|
182
194
|
set onHover(cb: onHoverCallback | undefined);
|
|
183
195
|
private _onMouseDown?;
|
|
184
|
-
get onMouseDown():
|
|
185
|
-
set onMouseDown(cb:
|
|
196
|
+
get onMouseDown(): onMouseDownCallback | undefined;
|
|
197
|
+
set onMouseDown(cb: onMouseDownCallback | undefined);
|
|
186
198
|
private _onMouseUp?;
|
|
187
|
-
get onMouseUp():
|
|
188
|
-
set onMouseUp(cb:
|
|
199
|
+
get onMouseUp(): onMouseUpCallback | undefined;
|
|
200
|
+
set onMouseUp(cb: onMouseUpCallback | undefined);
|
|
189
201
|
private _onMouseLeave?;
|
|
190
|
-
get onMouseLeave():
|
|
191
|
-
set onMouseLeave(cb:
|
|
202
|
+
get onMouseLeave(): onMouseLeaveCallback | undefined;
|
|
203
|
+
set onMouseLeave(cb: onMouseLeaveCallback | undefined);
|
|
192
204
|
private _onDraw?;
|
|
193
205
|
get onDraw(): onDrawCallback | undefined;
|
|
194
206
|
set onDraw(cb: onDrawCallback | undefined);
|
|
195
207
|
private _onResize?;
|
|
196
208
|
get onResize(): (() => void) | undefined;
|
|
197
209
|
set onResize(cb: (() => void) | undefined);
|
|
210
|
+
private _onZoom?;
|
|
211
|
+
/** Callback: zoom level changes (wheel or pinch) */
|
|
212
|
+
get onZoom(): ((scale: number) => void) | undefined;
|
|
213
|
+
set onZoom(cb: ((scale: number) => void) | undefined);
|
|
198
214
|
/**
|
|
199
215
|
* @param canvas Target canvas element.
|
|
200
216
|
* @param config Initial engine configuration.
|
|
@@ -240,6 +256,25 @@ declare class CanvasTileEngine {
|
|
|
240
256
|
getConfig(): Required<CanvasTileEngineConfig>;
|
|
241
257
|
/** Center coordinates of the map. */
|
|
242
258
|
getCenterCoords(): Coords;
|
|
259
|
+
/**
|
|
260
|
+
* Get the visible world coordinate bounds of the viewport.
|
|
261
|
+
* Returns floored/ceiled values representing which cells are visible.
|
|
262
|
+
* @returns Visible bounds with min/max coordinates.
|
|
263
|
+
* @example
|
|
264
|
+
* ```ts
|
|
265
|
+
* const bounds = engine.getVisibleBounds();
|
|
266
|
+
* // { minX: 0, maxX: 10, minY: 0, maxY: 10 }
|
|
267
|
+
*
|
|
268
|
+
* // Use for random placement within visible area
|
|
269
|
+
* const x = bounds.minX + Math.floor(Math.random() * (bounds.maxX - bounds.minX));
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
getVisibleBounds(): {
|
|
273
|
+
minX: number;
|
|
274
|
+
maxX: number;
|
|
275
|
+
minY: number;
|
|
276
|
+
maxY: number;
|
|
277
|
+
};
|
|
243
278
|
/** Set center coordinates from outside (adjusts the camera accordingly). */
|
|
244
279
|
updateCoords(newCenter: Coords): void;
|
|
245
280
|
/**
|
|
@@ -511,4 +546,4 @@ declare const VISIBILITY_BUFFER: {
|
|
|
511
546
|
readonly TILE_BUFFER: 1;
|
|
512
547
|
};
|
|
513
548
|
|
|
514
|
-
export { COORDINATE_OVERLAY, CanvasTileEngine, type CanvasTileEngineConfig, type Circle, type Coords, DEBUG_HUD, DEFAULT_VALUES, type DrawObject, type EventHandlers, type ImageItem, type LayerHandle, type Line, type Path, RENDER_DEFAULTS, type Rect, SCALE_LIMITS, SIZE_LIMITS, type Text, VISIBILITY_BUFFER, type onClickCallback, type onDrawCallback, type onHoverCallback };
|
|
549
|
+
export { COORDINATE_OVERLAY, CanvasTileEngine, type CanvasTileEngineConfig, type Circle, type Coords, DEBUG_HUD, DEFAULT_VALUES, type DrawObject, type EventHandlers, type ImageItem, type LayerHandle, type Line, type Path, RENDER_DEFAULTS, type Rect, SCALE_LIMITS, SIZE_LIMITS, type Text, VISIBILITY_BUFFER, type onClickCallback, type onDrawCallback, type onHoverCallback, type onMouseDownCallback, type onMouseLeaveCallback, type onMouseUpCallback, type onRightClickCallback, type onZoomCallback };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var he=Object.create;var A=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var de=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var ue=(p,e)=>{for(var t in e)A(p,t,{get:e[t],enumerable:!0})},te=(p,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ce(e))!me.call(p,i)&&i!==t&&A(p,i,{get:()=>e[i],enumerable:!(r=le(e,i))||r.enumerable});return p};var fe=(p,e,t)=>(t=p!=null?he(de(p)):{},te(e||!p||!p.__esModule?A(t,"default",{value:p,enumerable:!0}):t,p)),ve=p=>te(A({},"__esModule",{value:!0}),p);var ge={};ue(ge,{COORDINATE_OVERLAY:()=>x,CanvasTileEngine:()=>J,DEBUG_HUD:()=>T,DEFAULT_VALUES:()=>w,RENDER_DEFAULTS:()=>k,SCALE_LIMITS:()=>O,SIZE_LIMITS:()=>R,VISIBILITY_BUFFER:()=>S});module.exports=ve(ge);var w={ANIMATION_DURATION_MS:500,CELL_CENTER_OFFSET:.5,IMAGE_LOAD_RETRY_COUNT:1,MAX_WHEEL_DELTA:100,MIN_WHEEL_DELTA:-100,ZOOM_SENSITIVITY:.001},O={MIN_SCALE_MULTIPLIER:.5,MAX_SCALE_MULTIPLIER:2},R={MIN_WIDTH:100,MIN_HEIGHT:100,MAX_WIDTH:1/0,MAX_HEIGHT:1/0},k={BACKGROUND_COLOR:"#ffffff",RENDERER_TYPE:"canvas"},x={BORDER_WIDTH:20,TEXT_OPACITY:.8,BORDER_OPACITY:.1,MIN_FONT_SIZE:8,MAX_FONT_SIZE:12,FONT_SIZE_SCALE_FACTOR:.25},T={PANEL_WIDTH:160,PADDING:8,LINE_HEIGHT:16},S={TILE_BUFFER:1};function re(p,e,t,r){return{x:p.x-t/e,y:p.y-r/e}}function ie(p,e,t,r,i,n){let s=Math.min(Math.max(t,w.MIN_WHEEL_DELTA),w.MAX_WHEEL_DELTA),a=Math.exp(-s*w.ZOOM_SENSITIVITY),o=Math.min(i,Math.max(r,e*a));return o===e?{topLeft:p,scale:e}:{topLeft:{x:p.x+n.x*(1/e-1/o),y:p.y+n.y*(1/e-1/o)},scale:o}}function se(p,e){return{x:(p.x+w.CELL_CENTER_OFFSET-e.x)*e.scale,y:(p.y+w.CELL_CENTER_OFFSET-e.y)*e.scale}}function ne(p,e){return{x:e.x+p.x/e.scale,y:e.y+p.y/e.scale}}var D=class{_x;_y;_scale;minScale;maxScale;bounds;viewport;constructor(e,t=1,r=.1,i=10,n){this._x=e.x+w.CELL_CENTER_OFFSET,this._y=e.y+w.CELL_CENTER_OFFSET,this._scale=t,this.minScale=r,this.maxScale=i,this.viewport=n}setBounds(e){this.bounds=e,this.bounds&&this.clampToBounds()}clampToBounds(){if(!this.bounds||!this.viewport)return;let{width:e,height:t}=this.viewport.getSize(),r=e/this._scale,i=t/this._scale;this._x=this.clampAxis(this._x,r,this.bounds.minX,this.bounds.maxX),this._y=this.clampAxis(this._y,i,this.bounds.minY,this.bounds.maxY)}clampAxis(e,t,r,i){let n=i-r;return t>=n?r-(t-n)/2:e<r?r:e+t>i?i-t:e}get x(){return this._x}get y(){return this._y}get scale(){return this._scale}pan(e,t){let r=re({x:this._x,y:this._y},this._scale,e,t);this._x=r.x,this._y=r.y,this.clampToBounds()}zoom(e,t,r,i){let n=e-i.left,s=t-i.top,a=ie({x:this._x,y:this._y},this._scale,r,this.minScale,this.maxScale,{x:n,y:s});this._x=a.topLeft.x,this._y=a.topLeft.y,this._scale=a.scale,this.clampToBounds()}zoomByFactor(e,t,r){let i=Math.min(this.maxScale,Math.max(this.minScale,this._scale*e));i!==this._scale&&(this._x=this._x+t*(1/this._scale-1/i),this._y=this._y+r*(1/this._scale-1/i),this._scale=i,this.clampToBounds())}getCenter(e,t){return{x:this._x+e/(2*this._scale)-.5,y:this._y+t/(2*this._scale)-.5}}setCenter(e,t,r){this._x=e.x-t/(2*this._scale)+.5,this._y=e.y-r/(2*this._scale)+.5,this.clampToBounds()}adjustForResize(e,t){this._x-=e/(2*this._scale),this._y-=t/(2*this._scale),this.clampToBounds()}};var F=class{config;constructor(e){let t={renderer:k.RENDERER_TYPE,scale:e.scale,minScale:e.minScale??e.scale*O.MIN_SCALE_MULTIPLIER,maxScale:e.maxScale??e.scale*O.MAX_SCALE_MULTIPLIER,size:{width:e.size.width,height:e.size.height,maxHeight:e.size.maxHeight??R.MAX_HEIGHT,maxWidth:e.size.maxWidth??R.MAX_WIDTH,minHeight:e.size.minHeight??R.MIN_HEIGHT,minWidth:e.size.minWidth??R.MIN_WIDTH},backgroundColor:e.backgroundColor??k.BACKGROUND_COLOR,eventHandlers:{click:e.eventHandlers?.click??!1,hover:e.eventHandlers?.hover??!1,drag:e.eventHandlers?.drag??!1,zoom:e.eventHandlers?.zoom??!1,resize:e.eventHandlers?.resize??!1},bounds:e.bounds??{minX:-1/0,maxX:1/0,minY:-1/0,maxY:1/0},coordinates:{enabled:e.coordinates?.enabled??!1,shownScaleRange:e.coordinates?.shownScaleRange??{min:0,max:1/0}},cursor:{default:e.cursor?.default??"default",move:e.cursor?.move??"move"},debug:{enabled:e.debug?.enabled??!1,hud:{enabled:e.debug?.hud?.enabled??!1,topLeftCoordinates:e.debug?.hud?.topLeftCoordinates??!1,coordinates:e.debug?.hud?.coordinates??!1,scale:e.debug?.hud?.scale??!1,tilesInView:e.debug?.hud?.tilesInView??!1,fps:e.debug?.hud?.fps??!1},eventHandlers:{click:e.debug?.eventHandlers?.click??!0,hover:e.debug?.eventHandlers?.hover??!0,drag:e.debug?.eventHandlers?.drag??!0,zoom:e.debug?.eventHandlers?.zoom??!0,resize:e.debug?.eventHandlers?.resize??!0}}};this.config={...t,size:Object.freeze(t.size),eventHandlers:Object.freeze(t.eventHandlers),bounds:Object.freeze(t.bounds),coordinates:Object.freeze({...t.coordinates,shownScaleRange:Object.freeze(t.coordinates.shownScaleRange)}),cursor:Object.freeze(t.cursor),debug:Object.freeze({enabled:t.debug.enabled,hud:Object.freeze(t.debug.hud),eventHandlers:Object.freeze(t.debug.eventHandlers)})}}get(){let e=this.config;return{...e,size:{...e.size},eventHandlers:{...e.eventHandlers},bounds:{...e.bounds},coordinates:{...e.coordinates,shownScaleRange:{min:e.coordinates.shownScaleRange?.min??0,max:e.coordinates.shownScaleRange?.max??1/0}},cursor:{...e.cursor},debug:{...e.debug,hud:{...e.debug.hud},eventHandlers:{...e.debug.eventHandlers}}}}updateEventHandlers(e){this.config={...this.config,eventHandlers:Object.freeze({...this.config.eventHandlers,...e})}}updateBounds(e){this.config={...this.config,bounds:Object.freeze(e)}}};var W=class{constructor(e){this.camera=e}worldToScreen(e,t){return se({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}screenToWorld(e,t){return ne({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}};var ae=fe(require("rbush")),_=class p{tree;constructor(){this.tree=new ae.default}load(e){let t=e.map(r=>{let n=(typeof r.size=="number"?r.size:0)/2;return{minX:r.x-n,minY:r.y-n,maxX:r.x+n,maxY:r.y+n,item:r}});this.tree.load(t)}query(e,t,r,i){return this.tree.search({minX:e,minY:t,maxX:r,maxY:i}).map(s=>s.item)}clear(){this.tree.clear()}static fromArray(e){let t=new p;return t.load(e),t}};var ee=500,oe=16384,P=class{constructor(e,t,r){this.layers=e;this.transformer=t;this.camera=r;this.staticCacheSupported=typeof OffscreenCanvas<"u"||typeof document<"u"}staticCaches=new Map;staticCacheSupported;warnedStaticCacheDisabled=!1;isVisible(e,t,r,i,n){let s=n.size.width/n.scale,a=n.size.height/n.scale,o=i.x-S.TILE_BUFFER,l=i.y-S.TILE_BUFFER,c=i.x+s+S.TILE_BUFFER,h=i.y+a+S.TILE_BUFFER;return e+r>=o&&e-r<=c&&t+r>=l&&t-r<=h}getViewportBounds(e,t){let r=t.size.width/t.scale,i=t.size.height/t.scale;return{minX:e.x-S.TILE_BUFFER,minY:e.y-S.TILE_BUFFER,maxX:e.x+r+S.TILE_BUFFER,maxY:e.y+i+S.TILE_BUFFER}}addDrawFunction(e,t=1){return this.layers.add(t,({ctx:r,config:i,topLeft:n})=>{e(r,n,i)})}drawRect(e,t=1){let r=Array.isArray(e)?e:[e],n=r.length>ee?_.fromArray(r):null;return this.layers.add(t,({ctx:s,config:a,topLeft:o})=>{let l=this.getViewportBounds(o,a),c=n?n.query(l.minX,l.minY,l.maxX,l.maxY):r;s.save();let h,v,u;for(let d of c){let m=d.size??1,C={mode:d.origin?.mode==="self"?"self":"cell",x:d.origin?.x??.5,y:d.origin?.y??.5},f=d.style;if(!n&&!this.isVisible(d.x,d.y,m/2,o,a))continue;let y=this.transformer.worldToScreen(d.x,d.y),g=m*this.camera.scale,{x:b,y:E}=this.computeOriginOffset(y,g,C,this.camera);f?.fillStyle&&f.fillStyle!==h&&(s.fillStyle=f.fillStyle,h=f.fillStyle),f?.strokeStyle&&f.strokeStyle!==v&&(s.strokeStyle=f.strokeStyle,v=f.strokeStyle),f?.lineWidth&&f.lineWidth!==u&&(s.lineWidth=f.lineWidth,u=f.lineWidth);let I=d.rotate??0,z=I*(Math.PI/180),L=d.radius;if(I!==0){let K=b+g/2,Q=E+g/2;s.save(),s.translate(K,Q),s.rotate(z),s.beginPath(),L&&s.roundRect?s.roundRect(-g/2,-g/2,g,g,L):s.rect(-g/2,-g/2,g,g),f?.fillStyle&&s.fill(),f?.strokeStyle&&s.stroke(),s.restore()}else s.beginPath(),L&&s.roundRect?s.roundRect(b,E,g,g,L):s.rect(b,E,g,g),f?.fillStyle&&s.fill(),f?.strokeStyle&&s.stroke()}s.restore()})}drawLine(e,t,r=1){let i=Array.isArray(e)?e:[e];return this.layers.add(r,({ctx:n,config:s,topLeft:a})=>{n.save(),t?.strokeStyle&&(n.strokeStyle=t.strokeStyle),t?.lineWidth&&(n.lineWidth=t.lineWidth),n.beginPath();for(let o of i){let l=(o.from.x+o.to.x)/2,c=(o.from.y+o.to.y)/2,h=Math.max(Math.abs(o.from.x-o.to.x),Math.abs(o.from.y-o.to.y))/2;if(!this.isVisible(l,c,h,a,s))continue;let v=this.transformer.worldToScreen(o.from.x,o.from.y),u=this.transformer.worldToScreen(o.to.x,o.to.y);n.moveTo(v.x,v.y),n.lineTo(u.x,u.y)}n.stroke(),n.restore()})}drawCircle(e,t=1){let r=Array.isArray(e)?e:[e],n=r.length>ee?_.fromArray(r):null;return this.layers.add(t,({ctx:s,config:a,topLeft:o})=>{let l=this.getViewportBounds(o,a),c=n?n.query(l.minX,l.minY,l.maxX,l.maxY):r;s.save();let h,v,u;for(let d of c){let m=d.size??1,C={mode:d.origin?.mode==="self"?"self":"cell",x:d.origin?.x??.5,y:d.origin?.y??.5},f=d.style;if(!n&&!this.isVisible(d.x,d.y,m/2,o,a))continue;let y=this.transformer.worldToScreen(d.x,d.y),g=m*this.camera.scale,b=g/2,{x:E,y:I}=this.computeOriginOffset(y,g,C,this.camera);f?.fillStyle&&f.fillStyle!==h&&(s.fillStyle=f.fillStyle,h=f.fillStyle),f?.strokeStyle&&f.strokeStyle!==v&&(s.strokeStyle=f.strokeStyle,v=f.strokeStyle),f?.lineWidth&&f.lineWidth!==u&&(s.lineWidth=f.lineWidth,u=f.lineWidth),s.beginPath(),s.arc(E+b,I+b,b,0,Math.PI*2),f?.fillStyle&&s.fill(),f?.strokeStyle&&s.stroke()}s.restore()})}drawText(e,t,r=2){let i=Array.isArray(e)?e:[e];return this.layers.add(r,({ctx:n,config:s,topLeft:a})=>{n.save(),t?.font&&(n.font=t.font),t?.fillStyle&&(n.fillStyle=t.fillStyle),n.textAlign=t?.textAlign??"center",n.textBaseline=t?.textBaseline??"middle";for(let o of i){if(!this.isVisible(o.coords.x,o.coords.y,0,a,s))continue;let l=this.transformer.worldToScreen(o.coords.x,o.coords.y);n.fillText(o.text,l.x,l.y)}n.restore()})}drawPath(e,t,r=1){let i=Array.isArray(e[0])?e:[e];return this.layers.add(r,({ctx:n,config:s,topLeft:a})=>{n.save(),t?.strokeStyle&&(n.strokeStyle=t.strokeStyle),t?.lineWidth&&(n.lineWidth=t.lineWidth),n.beginPath();for(let o of i){if(!o.length)continue;let l=o.map(g=>g.x),c=o.map(g=>g.y),h=Math.min(...l),v=Math.max(...l),u=Math.min(...c),d=Math.max(...c),m=(h+v)/2,C=(u+d)/2,f=Math.max(v-h,d-u)/2;if(!this.isVisible(m,C,f,a,s))continue;let y=this.transformer.worldToScreen(o[0].x,o[0].y);n.moveTo(y.x,y.y);for(let g=1;g<o.length;g++){let b=this.transformer.worldToScreen(o[g].x,o[g].y);n.lineTo(b.x,b.y)}}n.stroke(),n.restore()})}drawImage(e,t=1){let r=Array.isArray(e)?e:[e],n=r.length>ee?_.fromArray(r):null;return this.layers.add(t,({ctx:s,config:a,topLeft:o})=>{let l=this.getViewportBounds(o,a),c=n?n.query(l.minX,l.minY,l.maxX,l.maxY):r;for(let h of c){let v=h.size??1,u={mode:h.origin?.mode==="self"?"self":"cell",x:h.origin?.x??.5,y:h.origin?.y??.5};if(!n&&!this.isVisible(h.x,h.y,v/2,o,a))continue;let d=this.transformer.worldToScreen(h.x,h.y),m=v*this.camera.scale,C=h.img.width/h.img.height,f=m,y=m;C>1?y=m/C:f=m*C;let{x:g,y:b}=this.computeOriginOffset(d,m,u,this.camera),E=g+(m-f)/2,I=b+(m-y)/2,z=h.rotate??0,L=z*(Math.PI/180);if(z!==0){let K=E+f/2,Q=I+y/2;s.save(),s.translate(K,Q),s.rotate(L),s.drawImage(h.img,-f/2,-y/2,f,y),s.restore()}else s.drawImage(h.img,E,I,f,y)}})}drawGridLines(e,t,r=0){return this.layers.add(r,({ctx:i,config:n,topLeft:s})=>{let a=n.size.width/n.scale,o=n.size.height/n.scale,l=Math.floor(s.x/e)*e-w.CELL_CENTER_OFFSET,c=Math.ceil((s.x+a)/e)*e-w.CELL_CENTER_OFFSET,h=Math.floor(s.y/e)*e-w.CELL_CENTER_OFFSET,v=Math.ceil((s.y+o)/e)*e-w.CELL_CENTER_OFFSET;i.save(),i.strokeStyle=t.strokeStyle,i.lineWidth=t.lineWidth,i.beginPath();for(let u=l;u<=c;u+=e){let d=this.transformer.worldToScreen(u,h),m=this.transformer.worldToScreen(u,v);i.moveTo(d.x,d.y),i.lineTo(m.x,m.y)}for(let u=h;u<=v;u+=e){let d=this.transformer.worldToScreen(l,u),m=this.transformer.worldToScreen(c,u);i.moveTo(d.x,d.y),i.lineTo(m.x,m.y)}i.stroke(),i.restore()})}computeOriginOffset(e,t,r,i){if(r.mode==="cell"){let n=i.scale;return{x:e.x-n/2+r.x*n-t/2,y:e.y-n/2+r.y*n-t/2}}return{x:e.x-r.x*t,y:e.y-r.y*t}}getOrCreateStaticCache(e,t,r){if(!this.staticCacheSupported)return this.warnedStaticCacheDisabled||(console.warn("[CanvasDraw] Static cache disabled: OffscreenCanvas not available."),this.warnedStaticCacheDisabled=!0),null;let i=1/0,n=-1/0,s=1/0,a=-1/0;for(let m of e){let C=m.size??1;m.x-C/2<i&&(i=m.x-C/2),m.x+C/2>n&&(n=m.x+C/2),m.y-C/2<s&&(s=m.y-C/2),m.y+C/2>a&&(a=m.y+C/2)}i-=1,s-=1,n+=1,a+=1;let o=n-i,l=a-s,c=this.camera.scale,h=Math.ceil(o*c),v=Math.ceil(l*c);if(h>oe||v>oe)return this.warnedStaticCacheDisabled||(console.warn(`Static cache disabled: offscreen canvas too large (${h}x${v}).`),this.warnedStaticCacheDisabled=!0),null;let u=this.staticCaches.get(t);if(!u||u.scale!==c||u.worldBounds.minX!==i||u.worldBounds.maxX!==n||u.worldBounds.minY!==s||u.worldBounds.maxY!==a){let m=typeof OffscreenCanvas<"u"?new OffscreenCanvas(h,v):document.createElement("canvas");typeof OffscreenCanvas<"u"&&m instanceof OffscreenCanvas||(m.width=h,m.height=v);let f=m.getContext("2d");if(!f)return this.warnedStaticCacheDisabled||(console.warn("[CanvasDraw] Static cache disabled: 2D context unavailable."),this.warnedStaticCacheDisabled=!0),null;for(let y of e){let b=(y.size??1)*c,E=(y.x+w.CELL_CENTER_OFFSET-i)*c-b/2,I=(y.y+w.CELL_CENTER_OFFSET-s)*c-b/2;r(f,y,E,I,b)}u={canvas:m,ctx:f,worldBounds:{minX:i,minY:s,maxX:n,maxY:a},scale:c},this.staticCaches.set(t,u)}return u||null}addStaticCacheLayer(e,t){if(!e)return null;let r=e.canvas,i=e.worldBounds,n=e.scale;return this.layers.add(t,({ctx:s,config:a,topLeft:o})=>{let l=a.size.width/a.scale,c=a.size.height/a.scale,h=(o.x-i.minX)*n,v=(o.y-i.minY)*n,u=l*n,d=c*n;s.drawImage(r,h,v,u,d,0,0,a.size.width,a.size.height)})}drawStaticRect(e,t,r=1){let i,n=this.getOrCreateStaticCache(e,t,(s,a,o,l,c)=>{let h=a.style,v=a.rotate??0,u=v*(Math.PI/180),d=a.radius;if(h?.fillStyle&&h.fillStyle!==i&&(s.fillStyle=h.fillStyle,i=h.fillStyle),v!==0){let m=o+c/2,C=l+c/2;s.save(),s.translate(m,C),s.rotate(u),d&&s.roundRect?(s.beginPath(),s.roundRect(-c/2,-c/2,c,c,d),s.fill()):s.fillRect(-c/2,-c/2,c,c),s.restore()}else d&&s.roundRect?(s.beginPath(),s.roundRect(o,l,c,c,d),s.fill()):s.fillRect(o,l,c,c)});return n?this.addStaticCacheLayer(n,r):this.drawRect(e,r)}drawStaticImage(e,t,r=1){let i=this.getOrCreateStaticCache(e,t,(n,s,a,o,l)=>{let c=s.img,h=s.rotate??0,v=h*(Math.PI/180),u=c.width/c.height,d=l,m=l;u>1?m=l/u:d=l*u;let C=a+(l-d)/2,f=o+(l-m)/2;if(h!==0){let y=C+d/2,g=f+m/2;n.save(),n.translate(y,g),n.rotate(v),n.drawImage(c,-d/2,-m/2,d,m),n.restore()}else n.drawImage(c,C,f,d,m)});return i?this.addStaticCacheLayer(i,r):this.drawImage(e,r)}drawStaticCircle(e,t,r=1){let i,n=this.getOrCreateStaticCache(e,t,(s,a,o,l,c)=>{let h=a.style,v=c/2;h?.fillStyle&&h.fillStyle!==i&&(s.fillStyle=h.fillStyle,i=h.fillStyle),s.beginPath(),s.arc(o+v,l+v,v,0,Math.PI*2),s.fill()});return n?this.addStaticCacheLayer(n,r):this.drawCircle(e,r)}clearStaticCache(e){e?this.staticCaches.delete(e):this.staticCaches.clear()}destroy(){this.staticCaches.clear(),this.layers.clear()}};var Y=class{constructor(e,t){this.canvas=e;this.handlers=t}attach(){this.handlers.click&&this.canvas.addEventListener("click",this.handlers.click),this.handlers.mousedown&&this.canvas.addEventListener("mousedown",this.handlers.mousedown),this.handlers.mousemove&&this.canvas.addEventListener("mousemove",this.handlers.mousemove),this.handlers.mouseup&&this.canvas.addEventListener("mouseup",this.handlers.mouseup),this.handlers.mouseleave&&this.canvas.addEventListener("mouseleave",this.handlers.mouseleave),this.handlers.wheel&&this.canvas.addEventListener("wheel",this.handlers.wheel,{passive:!1}),this.handlers.touchstart&&this.canvas.addEventListener("touchstart",this.handlers.touchstart,{passive:!1}),this.handlers.touchmove&&this.canvas.addEventListener("touchmove",this.handlers.touchmove,{passive:!1}),this.handlers.touchend&&this.canvas.addEventListener("touchend",this.handlers.touchend,{passive:!1})}detach(){this.handlers.click&&this.canvas.removeEventListener("click",this.handlers.click),this.handlers.mousedown&&this.canvas.removeEventListener("mousedown",this.handlers.mousedown),this.handlers.mousemove&&this.canvas.removeEventListener("mousemove",this.handlers.mousemove),this.handlers.mouseup&&this.canvas.removeEventListener("mouseup",this.handlers.mouseup),this.handlers.mouseleave&&this.canvas.removeEventListener("mouseleave",this.handlers.mouseleave),this.handlers.wheel&&this.canvas.removeEventListener("wheel",this.handlers.wheel),this.handlers.touchstart&&this.canvas.removeEventListener("touchstart",this.handlers.touchstart),this.handlers.touchmove&&this.canvas.removeEventListener("touchmove",this.handlers.touchmove),this.handlers.touchend&&this.canvas.removeEventListener("touchend",this.handlers.touchend)}};var X=class{constructor(e,t,r,i,n,s){this.canvas=e;this.camera=t;this.viewport=r;this.config=i;this.transformer=n;this.onCameraChange=s}isDragging=!1;shouldPreventClick=!1;lastPos={x:0,y:0};isPinching=!1;lastPinchDistance=0;lastPinchCenter={x:0,y:0};onClick;onHover;onMouseDown;onMouseUp;onMouseLeave;handleClick=e=>{if(this.shouldPreventClick){this.shouldPreventClick=!1;return}if(!this.config.get().eventHandlers.click||!this.onClick)return;let t=this.canvas.getBoundingClientRect(),r=e.clientX-t.left,i=e.clientY-t.top,n=this.transformer.screenToWorld(r,i),s=this.transformer.worldToScreen(Math.floor(n.x),Math.floor(n.y));this.onClick({raw:n,snapped:{x:Math.floor(n.x),y:Math.floor(n.y)}},{raw:{x:e.clientX-t.left,y:e.clientY-t.top},snapped:{x:s.x,y:s.y}},{raw:{x:e.clientX,y:e.clientY},snapped:{x:s.x+t.left,y:s.y+t.top}})};handleMouseDown=e=>{this.onMouseDown&&this.onMouseDown(),this.config.get().eventHandlers.drag&&(this.isDragging=!0,this.shouldPreventClick=!1,this.lastPos={x:e.clientX,y:e.clientY})};handleMouseMove=e=>{if(!this.isDragging){if(this.onHover&&this.config.get().eventHandlers.hover){let i=this.canvas.getBoundingClientRect(),n=e.clientX-i.left,s=e.clientY-i.top,a=this.transformer.screenToWorld(n,s),o=this.transformer.worldToScreen(Math.floor(a.x),Math.floor(a.y));this.onHover({raw:a,snapped:{x:Math.floor(a.x),y:Math.floor(a.y)}},{raw:{x:e.clientX-i.left,y:e.clientY-i.top},snapped:{x:o.x,y:o.y}},{raw:{x:e.clientX,y:e.clientY},snapped:{x:o.x+i.left,y:o.y+i.top}})}return}let t=e.clientX-this.lastPos.x,r=e.clientY-this.lastPos.y;(t!==0||r!==0)&&(this.canvas.style.cursor=this.config.get().cursor.move||"move",this.shouldPreventClick=!0),this.camera.pan(t,r),this.lastPos={x:e.clientX,y:e.clientY},this.onCameraChange()};handleMouseUp=()=>{this.onMouseUp&&this.onMouseUp(),this.isDragging=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};handleMouseLeave=()=>{this.onMouseLeave&&this.onMouseLeave(),this.isDragging=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};handleTouchStart=e=>{let t=this.config.get().eventHandlers;if(e.touches.length===2&&t.zoom){e.preventDefault(),this.isPinching=!0,this.isDragging=!1,this.lastPinchDistance=this.getTouchDistance(e.touches),this.lastPinchCenter=this.getTouchCenter(e.touches);return}if(!t.drag||e.touches.length!==1)return;let r=e.touches[0];this.isDragging=!0,this.isPinching=!1,this.shouldPreventClick=!1,this.lastPos={x:r.clientX,y:r.clientY}};handleTouchMove=e=>{if(this.isPinching&&e.touches.length===2){e.preventDefault();let n=this.getTouchDistance(e.touches),s=this.getTouchCenter(e.touches),a=this.canvas.getBoundingClientRect(),o=n/this.lastPinchDistance,l=s.x-a.left,c=s.y-a.top;this.camera.zoomByFactor(o,l,c);let h=s.x-this.lastPinchCenter.x,v=s.y-this.lastPinchCenter.y;(h!==0||v!==0)&&this.camera.pan(h,v),this.lastPinchDistance=n,this.lastPinchCenter=s,this.onCameraChange();return}if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0],r=t.clientX-this.lastPos.x,i=t.clientY-this.lastPos.y;(r!==0||i!==0)&&(this.canvas.style.cursor=this.config.get().cursor.move||"move",this.shouldPreventClick=!0),this.camera.pan(r,i),this.lastPos={x:t.clientX,y:t.clientY},this.onCameraChange()};handleTouchEnd=e=>{if(e.touches.length>=2&&this.isPinching){this.lastPinchDistance=this.getTouchDistance(e.touches),this.lastPinchCenter=this.getTouchCenter(e.touches);return}if(e.touches.length===1&&this.isPinching){if(this.isPinching=!1,this.config.get().eventHandlers.drag){this.isDragging=!0;let t=e.touches[0];this.lastPos={x:t.clientX,y:t.clientY}}return}this.isDragging=!1,this.isPinching=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};getTouchDistance(e){let t=e[1].clientX-e[0].clientX,r=e[1].clientY-e[0].clientY;return Math.sqrt(t*t+r*r)}getTouchCenter(e){return{x:(e[0].clientX+e[1].clientX)/2,y:(e[0].clientY+e[1].clientY)/2}}handleWheel=e=>{if(!this.config.get().eventHandlers.zoom)return;e.preventDefault();let t=this.canvas.getBoundingClientRect();this.camera.zoom(e.clientX,e.clientY,e.deltaY,t),this.onCameraChange()}};var B=class{constructor(e,t,r,i,n,s){this.wrapper=e;this.canvas=t;this.viewport=r;this.camera=i;this.config=n;this.onCameraChange=s;this.currentDpr=this.viewport.dpr}resizeObserver;handleWindowResize;currentDpr;onResize;start(){this.viewport.updateDpr(),this.currentDpr=this.viewport.dpr;let e=this.viewport.getSize(),t=this.config.get().size,r=t?.maxWidth,i=t?.maxHeight,n=t?.minWidth,s=t?.minHeight;e.width=this.clamp(e.width,n,r),e.height=this.clamp(e.height,s,i),Object.assign(this.wrapper.style,{resize:"both",overflow:"hidden",width:`${e.width}px`,height:`${e.height}px`,touchAction:"none",position:"relative",maxWidth:r?`${r}px`:"",maxHeight:i?`${i}px`:"",minWidth:n?`${n}px`:"",minHeight:s?`${s}px`:""}),this.resizeObserver=new ResizeObserver(a=>{for(let o of a){let{width:l,height:c}=o.contentRect,h=this.clamp(l,n,r),v=this.clamp(c,s,i),u=this.viewport.getSize();if(h===u.width&&v===u.height)continue;let d=h-u.width,m=v-u.height,C=this.viewport.dpr;this.camera.adjustForResize(d,m),this.viewport.setSize(h,v),this.canvas.width=h*C,this.canvas.height=v*C,this.canvas.style.width=`${h}px`,this.canvas.style.height=`${v}px`,this.wrapper.style.width=`${h}px`,this.wrapper.style.height=`${v}px`,this.onResize&&this.onResize(),this.onCameraChange()}}),this.resizeObserver.observe(this.wrapper),this.attachDprWatcher()}stop(){this.resizeObserver&&(this.resizeObserver.unobserve(this.wrapper),this.resizeObserver.disconnect()),this.resizeObserver=void 0,this.handleWindowResize&&(window.removeEventListener("resize",this.handleWindowResize),this.handleWindowResize=void 0)}clamp(e,t,r){let i=e;return t!==void 0&&(i=Math.max(t,i)),r!==void 0&&(i=Math.min(r,i)),i}attachDprWatcher(){typeof window>"u"||(this.handleWindowResize=()=>{let e=this.currentDpr;this.viewport.updateDpr();let t=this.viewport.dpr;if(t===e)return;this.currentDpr=t;let{width:r,height:i}=this.viewport.getSize();this.canvas.width=r*t,this.canvas.height=i*t,this.canvas.style.width=`${r}px`,this.canvas.style.height=`${i}px`,this.onResize&&this.onResize(),this.onCameraChange()},window.addEventListener("resize",this.handleWindowResize,{passive:!0}))}};var N=class{constructor(e,t,r,i,n,s,a){this.canvasWrapper=e;this.canvas=t;this.camera=r;this.viewport=i;this.config=n;this.coordinateTransformer=s;this.onCameraChange=a;this.gestures=new X(this.canvas,this.camera,this.viewport,this.config,this.coordinateTransformer,this.onCameraChange),this.binder=new Y(this.canvas,{click:this.gestures.handleClick,mousedown:this.gestures.handleMouseDown,mousemove:this.gestures.handleMouseMove,mouseup:this.gestures.handleMouseUp,mouseleave:this.gestures.handleMouseLeave,wheel:this.gestures.handleWheel,touchstart:this.gestures.handleTouchStart,touchmove:this.gestures.handleTouchMove,touchend:this.gestures.handleTouchEnd})}binder;gestures;resizeWatcher;attached=!1;onResize;get onClick(){return this.gestures.onClick}set onClick(e){this.gestures.onClick=e}get onHover(){return this.gestures.onHover}set onHover(e){this.gestures.onHover=e}get onMouseDown(){return this.gestures.onMouseDown}set onMouseDown(e){this.gestures.onMouseDown=e}get onMouseUp(){return this.gestures.onMouseUp}set onMouseUp(e){this.gestures.onMouseUp=e}get onMouseLeave(){return this.gestures.onMouseLeave}set onMouseLeave(e){this.gestures.onMouseLeave=e}setupEvents(){this.attached||(this.binder.attach(),this.attached=!0,this.config.get().eventHandlers.resize&&this.camera instanceof D&&(this.resizeWatcher=new B(this.canvasWrapper,this.canvas,this.viewport,this.camera,this.config,this.onCameraChange),this.resizeWatcher.onResize=()=>{this.onResize&&this.onResize()},this.resizeWatcher.start()))}destroy(){this.attached&&(this.binder.detach(),this.resizeWatcher?.stop(),this.resizeWatcher=void 0,this.attached=!1)}};var U=class{cache=new Map;inflight=new Map;listeners=new Set;onLoad(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notifyLoaded(){for(let e of this.listeners)e()}async load(e,t=w.IMAGE_LOAD_RETRY_COUNT){if(this.cache.has(e))return this.cache.get(e);if(this.inflight.has(e))return this.inflight.get(e);let r=new Promise((i,n)=>{let s=new Image;s.crossOrigin="anonymous",s.decoding="async",s.loading="eager",s.onload=async()=>{try{"decode"in s&&await s.decode?.()}catch{}this.cache.set(e,s),this.inflight.delete(e),this.notifyLoaded(),i(s)},s.onerror=a=>{if(this.inflight.delete(e),t>0)console.warn(`Retrying image: ${e}`),i(this.load(e,t-1));else{console.error(`Image failed to load: ${e}`,a);let o=a instanceof Error?a.message:typeof a=="string"?a:JSON.stringify(a);n(new Error(`Image failed to load: ${e}. Reason: ${o}`))}},s.src=e});return this.inflight.set(e,r),r}get(e){return this.cache.get(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear(),this.inflight.clear(),this.listeners.clear()}};var V=class{layers=new Map;add(e,t){let r=Symbol("layer-callback"),i={id:r,fn:t};return this.layers.has(e)||this.layers.set(e,[]),this.layers.get(e).push(i),{layer:e,id:r}}remove(e){let t=this.layers.get(e.layer);t&&this.layers.set(e.layer,t.filter(r=>r.id!==e.id))}clear(e){if(e===void 0){this.layers.clear();return}this.layers.set(e,[])}drawAll(e){let t=[...this.layers.keys()].sort((r,i)=>r-i);for(let r of t){let i=this.layers.get(r);if(i)for(let{fn:n}of i)e.ctx.save(),n(e),e.ctx.restore()}}};var $=class{width;height;_dpr;constructor(e,t){this.width=e,this.height=t,this._dpr=typeof window<"u"&&window.devicePixelRatio||1}getSize(){return{width:this.width,height:this.height}}setSize(e,t){this.width=e,this.height=t}get dpr(){return this._dpr}updateDpr(){this._dpr=typeof window<"u"&&window.devicePixelRatio||1}};var j=class{ctx;camera;config;viewport;constructor(e,t,r,i){this.ctx=e,this.camera=t,this.config=r,this.viewport=i}draw(){this.ctx.save(),this.ctx.fillStyle=`rgba(0, 0, 0, ${x.BORDER_OPACITY})`;let{width:e,height:t}=this.viewport.getSize();this.ctx.fillRect(0,0,x.BORDER_WIDTH,t),this.ctx.fillRect(x.BORDER_WIDTH,t-x.BORDER_WIDTH,e,x.BORDER_WIDTH),this.ctx.fillStyle=`rgba(255, 255, 255, ${x.TEXT_OPACITY})`;let r=Math.min(x.MAX_FONT_SIZE,Math.max(x.MIN_FONT_SIZE,this.camera.scale*x.FONT_SIZE_SCALE_FACTOR));this.ctx.font=`${r}px Arial`,this.ctx.textAlign="center",this.ctx.textBaseline="middle";let i=this.camera.scale,n=e/i,s=t/i;for(let a=0-this.camera.y%1;a<=s+1;a++)this.ctx.fillText(Math.round(this.camera.y+a).toString(),10,i*a+i/2);for(let a=0-this.camera.x%1;a<=n+1;a++)this.ctx.fillText(Math.round(this.camera.x+a).toString(),i*a+i/2,t-10);this.ctx.restore()}shouldDraw(e){let t=this.config.get().coordinates;if(!t.enabled||!t.shownScaleRange)return!1;let{min:r,max:i}=t.shownScaleRange;return e>=r&&e<=i}};var pe=10,H=class{ctx;camera;transformer;config;viewport;frameTimes=[];lastFrameTime=0;currentFps=0;fpsLoopRunning=!1;onFpsUpdate=null;constructor(e,t,r,i,n){this.ctx=e,this.camera=t,this.transformer=r,this.config=i,this.viewport=n}setFpsUpdateCallback(e){this.onFpsUpdate=e}startFpsLoop(){this.fpsLoopRunning||(this.fpsLoopRunning=!0,this.lastFrameTime=performance.now(),this.fpsLoop())}stopFpsLoop(){this.fpsLoopRunning=!1}fpsLoop(){if(!this.fpsLoopRunning)return;let e=performance.now(),t=e-this.lastFrameTime;this.lastFrameTime=e,this.frameTimes.push(t),this.frameTimes.length>pe&&this.frameTimes.shift();let r=this.frameTimes.reduce((n,s)=>n+s,0)/this.frameTimes.length,i=Math.round(1e3/r);i!==this.currentFps&&(this.currentFps=i,this.onFpsUpdate?.()),requestAnimationFrame(()=>this.fpsLoop())}draw(){this.drawHud()}destroy(){this.stopFpsLoop(),this.onFpsUpdate=null}drawHud(){let e=this.config.get();if(!e.debug.hud||!e.debug.hud.enabled)return;let t=[],r={x:this.camera.x,y:this.camera.y};if(e.debug.hud.topLeftCoordinates&&t.push(`TopLeft: ${r.x.toFixed(2)}, ${r.y.toFixed(2)}`),e.debug.hud.coordinates){let{width:n,height:s}=this.viewport.getSize(),a=this.camera.getCenter(n,s);t.push(`Coords: ${a.x.toFixed(2)}, ${a.y.toFixed(2)}`)}if(e.debug.hud.scale&&t.push(`Scale: ${this.camera.scale.toFixed(2)}`),e.debug.hud.tilesInView){let{width:n,height:s}=this.viewport.getSize();t.push(`Tiles in view: ${Math.ceil(n/this.camera.scale)} x ${Math.ceil(s/this.camera.scale)}`)}e.debug.hud.fps&&t.push(`FPS: ${this.currentFps}`);let{width:i}=this.viewport.getSize();this.ctx.save(),this.ctx.fillStyle="rgba(0,0,0,0.5)",this.ctx.fillRect(i-T.PANEL_WIDTH-T.PADDING,T.PADDING/2,T.PANEL_WIDTH,t.length*T.LINE_HEIGHT+T.PADDING),this.ctx.fillStyle="#00ff99",this.ctx.font="12px monospace";for(let n=0;n<t.length;n++)this.ctx.fillText(t[n],i-T.PANEL_WIDTH-T.PADDING+5,18+n*T.LINE_HEIGHT);this.ctx.restore()}};var M=class{constructor(e,t,r,i,n,s){this.canvas=e;this.camera=t;this.coordinateTransformer=r;this.config=i;this.viewport=n;this.layers=s;let a=e.getContext("2d");if(!a)throw new Error("Failed to get 2D canvas context");this.ctx=a,this.applyCanvasSize(),this.coordinateOverlayRenderer=new j(this.ctx,this.camera,this.config,this.viewport),this.config.get().debug?.enabled&&(this.debugOverlay=new H(this.ctx,this.camera,this.coordinateTransformer,this.config,this.viewport),this.config.get().debug?.hud?.fps&&(this.debugOverlay.setFpsUpdateCallback(()=>this.render()),this.debugOverlay.startFpsLoop()))}ctx;coordinateOverlayRenderer;debugOverlay;onDraw;init(){this.applyCanvasSize()}applyCanvasSize(){let e=this.viewport.getSize(),t=this.viewport.dpr;this.canvas.width=e.width*t,this.canvas.height=e.height*t,this.canvas.style.width=`${e.width}px`,this.canvas.style.height=`${e.height}px`,this.ctx.setTransform(t,0,0,t,0,0)}render(){let e=this.viewport.getSize(),t=this.viewport.dpr,r={...this.config.get(),size:{...e},scale:this.camera.scale},i={x:this.camera.x,y:this.camera.y};this.ctx.setTransform(t,0,0,t,0,0),this.ctx.clearRect(0,0,r.size.width,r.size.height),this.ctx.fillStyle=r.backgroundColor,this.ctx.fillRect(0,0,r.size.width,r.size.height),this.layers.drawAll({ctx:this.ctx,camera:this.camera,transformer:this.coordinateTransformer,config:r,topLeft:i}),this.onDraw?.(this.ctx,{scale:this.camera.scale,width:r.size.width,height:r.size.height,coords:i}),this.coordinateOverlayRenderer.shouldDraw(this.camera.scale)&&this.coordinateOverlayRenderer.draw(),r.debug?.enabled&&(this.debugOverlay||(this.debugOverlay=new H(this.ctx,this.camera,this.coordinateTransformer,this.config,this.viewport),r.debug?.hud?.fps&&(this.debugOverlay.setFpsUpdateCallback(()=>this.render()),this.debugOverlay.startFpsLoop())),this.debugOverlay.draw())}resize(e,t){let r=this.viewport.dpr;this.viewport.setSize(e,t),this.canvas.width=e*r,this.canvas.height=t*r,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.ctx.setTransform(r,0,0,r,0,0)}destroy(){this.debugOverlay&&(this.debugOverlay.destroy(),this.debugOverlay=void 0),this.layers.clear()}getContext(){return this.ctx}};var G=class{canvasWrapper;canvas;camera;viewport;renderer;config;onSizeApplied;constructor(e,t,r,i,n,s,a){this.canvasWrapper=e,this.canvas=t,this.camera=r,this.renderer=i,this.viewport=n,this.config=s,this.onSizeApplied=a}resizeWithAnimation(e,t,r,i,n){if(e<=0||t<=0)return;let s=this.config.get().size,a=(o,l,c)=>{let h=o;return l!==void 0&&(h=Math.max(l,h)),c!==void 0&&(h=Math.min(c,h)),h};e=a(e,s?.minWidth,s?.maxWidth),t=a(t,s?.minHeight,s?.maxHeight),i.animateResize(e,t,r,(o,l,c)=>this.applySize(o,l,c),n)}applySize(e,t,r){let i=Math.round(e),n=Math.round(t),s=this.viewport.dpr;this.viewport.setSize(i,n),this.canvasWrapper.style.width=`${i}px`,this.canvasWrapper.style.height=`${n}px`,this.canvas.width=i*s,this.canvas.height=n*s,this.canvas.style.width=`${i}px`,this.canvas.style.height=`${n}px`,this.camera.setCenter(r,i,n),this.renderer.resize(i,n),this.onSizeApplied()}};var q=class{constructor(e,t,r){this.camera=e;this.viewport=t;this.onAnimationFrame=r}moveAnimationId;resizeAnimationId;animateMoveTo(e,t,r=w.ANIMATION_DURATION_MS,i){if(this.cancelMove(),r<=0){let l=this.viewport.getSize();this.camera.setCenter({x:e,y:t},l.width,l.height),this.onAnimationFrame(),i?.();return}let n=this.viewport.getSize(),s=this.camera.getCenter(n.width,n.height),a=performance.now(),o=l=>{let c=l-a,h=Math.min(1,c/r),v=h<.5?2*h*h:1-Math.pow(-2*h+2,2)/2,u=s.x+(e-s.x)*v,d=s.y+(t-s.y)*v,m=this.viewport.getSize();this.camera.setCenter({x:u,y:d},m.width,m.height),this.onAnimationFrame(),h<1?this.moveAnimationId=requestAnimationFrame(o):(this.moveAnimationId=void 0,i?.())};this.moveAnimationId=requestAnimationFrame(o)}animateResize(e,t,r=w.ANIMATION_DURATION_MS,i,n){if(e<=0||t<=0)return;this.cancelResize();let s=this.viewport.getSize(),a=this.camera.getCenter(s.width,s.height);if(r<=0){i(e,t,a),n?.();return}let o=s.width,l=s.height,c=e-s.width,h=t-s.height,v=performance.now(),u=d=>{let m=d-v,C=Math.min(1,m/r),f=o+c*C,y=l+h*C;i(f,y,a),C<1?this.resizeAnimationId=requestAnimationFrame(u):(this.resizeAnimationId=void 0,n?.())};this.resizeAnimationId=requestAnimationFrame(u)}cancelMove(){this.moveAnimationId!==void 0&&(cancelAnimationFrame(this.moveAnimationId),this.moveAnimationId=void 0)}cancelResize(){this.resizeAnimationId!==void 0&&(cancelAnimationFrame(this.resizeAnimationId),this.resizeAnimationId=void 0)}cancelAll(){this.cancelMove(),this.cancelResize()}isAnimating(){return this.moveAnimationId!==void 0||this.resizeAnimationId!==void 0}};var Z=class{static createRenderer(e,t,r,i,n,s,a){switch(e){case"canvas":return new M(t,r,i,n,s,a);default:throw new Error(`Unsupported renderer type: ${e}`)}}static isSupported(e){return e==="canvas"}static getSupportedTypes(){return["canvas"]}};var J=class{config;camera;viewport;coordinateTransformer;layers;renderer;events;draw;images;sizeController;animationController;canvasWrapper;canvas;onCoordsChange;_onClick;get onClick(){return this._onClick}set onClick(e){this._onClick=e,this.events.onClick=e}_onHover;get onHover(){return this._onHover}set onHover(e){this._onHover=e,this.events.onHover=e}_onMouseDown;get onMouseDown(){return this._onMouseDown}set onMouseDown(e){this._onMouseDown=e,this.events.onMouseDown=e}_onMouseUp;get onMouseUp(){return this._onMouseUp}set onMouseUp(e){this._onMouseUp=e,this.events.onMouseUp=e}_onMouseLeave;get onMouseLeave(){return this._onMouseLeave}set onMouseLeave(e){this._onMouseLeave=e,this.events.onMouseLeave=e}_onDraw;get onDraw(){return this._onDraw}set onDraw(e){this._onDraw=e,this.getCanvasRenderer().onDraw=e}_onResize;get onResize(){return this._onResize}set onResize(e){this._onResize=e,this.events.onResize=e}constructor(e,t,r={x:0,y:0}){this.canvasWrapper=e,this.canvas=e.querySelector("canvas"),this.canvasWrapper.style.position="relative",this.canvasWrapper.style.width=t.size.width+"px",this.canvasWrapper.style.height=t.size.height+"px",this.canvas.style.position="absolute",this.config=new F(t);let i=t.renderer??"canvas",n={x:r.x-t.size.width/(2*t.scale),y:r.y-t.size.height/(2*t.scale)};this.viewport=new $(t.size.width,t.size.height),this.camera=new D(n,this.config.get().scale,this.config.get().minScale,this.config.get().maxScale,this.viewport),this.coordinateTransformer=new W(this.camera),this.animationController=new q(this.camera,this.viewport,()=>this.handleCameraChange()),this.renderer=this.createRenderer(i),this.images=new U,this.events=new N(this.canvasWrapper,this.canvas,this.camera,this.viewport,this.config,this.coordinateTransformer,()=>this.handleCameraChange()),this.sizeController=new G(this.canvasWrapper,this.canvas,this.camera,this.renderer,this.viewport,this.config,()=>this.handleCameraChange()),this.events.setupEvents(),t.bounds&&this.camera.setBounds(t.bounds)}destroy(){this.events.destroy(),this.animationController.cancelAll(),this.draw?.destroy(),this.layers?.clear(),this.images.clear(),this.renderer.destroy()}render(){this.renderer.render()}resize(e,t,r=500,i){this.sizeController.resizeWithAnimation(e,t,r,this.animationController,()=>{this._onResize?.(),i?.()})}getSize(){return this.viewport.getSize()}getScale(){return this.camera.scale}zoomIn(e=1.5){let t=this.viewport.getSize();this.camera.zoomByFactor(e,t.width/2,t.height/2),this.handleCameraChange()}zoomOut(e=1.5){let t=this.viewport.getSize();this.camera.zoomByFactor(1/e,t.width/2,t.height/2),this.handleCameraChange()}getConfig(){let e=this.config.get(),t=this.viewport.getSize();return{...e,scale:this.camera.scale,size:{...t}}}getCenterCoords(){let e=this.viewport.getSize();return this.camera.getCenter(e.width,e.height)}updateCoords(e){let t=this.viewport.getSize();this.camera.setCenter(e,t.width,t.height),this.handleCameraChange()}goCoords(e,t,r=500,i){this.animationController.animateMoveTo(e,t,r,i)}setEventHandlers(e){this.config.updateEventHandlers(e)}setBounds(e){this.config.updateBounds(e),this.camera.setBounds(e),this.render()}addDrawFunction(e,t=1){return this.ensureCanvasDraw().addDrawFunction(e,t)}drawRect(e,t=1){return this.ensureCanvasDraw().drawRect(e,t)}drawStaticRect(e,t,r=1){return this.ensureCanvasDraw().drawStaticRect(e,t,r)}drawStaticCircle(e,t,r=1){return this.ensureCanvasDraw().drawStaticCircle(e,t,r)}drawStaticImage(e,t,r=1){return this.ensureCanvasDraw().drawStaticImage(e,t,r)}clearStaticCache(e){this.ensureCanvasDraw().clearStaticCache(e)}drawLine(e,t,r=1){return this.ensureCanvasDraw().drawLine(e,t,r)}drawCircle(e,t=1){return this.ensureCanvasDraw().drawCircle(e,t)}drawText(e,t,r=2){return this.ensureCanvasDraw().drawText(e,t,r)}drawPath(e,t,r=1){return this.ensureCanvasDraw().drawPath(e,t,r)}drawImage(e,t=1){return this.ensureCanvasDraw().drawImage(e,t)}drawGridLines(e,t=1,r="black",i=0){return this.ensureCanvasDraw().drawGridLines(e,{lineWidth:t,strokeStyle:r},i)}removeLayerHandle(e){if(!this.layers)throw new Error("removeLayerHandle is only available when renderer is set to 'canvas'.");this.layers.remove(e)}clearLayer(e){if(!this.layers)throw new Error("clearLayer is only available when renderer is set to 'canvas'.");this.layers.clear(e)}clearAll(){if(!this.layers)throw new Error("clearAll is only available when renderer is set to 'canvas'.");this.layers.clear()}createRenderer(e){return e==="canvas"&&(this.layers=new V,this.draw=new P(this.layers,this.coordinateTransformer,this.camera)),Z.createRenderer(e??"canvas",this.canvas,this.camera,this.coordinateTransformer,this.config,this.viewport,this.layers)}ensureCanvasDraw(){if(!this.draw)throw new Error("Draw helpers are only available when renderer is set to 'canvas'.");return this.draw}getCanvasRenderer(){if(!(this.renderer instanceof M))throw new Error("Canvas renderer required for this operation.");return this.renderer}handleCameraChange(){this.onCoordsChange&&this.onCoordsChange(this.getCenterCoords()),this.render()}};0&&(module.exports={COORDINATE_OVERLAY,CanvasTileEngine,DEBUG_HUD,DEFAULT_VALUES,RENDER_DEFAULTS,SCALE_LIMITS,SIZE_LIMITS,VISIBILITY_BUFFER});
|
|
1
|
+
"use strict";var le=Object.create;var z=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var de=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var ue=(p,e)=>{for(var t in e)z(p,t,{get:e[t],enumerable:!0})},te=(p,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ce(e))!me.call(p,r)&&r!==t&&z(p,r,{get:()=>e[r],enumerable:!(i=he(e,r))||i.enumerable});return p};var ve=(p,e,t)=>(t=p!=null?le(de(p)):{},te(e||!p||!p.__esModule?z(t,"default",{value:p,enumerable:!0}):t,p)),fe=p=>te(z({},"__esModule",{value:!0}),p);var ge={};ue(ge,{COORDINATE_OVERLAY:()=>x,CanvasTileEngine:()=>J,DEBUG_HUD:()=>T,DEFAULT_VALUES:()=>b,RENDER_DEFAULTS:()=>O,SCALE_LIMITS:()=>A,SIZE_LIMITS:()=>M,VISIBILITY_BUFFER:()=>S});module.exports=fe(ge);var b={ANIMATION_DURATION_MS:500,CELL_CENTER_OFFSET:.5,IMAGE_LOAD_RETRY_COUNT:1,MAX_WHEEL_DELTA:100,MIN_WHEEL_DELTA:-100,ZOOM_SENSITIVITY:.001},A={MIN_SCALE_MULTIPLIER:.5,MAX_SCALE_MULTIPLIER:2},M={MIN_WIDTH:100,MIN_HEIGHT:100,MAX_WIDTH:1/0,MAX_HEIGHT:1/0},O={BACKGROUND_COLOR:"#ffffff",RENDERER_TYPE:"canvas"},x={BORDER_WIDTH:20,TEXT_OPACITY:.8,BORDER_OPACITY:.1,MIN_FONT_SIZE:8,MAX_FONT_SIZE:12,FONT_SIZE_SCALE_FACTOR:.25},T={PANEL_WIDTH:160,PADDING:8,LINE_HEIGHT:16},S={TILE_BUFFER:1};function ie(p,e,t,i){return{x:p.x-t/e,y:p.y-i/e}}function re(p,e,t,i,r,s){let n=Math.min(Math.max(t,b.MIN_WHEEL_DELTA),b.MAX_WHEEL_DELTA),a=Math.exp(-n*b.ZOOM_SENSITIVITY),o=Math.min(r,Math.max(i,e*a));return o===e?{topLeft:p,scale:e}:{topLeft:{x:p.x+s.x*(1/e-1/o),y:p.y+s.y*(1/e-1/o)},scale:o}}function ne(p,e){return{x:(p.x+b.CELL_CENTER_OFFSET-e.x)*e.scale,y:(p.y+b.CELL_CENTER_OFFSET-e.y)*e.scale}}function se(p,e){return{x:e.x+p.x/e.scale,y:e.y+p.y/e.scale}}var R=class{_x;_y;_scale;minScale;maxScale;bounds;viewport;constructor(e,t=1,i=.1,r=10,s){this._x=e.x+b.CELL_CENTER_OFFSET,this._y=e.y+b.CELL_CENTER_OFFSET,this._scale=t,this.minScale=i,this.maxScale=r,this.viewport=s}setBounds(e){this.bounds=e,this.bounds&&this.clampToBounds()}clampToBounds(){if(!this.bounds||!this.viewport)return;let{width:e,height:t}=this.viewport.getSize(),i=e/this._scale,r=t/this._scale;this._x=this.clampAxis(this._x,i,this.bounds.minX,this.bounds.maxX),this._y=this.clampAxis(this._y,r,this.bounds.minY,this.bounds.maxY)}clampAxis(e,t,i,r){let s=r-i;return t>=s?i-(t-s)/2:e<i?i:e+t>r?r-t:e}get x(){return this._x}get y(){return this._y}get scale(){return this._scale}pan(e,t){let i=ie({x:this._x,y:this._y},this._scale,e,t);this._x=i.x,this._y=i.y,this.clampToBounds()}zoom(e,t,i,r){let s=e-r.left,n=t-r.top,a=re({x:this._x,y:this._y},this._scale,i,this.minScale,this.maxScale,{x:s,y:n});this._x=a.topLeft.x,this._y=a.topLeft.y,this._scale=a.scale,this.clampToBounds()}zoomByFactor(e,t,i){let r=Math.min(this.maxScale,Math.max(this.minScale,this._scale*e));r!==this._scale&&(this._x=this._x+t*(1/this._scale-1/r),this._y=this._y+i*(1/this._scale-1/r),this._scale=r,this.clampToBounds())}getCenter(e,t){return{x:this._x+e/(2*this._scale)-.5,y:this._y+t/(2*this._scale)-.5}}setCenter(e,t,i){this._x=e.x-t/(2*this._scale)+.5,this._y=e.y-i/(2*this._scale)+.5,this.clampToBounds()}adjustForResize(e,t){this._x-=e/(2*this._scale),this._y-=t/(2*this._scale),this.clampToBounds()}getVisibleBounds(e,t){let i=this._x-b.CELL_CENTER_OFFSET,r=this._y-b.CELL_CENTER_OFFSET,s=i+e/this._scale,n=r+t/this._scale;return{minX:Math.floor(i),maxX:Math.ceil(s),minY:Math.floor(r),maxY:Math.ceil(n)}}};var F=class{config;constructor(e){let t={renderer:O.RENDERER_TYPE,scale:e.scale,minScale:e.minScale??e.scale*A.MIN_SCALE_MULTIPLIER,maxScale:e.maxScale??e.scale*A.MAX_SCALE_MULTIPLIER,gridAligned:e.gridAligned??!1,size:{width:e.size.width,height:e.size.height,maxHeight:e.size.maxHeight??M.MAX_HEIGHT,maxWidth:e.size.maxWidth??M.MAX_WIDTH,minHeight:e.size.minHeight??M.MIN_HEIGHT,minWidth:e.size.minWidth??M.MIN_WIDTH},backgroundColor:e.backgroundColor??O.BACKGROUND_COLOR,eventHandlers:{click:e.eventHandlers?.click??!1,rightClick:e.eventHandlers?.rightClick??!1,hover:e.eventHandlers?.hover??!1,drag:e.eventHandlers?.drag??!1,zoom:e.eventHandlers?.zoom??!1,resize:e.eventHandlers?.resize??!1},bounds:e.bounds??{minX:-1/0,maxX:1/0,minY:-1/0,maxY:1/0},coordinates:{enabled:e.coordinates?.enabled??!1,shownScaleRange:e.coordinates?.shownScaleRange??{min:0,max:1/0}},cursor:{default:e.cursor?.default??"default",move:e.cursor?.move??"move"},debug:{enabled:e.debug?.enabled??!1,hud:{enabled:e.debug?.hud?.enabled??!1,topLeftCoordinates:e.debug?.hud?.topLeftCoordinates??!1,coordinates:e.debug?.hud?.coordinates??!1,scale:e.debug?.hud?.scale??!1,tilesInView:e.debug?.hud?.tilesInView??!1,fps:e.debug?.hud?.fps??!1},eventHandlers:{click:e.debug?.eventHandlers?.click??!0,hover:e.debug?.eventHandlers?.hover??!0,drag:e.debug?.eventHandlers?.drag??!0,zoom:e.debug?.eventHandlers?.zoom??!0,resize:e.debug?.eventHandlers?.resize??!0}}};this.config={...t,size:Object.freeze(t.size),eventHandlers:Object.freeze(t.eventHandlers),bounds:Object.freeze(t.bounds),coordinates:Object.freeze({...t.coordinates,shownScaleRange:Object.freeze(t.coordinates.shownScaleRange)}),cursor:Object.freeze(t.cursor),debug:Object.freeze({enabled:t.debug.enabled,hud:Object.freeze(t.debug.hud),eventHandlers:Object.freeze(t.debug.eventHandlers)})}}get(){let e=this.config;return{...e,size:{...e.size},eventHandlers:{...e.eventHandlers},bounds:{...e.bounds},coordinates:{...e.coordinates,shownScaleRange:{min:e.coordinates.shownScaleRange?.min??0,max:e.coordinates.shownScaleRange?.max??1/0}},cursor:{...e.cursor},debug:{...e.debug,hud:{...e.debug.hud},eventHandlers:{...e.debug.eventHandlers}}}}updateEventHandlers(e){this.config={...this.config,eventHandlers:Object.freeze({...this.config.eventHandlers,...e})}}updateBounds(e){this.config={...this.config,bounds:Object.freeze(e)}}};var W=class{constructor(e){this.camera=e}worldToScreen(e,t){return ne({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}screenToWorld(e,t){return se({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}};var ae=ve(require("rbush")),D=class p{tree;constructor(){this.tree=new ae.default}load(e){let t=e.map(i=>{let s=(typeof i.size=="number"?i.size:0)/2;return{minX:i.x-s,minY:i.y-s,maxX:i.x+s,maxY:i.y+s,item:i}});this.tree.load(t)}query(e,t,i,r){return this.tree.search({minX:e,minY:t,maxX:i,maxY:r}).map(n=>n.item)}clear(){this.tree.clear()}static fromArray(e){let t=new p;return t.load(e),t}};var ee=500,oe=16384,Y=class{constructor(e,t,i){this.layers=e;this.transformer=t;this.camera=i;this.staticCacheSupported=typeof OffscreenCanvas<"u"||typeof document<"u"}staticCaches=new Map;staticCacheSupported;warnedStaticCacheDisabled=!1;isVisible(e,t,i,r,s){let n=s.size.width/s.scale,a=s.size.height/s.scale,o=r.x-S.TILE_BUFFER,h=r.y-S.TILE_BUFFER,c=r.x+n+S.TILE_BUFFER,l=r.y+a+S.TILE_BUFFER;return e+i>=o&&e-i<=c&&t+i>=h&&t-i<=l}getViewportBounds(e,t){let i=t.size.width/t.scale,r=t.size.height/t.scale;return{minX:e.x-S.TILE_BUFFER,minY:e.y-S.TILE_BUFFER,maxX:e.x+i+S.TILE_BUFFER,maxY:e.y+r+S.TILE_BUFFER}}addDrawFunction(e,t=1){return this.layers.add(t,({ctx:i,config:r,topLeft:s})=>{e(i,s,r)})}drawRect(e,t=1){let i=Array.isArray(e)?e:[e],s=i.length>ee?D.fromArray(i):null;return this.layers.add(t,({ctx:n,config:a,topLeft:o})=>{let h=this.getViewportBounds(o,a),c=s?s.query(h.minX,h.minY,h.maxX,h.maxY):i;n.save();let l,f,u;for(let d of c){let m=d.size??1,C={mode:d.origin?.mode==="self"?"self":"cell",x:d.origin?.x??.5,y:d.origin?.y??.5},v=d.style;if(!s&&!this.isVisible(d.x,d.y,m/2,o,a))continue;let w=this.transformer.worldToScreen(d.x,d.y),g=m*this.camera.scale,{x:y,y:E}=this.computeOriginOffset(w,g,C,this.camera);v?.fillStyle&&v.fillStyle!==l&&(n.fillStyle=v.fillStyle,l=v.fillStyle),v?.strokeStyle&&v.strokeStyle!==f&&(n.strokeStyle=v.strokeStyle,f=v.strokeStyle),v?.lineWidth&&v.lineWidth!==u&&(n.lineWidth=v.lineWidth,u=v.lineWidth);let I=d.rotate??0,k=I*(Math.PI/180),L=d.radius;if(I!==0){let K=y+g/2,Q=E+g/2;n.save(),n.translate(K,Q),n.rotate(k),n.beginPath(),L&&n.roundRect?n.roundRect(-g/2,-g/2,g,g,L):n.rect(-g/2,-g/2,g,g),v?.fillStyle&&n.fill(),v?.strokeStyle&&n.stroke(),n.restore()}else n.beginPath(),L&&n.roundRect?n.roundRect(y,E,g,g,L):n.rect(y,E,g,g),v?.fillStyle&&n.fill(),v?.strokeStyle&&n.stroke()}n.restore()})}drawLine(e,t,i=1){let r=Array.isArray(e)?e:[e];return this.layers.add(i,({ctx:s,config:n,topLeft:a})=>{s.save(),t?.strokeStyle&&(s.strokeStyle=t.strokeStyle),t?.lineWidth&&(s.lineWidth=t.lineWidth),s.beginPath();for(let o of r){let h=(o.from.x+o.to.x)/2,c=(o.from.y+o.to.y)/2,l=Math.max(Math.abs(o.from.x-o.to.x),Math.abs(o.from.y-o.to.y))/2;if(!this.isVisible(h,c,l,a,n))continue;let f=this.transformer.worldToScreen(o.from.x,o.from.y),u=this.transformer.worldToScreen(o.to.x,o.to.y);s.moveTo(f.x,f.y),s.lineTo(u.x,u.y)}s.stroke(),s.restore()})}drawCircle(e,t=1){let i=Array.isArray(e)?e:[e],s=i.length>ee?D.fromArray(i):null;return this.layers.add(t,({ctx:n,config:a,topLeft:o})=>{let h=this.getViewportBounds(o,a),c=s?s.query(h.minX,h.minY,h.maxX,h.maxY):i;n.save();let l,f,u;for(let d of c){let m=d.size??1,C={mode:d.origin?.mode==="self"?"self":"cell",x:d.origin?.x??.5,y:d.origin?.y??.5},v=d.style;if(!s&&!this.isVisible(d.x,d.y,m/2,o,a))continue;let w=this.transformer.worldToScreen(d.x,d.y),g=m*this.camera.scale,y=g/2,{x:E,y:I}=this.computeOriginOffset(w,g,C,this.camera);v?.fillStyle&&v.fillStyle!==l&&(n.fillStyle=v.fillStyle,l=v.fillStyle),v?.strokeStyle&&v.strokeStyle!==f&&(n.strokeStyle=v.strokeStyle,f=v.strokeStyle),v?.lineWidth&&v.lineWidth!==u&&(n.lineWidth=v.lineWidth,u=v.lineWidth),n.beginPath(),n.arc(E+y,I+y,y,0,Math.PI*2),v?.fillStyle&&n.fill(),v?.strokeStyle&&n.stroke()}n.restore()})}drawText(e,t,i=2){let r=Array.isArray(e)?e:[e];return this.layers.add(i,({ctx:s,config:n,topLeft:a})=>{s.save(),t?.font&&(s.font=t.font),t?.fillStyle&&(s.fillStyle=t.fillStyle),s.textAlign=t?.textAlign??"center",s.textBaseline=t?.textBaseline??"middle";for(let o of r){if(!this.isVisible(o.coords.x,o.coords.y,0,a,n))continue;let h=this.transformer.worldToScreen(o.coords.x,o.coords.y);s.fillText(o.text,h.x,h.y)}s.restore()})}drawPath(e,t,i=1){let r=Array.isArray(e[0])?e:[e];return this.layers.add(i,({ctx:s,config:n,topLeft:a})=>{s.save(),t?.strokeStyle&&(s.strokeStyle=t.strokeStyle),t?.lineWidth&&(s.lineWidth=t.lineWidth),s.beginPath();for(let o of r){if(!o.length)continue;let h=o.map(g=>g.x),c=o.map(g=>g.y),l=Math.min(...h),f=Math.max(...h),u=Math.min(...c),d=Math.max(...c),m=(l+f)/2,C=(u+d)/2,v=Math.max(f-l,d-u)/2;if(!this.isVisible(m,C,v,a,n))continue;let w=this.transformer.worldToScreen(o[0].x,o[0].y);s.moveTo(w.x,w.y);for(let g=1;g<o.length;g++){let y=this.transformer.worldToScreen(o[g].x,o[g].y);s.lineTo(y.x,y.y)}}s.stroke(),s.restore()})}drawImage(e,t=1){let i=Array.isArray(e)?e:[e],s=i.length>ee?D.fromArray(i):null;return this.layers.add(t,({ctx:n,config:a,topLeft:o})=>{let h=this.getViewportBounds(o,a),c=s?s.query(h.minX,h.minY,h.maxX,h.maxY):i;for(let l of c){let f=l.size??1,u={mode:l.origin?.mode==="self"?"self":"cell",x:l.origin?.x??.5,y:l.origin?.y??.5};if(!s&&!this.isVisible(l.x,l.y,f/2,o,a))continue;let d=this.transformer.worldToScreen(l.x,l.y),m=f*this.camera.scale,C=l.img.width/l.img.height,v=m,w=m;C>1?w=m/C:v=m*C;let{x:g,y}=this.computeOriginOffset(d,m,u,this.camera),E=g+(m-v)/2,I=y+(m-w)/2,k=l.rotate??0,L=k*(Math.PI/180);if(k!==0){let K=E+v/2,Q=I+w/2;n.save(),n.translate(K,Q),n.rotate(L),n.drawImage(l.img,-v/2,-w/2,v,w),n.restore()}else n.drawImage(l.img,E,I,v,w)}})}drawGridLines(e,t,i=0){return this.layers.add(i,({ctx:r,config:s,topLeft:n})=>{let a=s.size.width/s.scale,o=s.size.height/s.scale,h=Math.floor(n.x/e)*e-b.CELL_CENTER_OFFSET,c=Math.ceil((n.x+a)/e)*e-b.CELL_CENTER_OFFSET,l=Math.floor(n.y/e)*e-b.CELL_CENTER_OFFSET,f=Math.ceil((n.y+o)/e)*e-b.CELL_CENTER_OFFSET;r.save(),r.strokeStyle=t.strokeStyle,r.lineWidth=t.lineWidth,r.beginPath();for(let u=h;u<=c;u+=e){let d=this.transformer.worldToScreen(u,l),m=this.transformer.worldToScreen(u,f);r.moveTo(d.x,d.y),r.lineTo(m.x,m.y)}for(let u=l;u<=f;u+=e){let d=this.transformer.worldToScreen(h,u),m=this.transformer.worldToScreen(c,u);r.moveTo(d.x,d.y),r.lineTo(m.x,m.y)}r.stroke(),r.restore()})}computeOriginOffset(e,t,i,r){if(i.mode==="cell"){let s=r.scale;return{x:e.x-s/2+i.x*s-t/2,y:e.y-s/2+i.y*s-t/2}}return{x:e.x-i.x*t,y:e.y-i.y*t}}getOrCreateStaticCache(e,t,i){if(!this.staticCacheSupported)return this.warnedStaticCacheDisabled||(console.warn("[CanvasDraw] Static cache disabled: OffscreenCanvas not available."),this.warnedStaticCacheDisabled=!0),null;let r=1/0,s=-1/0,n=1/0,a=-1/0;for(let m of e){let C=m.size??1;m.x-C/2<r&&(r=m.x-C/2),m.x+C/2>s&&(s=m.x+C/2),m.y-C/2<n&&(n=m.y-C/2),m.y+C/2>a&&(a=m.y+C/2)}r-=1,n-=1,s+=1,a+=1;let o=s-r,h=a-n,c=this.camera.scale,l=Math.ceil(o*c),f=Math.ceil(h*c);if(l>oe||f>oe)return this.warnedStaticCacheDisabled||(console.warn(`Static cache disabled: offscreen canvas too large (${l}x${f}).`),this.warnedStaticCacheDisabled=!0),null;let u=this.staticCaches.get(t);if(!u||u.scale!==c||u.worldBounds.minX!==r||u.worldBounds.maxX!==s||u.worldBounds.minY!==n||u.worldBounds.maxY!==a){let m=typeof OffscreenCanvas<"u"?new OffscreenCanvas(l,f):document.createElement("canvas");typeof OffscreenCanvas<"u"&&m instanceof OffscreenCanvas||(m.width=l,m.height=f);let v=m.getContext("2d");if(!v)return this.warnedStaticCacheDisabled||(console.warn("[CanvasDraw] Static cache disabled: 2D context unavailable."),this.warnedStaticCacheDisabled=!0),null;for(let w of e){let y=(w.size??1)*c,E=(w.x+b.CELL_CENTER_OFFSET-r)*c-y/2,I=(w.y+b.CELL_CENTER_OFFSET-n)*c-y/2;i(v,w,E,I,y)}u={canvas:m,ctx:v,worldBounds:{minX:r,minY:n,maxX:s,maxY:a},scale:c},this.staticCaches.set(t,u)}return u||null}addStaticCacheLayer(e,t){if(!e)return null;let i=e.canvas,r=e.worldBounds,s=e.scale;return this.layers.add(t,({ctx:n,config:a,topLeft:o})=>{let h=a.size.width/a.scale,c=a.size.height/a.scale,l=(o.x-r.minX)*s,f=(o.y-r.minY)*s,u=h*s,d=c*s;n.drawImage(i,l,f,u,d,0,0,a.size.width,a.size.height)})}drawStaticRect(e,t,i=1){let r,s=this.getOrCreateStaticCache(e,t,(n,a,o,h,c)=>{let l=a.style,f=a.rotate??0,u=f*(Math.PI/180),d=a.radius;if(l?.fillStyle&&l.fillStyle!==r&&(n.fillStyle=l.fillStyle,r=l.fillStyle),f!==0){let m=o+c/2,C=h+c/2;n.save(),n.translate(m,C),n.rotate(u),d&&n.roundRect?(n.beginPath(),n.roundRect(-c/2,-c/2,c,c,d),n.fill()):n.fillRect(-c/2,-c/2,c,c),n.restore()}else d&&n.roundRect?(n.beginPath(),n.roundRect(o,h,c,c,d),n.fill()):n.fillRect(o,h,c,c)});return s?this.addStaticCacheLayer(s,i):this.drawRect(e,i)}drawStaticImage(e,t,i=1){let r=this.getOrCreateStaticCache(e,t,(s,n,a,o,h)=>{let c=n.img,l=n.rotate??0,f=l*(Math.PI/180),u=c.width/c.height,d=h,m=h;u>1?m=h/u:d=h*u;let C=a+(h-d)/2,v=o+(h-m)/2;if(l!==0){let w=C+d/2,g=v+m/2;s.save(),s.translate(w,g),s.rotate(f),s.drawImage(c,-d/2,-m/2,d,m),s.restore()}else s.drawImage(c,C,v,d,m)});return r?this.addStaticCacheLayer(r,i):this.drawImage(e,i)}drawStaticCircle(e,t,i=1){let r,s=this.getOrCreateStaticCache(e,t,(n,a,o,h,c)=>{let l=a.style,f=c/2;l?.fillStyle&&l.fillStyle!==r&&(n.fillStyle=l.fillStyle,r=l.fillStyle),n.beginPath(),n.arc(o+f,h+f,f,0,Math.PI*2),n.fill()});return s?this.addStaticCacheLayer(s,i):this.drawCircle(e,i)}clearStaticCache(e){e?this.staticCaches.delete(e):this.staticCaches.clear()}destroy(){this.staticCaches.clear(),this.layers.clear()}};var P=class{constructor(e,t){this.canvas=e;this.handlers=t}attach(){this.handlers.click&&this.canvas.addEventListener("click",this.handlers.click),this.handlers.contextmenu&&this.canvas.addEventListener("contextmenu",this.handlers.contextmenu),this.handlers.mousedown&&this.canvas.addEventListener("mousedown",this.handlers.mousedown),this.handlers.mousemove&&this.canvas.addEventListener("mousemove",this.handlers.mousemove),this.handlers.mouseup&&this.canvas.addEventListener("mouseup",this.handlers.mouseup),this.handlers.mouseleave&&this.canvas.addEventListener("mouseleave",this.handlers.mouseleave),this.handlers.wheel&&this.canvas.addEventListener("wheel",this.handlers.wheel,{passive:!1}),this.handlers.touchstart&&this.canvas.addEventListener("touchstart",this.handlers.touchstart,{passive:!1}),this.handlers.touchmove&&this.canvas.addEventListener("touchmove",this.handlers.touchmove,{passive:!1}),this.handlers.touchend&&this.canvas.addEventListener("touchend",this.handlers.touchend,{passive:!1})}detach(){this.handlers.click&&this.canvas.removeEventListener("click",this.handlers.click),this.handlers.contextmenu&&this.canvas.removeEventListener("contextmenu",this.handlers.contextmenu),this.handlers.mousedown&&this.canvas.removeEventListener("mousedown",this.handlers.mousedown),this.handlers.mousemove&&this.canvas.removeEventListener("mousemove",this.handlers.mousemove),this.handlers.mouseup&&this.canvas.removeEventListener("mouseup",this.handlers.mouseup),this.handlers.mouseleave&&this.canvas.removeEventListener("mouseleave",this.handlers.mouseleave),this.handlers.wheel&&this.canvas.removeEventListener("wheel",this.handlers.wheel),this.handlers.touchstart&&this.canvas.removeEventListener("touchstart",this.handlers.touchstart),this.handlers.touchmove&&this.canvas.removeEventListener("touchmove",this.handlers.touchmove),this.handlers.touchend&&this.canvas.removeEventListener("touchend",this.handlers.touchend)}};var X=class{constructor(e,t,i,r,s,n){this.canvas=e;this.camera=t;this.viewport=i;this.config=r;this.transformer=s;this.onCameraChange=n}isDragging=!1;shouldPreventClick=!1;lastPos={x:0,y:0};isPinching=!1;lastPinchDistance=0;lastPinchCenter={x:0,y:0};onClick;onRightClick;onHover;onMouseDown;onMouseUp;onMouseLeave;onZoom;getEventCoords=e=>{let t=this.canvas.getBoundingClientRect(),i=e.clientX-t.left,r=e.clientY-t.top,s=this.transformer.screenToWorld(i,r),n=this.transformer.worldToScreen(Math.floor(s.x),Math.floor(s.y));return{coords:{raw:s,snapped:{x:Math.floor(s.x),y:Math.floor(s.y)}},mouse:{raw:{x:i,y:r},snapped:{x:n.x,y:n.y}},client:{raw:{x:e.clientX,y:e.clientY},snapped:{x:n.x+t.left,y:n.y+t.top}}}};handleClick=e=>{if(this.shouldPreventClick){this.shouldPreventClick=!1;return}if(!this.config.get().eventHandlers.click||!this.onClick)return;let{coords:t,mouse:i,client:r}=this.getEventCoords(e);this.onClick(t,i,r)};handleContextMenu=e=>{if(!this.config.get().eventHandlers.rightClick||!this.onRightClick)return;e.preventDefault();let{coords:t,mouse:i,client:r}=this.getEventCoords(e);this.onRightClick(t,i,r)};handleMouseDown=e=>{if(this.onMouseDown){let{coords:t,mouse:i,client:r}=this.getEventCoords(e);this.onMouseDown(t,i,r)}this.config.get().eventHandlers.drag&&(this.isDragging=!0,this.shouldPreventClick=!1,this.lastPos={x:e.clientX,y:e.clientY})};handleMouseMove=e=>{if(!this.isDragging){if(this.onHover&&this.config.get().eventHandlers.hover){let{coords:r,mouse:s,client:n}=this.getEventCoords(e);this.onHover(r,s,n)}return}let t=e.clientX-this.lastPos.x,i=e.clientY-this.lastPos.y;(t!==0||i!==0)&&(this.canvas.style.cursor=this.config.get().cursor.move||"move",this.shouldPreventClick=!0),this.camera.pan(t,i),this.lastPos={x:e.clientX,y:e.clientY},this.onCameraChange()};handleMouseUp=e=>{if(this.onMouseUp){let{coords:t,mouse:i,client:r}=this.getEventCoords(e);this.onMouseUp(t,i,r)}this.isDragging=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};handleMouseLeave=e=>{if(this.onMouseLeave){let{coords:t,mouse:i,client:r}=this.getEventCoords(e);this.onMouseLeave(t,i,r)}this.isDragging=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};handleTouchStart=e=>{let t=this.config.get().eventHandlers;if(e.touches.length===2&&t.zoom){e.preventDefault(),this.isPinching=!0,this.isDragging=!1,this.lastPinchDistance=this.getTouchDistance(e.touches),this.lastPinchCenter=this.getTouchCenter(e.touches);return}if(!t.drag||e.touches.length!==1)return;let i=e.touches[0];this.isDragging=!0,this.isPinching=!1,this.shouldPreventClick=!1,this.lastPos={x:i.clientX,y:i.clientY}};handleTouchMove=e=>{if(this.isPinching&&e.touches.length===2){e.preventDefault();let s=this.getTouchDistance(e.touches),n=this.getTouchCenter(e.touches),a=this.canvas.getBoundingClientRect(),o=s/this.lastPinchDistance,h=n.x-a.left,c=n.y-a.top;this.camera.zoomByFactor(o,h,c);let l=n.x-this.lastPinchCenter.x,f=n.y-this.lastPinchCenter.y;(l!==0||f!==0)&&this.camera.pan(l,f),this.lastPinchDistance=s,this.lastPinchCenter=n,this.onZoom&&this.onZoom(this.camera.scale),this.onCameraChange();return}if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0],i=t.clientX-this.lastPos.x,r=t.clientY-this.lastPos.y;(i!==0||r!==0)&&(this.canvas.style.cursor=this.config.get().cursor.move||"move",this.shouldPreventClick=!0),this.camera.pan(i,r),this.lastPos={x:t.clientX,y:t.clientY},this.onCameraChange()};handleTouchEnd=e=>{if(e.touches.length>=2&&this.isPinching){this.lastPinchDistance=this.getTouchDistance(e.touches),this.lastPinchCenter=this.getTouchCenter(e.touches);return}if(e.touches.length===1&&this.isPinching){if(this.isPinching=!1,this.config.get().eventHandlers.drag){this.isDragging=!0;let t=e.touches[0];this.lastPos={x:t.clientX,y:t.clientY}}return}this.isDragging=!1,this.isPinching=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};getTouchDistance(e){let t=e[1].clientX-e[0].clientX,i=e[1].clientY-e[0].clientY;return Math.sqrt(t*t+i*i)}getTouchCenter(e){return{x:(e[0].clientX+e[1].clientX)/2,y:(e[0].clientY+e[1].clientY)/2}}handleWheel=e=>{if(!this.config.get().eventHandlers.zoom)return;e.preventDefault();let t=this.canvas.getBoundingClientRect();this.camera.zoom(e.clientX,e.clientY,e.deltaY,t),this.onZoom&&this.onZoom(this.camera.scale),this.onCameraChange()}};var B=class{constructor(e,t,i,r,s,n){this.wrapper=e;this.canvas=t;this.viewport=i;this.camera=r;this.config=s;this.onCameraChange=n;this.currentDpr=this.viewport.dpr}resizeObserver;handleWindowResize;currentDpr;onResize;start(){this.viewport.updateDpr(),this.currentDpr=this.viewport.dpr;let e=this.viewport.getSize(),t=this.config.get().size,i=t?.maxWidth,r=t?.maxHeight,s=t?.minWidth,n=t?.minHeight;e.width=this.clamp(e.width,s,i),e.height=this.clamp(e.height,n,r),Object.assign(this.wrapper.style,{resize:"both",overflow:"hidden",width:`${e.width}px`,height:`${e.height}px`,touchAction:"none",position:"relative",maxWidth:i?`${i}px`:"",maxHeight:r?`${r}px`:"",minWidth:s?`${s}px`:"",minHeight:n?`${n}px`:""}),this.resizeObserver=new ResizeObserver(a=>{for(let o of a){let{width:h,height:c}=o.contentRect,l=this.clamp(h,s,i),f=this.clamp(c,n,r),u=this.viewport.getSize();if(l===u.width&&f===u.height)continue;let d=l-u.width,m=f-u.height,C=this.viewport.dpr;this.camera.adjustForResize(d,m),this.viewport.setSize(l,f),this.canvas.width=l*C,this.canvas.height=f*C,this.canvas.style.width=`${l}px`,this.canvas.style.height=`${f}px`,this.wrapper.style.width=`${l}px`,this.wrapper.style.height=`${f}px`,this.onResize&&this.onResize(),this.onCameraChange()}}),this.resizeObserver.observe(this.wrapper),this.attachDprWatcher()}stop(){this.resizeObserver&&(this.resizeObserver.unobserve(this.wrapper),this.resizeObserver.disconnect()),this.resizeObserver=void 0,this.handleWindowResize&&(window.removeEventListener("resize",this.handleWindowResize),this.handleWindowResize=void 0)}clamp(e,t,i){let r=e;return t!==void 0&&(r=Math.max(t,r)),i!==void 0&&(r=Math.min(i,r)),r}attachDprWatcher(){typeof window>"u"||(this.handleWindowResize=()=>{let e=this.currentDpr;this.viewport.updateDpr();let t=this.viewport.dpr;if(t===e)return;this.currentDpr=t;let{width:i,height:r}=this.viewport.getSize();this.canvas.width=i*t,this.canvas.height=r*t,this.canvas.style.width=`${i}px`,this.canvas.style.height=`${r}px`,this.onResize&&this.onResize(),this.onCameraChange()},window.addEventListener("resize",this.handleWindowResize,{passive:!0}))}};var U=class{constructor(e,t,i,r,s,n,a){this.canvasWrapper=e;this.canvas=t;this.camera=i;this.viewport=r;this.config=s;this.coordinateTransformer=n;this.onCameraChange=a;this.gestures=new X(this.canvas,this.camera,this.viewport,this.config,this.coordinateTransformer,this.onCameraChange),this.binder=new P(this.canvas,{click:this.gestures.handleClick,contextmenu:this.gestures.handleContextMenu,mousedown:this.gestures.handleMouseDown,mousemove:this.gestures.handleMouseMove,mouseup:this.gestures.handleMouseUp,mouseleave:this.gestures.handleMouseLeave,wheel:this.gestures.handleWheel,touchstart:this.gestures.handleTouchStart,touchmove:this.gestures.handleTouchMove,touchend:this.gestures.handleTouchEnd})}binder;gestures;resizeWatcher;attached=!1;onResize;get onClick(){return this.gestures.onClick}set onClick(e){this.gestures.onClick=e}get onRightClick(){return this.gestures.onRightClick}set onRightClick(e){this.gestures.onRightClick=e}get onHover(){return this.gestures.onHover}set onHover(e){this.gestures.onHover=e}get onMouseDown(){return this.gestures.onMouseDown}set onMouseDown(e){this.gestures.onMouseDown=e}get onMouseUp(){return this.gestures.onMouseUp}set onMouseUp(e){this.gestures.onMouseUp=e}get onMouseLeave(){return this.gestures.onMouseLeave}set onMouseLeave(e){this.gestures.onMouseLeave=e}get onZoom(){return this.gestures.onZoom}set onZoom(e){this.gestures.onZoom=e}setupEvents(){this.attached||(this.binder.attach(),this.attached=!0,this.config.get().eventHandlers.resize&&this.camera instanceof R&&(this.resizeWatcher=new B(this.canvasWrapper,this.canvas,this.viewport,this.camera,this.config,this.onCameraChange),this.resizeWatcher.onResize=()=>{this.onResize&&this.onResize()},this.resizeWatcher.start()))}destroy(){this.attached&&(this.binder.detach(),this.resizeWatcher?.stop(),this.resizeWatcher=void 0,this.attached=!1)}};var N=class{cache=new Map;inflight=new Map;listeners=new Set;onLoad(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notifyLoaded(){for(let e of this.listeners)e()}async load(e,t=b.IMAGE_LOAD_RETRY_COUNT){if(this.cache.has(e))return this.cache.get(e);if(this.inflight.has(e))return this.inflight.get(e);let i=new Promise((r,s)=>{let n=new Image;n.crossOrigin="anonymous",n.decoding="async",n.loading="eager",n.onload=async()=>{try{"decode"in n&&await n.decode?.()}catch{}this.cache.set(e,n),this.inflight.delete(e),this.notifyLoaded(),r(n)},n.onerror=a=>{if(this.inflight.delete(e),t>0)console.warn(`Retrying image: ${e}`),r(this.load(e,t-1));else{console.error(`Image failed to load: ${e}`,a);let o=a instanceof Error?a.message:typeof a=="string"?a:JSON.stringify(a);s(new Error(`Image failed to load: ${e}. Reason: ${o}`))}},n.src=e});return this.inflight.set(e,i),i}get(e){return this.cache.get(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear(),this.inflight.clear(),this.listeners.clear()}};var V=class{layers=new Map;add(e,t){let i=Symbol("layer-callback"),r={id:i,fn:t};return this.layers.has(e)||this.layers.set(e,[]),this.layers.get(e).push(r),{layer:e,id:i}}remove(e){let t=this.layers.get(e.layer);t&&this.layers.set(e.layer,t.filter(i=>i.id!==e.id))}clear(e){if(e===void 0){this.layers.clear();return}this.layers.set(e,[])}drawAll(e){let t=[...this.layers.keys()].sort((i,r)=>i-r);for(let i of t){let r=this.layers.get(i);if(r)for(let{fn:s}of r)e.ctx.save(),s(e),e.ctx.restore()}}};var $=class{width;height;_dpr;constructor(e,t){this.width=e,this.height=t,this._dpr=typeof window<"u"&&window.devicePixelRatio||1}getSize(){return{width:this.width,height:this.height}}setSize(e,t){this.width=e,this.height=t}get dpr(){return this._dpr}updateDpr(){this._dpr=typeof window<"u"&&window.devicePixelRatio||1}};var Z=class{ctx;camera;config;viewport;constructor(e,t,i,r){this.ctx=e,this.camera=t,this.config=i,this.viewport=r}draw(){this.ctx.save(),this.ctx.fillStyle=`rgba(0, 0, 0, ${x.BORDER_OPACITY})`;let{width:e,height:t}=this.viewport.getSize();this.ctx.fillRect(0,0,x.BORDER_WIDTH,t),this.ctx.fillRect(x.BORDER_WIDTH,t-x.BORDER_WIDTH,e,x.BORDER_WIDTH),this.ctx.fillStyle=`rgba(255, 255, 255, ${x.TEXT_OPACITY})`;let i=Math.min(x.MAX_FONT_SIZE,Math.max(x.MIN_FONT_SIZE,this.camera.scale*x.FONT_SIZE_SCALE_FACTOR));this.ctx.font=`${i}px Arial`,this.ctx.textAlign="center",this.ctx.textBaseline="middle";let r=this.camera.scale,s=e/r,n=t/r;for(let a=0-this.camera.y%1;a<=n+1;a++)this.ctx.fillText(Math.round(this.camera.y+a).toString(),10,r*a+r/2);for(let a=0-this.camera.x%1;a<=s+1;a++)this.ctx.fillText(Math.round(this.camera.x+a).toString(),r*a+r/2,t-10);this.ctx.restore()}shouldDraw(e){let t=this.config.get().coordinates;if(!t.enabled||!t.shownScaleRange)return!1;let{min:i,max:r}=t.shownScaleRange;return e>=i&&e<=r}};var pe=10,H=class{ctx;camera;transformer;config;viewport;frameTimes=[];lastFrameTime=0;currentFps=0;fpsLoopRunning=!1;onFpsUpdate=null;constructor(e,t,i,r,s){this.ctx=e,this.camera=t,this.transformer=i,this.config=r,this.viewport=s}setFpsUpdateCallback(e){this.onFpsUpdate=e}startFpsLoop(){this.fpsLoopRunning||(this.fpsLoopRunning=!0,this.lastFrameTime=performance.now(),this.fpsLoop())}stopFpsLoop(){this.fpsLoopRunning=!1}fpsLoop(){if(!this.fpsLoopRunning)return;let e=performance.now(),t=e-this.lastFrameTime;this.lastFrameTime=e,this.frameTimes.push(t),this.frameTimes.length>pe&&this.frameTimes.shift();let i=this.frameTimes.reduce((s,n)=>s+n,0)/this.frameTimes.length,r=Math.round(1e3/i);r!==this.currentFps&&(this.currentFps=r,this.onFpsUpdate?.()),requestAnimationFrame(()=>this.fpsLoop())}draw(){this.drawHud()}destroy(){this.stopFpsLoop(),this.onFpsUpdate=null}drawHud(){let e=this.config.get();if(!e.debug.hud||!e.debug.hud.enabled)return;let t=[],i={x:this.camera.x,y:this.camera.y};if(e.debug.hud.topLeftCoordinates&&t.push(`TopLeft: ${i.x.toFixed(2)}, ${i.y.toFixed(2)}`),e.debug.hud.coordinates){let{width:s,height:n}=this.viewport.getSize(),a=this.camera.getCenter(s,n);t.push(`Coords: ${a.x.toFixed(2)}, ${a.y.toFixed(2)}`)}if(e.debug.hud.scale&&t.push(`Scale: ${this.camera.scale.toFixed(2)}`),e.debug.hud.tilesInView){let{width:s,height:n}=this.viewport.getSize();t.push(`Tiles in view: ${Math.ceil(s/this.camera.scale)} x ${Math.ceil(n/this.camera.scale)}`)}e.debug.hud.fps&&t.push(`FPS: ${this.currentFps}`);let{width:r}=this.viewport.getSize();this.ctx.save(),this.ctx.fillStyle="rgba(0,0,0,0.5)",this.ctx.fillRect(r-T.PANEL_WIDTH-T.PADDING,T.PADDING/2,T.PANEL_WIDTH,t.length*T.LINE_HEIGHT+T.PADDING),this.ctx.fillStyle="#00ff99",this.ctx.font="12px monospace";for(let s=0;s<t.length;s++)this.ctx.fillText(t[s],r-T.PANEL_WIDTH-T.PADDING+5,18+s*T.LINE_HEIGHT);this.ctx.restore()}};var _=class{constructor(e,t,i,r,s,n){this.canvas=e;this.camera=t;this.coordinateTransformer=i;this.config=r;this.viewport=s;this.layers=n;let a=e.getContext("2d");if(!a)throw new Error("Failed to get 2D canvas context");this.ctx=a,this.applyCanvasSize(),this.coordinateOverlayRenderer=new Z(this.ctx,this.camera,this.config,this.viewport),this.config.get().debug?.enabled&&(this.debugOverlay=new H(this.ctx,this.camera,this.coordinateTransformer,this.config,this.viewport),this.config.get().debug?.hud?.fps&&(this.debugOverlay.setFpsUpdateCallback(()=>this.render()),this.debugOverlay.startFpsLoop()))}ctx;coordinateOverlayRenderer;debugOverlay;onDraw;init(){this.applyCanvasSize()}applyCanvasSize(){let e=this.viewport.getSize(),t=this.viewport.dpr;this.canvas.width=e.width*t,this.canvas.height=e.height*t,this.canvas.style.width=`${e.width}px`,this.canvas.style.height=`${e.height}px`,this.ctx.setTransform(t,0,0,t,0,0)}render(){let e=this.viewport.getSize(),t=this.viewport.dpr,i={...this.config.get(),size:{...e},scale:this.camera.scale},r={x:this.camera.x,y:this.camera.y};this.ctx.setTransform(t,0,0,t,0,0),this.ctx.clearRect(0,0,i.size.width,i.size.height),this.ctx.fillStyle=i.backgroundColor,this.ctx.fillRect(0,0,i.size.width,i.size.height),this.layers.drawAll({ctx:this.ctx,camera:this.camera,transformer:this.coordinateTransformer,config:i,topLeft:r}),this.onDraw?.(this.ctx,{scale:this.camera.scale,width:i.size.width,height:i.size.height,coords:r}),this.coordinateOverlayRenderer.shouldDraw(this.camera.scale)&&this.coordinateOverlayRenderer.draw(),i.debug?.enabled&&(this.debugOverlay||(this.debugOverlay=new H(this.ctx,this.camera,this.coordinateTransformer,this.config,this.viewport),i.debug?.hud?.fps&&(this.debugOverlay.setFpsUpdateCallback(()=>this.render()),this.debugOverlay.startFpsLoop())),this.debugOverlay.draw())}resize(e,t){let i=this.viewport.dpr;this.viewport.setSize(e,t),this.canvas.width=e*i,this.canvas.height=t*i,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.ctx.setTransform(i,0,0,i,0,0)}destroy(){this.debugOverlay&&(this.debugOverlay.destroy(),this.debugOverlay=void 0),this.layers.clear()}getContext(){return this.ctx}};var j=class{canvasWrapper;canvas;camera;viewport;renderer;config;onSizeApplied;constructor(e,t,i,r,s,n,a){this.canvasWrapper=e,this.canvas=t,this.camera=i,this.renderer=r,this.viewport=s,this.config=n,this.onSizeApplied=a}resizeWithAnimation(e,t,i,r,s){if(e<=0||t<=0)return;let n=this.config.get().size,a=(o,h,c)=>{let l=o;return h!==void 0&&(l=Math.max(h,l)),c!==void 0&&(l=Math.min(c,l)),l};e=a(e,n?.minWidth,n?.maxWidth),t=a(t,n?.minHeight,n?.maxHeight),r.animateResize(e,t,i,(o,h,c)=>this.applySize(o,h,c),s)}applySize(e,t,i){let r=Math.round(e),s=Math.round(t),n=this.viewport.dpr;this.viewport.setSize(r,s),this.canvasWrapper.style.width=`${r}px`,this.canvasWrapper.style.height=`${s}px`,this.canvas.width=r*n,this.canvas.height=s*n,this.canvas.style.width=`${r}px`,this.canvas.style.height=`${s}px`,this.camera.setCenter(i,r,s),this.renderer.resize(r,s),this.onSizeApplied()}};var G=class{constructor(e,t,i){this.camera=e;this.viewport=t;this.onAnimationFrame=i}moveAnimationId;resizeAnimationId;animateMoveTo(e,t,i=b.ANIMATION_DURATION_MS,r){if(this.cancelMove(),i<=0){let h=this.viewport.getSize();this.camera.setCenter({x:e,y:t},h.width,h.height),this.onAnimationFrame(),r?.();return}let s=this.viewport.getSize(),n=this.camera.getCenter(s.width,s.height),a=performance.now(),o=h=>{let c=h-a,l=Math.min(1,c/i),f=l<.5?2*l*l:1-Math.pow(-2*l+2,2)/2,u=n.x+(e-n.x)*f,d=n.y+(t-n.y)*f,m=this.viewport.getSize();this.camera.setCenter({x:u,y:d},m.width,m.height),this.onAnimationFrame(),l<1?this.moveAnimationId=requestAnimationFrame(o):(this.moveAnimationId=void 0,r?.())};this.moveAnimationId=requestAnimationFrame(o)}animateResize(e,t,i=b.ANIMATION_DURATION_MS,r,s){if(e<=0||t<=0)return;this.cancelResize();let n=this.viewport.getSize(),a=this.camera.getCenter(n.width,n.height);if(i<=0){r(e,t,a),s?.();return}let o=n.width,h=n.height,c=e-n.width,l=t-n.height,f=performance.now(),u=d=>{let m=d-f,C=Math.min(1,m/i),v=o+c*C,w=h+l*C;r(v,w,a),C<1?this.resizeAnimationId=requestAnimationFrame(u):(this.resizeAnimationId=void 0,s?.())};this.resizeAnimationId=requestAnimationFrame(u)}cancelMove(){this.moveAnimationId!==void 0&&(cancelAnimationFrame(this.moveAnimationId),this.moveAnimationId=void 0)}cancelResize(){this.resizeAnimationId!==void 0&&(cancelAnimationFrame(this.resizeAnimationId),this.resizeAnimationId=void 0)}cancelAll(){this.cancelMove(),this.cancelResize()}isAnimating(){return this.moveAnimationId!==void 0||this.resizeAnimationId!==void 0}};var q=class{static createRenderer(e,t,i,r,s,n,a){switch(e){case"canvas":return new _(t,i,r,s,n,a);default:throw new Error(`Unsupported renderer type: ${e}`)}}static isSupported(e){return e==="canvas"}static getSupportedTypes(){return["canvas"]}};var J=class{config;camera;viewport;coordinateTransformer;layers;renderer;events;draw;images;sizeController;animationController;canvasWrapper;canvas;onCoordsChange;_onClick;get onClick(){return this._onClick}set onClick(e){this._onClick=e,this.events.onClick=e}_onRightClick;get onRightClick(){return this._onRightClick}set onRightClick(e){this._onRightClick=e,this.events.onRightClick=e}_onHover;get onHover(){return this._onHover}set onHover(e){this._onHover=e,this.events.onHover=e}_onMouseDown;get onMouseDown(){return this._onMouseDown}set onMouseDown(e){this._onMouseDown=e,this.events.onMouseDown=e}_onMouseUp;get onMouseUp(){return this._onMouseUp}set onMouseUp(e){this._onMouseUp=e,this.events.onMouseUp=e}_onMouseLeave;get onMouseLeave(){return this._onMouseLeave}set onMouseLeave(e){this._onMouseLeave=e,this.events.onMouseLeave=e}_onDraw;get onDraw(){return this._onDraw}set onDraw(e){this._onDraw=e,this.getCanvasRenderer().onDraw=e}_onResize;get onResize(){return this._onResize}set onResize(e){this._onResize=e,this.events.onResize=e}_onZoom;get onZoom(){return this._onZoom}set onZoom(e){this._onZoom=e,this.events.onZoom=e}constructor(e,t,i={x:0,y:0}){this.canvasWrapper=e,this.canvas=e.querySelector("canvas"),Object.assign(this.canvasWrapper.style,{position:"relative",width:t.size.width+"px",height:t.size.height+"px"}),Object.assign(this.canvas.style,{position:"absolute",top:"0",left:"0"}),this.config=new F(t);let r=t.renderer??"canvas",s=t.gridAligned?{x:Math.floor(i.x)+.5,y:Math.floor(i.y)+.5}:i,n={x:s.x-t.size.width/(2*t.scale),y:s.y-t.size.height/(2*t.scale)};this.viewport=new $(t.size.width,t.size.height),this.camera=new R(n,this.config.get().scale,this.config.get().minScale,this.config.get().maxScale,this.viewport),this.coordinateTransformer=new W(this.camera),this.animationController=new G(this.camera,this.viewport,()=>this.handleCameraChange()),this.renderer=this.createRenderer(r),this.images=new N,this.events=new U(this.canvasWrapper,this.canvas,this.camera,this.viewport,this.config,this.coordinateTransformer,()=>this.handleCameraChange()),this.sizeController=new j(this.canvasWrapper,this.canvas,this.camera,this.renderer,this.viewport,this.config,()=>this.handleCameraChange()),this.events.setupEvents(),t.bounds&&this.camera.setBounds(t.bounds)}destroy(){this.events.destroy(),this.animationController.cancelAll(),this.draw?.destroy(),this.layers?.clear(),this.images.clear(),this.renderer.destroy()}render(){this.renderer.render()}resize(e,t,i=500,r){this.sizeController.resizeWithAnimation(e,t,i,this.animationController,()=>{this._onResize?.(),r?.()})}getSize(){return this.viewport.getSize()}getScale(){return this.camera.scale}zoomIn(e=1.5){let t=this.viewport.getSize();this.camera.zoomByFactor(e,t.width/2,t.height/2),this.handleCameraChange()}zoomOut(e=1.5){let t=this.viewport.getSize();this.camera.zoomByFactor(1/e,t.width/2,t.height/2),this.handleCameraChange()}getConfig(){let e=this.config.get(),t=this.viewport.getSize();return{...e,scale:this.camera.scale,size:{...t}}}getCenterCoords(){let e=this.viewport.getSize();return this.camera.getCenter(e.width,e.height)}getVisibleBounds(){let e=this.viewport.getSize();return this.camera.getVisibleBounds(e.width,e.height)}updateCoords(e){let t=this.viewport.getSize();this.camera.setCenter(e,t.width,t.height),this.handleCameraChange()}goCoords(e,t,i=500,r){this.animationController.animateMoveTo(e,t,i,r)}setEventHandlers(e){this.config.updateEventHandlers(e)}setBounds(e){this.config.updateBounds(e),this.camera.setBounds(e),this.render()}addDrawFunction(e,t=1){return this.ensureCanvasDraw().addDrawFunction(e,t)}drawRect(e,t=1){return this.ensureCanvasDraw().drawRect(e,t)}drawStaticRect(e,t,i=1){return this.ensureCanvasDraw().drawStaticRect(e,t,i)}drawStaticCircle(e,t,i=1){return this.ensureCanvasDraw().drawStaticCircle(e,t,i)}drawStaticImage(e,t,i=1){return this.ensureCanvasDraw().drawStaticImage(e,t,i)}clearStaticCache(e){this.ensureCanvasDraw().clearStaticCache(e)}drawLine(e,t,i=1){return this.ensureCanvasDraw().drawLine(e,t,i)}drawCircle(e,t=1){return this.ensureCanvasDraw().drawCircle(e,t)}drawText(e,t,i=2){return this.ensureCanvasDraw().drawText(e,t,i)}drawPath(e,t,i=1){return this.ensureCanvasDraw().drawPath(e,t,i)}drawImage(e,t=1){return this.ensureCanvasDraw().drawImage(e,t)}drawGridLines(e,t=1,i="black",r=0){return this.ensureCanvasDraw().drawGridLines(e,{lineWidth:t,strokeStyle:i},r)}removeLayerHandle(e){if(!this.layers)throw new Error("removeLayerHandle is only available when renderer is set to 'canvas'.");this.layers.remove(e)}clearLayer(e){if(!this.layers)throw new Error("clearLayer is only available when renderer is set to 'canvas'.");this.layers.clear(e)}clearAll(){if(!this.layers)throw new Error("clearAll is only available when renderer is set to 'canvas'.");this.layers.clear()}createRenderer(e){return e==="canvas"&&(this.layers=new V,this.draw=new Y(this.layers,this.coordinateTransformer,this.camera)),q.createRenderer(e??"canvas",this.canvas,this.camera,this.coordinateTransformer,this.config,this.viewport,this.layers)}ensureCanvasDraw(){if(!this.draw)throw new Error("Draw helpers are only available when renderer is set to 'canvas'.");return this.draw}getCanvasRenderer(){if(!(this.renderer instanceof _))throw new Error("Canvas renderer required for this operation.");return this.renderer}handleCameraChange(){this.onCoordsChange&&this.onCoordsChange(this.getCenterCoords()),this.render()}};0&&(module.exports={COORDINATE_OVERLAY,CanvasTileEngine,DEBUG_HUD,DEFAULT_VALUES,RENDER_DEFAULTS,SCALE_LIMITS,SIZE_LIMITS,VISIBILITY_BUFFER});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|