@canvas-tile-engine/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +162 -49
- package/dist/index.d.ts +162 -49
- 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 +1 -1
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var me=Object.create;var A=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var ge=(m,e)=>{for(var t in e)A(m,t,{get:e[t],enumerable:!0})},se=(m,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of pe(e))!fe.call(m,s)&&s!==t&&A(m,s,{get:()=>e[s],enumerable:!(i=ue(e,s))||i.enumerable});return m};var Ce=(m,e,t)=>(t=m!=null?me(ve(m)):{},se(e||!m||!m.__esModule?A(t,"default",{value:m,enumerable:!0}):t,m)),be=m=>se(A({},"__esModule",{value:!0}),m);var ye={};ge(ye,{COORDINATE_OVERLAY:()=>E,CanvasTileEngine:()=>Q,DEBUG_HUD:()=>S,DEFAULT_VALUES:()=>y,RENDER_DEFAULTS:()=>W,SCALE_LIMITS:()=>O,SIZE_LIMITS:()=>I,VISIBILITY_BUFFER:()=>R,gridToSize:()=>ce});module.exports=be(ye);var y={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},I={MIN_WIDTH:100,MIN_HEIGHT:100,MAX_WIDTH:1/0,MAX_HEIGHT:1/0},W={BACKGROUND_COLOR:"#ffffff",RENDERER_TYPE:"canvas"},E={BORDER_WIDTH:20,TEXT_OPACITY:.8,BORDER_OPACITY:.1,MIN_FONT_SIZE:8,MAX_FONT_SIZE:12,FONT_SIZE_SCALE_FACTOR:.25},S={PANEL_WIDTH:160,PADDING:8,LINE_HEIGHT:16},R={TILE_BUFFER:1};function re(m,e,t,i){return{x:m.x-t/e,y:m.y-i/e}}function ne(m,e,t,i,s,r){let n=Math.min(Math.max(t,y.MIN_WHEEL_DELTA),y.MAX_WHEEL_DELTA),a=Math.exp(-n*y.ZOOM_SENSITIVITY),l=Math.min(s,Math.max(i,e*a));return l===e?{topLeft:m,scale:e}:{topLeft:{x:m.x+r.x*(1/e-1/l),y:m.y+r.y*(1/e-1/l)},scale:l}}function ae(m,e){return{x:(m.x+y.CELL_CENTER_OFFSET-e.x)*e.scale,y:(m.y+y.CELL_CENTER_OFFSET-e.y)*e.scale}}function oe(m,e){return{x:e.x+m.x/e.scale,y:e.y+m.y/e.scale}}var D=class{_x;_y;_scale;minScale;maxScale;bounds;viewport;constructor(e,t=1,i=.1,s=10,r){this._x=e.x+y.CELL_CENTER_OFFSET,this._y=e.y+y.CELL_CENTER_OFFSET,this._scale=t,this.minScale=i,this.maxScale=s,this.viewport=r}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,s=t/this._scale;this._x=this.clampAxis(this._x,i,this.bounds.minX,this.bounds.maxX),this._y=this.clampAxis(this._y,s,this.bounds.minY,this.bounds.maxY)}clampAxis(e,t,i,s){let r=s-i;return t>=r?i-(t-r)/2:e<i?i:e+t>s?s-t:e}get x(){return this._x}get y(){return this._y}get scale(){return this._scale}setScale(e){this._scale=Math.min(this.maxScale,Math.max(this.minScale,e)),this.clampToBounds()}pan(e,t){let i=re({x:this._x,y:this._y},this._scale,e,t);this._x=i.x,this._y=i.y,this.clampToBounds()}zoom(e,t,i,s){let r=e-s.left,n=t-s.top,a=ne({x:this._x,y:this._y},this._scale,i,this.minScale,this.maxScale,{x:r,y:n});this._x=a.topLeft.x,this._y=a.topLeft.y,this._scale=a.scale,this.clampToBounds()}zoomByFactor(e,t,i){let s=Math.min(this.maxScale,Math.max(this.minScale,this._scale*e));s!==this._scale&&(this._x=this._x+t*(1/this._scale-1/s),this._y=this._y+i*(1/this._scale-1/s),this._scale=s,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-y.CELL_CENTER_OFFSET,s=this._y-y.CELL_CENTER_OFFSET,r=i+e/this._scale,n=s+t/this._scale;return{minX:Math.floor(i),maxX:Math.ceil(r),minY:Math.floor(s),maxY:Math.ceil(n)}}};var F=class{config;constructor(e){let t={renderer:W.RENDERER_TYPE,scale:e.scale,minScale:e.minScale??e.scale*O.MIN_SCALE_MULTIPLIER,maxScale:e.maxScale??e.scale*O.MAX_SCALE_MULTIPLIER,gridAligned:e.gridAligned??!1,size:{width:e.size.width,height:e.size.height,maxHeight:e.size.maxHeight??I.MAX_HEIGHT,maxWidth:e.size.maxWidth??I.MAX_WIDTH,minHeight:e.size.minHeight??I.MIN_HEIGHT,minWidth:e.size.minWidth??I.MIN_WIDTH},responsive:e.responsive??!1,backgroundColor:e.backgroundColor??W.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},responsive:e.responsive,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 Y=class{constructor(e){this.camera=e}worldToScreen(e,t){return ae({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}screenToWorld(e,t){return oe({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}};var he=Ce(require("rbush")),z=class m{tree;constructor(){this.tree=new he.default}load(e){let t=e.map(i=>{let r=(typeof i.size=="number"?i.size:0)/2;return{minX:i.x-r,minY:i.y-r,maxX:i.x+r,maxY:i.y+r,item:i}});this.tree.load(t)}query(e,t,i,s){return this.tree.search({minX:e,minY:t,maxX:i,maxY:s}).map(n=>n.item)}clear(){this.tree.clear()}static fromArray(e){let t=new m;return t.load(e),t}};function _(m,e){if(e>=1)return m.lineWidth=e,()=>{};let t=Math.max(0,Math.min(e,1));return m.lineWidth=1,m.globalAlpha=t,()=>{m.globalAlpha=1}}var ie=500,le=16384,X=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,s,r){let n=r.size.width/r.scale,a=r.size.height/r.scale,l=s.x-R.TILE_BUFFER,o=s.y-R.TILE_BUFFER,d=s.x+n+R.TILE_BUFFER,h=s.y+a+R.TILE_BUFFER;return e+i>=l&&e-i<=d&&t+i>=o&&t-i<=h}getViewportBounds(e,t){let i=t.size.width/t.scale,s=t.size.height/t.scale;return{minX:e.x-R.TILE_BUFFER,minY:e.y-R.TILE_BUFFER,maxX:e.x+i+R.TILE_BUFFER,maxY:e.y+s+R.TILE_BUFFER}}addDrawFunction(e,t=1){return this.layers.add(t,({ctx:i,config:s,topLeft:r})=>{e(i,r,s)})}drawRect(e,t=1){let i=Array.isArray(e)?e:[e],r=i.length>ie?z.fromArray(i):null;return this.layers.add(t,({ctx:n,config:a,topLeft:l})=>{let o=this.getViewportBounds(l,a),d=r?r.query(o.minX,o.minY,o.maxX,o.maxY):i;n.save();let h,p,f;for(let c of d){let u=c.size??1,g={mode:c.origin?.mode==="self"?"self":"cell",x:c.origin?.x??.5,y:c.origin?.y??.5},v=c.style;if(!r&&!this.isVisible(c.x,c.y,u/2,l,a))continue;let b=this.transformer.worldToScreen(c.x,c.y),C=u*this.camera.scale,{x:w,y:x}=this.computeOriginOffset(b,C,g,this.camera);v?.fillStyle&&v.fillStyle!==h&&(n.fillStyle=v.fillStyle,h=v.fillStyle),v?.strokeStyle&&v.strokeStyle!==p&&(n.strokeStyle=v.strokeStyle,p=v.strokeStyle);let T;v?.lineWidth&&v.lineWidth!==f&&(T=_(n,v.lineWidth),f=v.lineWidth);let L=c.rotate??0,ee=L*(Math.PI/180),M=c.radius;if(L!==0){let te=w+C/2,de=x+C/2;n.save(),n.translate(te,de),n.rotate(ee),n.beginPath(),M&&n.roundRect?n.roundRect(-C/2,-C/2,C,C,M):n.rect(-C/2,-C/2,C,C),v?.fillStyle&&n.fill(),v?.strokeStyle&&n.stroke(),n.restore()}else n.beginPath(),M&&n.roundRect?n.roundRect(w,x,C,C,M):n.rect(w,x,C,C),v?.fillStyle&&n.fill(),v?.strokeStyle&&n.stroke();T?.()}n.restore()})}drawLine(e,t,i=1){let s=Array.isArray(e)?e:[e];return this.layers.add(i,({ctx:r,config:n,topLeft:a})=>{r.save(),t?.strokeStyle&&(r.strokeStyle=t.strokeStyle);let l=t?.lineWidth?_(r,t.lineWidth):void 0;r.beginPath();for(let o of s){let d=(o.from.x+o.to.x)/2,h=(o.from.y+o.to.y)/2,p=Math.max(Math.abs(o.from.x-o.to.x),Math.abs(o.from.y-o.to.y))/2;if(!this.isVisible(d,h,p,a,n))continue;let f=this.transformer.worldToScreen(o.from.x,o.from.y),c=this.transformer.worldToScreen(o.to.x,o.to.y);r.moveTo(f.x,f.y),r.lineTo(c.x,c.y)}r.stroke(),l?.(),r.restore()})}drawCircle(e,t=1){let i=Array.isArray(e)?e:[e],r=i.length>ie?z.fromArray(i):null;return this.layers.add(t,({ctx:n,config:a,topLeft:l})=>{let o=this.getViewportBounds(l,a),d=r?r.query(o.minX,o.minY,o.maxX,o.maxY):i;n.save();let h,p,f;for(let c of d){let u=c.size??1,g={mode:c.origin?.mode==="self"?"self":"cell",x:c.origin?.x??.5,y:c.origin?.y??.5},v=c.style;if(!r&&!this.isVisible(c.x,c.y,u/2,l,a))continue;let b=this.transformer.worldToScreen(c.x,c.y),C=u*this.camera.scale,w=C/2,{x,y:T}=this.computeOriginOffset(b,C,g,this.camera);v?.fillStyle&&v.fillStyle!==h&&(n.fillStyle=v.fillStyle,h=v.fillStyle),v?.strokeStyle&&v.strokeStyle!==p&&(n.strokeStyle=v.strokeStyle,p=v.strokeStyle);let L;v?.lineWidth&&v.lineWidth!==f&&(L=_(n,v.lineWidth),f=v.lineWidth),n.beginPath(),n.arc(x+w,T+w,w,0,Math.PI*2),v?.fillStyle&&n.fill(),v?.strokeStyle&&n.stroke(),L?.()}n.restore()})}drawText(e,t,i=2){let s=Array.isArray(e)?e:[e];return this.layers.add(i,({ctx:r,config:n,topLeft:a})=>{r.save(),t?.font&&(r.font=t.font),t?.fillStyle&&(r.fillStyle=t.fillStyle),r.textAlign=t?.textAlign??"center",r.textBaseline=t?.textBaseline??"middle";for(let l of s){if(!this.isVisible(l.coords.x,l.coords.y,0,a,n))continue;let o=this.transformer.worldToScreen(l.coords.x,l.coords.y);r.fillText(l.text,o.x,o.y)}r.restore()})}drawPath(e,t,i=1){let s=Array.isArray(e[0])?e:[e];return this.layers.add(i,({ctx:r,config:n,topLeft:a})=>{r.save(),t?.strokeStyle&&(r.strokeStyle=t.strokeStyle);let l=t?.lineWidth?_(r,t.lineWidth):void 0;r.beginPath();for(let o of s){if(!o.length)continue;let d=o.map(w=>w.x),h=o.map(w=>w.y),p=Math.min(...d),f=Math.max(...d),c=Math.min(...h),u=Math.max(...h),g=(p+f)/2,v=(c+u)/2,b=Math.max(f-p,u-c)/2;if(!this.isVisible(g,v,b,a,n))continue;let C=this.transformer.worldToScreen(o[0].x,o[0].y);r.moveTo(C.x,C.y);for(let w=1;w<o.length;w++){let x=this.transformer.worldToScreen(o[w].x,o[w].y);r.lineTo(x.x,x.y)}}r.stroke(),l?.(),r.restore()})}drawImage(e,t=1){let i=Array.isArray(e)?e:[e],r=i.length>ie?z.fromArray(i):null;return this.layers.add(t,({ctx:n,config:a,topLeft:l})=>{let o=this.getViewportBounds(l,a),d=r?r.query(o.minX,o.minY,o.maxX,o.maxY):i;for(let h of d){let p=h.size??1,f={mode:h.origin?.mode==="self"?"self":"cell",x:h.origin?.x??.5,y:h.origin?.y??.5};if(!r&&!this.isVisible(h.x,h.y,p/2,l,a))continue;let c=this.transformer.worldToScreen(h.x,h.y),u=p*this.camera.scale,g=h.img.width/h.img.height,v=u,b=u;g>1?b=u/g:v=u*g;let{x:C,y:w}=this.computeOriginOffset(c,u,f,this.camera),x=C+(u-v)/2,T=w+(u-b)/2,L=h.rotate??0,ee=L*(Math.PI/180);if(L!==0){let M=x+v/2,te=T+b/2;n.save(),n.translate(M,te),n.rotate(ee),n.drawImage(h.img,-v/2,-b/2,v,b),n.restore()}else n.drawImage(h.img,x,T,v,b)}})}drawGridLines(e,t,i=0){return this.layers.add(i,({ctx:s,config:r,topLeft:n})=>{let a=r.size.width/r.scale,l=r.size.height/r.scale,o=Math.floor(n.x/e)*e-y.CELL_CENTER_OFFSET,d=Math.ceil((n.x+a)/e)*e-y.CELL_CENTER_OFFSET,h=Math.floor(n.y/e)*e-y.CELL_CENTER_OFFSET,p=Math.ceil((n.y+l)/e)*e-y.CELL_CENTER_OFFSET;s.save(),s.strokeStyle=t.strokeStyle;let f=_(s,t.lineWidth);s.beginPath();for(let c=o;c<=d;c+=e){let u=this.transformer.worldToScreen(c,h),g=this.transformer.worldToScreen(c,p);s.moveTo(u.x,u.y),s.lineTo(g.x,g.y)}for(let c=h;c<=p;c+=e){let u=this.transformer.worldToScreen(o,c),g=this.transformer.worldToScreen(d,c);s.moveTo(u.x,u.y),s.lineTo(g.x,g.y)}s.stroke(),f(),s.restore()})}computeOriginOffset(e,t,i,s){if(i.mode==="cell"){let r=s.scale;return{x:e.x-r/2+i.x*r-t/2,y:e.y-r/2+i.y*r-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 s=1/0,r=-1/0,n=1/0,a=-1/0;for(let u of e){let g=u.size??1;u.x-g/2<s&&(s=u.x-g/2),u.x+g/2>r&&(r=u.x+g/2),u.y-g/2<n&&(n=u.y-g/2),u.y+g/2>a&&(a=u.y+g/2)}s-=1,n-=1,r+=1,a+=1;let l=r-s,o=a-n,d=this.camera.scale,h=Math.ceil(l*d),p=Math.ceil(o*d);if(h>le||p>le)return this.warnedStaticCacheDisabled||(console.warn(`Static cache disabled: offscreen canvas too large (${h}x${p}).`),this.warnedStaticCacheDisabled=!0),null;let f=this.staticCaches.get(t);if(!f||f.scale!==d||f.worldBounds.minX!==s||f.worldBounds.maxX!==r||f.worldBounds.minY!==n||f.worldBounds.maxY!==a){let u=typeof OffscreenCanvas<"u"?new OffscreenCanvas(h,p):document.createElement("canvas");typeof OffscreenCanvas<"u"&&u instanceof OffscreenCanvas||(u.width=h,u.height=p);let v=u.getContext("2d");if(!v)return this.warnedStaticCacheDisabled||(console.warn("[CanvasDraw] Static cache disabled: 2D context unavailable."),this.warnedStaticCacheDisabled=!0),null;for(let b of e){let w=(b.size??1)*d,x=(b.x+y.CELL_CENTER_OFFSET-s)*d-w/2,T=(b.y+y.CELL_CENTER_OFFSET-n)*d-w/2;i(v,b,x,T,w)}f={canvas:u,ctx:v,worldBounds:{minX:s,minY:n,maxX:r,maxY:a},scale:d},this.staticCaches.set(t,f)}return f||null}addStaticCacheLayer(e,t){if(!e)return null;let i=e.canvas,s=e.worldBounds,r=e.scale;return this.layers.add(t,({ctx:n,config:a,topLeft:l})=>{let o=a.size.width/a.scale,d=a.size.height/a.scale,h=(l.x-s.minX)*r,p=(l.y-s.minY)*r,f=o*r,c=d*r,u=0,g=0,v=a.size.width,b=a.size.height,C=i.width,w=i.height;if(h<0&&(u=-h/r*a.scale,v-=u,f+=h,h=0),p<0&&(g=-p/r*a.scale,b-=g,c+=p,p=0),h+f>C){let T=(h+f-C)/r;f=C-h,v-=T*a.scale}if(p+c>w){let T=(p+c-w)/r;c=w-p,b-=T*a.scale}f>0&&c>0&&v>0&&b>0&&n.drawImage(i,h,p,f,c,u,g,v,b)})}drawStaticRect(e,t,i=1){let s,r=this.getOrCreateStaticCache(e,t,(n,a,l,o,d)=>{let h=a.style,p=a.rotate??0,f=p*(Math.PI/180),c=a.radius;if(h?.fillStyle&&h.fillStyle!==s&&(n.fillStyle=h.fillStyle,s=h.fillStyle),p!==0){let u=l+d/2,g=o+d/2;n.save(),n.translate(u,g),n.rotate(f),c&&n.roundRect?(n.beginPath(),n.roundRect(-d/2,-d/2,d,d,c),n.fill()):n.fillRect(-d/2,-d/2,d,d),n.restore()}else c&&n.roundRect?(n.beginPath(),n.roundRect(l,o,d,d,c),n.fill()):n.fillRect(l,o,d,d)});return r?this.addStaticCacheLayer(r,i):this.drawRect(e,i)}drawStaticImage(e,t,i=1){let s=this.getOrCreateStaticCache(e,t,(r,n,a,l,o)=>{let d=n.img,h=n.rotate??0,p=h*(Math.PI/180),f=d.width/d.height,c=o,u=o;f>1?u=o/f:c=o*f;let g=a+(o-c)/2,v=l+(o-u)/2;if(h!==0){let b=g+c/2,C=v+u/2;r.save(),r.translate(b,C),r.rotate(p),r.drawImage(d,-c/2,-u/2,c,u),r.restore()}else r.drawImage(d,g,v,c,u)});return s?this.addStaticCacheLayer(s,i):this.drawImage(e,i)}drawStaticCircle(e,t,i=1){let s,r=this.getOrCreateStaticCache(e,t,(n,a,l,o,d)=>{let h=a.style,p=d/2;h?.fillStyle&&h.fillStyle!==s&&(n.fillStyle=h.fillStyle,s=h.fillStyle),n.beginPath(),n.arc(l+p,o+p,p,0,Math.PI*2),n.fill()});return r?this.addStaticCacheLayer(r,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 B=class{constructor(e,t,i,s,r,n){this.canvas=e;this.camera=t;this.viewport=i;this.config=s;this.transformer=r;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,s=e.clientY-t.top,r=this.transformer.screenToWorld(i,s),n=this.transformer.worldToScreen(Math.floor(r.x),Math.floor(r.y));return{coords:{raw:r,snapped:{x:Math.floor(r.x),y:Math.floor(r.y)}},mouse:{raw:{x:i,y:s},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:s}=this.getEventCoords(e);this.onClick(t,i,s)};handleContextMenu=e=>{if(!this.config.get().eventHandlers.rightClick||!this.onRightClick)return;e.preventDefault();let{coords:t,mouse:i,client:s}=this.getEventCoords(e);this.onRightClick(t,i,s)};handleMouseDown=e=>{if(this.onMouseDown){let{coords:t,mouse:i,client:s}=this.getEventCoords(e);this.onMouseDown(t,i,s)}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:s,mouse:r,client:n}=this.getEventCoords(e);this.onHover(s,r,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:s}=this.getEventCoords(e);this.onMouseUp(t,i,s)}this.isDragging=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};handleMouseLeave=e=>{if(this.onMouseLeave){let{coords:t,mouse:i,client:s}=this.getEventCoords(e);this.onMouseLeave(t,i,s)}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(e.touches.length!==1)return;let i=e.touches[0];if(this.onMouseDown){e.preventDefault();let{coords:s,mouse:r,client:n}=this.getEventCoords(i);this.onMouseDown(s,r,n)}t.drag&&(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 r=this.getTouchDistance(e.touches),n=this.getTouchCenter(e.touches),a=this.canvas.getBoundingClientRect(),l=r/this.lastPinchDistance,o=n.x-a.left,d=n.y-a.top;this.camera.zoomByFactor(l,o,d);let h=n.x-this.lastPinchCenter.x,p=n.y-this.lastPinchCenter.y;(h!==0||p!==0)&&this.camera.pan(h,p),this.lastPinchDistance=r,this.lastPinchCenter=n,this.onZoom&&this.onZoom(this.camera.scale),this.onCameraChange();return}if(e.touches.length!==1)return;let t=e.touches[0];if(this.onHover&&this.config.get().eventHandlers.hover){e.preventDefault();let{coords:r,mouse:n,client:a}=this.getEventCoords(t);this.onHover(r,n,a)}if(!this.isDragging)return;e.preventDefault();let i=t.clientX-this.lastPos.x,s=t.clientY-this.lastPos.y;(i!==0||s!==0)&&(this.canvas.style.cursor=this.config.get().cursor.move||"move",this.shouldPreventClick=!0),this.camera.pan(i,s),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}if(e.changedTouches.length>0&&this.onMouseUp){let t=e.changedTouches[0],{coords:i,mouse:s,client:r}=this.getEventCoords(t);this.onMouseUp(i,s,r)}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 U=class{constructor(e,t,i,s,r,n){this.wrapper=e;this.canvas=t;this.viewport=i;this.camera=s;this.config=r;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,s=t?.maxHeight,r=t?.minWidth,n=t?.minHeight;e.width=this.clamp(e.width,r,i),e.height=this.clamp(e.height,n,s),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:s?`${s}px`:"",minWidth:r?`${r}px`:"",minHeight:n?`${n}px`:""}),this.resizeObserver=new ResizeObserver(a=>{for(let l of a){let{width:o,height:d}=l.contentRect,h=this.clamp(o,r,i),p=this.clamp(d,n,s),f=this.viewport.getSize();if(h===f.width&&p===f.height)continue;let c=h-f.width,u=p-f.height,g=this.viewport.dpr;this.camera.adjustForResize(c,u),this.viewport.setSize(h,p),this.canvas.width=h*g,this.canvas.height=p*g,this.canvas.style.width=`${h}px`,this.canvas.style.height=`${p}px`,this.wrapper.style.width=`${h}px`,this.wrapper.style.height=`${p}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 s=e;return t!==void 0&&(s=Math.max(t,s)),i!==void 0&&(s=Math.min(i,s)),s}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:s}=this.viewport.getSize();this.canvas.width=i*t,this.canvas.height=s*t,this.canvas.style.width=`${i}px`,this.canvas.style.height=`${s}px`,this.onResize&&this.onResize(),this.onCameraChange()},window.addEventListener("resize",this.handleWindowResize,{passive:!0}))}};var N=class{constructor(e,t,i,s,r,n,a){this.canvasWrapper=e;this.canvas=t;this.camera=i;this.viewport=s;this.config=r;this.coordinateTransformer=n;this.onCameraChange=a;this.gestures=new B(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().responsive?this.config.get().eventHandlers.resize&&console.warn("Canvas Tile Engine: eventHandlers.resize is ignored when responsive mode is enabled. Resizing is handled automatically."):this.config.get().eventHandlers.resize&&this.camera instanceof D&&(this.resizeWatcher=new U(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 V=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=y.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((s,r)=>{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(),s(n)},n.onerror=a=>{if(this.inflight.delete(e),t>0)console.warn(`Retrying image: ${e}`),s(this.load(e,t-1));else{console.error(`Image failed to load: ${e}`,a);let l=a instanceof Error?a.message:typeof a=="string"?a:JSON.stringify(a);r(new Error(`Image failed to load: ${e}. Reason: ${l}`))}},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 $=class{layers=new Map;add(e,t){let i=Symbol("layer-callback"),s={id:i,fn:t};return this.layers.has(e)||this.layers.set(e,[]),this.layers.get(e).push(s),{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,s)=>i-s);for(let i of t){let s=this.layers.get(i);if(s)for(let{fn:r}of s)e.ctx.save(),r(e),e.ctx.restore()}}};var Z=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,i,s){this.ctx=e,this.camera=t,this.config=i,this.viewport=s}draw(){this.ctx.save(),this.ctx.fillStyle=`rgba(0, 0, 0, ${E.BORDER_OPACITY})`;let{width:e,height:t}=this.viewport.getSize();this.ctx.fillRect(0,0,E.BORDER_WIDTH,t),this.ctx.fillRect(E.BORDER_WIDTH,t-E.BORDER_WIDTH,e,E.BORDER_WIDTH),this.ctx.fillStyle=`rgba(255, 255, 255, ${E.TEXT_OPACITY})`;let i=Math.min(E.MAX_FONT_SIZE,Math.max(E.MIN_FONT_SIZE,this.camera.scale*E.FONT_SIZE_SCALE_FACTOR));this.ctx.font=`${i}px Arial`,this.ctx.textAlign="center",this.ctx.textBaseline="middle";let s=this.camera.scale,r=e/s,n=t/s;for(let a=0-this.camera.y%1;a<=n+1;a++)this.ctx.fillText(Math.round(this.camera.y+a).toString(),10,s*a+s/2);for(let a=0-this.camera.x%1;a<=r+1;a++)this.ctx.fillText(Math.round(this.camera.x+a).toString(),s*a+s/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:s}=t.shownScaleRange;return e>=i&&e<=s}};var we=10,k=class{ctx;camera;transformer;config;viewport;frameTimes=[];lastFrameTime=0;currentFps=0;fpsLoopRunning=!1;onFpsUpdate=null;constructor(e,t,i,s,r){this.ctx=e,this.camera=t,this.transformer=i,this.config=s,this.viewport=r}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>we&&this.frameTimes.shift();let i=this.frameTimes.reduce((r,n)=>r+n,0)/this.frameTimes.length,s=Math.round(1e3/i);s!==this.currentFps&&(this.currentFps=s,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:r,height:n}=this.viewport.getSize(),a=this.camera.getCenter(r,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:r,height:n}=this.viewport.getSize();t.push(`Tiles in view: ${Math.ceil(r/this.camera.scale)} x ${Math.ceil(n/this.camera.scale)}`)}e.debug.hud.fps&&t.push(`FPS: ${this.currentFps}`);let{width:s}=this.viewport.getSize();this.ctx.save(),this.ctx.fillStyle="rgba(0,0,0,0.5)",this.ctx.fillRect(s-S.PANEL_WIDTH-S.PADDING,S.PADDING/2,S.PANEL_WIDTH,t.length*S.LINE_HEIGHT+S.PADDING),this.ctx.fillStyle="#00ff99",this.ctx.font="12px monospace";for(let r=0;r<t.length;r++)this.ctx.fillText(t[r],s-S.PANEL_WIDTH-S.PADDING+5,18+r*S.LINE_HEIGHT);this.ctx.restore()}};var H=class{constructor(e,t,i,s,r,n){this.canvas=e;this.camera=t;this.coordinateTransformer=i;this.config=s;this.viewport=r;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 j(this.ctx,this.camera,this.config,this.viewport),this.config.get().debug?.enabled&&(this.debugOverlay=new k(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},s={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:s}),this.onDraw?.(this.ctx,{scale:this.camera.scale,width:i.size.width,height:i.size.height,coords:s}),this.coordinateOverlayRenderer.shouldDraw(this.camera.scale)&&this.coordinateOverlayRenderer.draw(),i.debug?.enabled&&(this.debugOverlay||(this.debugOverlay=new k(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 G=class{canvasWrapper;canvas;camera;viewport;renderer;config;onSizeApplied;constructor(e,t,i,s,r,n,a){this.canvasWrapper=e,this.canvas=t,this.camera=i,this.renderer=s,this.viewport=r,this.config=n,this.onSizeApplied=a}resizeWithAnimation(e,t,i,s,r){if(e<=0||t<=0)return;let n=this.config.get().size,a=(l,o,d)=>{let h=l;return o!==void 0&&(h=Math.max(o,h)),d!==void 0&&(h=Math.min(d,h)),h};e=a(e,n?.minWidth,n?.maxWidth),t=a(t,n?.minHeight,n?.maxHeight),s.animateResize(e,t,i,(l,o,d)=>this.applySize(l,o,d),r)}applySize(e,t,i){let s=Math.round(e),r=Math.round(t),n=this.viewport.dpr;this.viewport.setSize(s,r),this.canvasWrapper.style.width=`${s}px`,this.canvasWrapper.style.height=`${r}px`,this.canvas.width=s*n,this.canvas.height=r*n,this.canvas.style.width=`${s}px`,this.canvas.style.height=`${r}px`,this.camera.setCenter(i,s,r),this.renderer.resize(s,r),this.onSizeApplied()}};var q=class{constructor(e,t,i){this.camera=e;this.viewport=t;this.onAnimationFrame=i}moveAnimationId;resizeAnimationId;animateMoveTo(e,t,i=y.ANIMATION_DURATION_MS,s){if(this.cancelMove(),i<=0){let o=this.viewport.getSize();this.camera.setCenter({x:e,y:t},o.width,o.height),this.onAnimationFrame(),s?.();return}let r=this.viewport.getSize(),n=this.camera.getCenter(r.width,r.height),a=performance.now(),l=o=>{let d=o-a,h=Math.min(1,d/i),p=h<.5?2*h*h:1-Math.pow(-2*h+2,2)/2,f=n.x+(e-n.x)*p,c=n.y+(t-n.y)*p,u=this.viewport.getSize();this.camera.setCenter({x:f,y:c},u.width,u.height),this.onAnimationFrame(),h<1?this.moveAnimationId=requestAnimationFrame(l):(this.moveAnimationId=void 0,s?.())};this.moveAnimationId=requestAnimationFrame(l)}animateResize(e,t,i=y.ANIMATION_DURATION_MS,s,r){if(e<=0||t<=0)return;this.cancelResize();let n=this.viewport.getSize(),a=this.camera.getCenter(n.width,n.height);if(i<=0){s(e,t,a),r?.();return}let l=n.width,o=n.height,d=e-n.width,h=t-n.height,p=performance.now(),f=c=>{let u=c-p,g=Math.min(1,u/i),v=l+d*g,b=o+h*g;s(v,b,a),g<1?this.resizeAnimationId=requestAnimationFrame(f):(this.resizeAnimationId=void 0,r?.())};this.resizeAnimationId=requestAnimationFrame(f)}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 J=class{static createRenderer(e,t,i,s,r,n,a){switch(e){case"canvas":return new H(t,i,s,r,n,a);default:throw new Error(`Unsupported renderer type: ${e}`)}}static isSupported(e){return e==="canvas"}static getSupportedTypes(){return["canvas"]}};var K=class{constructor(e,t,i,s,r,n,a){this.wrapper=e;this.canvas=t;this.camera=i;this.renderer=s;this.viewport=r;this.config=n;this.onCameraChange=a;this.currentDpr=this.viewport.dpr;let l=this.config.get();this.initialVisibleTiles={x:l.size.width/l.scale,y:l.size.height/l.scale},this.widthLimits={min:l.minScale*this.initialVisibleTiles.x,max:l.maxScale*this.initialVisibleTiles.x}}resizeObserver;handleWindowResize;currentDpr;initialVisibleTiles;widthLimits;onResize;start(){let e=this.config.get().responsive;if(!e)return;if(this.viewport.updateDpr(),this.currentDpr=this.viewport.dpr,e==="preserve-viewport"){let r=this.initialVisibleTiles.y/this.initialVisibleTiles.x;this.wrapper.style.width="100%",this.wrapper.style.minWidth=`${this.widthLimits.min}px`,this.wrapper.style.maxWidth=`${this.widthLimits.max}px`,this.wrapper.style.minHeight=`${this.widthLimits.min*r}px`,this.wrapper.style.maxHeight=`${this.widthLimits.max*r}px`}let t=this.wrapper.getBoundingClientRect(),i=Math.round(t.width),s=Math.round(t.height);this.applySize(i,s,e),this.resizeObserver=new ResizeObserver(r=>{for(let n of r){let{width:a,height:l}=n.contentRect,o=Math.round(a),d=Math.round(l);if(o<=0||d<=0)continue;let h=this.viewport.getSize();o===h.width&&d===h.height||(this.applySize(o,d,e),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)}applySize(e,t,i){let s=this.viewport.dpr,r=this.viewport.getSize();if(i==="preserve-viewport"){let n=e/this.initialVisibleTiles.x,a=Math.round(this.initialVisibleTiles.y*n);t=a,this.wrapper.style.height=`${a}px`;let l=this.camera.getCenter(r.width,r.height);this.camera.setScale(n),this.camera.setCenter(l,e,t)}else{let n=e-r.width,a=t-r.height;this.camera.adjustForResize(n,a)}this.viewport.setSize(e,t),this.canvas.width=e*s,this.canvas.height=t*s,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.renderer.resize(e,t)}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:s}=this.viewport.getSize();this.canvas.width=i*t,this.canvas.height=s*t,this.canvas.style.width=`${i}px`,this.canvas.style.height=`${s}px`,this.onResize?.(),this.onCameraChange()},window.addEventListener("resize",this.handleWindowResize,{passive:!0}))}};var Q=class{config;camera;viewport;coordinateTransformer;layers;renderer;events;draw;images;sizeController;animationController;responsiveWatcher;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"),t.responsive?Object.assign(this.canvasWrapper.style,{position:"relative"}):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 s=t.renderer??"canvas",r=t.size.width/t.scale,n=t.size.height/t.scale,a=t.gridAligned&&r%2===0?Math.floor(i.x)+.5:i.x,l=t.gridAligned&&n%2===0?Math.floor(i.y)+.5:i.y,o={x:a-t.size.width/(2*t.scale),y:l-t.size.height/(2*t.scale)};this.viewport=new Z(t.size.width,t.size.height),this.camera=new D(o,this.config.get().scale,this.config.get().minScale,this.config.get().maxScale,this.viewport),this.coordinateTransformer=new Y(this.camera),this.animationController=new q(this.camera,this.viewport,()=>this.handleCameraChange()),this.renderer=this.createRenderer(s),this.images=new V,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.responsive&&(this.responsiveWatcher=new K(this.canvasWrapper,this.canvas,this.camera,this.renderer,this.viewport,this.config,()=>this.handleCameraChange()),this.responsiveWatcher.onResize=()=>{this._onResize?.()},this.responsiveWatcher.start()),t.bounds&&this.camera.setBounds(t.bounds)}destroy(){this.events.destroy(),this.responsiveWatcher?.stop(),this.animationController.cancelAll(),this.draw?.destroy(),this.layers?.clear(),this.images.clear(),this.renderer.destroy()}render(){this.renderer.render()}resize(e,t,i=500,s){if(this.config.get().responsive){console.warn("Canvas Tile Engine: resize() is disabled when responsive mode is enabled. Canvas size is controlled by the wrapper element.");return}this.sizeController.resizeWithAnimation(e,t,i,this.animationController,()=>{this._onResize?.(),s?.()})}getSize(){return this.viewport.getSize()}getScale(){return this.camera.scale}setScale(e){this.camera.setScale(e),this.handleCameraChange()}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,s){this.animationController.animateMoveTo(e,t,i,s)}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",s=0){return this.ensureCanvasDraw().drawGridLines(e,{lineWidth:t,strokeStyle:i},s)}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 $,this.draw=new X(this.layers,this.coordinateTransformer,this.camera)),J.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 H))throw new Error("Canvas renderer required for this operation.");return this.renderer}handleCameraChange(){this.onCoordsChange&&this.onCoordsChange(this.getCenterCoords()),this.render()}};function ce(m){return{size:{width:m.columns*m.cellSize,height:m.rows*m.cellSize},scale:m.cellSize}}0&&(module.exports={COORDINATE_OVERLAY,CanvasTileEngine,DEBUG_HUD,DEFAULT_VALUES,RENDER_DEFAULTS,SCALE_LIMITS,SIZE_LIMITS,VISIBILITY_BUFFER,gridToSize});
|
|
1
|
+
"use strict";var ge=Object.create;var W=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var we=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var xe=(a,e)=>{for(var t in e)W(a,t,{get:e[t],enumerable:!0})},ne=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ce(e))!ye.call(a,s)&&s!==t&&W(a,s,{get:()=>e[s],enumerable:!(i=be(e,s))||i.enumerable});return a};var Te=(a,e,t)=>(t=a!=null?ge(we(a)):{},ne(e||!a||!a.__esModule?W(t,"default",{value:a,enumerable:!0}):t,a)),Se=a=>ne(W({},"__esModule",{value:!0}),a);var ze={};xe(ze,{COORDINATE_OVERLAY:()=>E,CanvasTileEngine:()=>te,DEBUG_HUD:()=>z,DEFAULT_VALUES:()=>x,RENDER_DEFAULTS:()=>F,SCALE_LIMITS:()=>O,SIZE_LIMITS:()=>D,VISIBILITY_BUFFER:()=>R,gridToSize:()=>ve});module.exports=Se(ze);var x={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},D={MIN_WIDTH:100,MIN_HEIGHT:100,MAX_WIDTH:1/0,MAX_HEIGHT:1/0},F={BACKGROUND_COLOR:"#ffffff",RENDERER_TYPE:"canvas"},E={BORDER_WIDTH:20,TEXT_OPACITY:.8,BORDER_OPACITY:.1,MIN_FONT_SIZE:8,MAX_FONT_SIZE:12,FONT_SIZE_SCALE_FACTOR:.25},z={PANEL_WIDTH:160,PADDING:8,LINE_HEIGHT:16},R={TILE_BUFFER:1};function ae(a,e,t,i){return{x:a.x-t/e,y:a.y-i/e}}function oe(a,e,t,i,s,n){let r=Math.min(Math.max(t,x.MIN_WHEEL_DELTA),x.MAX_WHEEL_DELTA),o=Math.exp(-r*x.ZOOM_SENSITIVITY),m=Math.min(s,Math.max(i,e*o));return m===e?{topLeft:a,scale:e}:{topLeft:{x:a.x+n.x*(1/e-1/m),y:a.y+n.y*(1/e-1/m)},scale:m}}function he(a,e){return{x:(a.x+x.CELL_CENTER_OFFSET-e.x)*e.scale,y:(a.y+x.CELL_CENTER_OFFSET-e.y)*e.scale}}function le(a,e){return{x:e.x+a.x/e.scale,y:e.y+a.y/e.scale}}var H=class{_x;_y;_scale;minScale;maxScale;bounds;viewport;constructor(e,t=1,i=.1,s=10,n){this._x=e.x+x.CELL_CENTER_OFFSET,this._y=e.y+x.CELL_CENTER_OFFSET,this._scale=t,this.minScale=i,this.maxScale=s,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(),i=e/this._scale,s=t/this._scale;this._x=this.clampAxis(this._x,i,this.bounds.minX,this.bounds.maxX),this._y=this.clampAxis(this._y,s,this.bounds.minY,this.bounds.maxY)}clampAxis(e,t,i,s){let n=s-i;return t>=n?i-(t-n)/2:e<i?i:e+t>s?s-t:e}get x(){return this._x}get y(){return this._y}get scale(){return this._scale}setScale(e){this._scale=Math.min(this.maxScale,Math.max(this.minScale,e)),this.clampToBounds()}pan(e,t){let i=ae({x:this._x,y:this._y},this._scale,e,t);this._x=i.x,this._y=i.y,this.clampToBounds()}zoom(e,t,i,s){let n=e-s.left,r=t-s.top,o=oe({x:this._x,y:this._y},this._scale,i,this.minScale,this.maxScale,{x:n,y:r});this._x=o.topLeft.x,this._y=o.topLeft.y,this._scale=o.scale,this.clampToBounds()}zoomByFactor(e,t,i){let s=Math.min(this.maxScale,Math.max(this.minScale,this._scale*e));s!==this._scale&&(this._x=this._x+t*(1/this._scale-1/s),this._y=this._y+i*(1/this._scale-1/s),this._scale=s,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-x.CELL_CENTER_OFFSET,s=this._y-x.CELL_CENTER_OFFSET,n=i+e/this._scale,r=s+t/this._scale;return{minX:Math.floor(i),maxX:Math.ceil(n),minY:Math.floor(s),maxY:Math.ceil(r)}}};function C(a){return new Error(`[CanvasTileEngine] Invalid config: ${a}`)}function ce(a){if(typeof a.scale!="number"||!Number.isFinite(a.scale))throw C(`scale must be a finite number, got ${a.scale}`);if(a.scale<=0)throw C(`scale must be positive, got ${a.scale}`);if(a.minScale!==void 0){if(typeof a.minScale!="number"||!Number.isFinite(a.minScale))throw C(`minScale must be a finite number, got ${a.minScale}`);if(a.minScale<=0)throw C(`minScale must be positive, got ${a.minScale}`)}if(a.maxScale!==void 0){if(typeof a.maxScale!="number"||!Number.isFinite(a.maxScale))throw C(`maxScale must be a finite number, got ${a.maxScale}`);if(a.maxScale<=0)throw C(`maxScale must be positive, got ${a.maxScale}`)}if(a.minScale!==void 0&&a.maxScale!==void 0&&a.minScale>a.maxScale)throw C(`minScale (${a.minScale}) cannot be greater than maxScale (${a.maxScale})`);if(!a.size||typeof a.size!="object")throw C("size is required and must be an object");if(typeof a.size.width!="number"||!Number.isFinite(a.size.width))throw C(`size.width must be a finite number, got ${a.size.width}`);if(a.size.width<=0)throw C(`size.width must be positive, got ${a.size.width}`);if(typeof a.size.height!="number"||!Number.isFinite(a.size.height))throw C(`size.height must be a finite number, got ${a.size.height}`);if(a.size.height<=0)throw C(`size.height must be positive, got ${a.size.height}`);if(a.size.minWidth!==void 0&&a.size.minWidth<=0)throw C(`size.minWidth must be positive, got ${a.size.minWidth}`);if(a.size.maxWidth!==void 0&&a.size.maxWidth<=0)throw C(`size.maxWidth must be positive, got ${a.size.maxWidth}`);if(a.size.minHeight!==void 0&&a.size.minHeight<=0)throw C(`size.minHeight must be positive, got ${a.size.minHeight}`);if(a.size.maxHeight!==void 0&&a.size.maxHeight<=0)throw C(`size.maxHeight must be positive, got ${a.size.maxHeight}`);if(a.size.minWidth!==void 0&&a.size.maxWidth!==void 0&&a.size.minWidth>a.size.maxWidth)throw C(`size.minWidth (${a.size.minWidth}) cannot be greater than size.maxWidth (${a.size.maxWidth})`);if(a.size.minHeight!==void 0&&a.size.maxHeight!==void 0&&a.size.minHeight>a.size.maxHeight)throw C(`size.minHeight (${a.size.minHeight}) cannot be greater than size.maxHeight (${a.size.maxHeight})`);if(a.bounds){let{minX:e,maxX:t,minY:i,maxY:s}=a.bounds;if(typeof e!="number"||typeof t!="number")throw C("bounds.minX and bounds.maxX must be numbers");if(typeof i!="number"||typeof s!="number")throw C("bounds.minY and bounds.maxY must be numbers");if(Number.isFinite(e)&&Number.isFinite(t)&&e>=t)throw C(`bounds.minX (${e}) must be less than bounds.maxX (${t})`);if(Number.isFinite(i)&&Number.isFinite(s)&&i>=s)throw C(`bounds.minY (${i}) must be less than bounds.maxY (${s})`)}}function de(a){let{minX:e,maxX:t,minY:i,maxY:s}=a;if(typeof e!="number"||typeof t!="number")throw C("bounds.minX and bounds.maxX must be numbers");if(typeof i!="number"||typeof s!="number")throw C("bounds.minY and bounds.maxY must be numbers");if(Number.isFinite(e)&&Number.isFinite(t)&&e>=t)throw C(`bounds.minX (${e}) must be less than bounds.maxX (${t})`);if(Number.isFinite(i)&&Number.isFinite(s)&&i>=s)throw C(`bounds.minY (${i}) must be less than bounds.maxY (${s})`)}function re(a,e){if(typeof a!="number"||!Number.isFinite(a))throw C(`x coordinate must be a finite number, got ${a}`);if(typeof e!="number"||!Number.isFinite(e))throw C(`y coordinate must be a finite number, got ${e}`)}function me(a){if(typeof a!="number"||!Number.isFinite(a))throw C(`scale must be a finite number, got ${a}`);if(a<=0)throw C(`scale must be positive, got ${a}`)}var Y=class{config;constructor(e){ce(e);let t={renderer:F.RENDERER_TYPE,scale:e.scale,minScale:e.minScale??e.scale*O.MIN_SCALE_MULTIPLIER,maxScale:e.maxScale??e.scale*O.MAX_SCALE_MULTIPLIER,gridAligned:e.gridAligned??!1,size:{width:e.size.width,height:e.size.height,maxHeight:e.size.maxHeight??D.MAX_HEIGHT,maxWidth:e.size.maxWidth??D.MAX_WIDTH,minHeight:e.size.minHeight??D.MIN_HEIGHT,minWidth:e.size.minWidth??D.MIN_WIDTH},responsive:e.responsive??!1,backgroundColor:e.backgroundColor??F.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},responsive:e.responsive,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){de(e),this.config={...this.config,bounds:Object.freeze(e)}}};var X=class{constructor(e){this.camera=e}worldToScreen(e,t){return he({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}screenToWorld(e,t){return le({x:e,y:t},{x:this.camera.x,y:this.camera.y,scale:this.camera.scale})}};var ue=Te(require("rbush")),L=class a{tree;constructor(){this.tree=new ue.default}load(e){let t=e.map(i=>{let n=(typeof i.size=="number"?i.size:0)/2;return{minX:i.x-n,minY:i.y-n,maxX:i.x+n,maxY:i.y+n,item:i}});this.tree.load(t)}query(e,t,i,s){return this.tree.search({minX:e,minY:t,maxX:i,maxY:s}).map(r=>r.item)}clear(){this.tree.clear()}static fromArray(e){let t=new a;return t.load(e),t}};function _(a,e){if(e>=1)return a.lineWidth=e,()=>{};let t=Math.max(0,Math.min(e,1));return a.lineWidth=1,a.globalAlpha=t,()=>{a.globalAlpha=1}}var P=500,pe=16384,N=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,s,n){let r=n.size.width/n.scale,o=n.size.height/n.scale,m=s.x-R.TILE_BUFFER,l=s.y-R.TILE_BUFFER,d=s.x+r+R.TILE_BUFFER,h=s.y+o+R.TILE_BUFFER;return e+i>=m&&e-i<=d&&t+i>=l&&t-i<=h}getViewportBounds(e,t){let i=t.size.width/t.scale,s=t.size.height/t.scale;return{minX:e.x-R.TILE_BUFFER,minY:e.y-R.TILE_BUFFER,maxX:e.x+i+R.TILE_BUFFER,maxY:e.y+s+R.TILE_BUFFER}}addDrawFunction(e,t=1){return this.layers.add(t,({ctx:i,config:s,topLeft:n})=>{e(i,n,s)})}drawRect(e,t=1){let i=Array.isArray(e)?e:[e],n=i.length>P?L.fromArray(i):null;return this.layers.add(t,({ctx:r,config:o,topLeft:m})=>{let l=this.getViewportBounds(m,o),d=n?n.query(l.minX,l.minY,l.maxX,l.maxY):i;r.save();let h,p,f;for(let c of d){let u=c.size??1,g={mode:c.origin?.mode==="self"?"self":"cell",x:c.origin?.x??.5,y:c.origin?.y??.5},v=c.style;if(!n&&!this.isVisible(c.x,c.y,u/2,m,o))continue;let w=this.transformer.worldToScreen(c.x,c.y),b=u*this.camera.scale,{x:y,y:T}=this.computeOriginOffset(w,b,g,this.camera);v?.fillStyle&&v.fillStyle!==h&&(r.fillStyle=v.fillStyle,h=v.fillStyle),v?.strokeStyle&&v.strokeStyle!==p&&(r.strokeStyle=v.strokeStyle,p=v.strokeStyle);let S;v?.lineWidth&&v.lineWidth!==f&&(S=_(r,v.lineWidth),f=v.lineWidth);let I=c.rotate??0,ie=I*(Math.PI/180),M=c.radius;if(I!==0){let se=y+b/2,fe=T+b/2;r.save(),r.translate(se,fe),r.rotate(ie),r.beginPath(),M&&r.roundRect?r.roundRect(-b/2,-b/2,b,b,M):r.rect(-b/2,-b/2,b,b),v?.fillStyle&&r.fill(),v?.strokeStyle&&r.stroke(),r.restore()}else r.beginPath(),M&&r.roundRect?r.roundRect(y,T,b,b,M):r.rect(y,T,b,b),v?.fillStyle&&r.fill(),v?.strokeStyle&&r.stroke();S?.()}r.restore()})}drawLine(e,t,i=1){let s=Array.isArray(e)?e:[e];return this.layers.add(i,({ctx:n,config:r,topLeft:o})=>{n.save(),t?.strokeStyle&&(n.strokeStyle=t.strokeStyle);let m=t?.lineWidth?_(n,t.lineWidth):void 0;n.beginPath();for(let l of s){let d=(l.from.x+l.to.x)/2,h=(l.from.y+l.to.y)/2,p=Math.max(Math.abs(l.from.x-l.to.x),Math.abs(l.from.y-l.to.y))/2;if(!this.isVisible(d,h,p,o,r))continue;let f=this.transformer.worldToScreen(l.from.x,l.from.y),c=this.transformer.worldToScreen(l.to.x,l.to.y);n.moveTo(f.x,f.y),n.lineTo(c.x,c.y)}n.stroke(),m?.(),n.restore()})}drawCircle(e,t=1){let i=Array.isArray(e)?e:[e],n=i.length>P?L.fromArray(i):null;return this.layers.add(t,({ctx:r,config:o,topLeft:m})=>{let l=this.getViewportBounds(m,o),d=n?n.query(l.minX,l.minY,l.maxX,l.maxY):i;r.save();let h,p,f;for(let c of d){let u=c.size??1,g={mode:c.origin?.mode==="self"?"self":"cell",x:c.origin?.x??.5,y:c.origin?.y??.5},v=c.style;if(!n&&!this.isVisible(c.x,c.y,u/2,m,o))continue;let w=this.transformer.worldToScreen(c.x,c.y),b=u*this.camera.scale,y=b/2,{x:T,y:S}=this.computeOriginOffset(w,b,g,this.camera);v?.fillStyle&&v.fillStyle!==h&&(r.fillStyle=v.fillStyle,h=v.fillStyle),v?.strokeStyle&&v.strokeStyle!==p&&(r.strokeStyle=v.strokeStyle,p=v.strokeStyle);let I;v?.lineWidth&&v.lineWidth!==f&&(I=_(r,v.lineWidth),f=v.lineWidth),r.beginPath(),r.arc(T+y,S+y,y,0,Math.PI*2),v?.fillStyle&&r.fill(),v?.strokeStyle&&r.stroke(),I?.()}r.restore()})}drawText(e,t=2){let i=Array.isArray(e)?e:[e],n=i.length>P?L.fromArray(i):null;return this.layers.add(t,({ctx:r,config:o,topLeft:m})=>{let l=this.getViewportBounds(m,o),d=n?n.query(l.minX,l.minY,l.maxX,l.maxY):i;r.save();for(let h of d){let p=h.size??1,f=h.style;if(!n&&!this.isVisible(h.x,h.y,p,m,o))continue;let c=p*this.camera.scale*.3,u=f?.fontFamily??"sans-serif";r.font=`${c}px ${u}`,f?.fillStyle&&(r.fillStyle=f.fillStyle),r.textAlign=f?.textAlign??"center",r.textBaseline=f?.textBaseline??"middle";let g=this.transformer.worldToScreen(h.x,h.y),v=h.rotate??0;if(v!==0){let w=v*(Math.PI/180);r.save(),r.translate(g.x,g.y),r.rotate(w),r.fillText(h.text,0,0),r.restore()}else r.fillText(h.text,g.x,g.y)}r.restore()})}drawPath(e,t,i=1){let s=Array.isArray(e[0])?e:[e];return this.layers.add(i,({ctx:n,config:r,topLeft:o})=>{n.save(),t?.strokeStyle&&(n.strokeStyle=t.strokeStyle);let m=t?.lineWidth?_(n,t.lineWidth):void 0;n.beginPath();for(let l of s){if(!l.length)continue;let d=l.map(y=>y.x),h=l.map(y=>y.y),p=Math.min(...d),f=Math.max(...d),c=Math.min(...h),u=Math.max(...h),g=(p+f)/2,v=(c+u)/2,w=Math.max(f-p,u-c)/2;if(!this.isVisible(g,v,w,o,r))continue;let b=this.transformer.worldToScreen(l[0].x,l[0].y);n.moveTo(b.x,b.y);for(let y=1;y<l.length;y++){let T=this.transformer.worldToScreen(l[y].x,l[y].y);n.lineTo(T.x,T.y)}}n.stroke(),m?.(),n.restore()})}drawImage(e,t=1){let i=Array.isArray(e)?e:[e],n=i.length>P?L.fromArray(i):null;return this.layers.add(t,({ctx:r,config:o,topLeft:m})=>{let l=this.getViewportBounds(m,o),d=n?n.query(l.minX,l.minY,l.maxX,l.maxY):i;for(let h of d){let p=h.size??1,f={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,p/2,m,o))continue;let c=this.transformer.worldToScreen(h.x,h.y),u=p*this.camera.scale,g=h.img.width/h.img.height,v=u,w=u;g>1?w=u/g:v=u*g;let{x:b,y}=this.computeOriginOffset(c,u,f,this.camera),T=b+(u-v)/2,S=y+(u-w)/2,I=h.rotate??0,ie=I*(Math.PI/180);if(I!==0){let M=T+v/2,se=S+w/2;r.save(),r.translate(M,se),r.rotate(ie),r.drawImage(h.img,-v/2,-w/2,v,w),r.restore()}else r.drawImage(h.img,T,S,v,w)}})}drawGridLines(e,t,i=0){return this.layers.add(i,({ctx:s,config:n,topLeft:r})=>{let o=n.size.width/n.scale,m=n.size.height/n.scale,l=Math.floor(r.x/e)*e-x.CELL_CENTER_OFFSET,d=Math.ceil((r.x+o)/e)*e-x.CELL_CENTER_OFFSET,h=Math.floor(r.y/e)*e-x.CELL_CENTER_OFFSET,p=Math.ceil((r.y+m)/e)*e-x.CELL_CENTER_OFFSET;s.save(),s.strokeStyle=t.strokeStyle;let f=_(s,t.lineWidth);s.beginPath();for(let c=l;c<=d;c+=e){let u=this.transformer.worldToScreen(c,h),g=this.transformer.worldToScreen(c,p);s.moveTo(u.x,u.y),s.lineTo(g.x,g.y)}for(let c=h;c<=p;c+=e){let u=this.transformer.worldToScreen(l,c),g=this.transformer.worldToScreen(d,c);s.moveTo(u.x,u.y),s.lineTo(g.x,g.y)}s.stroke(),f(),s.restore()})}computeOriginOffset(e,t,i,s){if(i.mode==="cell"){let n=s.scale;return{x:e.x-n/2+i.x*n-t/2,y:e.y-n/2+i.y*n-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 s=1/0,n=-1/0,r=1/0,o=-1/0;for(let u of e){let g=u.size??1;u.x-g/2<s&&(s=u.x-g/2),u.x+g/2>n&&(n=u.x+g/2),u.y-g/2<r&&(r=u.y-g/2),u.y+g/2>o&&(o=u.y+g/2)}s-=1,r-=1,n+=1,o+=1;let m=n-s,l=o-r,d=this.camera.scale,h=Math.ceil(m*d),p=Math.ceil(l*d);if(h>pe||p>pe)return this.warnedStaticCacheDisabled||(console.warn(`Static cache disabled: offscreen canvas too large (${h}x${p}).`),this.warnedStaticCacheDisabled=!0),null;let f=this.staticCaches.get(t);if(!f||f.scale!==d||f.worldBounds.minX!==s||f.worldBounds.maxX!==n||f.worldBounds.minY!==r||f.worldBounds.maxY!==o){let u=typeof OffscreenCanvas<"u"?new OffscreenCanvas(h,p):document.createElement("canvas");typeof OffscreenCanvas<"u"&&u instanceof OffscreenCanvas||(u.width=h,u.height=p);let v=u.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)*d,T=(w.x+x.CELL_CENTER_OFFSET-s)*d-y/2,S=(w.y+x.CELL_CENTER_OFFSET-r)*d-y/2;i(v,w,T,S,y)}f={canvas:u,ctx:v,worldBounds:{minX:s,minY:r,maxX:n,maxY:o},scale:d},this.staticCaches.set(t,f)}return f||null}addStaticCacheLayer(e,t){if(!e)return null;let i=e.canvas,s=e.worldBounds,n=e.scale;return this.layers.add(t,({ctx:r,config:o,topLeft:m})=>{let l=o.size.width/o.scale,d=o.size.height/o.scale,h=(m.x-s.minX)*n,p=(m.y-s.minY)*n,f=l*n,c=d*n,u=0,g=0,v=o.size.width,w=o.size.height,b=i.width,y=i.height;if(h<0&&(u=-h/n*o.scale,v-=u,f+=h,h=0),p<0&&(g=-p/n*o.scale,w-=g,c+=p,p=0),h+f>b){let S=(h+f-b)/n;f=b-h,v-=S*o.scale}if(p+c>y){let S=(p+c-y)/n;c=y-p,w-=S*o.scale}f>0&&c>0&&v>0&&w>0&&r.drawImage(i,h,p,f,c,u,g,v,w)})}drawStaticRect(e,t,i=1){let s,n=this.getOrCreateStaticCache(e,t,(r,o,m,l,d)=>{let h=o.style,p=o.rotate??0,f=p*(Math.PI/180),c=o.radius;if(h?.fillStyle&&h.fillStyle!==s&&(r.fillStyle=h.fillStyle,s=h.fillStyle),p!==0){let u=m+d/2,g=l+d/2;r.save(),r.translate(u,g),r.rotate(f),c&&r.roundRect?(r.beginPath(),r.roundRect(-d/2,-d/2,d,d,c),r.fill()):r.fillRect(-d/2,-d/2,d,d),r.restore()}else c&&r.roundRect?(r.beginPath(),r.roundRect(m,l,d,d,c),r.fill()):r.fillRect(m,l,d,d)});return n?this.addStaticCacheLayer(n,i):this.drawRect(e,i)}drawStaticImage(e,t,i=1){let s=this.getOrCreateStaticCache(e,t,(n,r,o,m,l)=>{let d=r.img,h=r.rotate??0,p=h*(Math.PI/180),f=d.width/d.height,c=l,u=l;f>1?u=l/f:c=l*f;let g=o+(l-c)/2,v=m+(l-u)/2;if(h!==0){let w=g+c/2,b=v+u/2;n.save(),n.translate(w,b),n.rotate(p),n.drawImage(d,-c/2,-u/2,c,u),n.restore()}else n.drawImage(d,g,v,c,u)});return s?this.addStaticCacheLayer(s,i):this.drawImage(e,i)}drawStaticCircle(e,t,i=1){let s,n=this.getOrCreateStaticCache(e,t,(r,o,m,l,d)=>{let h=o.style,p=d/2;h?.fillStyle&&h.fillStyle!==s&&(r.fillStyle=h.fillStyle,s=h.fillStyle),r.beginPath(),r.arc(m+p,l+p,p,0,Math.PI*2),r.fill()});return n?this.addStaticCacheLayer(n,i):this.drawCircle(e,i)}clearStaticCache(e){e?this.staticCaches.delete(e):this.staticCaches.clear()}destroy(){this.staticCaches.clear(),this.layers.clear()}};var $=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 B=class{constructor(e,t,i,s,n,r){this.canvas=e;this.camera=t;this.viewport=i;this.config=s;this.transformer=n;this.onCameraChange=r}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,s=e.clientY-t.top,n=this.transformer.screenToWorld(i,s),r=this.transformer.worldToScreen(Math.floor(n.x),Math.floor(n.y));return{coords:{raw:n,snapped:{x:Math.floor(n.x),y:Math.floor(n.y)}},mouse:{raw:{x:i,y:s},snapped:{x:r.x,y:r.y}},client:{raw:{x:e.clientX,y:e.clientY},snapped:{x:r.x+t.left,y:r.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:s}=this.getEventCoords(e);this.onClick(t,i,s)};handleContextMenu=e=>{if(!this.config.get().eventHandlers.rightClick||!this.onRightClick)return;e.preventDefault();let{coords:t,mouse:i,client:s}=this.getEventCoords(e);this.onRightClick(t,i,s)};handleMouseDown=e=>{if(this.onMouseDown){let{coords:t,mouse:i,client:s}=this.getEventCoords(e);this.onMouseDown(t,i,s)}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:s,mouse:n,client:r}=this.getEventCoords(e);this.onHover(s,n,r)}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:s}=this.getEventCoords(e);this.onMouseUp(t,i,s)}this.isDragging=!1,this.canvas.style.cursor=this.config.get().cursor.default||"default"};handleMouseLeave=e=>{if(this.onMouseLeave){let{coords:t,mouse:i,client:s}=this.getEventCoords(e);this.onMouseLeave(t,i,s)}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.shouldPreventClick=!0,this.lastPinchDistance=this.getTouchDistance(e.touches),this.lastPinchCenter=this.getTouchCenter(e.touches);return}if(e.touches.length!==1)return;let i=e.touches[0];if(this.onMouseDown){e.preventDefault();let{coords:s,mouse:n,client:r}=this.getEventCoords(i);this.onMouseDown(s,n,r)}t.drag&&(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 n=this.getTouchDistance(e.touches),r=this.getTouchCenter(e.touches),o=this.canvas.getBoundingClientRect(),m=n/this.lastPinchDistance,l=r.x-o.left,d=r.y-o.top;this.camera.zoomByFactor(m,l,d);let h=r.x-this.lastPinchCenter.x,p=r.y-this.lastPinchCenter.y;(h!==0||p!==0)&&this.camera.pan(h,p),this.lastPinchDistance=n,this.lastPinchCenter=r,this.onZoom&&this.onZoom(this.camera.scale),this.onCameraChange();return}if(e.touches.length!==1)return;let t=e.touches[0];if(this.onHover&&this.config.get().eventHandlers.hover){e.preventDefault();let{coords:n,mouse:r,client:o}=this.getEventCoords(t);this.onHover(n,r,o)}if(!this.isDragging)return;e.preventDefault();let i=t.clientX-this.lastPos.x,s=t.clientY-this.lastPos.y;(i!==0||s!==0)&&(this.canvas.style.cursor=this.config.get().cursor.move||"move",this.shouldPreventClick=!0),this.camera.pan(i,s),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}if(e.changedTouches.length>0&&this.onMouseUp){let t=e.changedTouches[0],{coords:i,mouse:s,client:n}=this.getEventCoords(t);this.onMouseUp(i,s,n)}if(e.changedTouches.length>0&&!this.shouldPreventClick&&this.config.get().eventHandlers.click&&this.onClick){e.preventDefault();let t=e.changedTouches[0],{coords:i,mouse:s,client:n}=this.getEventCoords(t);this.onClick(i,s,n)}this.isDragging=!1,this.isPinching=!1,this.shouldPreventClick=!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 U=class{constructor(e,t,i,s,n,r){this.wrapper=e;this.canvas=t;this.viewport=i;this.camera=s;this.config=n;this.onCameraChange=r;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,s=t?.maxHeight,n=t?.minWidth,r=t?.minHeight;e.width=this.clamp(e.width,n,i),e.height=this.clamp(e.height,r,s),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:s?`${s}px`:"",minWidth:n?`${n}px`:"",minHeight:r?`${r}px`:""}),this.resizeObserver=new ResizeObserver(o=>{for(let m of o){let{width:l,height:d}=m.contentRect,h=this.clamp(l,n,i),p=this.clamp(d,r,s),f=this.viewport.getSize();if(h===f.width&&p===f.height)continue;let c=h-f.width,u=p-f.height,g=this.viewport.dpr;this.camera.adjustForResize(c,u),this.viewport.setSize(h,p),this.canvas.width=h*g,this.canvas.height=p*g,this.canvas.style.width=`${h}px`,this.canvas.style.height=`${p}px`,this.wrapper.style.width=`${h}px`,this.wrapper.style.height=`${p}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 s=e;return t!==void 0&&(s=Math.max(t,s)),i!==void 0&&(s=Math.min(i,s)),s}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:s}=this.viewport.getSize();this.canvas.width=i*t,this.canvas.height=s*t,this.canvas.style.width=`${i}px`,this.canvas.style.height=`${s}px`,this.onResize&&this.onResize(),this.onCameraChange()},window.addEventListener("resize",this.handleWindowResize,{passive:!0}))}};var V=class{constructor(e,t,i,s,n,r,o){this.canvasWrapper=e;this.canvas=t;this.camera=i;this.viewport=s;this.config=n;this.coordinateTransformer=r;this.onCameraChange=o;this.gestures=new B(this.canvas,this.camera,this.viewport,this.config,this.coordinateTransformer,this.onCameraChange),this.binder=new $(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().responsive?this.config.get().eventHandlers.resize&&console.warn("Canvas Tile Engine: eventHandlers.resize is ignored when responsive mode is enabled. Resizing is handled automatically."):this.config.get().eventHandlers.resize&&this.camera instanceof H&&(this.resizeWatcher=new U(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 Z=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=x.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((s,n)=>{let r=new Image;r.crossOrigin="anonymous",r.decoding="async",r.loading="eager",r.onload=async()=>{try{"decode"in r&&await r.decode?.()}catch{}this.cache.set(e,r),this.inflight.delete(e),this.notifyLoaded(),s(r)},r.onerror=o=>{if(this.inflight.delete(e),t>0)console.warn(`Retrying image: ${e}`),s(this.load(e,t-1));else{console.error(`Image failed to load: ${e}`,o);let m=o instanceof Error?o.message:typeof o=="string"?o:JSON.stringify(o);n(new Error(`Image failed to load: ${e}. Reason: ${m}`))}},r.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 q=class{layers=new Map;add(e,t){let i=Symbol("layer-callback"),s={id:i,fn:t};return this.layers.has(e)||this.layers.set(e,[]),this.layers.get(e).push(s),{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,s)=>i-s);for(let i of t){let s=this.layers.get(i);if(s)for(let{fn:n}of s)e.ctx.save(),n(e),e.ctx.restore()}}};var G=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,i,s){this.ctx=e,this.camera=t,this.config=i,this.viewport=s}draw(){this.ctx.save(),this.ctx.fillStyle=`rgba(0, 0, 0, ${E.BORDER_OPACITY})`;let{width:e,height:t}=this.viewport.getSize();this.ctx.fillRect(0,0,E.BORDER_WIDTH,t),this.ctx.fillRect(E.BORDER_WIDTH,t-E.BORDER_WIDTH,e,E.BORDER_WIDTH),this.ctx.fillStyle=`rgba(255, 255, 255, ${E.TEXT_OPACITY})`;let i=Math.min(E.MAX_FONT_SIZE,Math.max(E.MIN_FONT_SIZE,this.camera.scale*E.FONT_SIZE_SCALE_FACTOR));this.ctx.font=`${i}px Arial`,this.ctx.textAlign="center",this.ctx.textBaseline="middle";let s=this.camera.scale,n=e/s,r=t/s;for(let o=0-this.camera.y%1;o<=r+1;o++)this.ctx.fillText(Math.round(this.camera.y+o).toString(),10,s*o+s/2);for(let o=0-this.camera.x%1;o<=n+1;o++)this.ctx.fillText(Math.round(this.camera.x+o).toString(),s*o+s/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:s}=t.shownScaleRange;return e>=i&&e<=s}};var Ee=10,A=class{ctx;camera;transformer;config;viewport;frameTimes=[];lastFrameTime=0;currentFps=0;fpsLoopRunning=!1;onFpsUpdate=null;constructor(e,t,i,s,n){this.ctx=e,this.camera=t,this.transformer=i,this.config=s,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>Ee&&this.frameTimes.shift();let i=this.frameTimes.reduce((n,r)=>n+r,0)/this.frameTimes.length,s=Math.round(1e3/i);s!==this.currentFps&&(this.currentFps=s,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:n,height:r}=this.viewport.getSize(),o=this.camera.getCenter(n,r);t.push(`Coords: ${o.x.toFixed(2)}, ${o.y.toFixed(2)}`)}if(e.debug.hud.scale&&t.push(`Scale: ${this.camera.scale.toFixed(2)}`),e.debug.hud.tilesInView){let{width:n,height:r}=this.viewport.getSize();t.push(`Tiles in view: ${Math.ceil(n/this.camera.scale)} x ${Math.ceil(r/this.camera.scale)}`)}e.debug.hud.fps&&t.push(`FPS: ${this.currentFps}`);let{width:s}=this.viewport.getSize();this.ctx.save(),this.ctx.fillStyle="rgba(0,0,0,0.5)",this.ctx.fillRect(s-z.PANEL_WIDTH-z.PADDING,z.PADDING/2,z.PANEL_WIDTH,t.length*z.LINE_HEIGHT+z.PADDING),this.ctx.fillStyle="#00ff99",this.ctx.font="12px monospace";for(let n=0;n<t.length;n++)this.ctx.fillText(t[n],s-z.PANEL_WIDTH-z.PADDING+5,18+n*z.LINE_HEIGHT);this.ctx.restore()}};var k=class{constructor(e,t,i,s,n,r){this.canvas=e;this.camera=t;this.coordinateTransformer=i;this.config=s;this.viewport=n;this.layers=r;let o=e.getContext("2d");if(!o)throw new Error("Failed to get 2D canvas context");this.ctx=o,this.applyCanvasSize(),this.coordinateOverlayRenderer=new j(this.ctx,this.camera,this.config,this.viewport),this.config.get().debug?.enabled&&(this.debugOverlay=new A(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},s={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:s}),this.onDraw?.(this.ctx,{scale:this.camera.scale,width:i.size.width,height:i.size.height,coords:s}),this.coordinateOverlayRenderer.shouldDraw(this.camera.scale)&&this.coordinateOverlayRenderer.draw(),i.debug?.enabled&&(this.debugOverlay||(this.debugOverlay=new A(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,s,n,r,o){this.canvasWrapper=e,this.canvas=t,this.camera=i,this.renderer=s,this.viewport=n,this.config=r,this.onSizeApplied=o}resizeWithAnimation(e,t,i,s,n){if(e<=0||t<=0)return;let r=this.config.get().size,o=(m,l,d)=>{let h=m;return l!==void 0&&(h=Math.max(l,h)),d!==void 0&&(h=Math.min(d,h)),h};e=o(e,r?.minWidth,r?.maxWidth),t=o(t,r?.minHeight,r?.maxHeight),s.animateResize(e,t,i,(m,l,d)=>this.applySize(m,l,d),n)}applySize(e,t,i){let s=Math.round(e),n=Math.round(t),r=this.viewport.dpr;this.viewport.setSize(s,n),this.canvasWrapper.style.width=`${s}px`,this.canvasWrapper.style.height=`${n}px`,this.canvas.width=s*r,this.canvas.height=n*r,this.canvas.style.width=`${s}px`,this.canvas.style.height=`${n}px`,this.camera.setCenter(i,s,n),this.renderer.resize(s,n),this.onSizeApplied()}};var K=class{constructor(e,t,i){this.camera=e;this.viewport=t;this.onAnimationFrame=i}moveAnimationId;resizeAnimationId;animateMoveTo(e,t,i=x.ANIMATION_DURATION_MS,s){if(this.cancelMove(),i<=0){let l=this.viewport.getSize();this.camera.setCenter({x:e,y:t},l.width,l.height),this.onAnimationFrame(),s?.();return}let n=this.viewport.getSize(),r=this.camera.getCenter(n.width,n.height),o=performance.now(),m=l=>{let d=l-o,h=Math.min(1,d/i),p=h<.5?2*h*h:1-Math.pow(-2*h+2,2)/2,f=r.x+(e-r.x)*p,c=r.y+(t-r.y)*p,u=this.viewport.getSize();this.camera.setCenter({x:f,y:c},u.width,u.height),this.onAnimationFrame(),h<1?this.moveAnimationId=requestAnimationFrame(m):(this.moveAnimationId=void 0,s?.())};this.moveAnimationId=requestAnimationFrame(m)}animateResize(e,t,i=x.ANIMATION_DURATION_MS,s,n){if(e<=0||t<=0)return;this.cancelResize();let r=this.viewport.getSize(),o=this.camera.getCenter(r.width,r.height);if(i<=0){s(e,t,o),n?.();return}let m=r.width,l=r.height,d=e-r.width,h=t-r.height,p=performance.now(),f=c=>{let u=c-p,g=Math.min(1,u/i),v=m+d*g,w=l+h*g;s(v,w,o),g<1?this.resizeAnimationId=requestAnimationFrame(f):(this.resizeAnimationId=void 0,n?.())};this.resizeAnimationId=requestAnimationFrame(f)}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,s,n,r,o){switch(e){case"canvas":return new k(t,i,s,n,r,o);default:throw new Error(`Unsupported renderer type: ${e}`)}}static isSupported(e){return e==="canvas"}static getSupportedTypes(){return["canvas"]}};var ee=class{constructor(e,t,i,s,n,r,o){this.wrapper=e;this.canvas=t;this.camera=i;this.renderer=s;this.viewport=n;this.config=r;this.onCameraChange=o;this.currentDpr=this.viewport.dpr;let m=this.config.get();this.initialVisibleTiles={x:m.size.width/m.scale,y:m.size.height/m.scale},this.widthLimits={min:m.minScale*this.initialVisibleTiles.x,max:m.maxScale*this.initialVisibleTiles.x}}resizeObserver;handleWindowResize;currentDpr;initialVisibleTiles;widthLimits;onResize;start(){let e=this.config.get().responsive;if(!e)return;if(this.viewport.updateDpr(),this.currentDpr=this.viewport.dpr,e==="preserve-viewport"){let n=this.initialVisibleTiles.y/this.initialVisibleTiles.x;this.wrapper.style.width="100%",this.wrapper.style.minWidth=`${this.widthLimits.min}px`,this.wrapper.style.maxWidth=`${this.widthLimits.max}px`,this.wrapper.style.minHeight=`${this.widthLimits.min*n}px`,this.wrapper.style.maxHeight=`${this.widthLimits.max*n}px`}else{let n=this.config.get();this.wrapper.style.width="100%",this.wrapper.style.height=`${n.size.height}px`}let t=this.wrapper.getBoundingClientRect(),i=Math.round(t.width),s=Math.round(t.height);this.applySize(i,s,e),this.resizeObserver=new ResizeObserver(n=>{for(let r of n){let{width:o,height:m}=r.contentRect,l=Math.round(o),d=Math.round(m);if(l<=0||d<=0)continue;let h=this.viewport.getSize();l===h.width&&d===h.height||(this.applySize(l,d,e),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)}applySize(e,t,i){let s=this.viewport.dpr,n=this.viewport.getSize();if(i==="preserve-viewport"){let r=e/this.initialVisibleTiles.x,o=Math.round(this.initialVisibleTiles.y*r);t=o,this.wrapper.style.height=`${o}px`;let m=this.camera.getCenter(n.width,n.height);this.camera.setScale(r),this.camera.setCenter(m,e,t)}else{let r=e-n.width,o=t-n.height;this.camera.adjustForResize(r,o)}this.viewport.setSize(e,t),this.canvas.width=e*s,this.canvas.height=t*s,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.renderer.resize(e,t)}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:s}=this.viewport.getSize();this.canvas.width=i*t,this.canvas.height=s*t,this.canvas.style.width=`${i}px`,this.canvas.style.height=`${s}px`,this.onResize?.(),this.onCameraChange()},window.addEventListener("resize",this.handleWindowResize,{passive:!0}))}};var te=class{config;camera;viewport;coordinateTransformer;layers;renderer;events;draw;images;sizeController;animationController;responsiveWatcher;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"),t.responsive?Object.assign(this.canvasWrapper.style,{position:"relative"}):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 Y(t);let s=t.renderer??"canvas",n=t.size.width/t.scale,r=t.size.height/t.scale,o=t.gridAligned&&n%2===0?Math.floor(i.x)+.5:i.x,m=t.gridAligned&&r%2===0?Math.floor(i.y)+.5:i.y,l={x:o-t.size.width/(2*t.scale),y:m-t.size.height/(2*t.scale)};this.viewport=new G(t.size.width,t.size.height),this.camera=new H(l,this.config.get().scale,this.config.get().minScale,this.config.get().maxScale,this.viewport),this.coordinateTransformer=new X(this.camera),this.animationController=new K(this.camera,this.viewport,()=>this.handleCameraChange()),this.renderer=this.createRenderer(s),this.images=new Z,this.events=new V(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.responsive&&(this.responsiveWatcher=new ee(this.canvasWrapper,this.canvas,this.camera,this.renderer,this.viewport,this.config,()=>this.handleCameraChange()),this.responsiveWatcher.onResize=()=>{this._onResize?.()},this.responsiveWatcher.start()),t.bounds&&this.camera.setBounds(t.bounds)}destroy(){this.events.destroy(),this.responsiveWatcher?.stop(),this.animationController.cancelAll(),this.draw?.destroy(),this.layers?.clear(),this.images.clear(),this.renderer.destroy()}render(){this.renderer.render()}resize(e,t,i=500,s){if(this.config.get().responsive){console.warn("Canvas Tile Engine: resize() is disabled when responsive mode is enabled. Canvas size is controlled by the wrapper element.");return}this.sizeController.resizeWithAnimation(e,t,i,this.animationController,()=>{this._onResize?.(),s?.()})}getSize(){return this.viewport.getSize()}getScale(){return this.camera.scale}setScale(e){me(e),this.camera.setScale(e),this.handleCameraChange()}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){re(e.x,e.y);let t=this.viewport.getSize();this.camera.setCenter(e,t.width,t.height),this.handleCameraChange()}goCoords(e,t,i=500,s){re(e,t),this.animationController.animateMoveTo(e,t,i,s)}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=2){return this.ensureCanvasDraw().drawText(e,t)}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",s=0){return this.ensureCanvasDraw().drawGridLines(e,{lineWidth:t,strokeStyle:i},s)}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 q,this.draw=new N(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 k))throw new Error("Canvas renderer required for this operation.");return this.renderer}handleCameraChange(){this.onCoordsChange&&this.onCoordsChange(this.getCenterCoords()),this.render()}};function ve(a){return{size:{width:a.columns*a.cellSize,height:a.rows*a.cellSize},scale:a.cellSize}}0&&(module.exports={COORDINATE_OVERLAY,CanvasTileEngine,DEBUG_HUD,DEFAULT_VALUES,RENDER_DEFAULTS,SCALE_LIMITS,SIZE_LIMITS,VISIBILITY_BUFFER,gridToSize});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|