@ray-js/robot-map-sdk 0.0.3-beta-12 → 0.0.3-beta-13
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/application/MapApplication.js +1 -1
- package/dist/components/Map/RoomFill.js +1 -1
- package/dist/components/RoomFloorType/index.js +1 -1
- package/dist/components/RoomInfo/RoomName.js +1 -1
- package/dist/components/RoomInfo/RoomProperty.js +1 -1
- package/dist/components/RoomInfo/RoomSelectionIndicator.js +1 -1
- package/dist/constant/config.js +1 -1
- package/dist/index.d.ts +26 -6
- package/dist/index.rjs.js +1 -1
- package/dist/managers/MapManager.js +1 -1
- package/dist/managers/RoomManager.js +1 -1
- package/dist/utils/algorithm.js +1 -1
- package/dist-app/assets/{index-BCC761Na.js → index-DEl6eabz.js} +1 -1
- package/dist-app/index.html +1 -1
- package/dist-docs/404.html +2 -2
- package/dist-docs/assets/{app.896xnLF3.js → app.D-obOMzx.js} +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.DjeFOaBq.js +1 -0
- package/dist-docs/assets/chunks/{VPLocalSearchBox.D2USf4cd.js → VPLocalSearchBox.BlP3UL6y.js} +1 -1
- package/dist-docs/assets/chunks/{theme.CMExH5VI.js → theme.DifRD7r0.js} +2 -2
- package/dist-docs/assets/{guide_advanced-usage.md.DUawnQ9c.js → guide_advanced-usage.md.CUkMfTh6.js} +4 -3
- package/dist-docs/assets/{guide_advanced-usage.md.DUawnQ9c.lean.js → guide_advanced-usage.md.CUkMfTh6.lean.js} +1 -1
- package/dist-docs/assets/{guide_getting-started.md.JQJjuJPZ.js → guide_getting-started.md.DpAaFNd5.js} +1 -1
- package/dist-docs/assets/reference_config.md.BAU8soPd.js +41 -0
- package/dist-docs/assets/{reference_config.md.DGFTKy3W.lean.js → reference_config.md.BAU8soPd.lean.js} +1 -1
- package/dist-docs/assets/{reference_methods.md.B71e_LYO.js → reference_methods.md.Cw2UFl8i.js} +3 -6
- package/dist-docs/assets/{reference_methods.md.B71e_LYO.lean.js → reference_methods.md.Cw2UFl8i.lean.js} +1 -1
- package/dist-docs/guide/advanced-usage.html +8 -7
- package/dist-docs/guide/concepts.html +3 -3
- package/dist-docs/guide/getting-started.html +5 -5
- package/dist-docs/hashmap.json +1 -1
- package/dist-docs/index.html +3 -3
- package/dist-docs/reference/callbacks.html +3 -3
- package/dist-docs/reference/config.html +5 -5
- package/dist-docs/reference/data.html +3 -3
- package/dist-docs/reference/methods.html +6 -9
- package/dist-docs/reference/runtime.html +3 -3
- package/dist-docs/reference/types.html +3 -3
- package/dist-docs/reference/utils.html +3 -3
- package/package.json +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.Cr-cfrpg.js +0 -1
- package/dist-docs/assets/reference_config.md.DGFTKy3W.js +0 -41
- /package/dist-docs/assets/{guide_getting-started.md.JQJjuJPZ.lean.js → guide_getting-started.md.DpAaFNd5.lean.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Application as e,isMobile as t,Assets as n}from"pixi.js";import{Interaction as a}from"./Interaction.js";import{merge as r}from"lodash-es";import{proxy as i}from"valtio/vanilla";import{MAIN_INSTANCE_KEY as o}from"../constant/index.js";import s from"mitt";import{Logger as c}from"../utils/logger.js";import{AppContext as h}from"./AppService.js";import{nanoid as d}from"nanoid/non-secure";import{calculateLineEndpoints as p,areStructuredRoomsAdjacent as m,areMultipleRoomsConnected as l,areRasterRoomsAdjacent as g}from"../utils/algorithm.js";import{ViewportContainer as u}from"./ViewportContainer.js";import{AppContainer as w}from"./AppContainer.js";import{MapManager as f}from"../managers/MapManager.js";import{PathManager as M}from"../managers/PathManager.js";import{HeatmapManager as y}from"../managers/HeatmapManager.js";import{ControlsManager as x}from"../managers/ControlsManager.js";import{DetectedObjectManager as S}from"../managers/DetectedObjectManager.js";import{CustomElementsManager as v}from"../managers/CustomElementsManager.js";import{RoomManager as b}from"../managers/RoomManager.js";import{getOptimalAntialiasingStrategy as P}from"../utils/browser.js";import{DEFAULT_CONFIG as C,DEFAULT_RUNTIME_CONFIG as R}from"../constant/config.js";class O extends e{mapState=null;components={};managers={};config=C;runtime;scaleMin=.5;scaleMax=5;events={};instanceKey;containerElement;emitter=s();tickerState={renderReasons:new Set,renderTimer:null};pendingAsyncRender=!1;isFirstMapDraw=!0;constructor(e=o){super(),this.instanceKey=e,h.registerInstance(e,this),globalThis.__PIXI_APP__=this}async initialize(e){return h.provideAsync(this,async()=>{const{resizeTo:n,events:a,config:s,runtime:c={},...h}=e;this.config=r(this.config,s??{}),this.runtime=i(Object.assign({},R,c));const d=this.instanceKey===o;this.containerElement=n;const p=d?{textureGCMaxIdle:t.any?180:3600,textureGCCheckCountMax:t.any?100:50,autoStart:!1,eventFeatures:{move:!0,globalMove:!1,click:!0,wheel:!0}}:{textureGCMaxIdle:60,textureGCCheckCountMax:10,autoStart:!1,eventFeatures:{move:!1,globalMove:!1,click:!1,wheel:!1}};await this.init({resizeTo:d?n:void 0,preferWebGLVersion:2,resolution:window.devicePixelRatio||1,antialias:P(),autoDensity:!0,backgroundColor:this.config.global.backgroundColor,...p,...h}),this.preloadAssets(),this.scaleMax=this.config.interaction.zoomRange.max,this.scaleMin=this.config.interaction.zoomRange.min,this.events=a,this.initializeViewportContainer(),this.initializeInteraction(),this.initializeAppContainer(),this.managers.mapManager=new f,this.managers.heatmapManager=new y,this.managers.pathManager=new M,this.managers.controlsManager=new x,this.managers.detectedObjectManager=new S,this.managers.customElementsManager=new v,this.managers.roomsManager=new b,document.addEventListener("visibilitychange",this.onVisibilityChange)})}async drawMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawMap",e);const{size:t,resolution:n,origin:a}=e;a[0]===this.mapState?.origin.x&&a[1]===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(...a),this.managers.controlsManager.updatePositionByOrigin(...a),this.managers.detectedObjectManager.updatePositionByOrigin(...a),this.managers.customElementsManager.updatePositionByOrigin(...a)),this.mapState={id:e.id,status:1===e.status,origin:{x:a[0],y:a[1]},charger:{x:e.charger.coordinate[0],y:e.charger.coordinate[1]},chargerDirection:e.charger.angle??0,resolution:n,width:t[0],height:t[1]},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawMap(e),this.renderOnce()})}async drawRasterMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawRasterMap",e);const{mapHeader:t,mapData:n}=e,{originX:a,originY:r}=t;a===this.mapState?.origin.x&&r===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(a,r),this.managers.controlsManager.updatePositionByOrigin(a,r),this.managers.detectedObjectManager.updatePositionByOrigin(a,r),this.managers.customElementsManager.updatePositionByOrigin(a,r)),this.mapState={id:t.id,status:t.mapStable,origin:{x:a,y:r},charger:{x:t.chargeX,y:t.chargeY},chargerDirection:t.chargeDirection??0,resolution:100*t.mapResolution,width:t.mapWidth,height:t.mapHeight,version:t.version},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawRasterMap(n.parsed,this.mapState),this.renderOnce()})}drawPath(e){return h.provide(this,()=>{c.log("[Path] drawPath",e),this.events?.onPathDrawed?.({id:e.pathHeader.pathId,type:e.pathHeader.type,direction:e.pathHeader.direction,count:e.pathHeader.count,initFlag:e.pathHeader.initFlag,robotPosition:e.pathPoints[e.pathPoints.length-1]??null}),this.managers.pathManager.draw(e),this.renderOnce()})}async drawRoomProperty(e){return h.provide(this,()=>{c.log("[Room] drawRoomProperty",e),this.events?.onRoomPropertiesDrawed?.(e),this.managers.roomsManager.drawRoomProperty(e),this.renderOnceNextFrame()})}drawHeatmap({mapData:e,heatmapPoints:t,useGradient:n=!0}){return h.provide(this,()=>{c.log("[Heatmap] drawHeatmap",t),this.managers.heatmapManager.draw({mapData:e,heatmapPoints:t,useGradient:n}),this.renderOnce()})}drawForbiddenSweepZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenSweepZones",e),this.managers.controlsManager.drawForbiddenSweepZones(e),this.renderOnceNextFrame()})}drawForbiddenMopZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenMopZones",e),this.managers.controlsManager.drawForbiddenMopZones(e),this.renderOnceNextFrame()})}drawCleanZones(e){return h.provide(this,()=>{c.log("[Controls] drawCleanZones",e),this.managers.controlsManager.drawCleanZones(e),this.renderOnceNextFrame()})}drawVirtualWalls(e){return h.provide(this,()=>{c.log("[Controls] drawVirtualWalls",e),this.managers.controlsManager.drawVirtualWalls(e),this.renderOnceNextFrame()})}drawSpots(e){return h.provide(this,()=>{c.log("[Controls] drawSpots",e),this.managers.controlsManager.drawSpots(e),this.renderOnceNextFrame()})}async drawDetectedObjects(e){return h.provideAsync(this,async()=>{c.log("[DetectedObject] drawDetectedObjects",e),await this.managers.detectedObjectManager.drawDetectedObjects(e),this.renderOnceNextFrame()})}async drawCustomElements(e){return h.provideAsync(this,async()=>{c.log("[CustomElements] drawCustomElements",e),await this.managers.customElementsManager.drawCustomElements(e),this.renderOnceNextFrame()})}getForbiddenSweepZones(){return this.managers.controlsManager.getForbiddenSweepZones()}getForbiddenMopZones(){return this.managers.controlsManager.getForbiddenMopZones()}getCleanZones(){return this.managers.controlsManager.getCleanZones()}getVirtualWalls(){return this.managers.controlsManager.getVirtualWalls()}getSpots(){return this.managers.controlsManager.getSpots()}getEffectiveDividerPoints(){return this.managers.controlsManager.getEffectiveDividerPoints()}getDividerEndPoints(){return this.managers.controlsManager.getDividerEndPoints()}resetPanZoom(){this.components.interaction.setPanZoom()}fitMapToView(e,t=!1){return h.provide(this,()=>{if(!e||e.minX===e.maxX||e.minY===e.maxY)return void c.warn("地图边界无效,无法自动适配视图");const n=this.config.map.autoPaddingPercent||.1,a=this.getViewportBounds(),r=e.maxX-e.minX,i=e.maxY-e.minY,o=a.width,s=a.height,h=o*(1-2*n)/r,d=s*(1-2*n)/i,p=Math.min(h,d),m=Math.max(this.config.interaction.fitMinScale,this.scaleMin),l=Math.min(this.config.interaction.fitMaxScale,this.scaleMax),g=Math.max(m,Math.min(l,p)),u=o/2-(e.minX+r/2)*g,w=s/2-(e.minY+i/2)*g;this.components.interaction.setPanZoom({targetPosition:{x:u,y:w},targetScale:{x:g,y:g},setCenter:!0,setScale:!0},t)})}getViewportBounds(){return this.components.viewportContainer?.getViewportBounds()||{x:0,y:0,width:this.renderer.width,height:this.renderer.height}}updateRuntime(e){Object.assign(this.runtime,e),this.renderOnceNextFrame()}metersToPixels(e){return this.mapState?.resolution?e*(1/(this.mapState.resolution/100)):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),20*e)}pixelsToMeters(e){return this.mapState?.resolution?e*(this.mapState.resolution/100):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),.05*e)}toFixedSize(e,t){return e/(t??this.components.appContainer.scale.x)}fromFixedSize(e,t){return e*(t??this.components.appContainer.scale.x)}getViewportCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate center point"),null;const e=this.getViewportBounds(),t=e.x+e.width/2,n=e.y+e.height/2,a=this.components.appContainer,r=a.scale.x,i=(t-a.x)/r,o=(n-a.y)/r;return{x:i-this.mapState.origin.x,y:o-this.mapState.origin.y}}getMapCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate map center point"),null;const e=this.managers.mapManager.mapBounds;if(e.minX===1/0||e.minY===1/0||e.maxX===-1/0||e.maxY===-1/0)return c.warn("Invalid map bounds, cannot calculate map center point"),null;const t=(e.minX+e.maxX)/2,n=(e.minY+e.maxY)/2;return{x:t-this.mapState.origin.x,y:n-this.mapState.origin.y}}getWallPointsByViewportCenter(e){const{width:t=this.config.controls.virtualWall.minWidth,direction:n="horizontal",offsetX:a=0,offsetY:r=0}=e||{},i=this.getViewportCenterPoint()||{x:0,y:0},o=this.metersToPixels(t);return p(i.x,i.y,o,n).map(e=>({x:e.x+a,y:e.y+r}))}getForbiddenSweepZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenSweepZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getForbiddenMopZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenMopZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getCleanZonePointsByViewportCenter(e){const t=this.config.controls.cleanZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getSpotPointByViewportCenter(e){const{offsetX:t=0,offsetY:n=0}=e||{},a=this.getViewportCenterPoint()||{x:0,y:0};return{x:a.x+t,y:a.y+n}}areRoomsAdjacent(e,t=3){return h.provide(this,()=>{if(!e||0===e.length)return c.warn("[Room] No room IDs provided"),!1;if(1===e.length)return!0;const n=Array.from(new Set(e));return 1===n.length||(void 0!==this.mapState?.version?this.areRasterRoomsAdjacentInternal(n,t):this.areStructuredRoomsAdjacentInternal(n,t))})}areStructuredRoomsAdjacentInternal(e,t){const n=[];for(const t of e){const e=this.managers.mapManager.getRoomById(t);if(!e)return c.warn(`[Room] Room ${t} not found in map`),!1;if(!e.outlinePoints||0===e.outlinePoints.length)return c.warn(`[Room] Room ${t} has no outline points`),!1;n.push({id:t,points:e.outlinePoints})}const a=[];for(let e=0;e<n.length;e++)for(let r=e+1;r<n.length;r++){const i=n[e],o=n[r];m(i.points,o.points,t)&&a.push([e,r])}return l(n.length,a)}areRasterRoomsAdjacentInternal(e,t){if(!this.mapState)return c.warn("[Room] Map state not available"),!1;const n=this.mapState.width,a=[];for(const t of e){const e=this.managers.mapManager.getRasterRoomPixels(t);if(!e)return c.warn(`[Room] Room ${t} pixel data not found in raster map`),!1;a.push({id:t,pixels:e})}const r=[];for(let e=0;e<a.length;e++)for(let i=e+1;i<a.length;i++){const o=a[e],s=a[i];g(o.pixels,s.pixels,n,t)&&r.push([e,i])}return l(a.length,r)}async snapshot(){this.render(),await new Promise(e=>setTimeout(e,0));const{snapshot:e}=this.config;return await this.renderer.extract.base64({target:this.components.appContainer,format:e.format,quality:e.quality,resolution:e.resolution,antialias:e.antialias})}async snapshotByData({map:e,path:t,roomProperties:n,customElements:a,forbiddenSweepZones:r,forbiddenMopZones:i,virtualWalls:o,detectedObjects:s},h={}){const p=`SNAPSHOT_${d()}`;c.log(`[MapApplication] ${p} snapshot start`);const m=new O(p);try{if(await m.initialize({config:this.config,runtime:h}),!e)throw new Error("Map data is required");if(e.startsWith("7b22")){const{decodeMapStructured:t}=await import("@ray-js/robot-protocol"),n=t(e);await m.drawMap(n)}else{const{decodeMap:t}=await import("@ray-js/robot-protocol"),n=t(e);if(!n)throw new Error("Failed to decode raster map data");await m.drawRasterMap(n)}if(t){const{decodePath:e}=await import("@ray-js/robot-protocol"),n=e(t);m.drawPath(n)}n&&n.length>0&&m.drawRoomProperty(n),r&&r.length>0&&m.drawForbiddenSweepZones(r),i&&i.length>0&&m.drawForbiddenMopZones(i),o&&o.length>0&&m.drawVirtualWalls(o),s&&s.length>0&&await m.drawDetectedObjects(s),a&&a.length>0&&await m.drawCustomElements(a);const d=await m.snapshot();return c.log(`[MapApplication] ${p} snapshot completed successfully`),d}catch(e){throw c.error(`[MapApplication] ${p} snapshot other map failed:`,e),e}finally{c.log(`[MapApplication] ${p} destroy`),m.destroy()}}renderOnce(){c.log("[Pixi] renderOnce"),this.render()}renderOnceNextFrame(){this.pendingAsyncRender||(this.pendingAsyncRender=!0,requestAnimationFrame(()=>{c.log("[Pixi] renderOnceNextFrame"),this.render(),this.pendingAsyncRender=!1}))}requestRender(e,t=!1){t?(this.tickerState.renderReasons.add(e),this.ticker.started||(c.debug(`🎬 [Ticker] START: ${e}`),this.ticker.start())):this.renderOnceNextFrame()}stopRender(e){this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&this.scheduleStopRender("final",100)}destroy(){h.unregisterInstance(this.instanceKey),this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderReasons.clear(),this.emitter.all.clear(),document.removeEventListener("visibilitychange",this.onVisibilityChange),this.managers.pathManager.destroy(),this.managers.mapManager.destroy(),this.managers.controlsManager.destroy(),this.managers.detectedObjectManager.destroy(),this.managers.customElementsManager.destroy(),this.managers.roomsManager.destroy(),this.components.interaction.destroy(),this.components.viewportContainer.destroy(),this.components.appContainer.destroy(),super.destroy()}initializeViewportContainer(){this.components.viewportContainer=new u(this.config,this.containerElement),this.stage.addChild(this.components.viewportContainer)}initializeAppContainer(){this.components.appContainer=new w,this.components.interaction.addChild(this.components.appContainer)}initializeInteraction(){this.components.interaction=new a,this.components.viewportContainer.addChild(this.components.interaction)}scheduleStopRender(e,t){this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderTimer=setTimeout(()=>{this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&(c.debug("⏸️ [Ticker] STOP"),this.ticker.stop())},t)}generateZonePoints(e,t,n){const a=this.getViewportCenterPoint()||{x:0,y:0},r=this.metersToPixels(e)/2,i=a.x+t,o=a.y+n;return[{x:i-r,y:o-r},{x:i+r,y:o-r},{x:i+r,y:o+r},{x:i-r,y:o+r}]}preloadAssets(){const e=this.config.robot.icon.src,t=this.config.chargingStation.icon.src,a=[];n.add({alias:"robot",src:e}),a.push("robot"),n.add({alias:"chargingStation",src:t}),a.push("chargingStation"),n.add({alias:"deleteIcon",src:this.config.controls.deleteIconSrc}),a.push("deleteIcon"),n.add({alias:"rotateIcon",src:this.config.controls.rotateIconSrc}),a.push("rotateIcon"),n.add({alias:"scaleIcon",src:this.config.controls.scaleIconSrc}),a.push("scaleIcon"),n.add({alias:"moveIcon",src:this.config.controls.moveIconSrc}),a.push("moveIcon"),n.add({alias:"checkmark",src:this.config.room.selectionIndicator.iconSrc}),a.push("checkmark"),n.add({alias:"spotIcon",src:this.config.controls.spot.iconSrc}),a.push("spotIcon"),this.config.room.property.cleanMode.assets.forEach((e,t)=>{const r=`cleanMode_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.suction.assets.forEach((e,t)=>{const r=`fan_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.cistern.assets.forEach((e,t)=>{const r=`water_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.cleanTimes.assets.forEach((e,t)=>{const r=`cleanTimes${t+1}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.floorType.assets.forEach((e,t)=>{if(!e)return;const r=`floorType${t}`;n.add({alias:r,src:e}),a.push(r)}),n.backgroundLoad(a)}onVisibilityChange=()=>{"visible"===document.visibilityState||this.components.interaction?.clearTouches()}}export{O as MapApplication};
|
|
1
|
+
import{Application as e,isMobile as t,Assets as n}from"pixi.js";import{Interaction as a}from"./Interaction.js";import{merge as r}from"lodash-es";import{proxy as i}from"valtio/vanilla";import{MAIN_INSTANCE_KEY as o}from"../constant/index.js";import s from"mitt";import{Logger as c}from"../utils/logger.js";import{AppContext as h}from"./AppService.js";import{nanoid as d}from"nanoid/non-secure";import{calculateLineEndpoints as p,areStructuredRoomsAdjacent as m,areMultipleRoomsConnected as l,areRasterRoomsAdjacent as g}from"../utils/algorithm.js";import{ViewportContainer as u}from"./ViewportContainer.js";import{AppContainer as w}from"./AppContainer.js";import{MapManager as f}from"../managers/MapManager.js";import{PathManager as M}from"../managers/PathManager.js";import{HeatmapManager as y}from"../managers/HeatmapManager.js";import{ControlsManager as x}from"../managers/ControlsManager.js";import{DetectedObjectManager as S}from"../managers/DetectedObjectManager.js";import{CustomElementsManager as v}from"../managers/CustomElementsManager.js";import{RoomManager as b}from"../managers/RoomManager.js";import{getOptimalAntialiasingStrategy as P}from"../utils/browser.js";import{DEFAULT_CONFIG as C,DEFAULT_RUNTIME_CONFIG as R}from"../constant/config.js";class O extends e{mapState=null;components={};managers={};config=C;runtime;scaleMin=.5;scaleMax=5;events={};instanceKey;containerElement;emitter=s();tickerState={renderReasons:new Set,renderTimer:null};pendingAsyncRender=!1;isFirstMapDraw=!0;constructor(e=o){super(),this.instanceKey=e,h.registerInstance(e,this),globalThis.__PIXI_APP__=this}async initialize(e){return h.provideAsync(this,async()=>{const{resizeTo:n,events:a,config:s,runtime:c={},...h}=e;this.config=r(this.config,s??{}),this.runtime=i(Object.assign({},R,c));const d=this.instanceKey===o;this.containerElement=n;const p=d?{textureGCMaxIdle:t.any?180:3600,textureGCCheckCountMax:t.any?100:50,autoStart:!1,eventFeatures:{move:!0,globalMove:!1,click:!0,wheel:!0}}:{textureGCMaxIdle:60,textureGCCheckCountMax:10,autoStart:!1,eventFeatures:{move:!1,globalMove:!1,click:!1,wheel:!1}};await this.init({resizeTo:d?n:void 0,preferWebGLVersion:2,resolution:window.devicePixelRatio||1,antialias:P(),autoDensity:!0,backgroundColor:this.config.global.backgroundColor,...p,...h}),this.preloadAssets(),this.scaleMax=this.config.interaction.zoomRange.max,this.scaleMin=this.config.interaction.zoomRange.min,this.events=a,this.initializeViewportContainer(),this.initializeInteraction(),this.initializeAppContainer(),this.managers.mapManager=new f,this.managers.heatmapManager=new y,this.managers.pathManager=new M,this.managers.controlsManager=new x,this.managers.detectedObjectManager=new S,this.managers.customElementsManager=new v,this.managers.roomsManager=new b,document.addEventListener("visibilitychange",this.onVisibilityChange)})}async drawMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawMap",e);const{size:t,resolution:n,origin:a}=e;a[0]===this.mapState?.origin.x&&a[1]===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(...a),this.managers.controlsManager.updatePositionByOrigin(...a),this.managers.detectedObjectManager.updatePositionByOrigin(...a),this.managers.customElementsManager.updatePositionByOrigin(...a)),this.mapState={id:e.id,status:1===e.status,origin:{x:a[0],y:a[1]},charger:{x:e.charger.coordinate[0],y:e.charger.coordinate[1]},chargerDirection:e.charger.angle??0,resolution:n,width:t[0],height:t[1]},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawMap(e),this.renderOnce()})}async drawRasterMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawRasterMap",e);const{mapHeader:t,mapData:n}=e,{originX:a,originY:r}=t;a===this.mapState?.origin.x&&r===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(a,r),this.managers.controlsManager.updatePositionByOrigin(a,r),this.managers.detectedObjectManager.updatePositionByOrigin(a,r),this.managers.customElementsManager.updatePositionByOrigin(a,r)),this.mapState={id:t.id,status:t.mapStable,origin:{x:a,y:r},charger:{x:t.chargeX,y:t.chargeY},chargerDirection:t.chargeDirection??0,resolution:100*t.mapResolution,width:t.mapWidth,height:t.mapHeight,version:t.version},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawRasterMap(n.parsed,this.mapState),this.renderOnce()})}drawPath(e){return h.provide(this,()=>{c.log("[Path] drawPath",e),this.events?.onPathDrawed?.({id:e.pathHeader.pathId,type:e.pathHeader.type,direction:e.pathHeader.direction,count:e.pathHeader.count,initFlag:e.pathHeader.initFlag,robotPosition:e.pathPoints[e.pathPoints.length-1]??null}),this.managers.pathManager.draw(e),this.renderOnce()})}async drawRoomProperty(e){return h.provide(this,()=>{c.log("[Room] drawRoomProperty",e),this.events?.onRoomPropertiesDrawed?.(e),this.managers.roomsManager.drawRoomProperty(e),this.renderOnceNextFrame()})}drawHeatmap({mapData:e,heatmapPoints:t,useGradient:n=!0}){return h.provide(this,()=>{c.log("[Heatmap] drawHeatmap",t),this.managers.heatmapManager.draw({mapData:e,heatmapPoints:t,useGradient:n}),this.renderOnce()})}drawForbiddenSweepZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenSweepZones",e),this.managers.controlsManager.drawForbiddenSweepZones(e),this.renderOnceNextFrame()})}drawForbiddenMopZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenMopZones",e),this.managers.controlsManager.drawForbiddenMopZones(e),this.renderOnceNextFrame()})}drawCleanZones(e){return h.provide(this,()=>{c.log("[Controls] drawCleanZones",e),this.managers.controlsManager.drawCleanZones(e),this.renderOnceNextFrame()})}drawVirtualWalls(e){return h.provide(this,()=>{c.log("[Controls] drawVirtualWalls",e),this.managers.controlsManager.drawVirtualWalls(e),this.renderOnceNextFrame()})}drawSpots(e){return h.provide(this,()=>{c.log("[Controls] drawSpots",e),this.managers.controlsManager.drawSpots(e),this.renderOnceNextFrame()})}async drawDetectedObjects(e){return h.provideAsync(this,async()=>{c.log("[DetectedObject] drawDetectedObjects",e),await this.managers.detectedObjectManager.drawDetectedObjects(e),this.renderOnceNextFrame()})}async drawCustomElements(e){return h.provideAsync(this,async()=>{c.log("[CustomElements] drawCustomElements",e),await this.managers.customElementsManager.drawCustomElements(e),this.renderOnceNextFrame()})}getForbiddenSweepZones(){return this.managers.controlsManager.getForbiddenSweepZones()}getForbiddenMopZones(){return this.managers.controlsManager.getForbiddenMopZones()}getCleanZones(){return this.managers.controlsManager.getCleanZones()}getVirtualWalls(){return this.managers.controlsManager.getVirtualWalls()}getSpots(){return this.managers.controlsManager.getSpots()}getEffectiveDividerPoints(){return this.managers.controlsManager.getEffectiveDividerPoints()}getDividerEndPoints(){return this.managers.controlsManager.getDividerEndPoints()}resetPanZoom(){this.components.interaction.setPanZoom()}fitMapToView(e,t=!1){return h.provide(this,()=>{if(!e||e.minX===e.maxX||e.minY===e.maxY)return void c.warn("地图边界无效,无法自动适配视图");const n=this.config.map.autoPaddingPercent||.1,a=this.getViewportBounds(),r=e.maxX-e.minX,i=e.maxY-e.minY,o=a.width,s=a.height,h=o*(1-2*n)/r,d=s*(1-2*n)/i,p=Math.min(h,d),m=Math.max(this.config.interaction.fitMinScale,this.scaleMin),l=Math.min(this.config.interaction.fitMaxScale,this.scaleMax),g=Math.max(m,Math.min(l,p)),u=o/2-(e.minX+r/2)*g,w=s/2-(e.minY+i/2)*g;this.components.interaction.setPanZoom({targetPosition:{x:u,y:w},targetScale:{x:g,y:g},setCenter:!0,setScale:!0},t)})}getViewportBounds(){return this.components.viewportContainer?.getViewportBounds()||{x:0,y:0,width:this.renderer.width,height:this.renderer.height}}updateRuntime(e){Object.assign(this.runtime,e),this.renderOnceNextFrame()}metersToPixels(e){return this.mapState?.resolution?e*(1/(this.mapState.resolution/100)):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),20*e)}pixelsToMeters(e){return this.mapState?.resolution?e*(this.mapState.resolution/100):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),.05*e)}toFixedSize(e,t){return e/(t??this.components.appContainer.scale.x)}fromFixedSize(e,t){return e*(t??this.components.appContainer.scale.x)}getViewportCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate center point"),null;const e=this.getViewportBounds(),t=e.x+e.width/2,n=e.y+e.height/2,a=this.components.appContainer,r=a.scale.x,i=(t-a.x)/r,o=(n-a.y)/r;return{x:i-this.mapState.origin.x,y:o-this.mapState.origin.y}}getMapCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate map center point"),null;const e=this.managers.mapManager.mapBounds;if(e.minX===1/0||e.minY===1/0||e.maxX===-1/0||e.maxY===-1/0)return c.warn("Invalid map bounds, cannot calculate map center point"),null;const t=(e.minX+e.maxX)/2,n=(e.minY+e.maxY)/2;return{x:t-this.mapState.origin.x,y:n-this.mapState.origin.y}}getWallPointsByViewportCenter(e){const{width:t=this.config.controls.virtualWall.minWidth,direction:n="horizontal",offsetX:a=0,offsetY:r=0}=e||{},i=this.getViewportCenterPoint()||{x:0,y:0},o=this.metersToPixels(t);return p(i.x,i.y,o,n).map(e=>({x:e.x+a,y:e.y+r}))}getForbiddenSweepZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenSweepZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getForbiddenMopZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenMopZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getCleanZonePointsByViewportCenter(e){const t=this.config.controls.cleanZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getSpotPointByViewportCenter(e){const{offsetX:t=0,offsetY:n=0}=e||{},a=this.getViewportCenterPoint()||{x:0,y:0};return{x:a.x+t,y:a.y+n}}areRoomsAdjacent(e){const t=this.config.map.adjacencyThreshold;return h.provide(this,()=>{if(!e||0===e.length)return c.warn("[Room] No room IDs provided"),!1;if(1===e.length)return!0;const n=Array.from(new Set(e));return 1===n.length||(void 0!==this.mapState?.version?this.areRasterRoomsAdjacentInternal(n,t):this.areStructuredRoomsAdjacentInternal(n,t))})}areStructuredRoomsAdjacentInternal(e,t){const n=[];for(const t of e){const e=this.managers.mapManager.getRoomById(t);if(!e)return c.warn(`[Room] Room ${t} not found in map`),!1;if(!e.outlinePoints||0===e.outlinePoints.length)return c.warn(`[Room] Room ${t} has no outline points`),!1;n.push({id:t,points:e.outlinePoints})}const a=[];for(let e=0;e<n.length;e++)for(let r=e+1;r<n.length;r++){const i=n[e],o=n[r];m(i.points,o.points,t)&&a.push([e,r])}return l(n.length,a)}areRasterRoomsAdjacentInternal(e,t){if(!this.mapState)return c.warn("[Room] Map state not available"),!1;const n=this.mapState.width,a=[];for(const t of e){const e=this.managers.mapManager.getRasterRoomPixels(t);if(!e)return c.warn(`[Room] Room ${t} pixel data not found in raster map`),!1;a.push({id:t,pixels:e})}const r=[];for(let e=0;e<a.length;e++)for(let i=e+1;i<a.length;i++){const o=a[e],s=a[i];g(o.pixels,s.pixels,n,t)&&r.push([e,i])}return l(a.length,r)}async snapshot(){this.render(),await new Promise(e=>setTimeout(e,0));const{snapshot:e}=this.config;return await this.renderer.extract.base64({target:this.components.appContainer,format:e.format,quality:e.quality,resolution:e.resolution,antialias:e.antialias})}async snapshotByData({map:e,path:t,roomProperties:n,customElements:a,forbiddenSweepZones:r,forbiddenMopZones:i,virtualWalls:o,detectedObjects:s},h={}){const p=`SNAPSHOT_${d()}`;c.log(`[MapApplication] ${p} snapshot start`);const m=new O(p);try{if(await m.initialize({config:this.config,runtime:h}),!e)throw new Error("Map data is required");if(e.startsWith("7b22")){const{decodeMapStructured:t}=await import("@ray-js/robot-protocol"),n=t(e);await m.drawMap(n)}else{const{decodeMap:t}=await import("@ray-js/robot-protocol"),n=t(e);if(!n)throw new Error("Failed to decode raster map data");await m.drawRasterMap(n)}if(t){const{decodePath:e}=await import("@ray-js/robot-protocol"),n=e(t);m.drawPath(n)}n&&n.length>0&&m.drawRoomProperty(n),r&&r.length>0&&m.drawForbiddenSweepZones(r),i&&i.length>0&&m.drawForbiddenMopZones(i),o&&o.length>0&&m.drawVirtualWalls(o),s&&s.length>0&&await m.drawDetectedObjects(s),a&&a.length>0&&await m.drawCustomElements(a);const d=await m.snapshot();return c.log(`[MapApplication] ${p} snapshot completed successfully`),d}catch(e){throw c.error(`[MapApplication] ${p} snapshot other map failed:`,e),e}finally{c.log(`[MapApplication] ${p} destroy`),m.destroy()}}renderOnce(){c.log("[Pixi] renderOnce"),this.render()}renderOnceNextFrame(){this.pendingAsyncRender||(this.pendingAsyncRender=!0,requestAnimationFrame(()=>{c.log("[Pixi] renderOnceNextFrame"),this.render(),this.pendingAsyncRender=!1}))}requestRender(e,t=!1){t?(this.tickerState.renderReasons.add(e),this.ticker.started||(c.debug(`🎬 [Ticker] START: ${e}`),this.ticker.start())):this.renderOnceNextFrame()}stopRender(e){this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&this.scheduleStopRender("final",100)}destroy(){h.unregisterInstance(this.instanceKey),this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderReasons.clear(),this.emitter.all.clear(),document.removeEventListener("visibilitychange",this.onVisibilityChange),this.managers.pathManager.destroy(),this.managers.mapManager.destroy(),this.managers.controlsManager.destroy(),this.managers.detectedObjectManager.destroy(),this.managers.customElementsManager.destroy(),this.managers.roomsManager.destroy(),this.components.interaction.destroy(),this.components.viewportContainer.destroy(),this.components.appContainer.destroy(),super.destroy()}initializeViewportContainer(){this.components.viewportContainer=new u(this.config,this.containerElement),this.stage.addChild(this.components.viewportContainer)}initializeAppContainer(){this.components.appContainer=new w,this.components.interaction.addChild(this.components.appContainer)}initializeInteraction(){this.components.interaction=new a,this.components.viewportContainer.addChild(this.components.interaction)}scheduleStopRender(e,t){this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderTimer=setTimeout(()=>{this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&(c.debug("⏸️ [Ticker] STOP"),this.ticker.stop())},t)}generateZonePoints(e,t,n){const a=this.getViewportCenterPoint()||{x:0,y:0},r=this.metersToPixels(e)/2,i=a.x+t,o=a.y+n;return[{x:i-r,y:o-r},{x:i+r,y:o-r},{x:i+r,y:o+r},{x:i-r,y:o+r}]}preloadAssets(){const e=this.config.robot.icon.src,t=this.config.chargingStation.icon.src,a=[];n.add({alias:"robot",src:e}),a.push("robot"),n.add({alias:"chargingStation",src:t}),a.push("chargingStation"),n.add({alias:"deleteIcon",src:this.config.controls.deleteIconSrc}),a.push("deleteIcon"),n.add({alias:"rotateIcon",src:this.config.controls.rotateIconSrc}),a.push("rotateIcon"),n.add({alias:"scaleIcon",src:this.config.controls.scaleIconSrc}),a.push("scaleIcon"),n.add({alias:"moveIcon",src:this.config.controls.moveIconSrc}),a.push("moveIcon"),n.add({alias:"checkmark",src:this.config.room.selectionIndicator.iconSrc}),a.push("checkmark"),n.add({alias:"spotIcon",src:this.config.controls.spot.iconSrc}),a.push("spotIcon"),this.config.room.property.cleanMode.assets.forEach((e,t)=>{const r=`cleanMode_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.suction.assets.forEach((e,t)=>{const r=`fan_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.cistern.assets.forEach((e,t)=>{const r=`water_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.cleanTimes.assets.forEach((e,t)=>{const r=`cleanTimes${t+1}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.floorType.assets.forEach((e,t)=>{if(!e)return;const r=`floorType${t}`;n.add({alias:r,src:e}),a.push(r)}),n.backgroundLoad(a)}onVisibilityChange=()=>{"visible"===document.visibilityState||this.components.interaction?.clearTouches()}}export{O as MapApplication};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as
|
|
1
|
+
import{Container as o,Graphics as t,GraphicsContext as e}from"pixi.js";import{RASTER_CHUNK_SIZE as i}from"../../constant/index.js";import{LAYER_ROOM_FILL as s}from"../../application/AppContainer.js";import{ClickHandler as r}from"../../mixins/ClickHandler.js";import{Logger as a}from"../../utils/logger.js";import{useAppService as n}from"../../application/AppService.js";class l extends o{roomGraphicsMap=new Map;roomContextMap=new Map;roomClickHandlerMap=new Map;unsubscribeFns=[];mapWidth=0;rasterRoomDataMap=new Map;constructor(){super({isRenderGroup:!0}),n().appContainer.addToLayer(s,this)}draw(o){const i=n();this.clearRooms();const s=i.roomConfig,{selectRoomIds:a,enableRoomSelection:l}=i.runtimeSnapshot;o.forEach(o=>{const i=o.id>=255,n=new t,c=new e,h=new e;if(i)c.setFillStyle({color:o.color}),h.setFillStyle({color:o.color});else{const t=o.colorIndex??0,e=s.colors.active[t%s.colors.active.length],i=s.colors.inactive[t%s.colors.inactive.length];c.setFillStyle({color:e}),h.setFillStyle({color:i})}if(c.poly(o.polyPoints).fill(),h.poly(o.polyPoints).fill(),o.outlinePoints.forEach(o=>{c.rect(o.x,o.y,1,1).fill(),h.rect(o.x,o.y,1,1).fill()}),n.context=i?c:l&&!a.includes(o.id)?h:c,!i){const t=new r(n,{clickThreshold:10,onClick:()=>{this.handleRoomClick(o.id)}});this.roomClickHandlerMap.set(o.id,t)}this.roomGraphicsMap.set(o.id,n),this.roomContextMap.set(o.id,{activeContext:c,inactiveContext:h}),this.addChild(n)})}drawRaster(o){const t=n();if(this.clearRooms(),this.mapWidth=o.width,0===o.sortedRooms.length)return;const{selectRoomIds:e,enableRoomSelection:i}=t.runtimeSnapshot;o.sortedRooms.forEach(o=>{this.drawRasterRoom(o,i,e)})}drawRasterRoom(o,s,a){const{roomId:n,pixelIndices:l,activeColor:c,inactiveColor:h}=o,p=new t,m=new e,d=new e;m.setFillStyle({color:c}),d.setFillStyle({color:h}),this.drawPixelPointsInBatches(m,l,i,this.mapWidth),this.drawPixelPointsInBatches(d,l,i,this.mapWidth);const f="number"==typeof n,C=!s||f&&a.includes(n);if(p.context=s&&f&&!C?d:m,f){const o=new r(p,{clickThreshold:10,onClick:()=>{this.handleRoomClick(n)}});this.roomClickHandlerMap.set(n,o)}this.roomGraphicsMap.set(n,p),this.roomContextMap.set(n,{activeContext:m,inactiveContext:d}),this.rasterRoomDataMap.set(n,o),this.addChild(p)}drawPixelPointsInBatches(o,t,e,i){for(let s=0;s<t.length;s+=e){const r=Math.min(s+e,t.length);for(let e=s;e<r;e++){const s=t[e],r=s%i,a=Math.floor(s/i);o.rect(r,a,1,1)}o.fill()}}handleRoomClick(o){const t=n();t.events?.onClickRoom?.(t.getRoomData(o)??{id:o})}setRoomStateBySelectIds(o){const t=n(),{enableRoomSelection:e}=t.runtimeSnapshot;this.roomGraphicsMap.forEach((t,i)=>{if("number"==typeof i){const s=!e||o.includes(i),r=this.roomContextMap.get(i);r&&(t.context=s?r.activeContext:r.inactiveContext)}})}setRoomState(o,t){const e=this.roomGraphicsMap.get(o),i=this.roomContextMap.get(o);e&&i?"number"==typeof o&&(e.context=t?i.activeContext:i.inactiveContext):a.warn(`Room ${o} not found`)}setAllRoomsState(o){this.roomGraphicsMap.forEach((t,e)=>{"number"==typeof e&&this.setRoomState(e,o)})}getRoomGraphicsMap(){const o=new Map;return this.roomGraphicsMap.forEach((t,e)=>{"number"==typeof e&&o.set(e,t)}),o}getRasterRoomData(o){return this.rasterRoomDataMap.get(o)||null}getMapWidth(){return this.mapWidth}clearRooms(){0===this.children.length&&0===this.roomGraphicsMap.size||(this.removeChildren(),this.roomClickHandlerMap.forEach(o=>{try{o.destroy()}catch(o){a.warn("Error destroying click handler:",o)}}),this.roomClickHandlerMap.clear(),this.roomGraphicsMap.clear(),this.roomContextMap.clear(),this.rasterRoomDataMap.clear())}destroy(){this.unsubscribeFns.forEach(o=>o()),this.unsubscribeFns=[],this.clearRooms(),super.destroy()}}export{l as RoomFill};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as o,Assets as r,TilingSprite as e,Graphics as t}from"pixi.js";import{calculateMergedBounds as s}from"../../utils/algorithm.js";import{LAYER_ROOM_FLOOR_TYPE as a}from"../../application/AppContainer.js";import{Logger as p}from"../../utils/logger.js";import{useAppService as i}from"../../application/AppService.js";class l extends o{floorTypeMap=new Map;floorTypeMasks=new Map;floorTypeToRooms=new Map;constructor(){super({isRenderGroup:!0}),i().appContainer.addToLayer(a,this)}async createFloorTypes(o){if(!i().runtimeSnapshot.showRoomFloorType)return;this.clearFloorTypes();const r=this.groupRoomsByFloorType(o),e=[];for(const[o,t]of r)e.push(this.createMergedFloorType(o,t));await Promise.all(e)}groupRoomsByFloorType(o){const r=new Map,e=i();return o.forEach((o,t)=>{const s=e.getRoomData(t),a=s?.floorType||0;a>=0&&(r.has(a)||r.set(a,[]),r.get(a).push({roomId:t,graphics:o}))}),r}async createMergedFloorType(o,t){const a=i(),{assets:l,opacity:n,scale:c}=a.roomConfig.floorType,h=
|
|
1
|
+
import{Container as o,Assets as r,TilingSprite as e,Graphics as t}from"pixi.js";import{calculateMergedBounds as s}from"../../utils/algorithm.js";import{LAYER_ROOM_FLOOR_TYPE as a}from"../../application/AppContainer.js";import{Logger as p}from"../../utils/logger.js";import{useAppService as i}from"../../application/AppService.js";class l extends o{floorTypeMap=new Map;floorTypeMasks=new Map;floorTypeToRooms=new Map;constructor(){super({isRenderGroup:!0}),i().appContainer.addToLayer(a,this)}async createFloorTypes(o){if(!i().runtimeSnapshot.showRoomFloorType)return;this.clearFloorTypes();const r=this.groupRoomsByFloorType(o),e=[];for(const[o,t]of r)e.push(this.createMergedFloorType(o,t));await Promise.all(e)}groupRoomsByFloorType(o){const r=new Map,e=i();return o.forEach((o,t)=>{const s=e.getRoomData(t),a=s?.floorType||0;a>=0&&(r.has(a)||r.set(a,[]),r.get(a).push({roomId:t,graphics:o}))}),r}async createMergedFloorType(o,t){const a=i(),{assets:l,opacity:n,scale:c}=a.roomConfig.floorType,h=o%l.length,y=`floorType${h}`;if(!l[h])return void p.warn(`No texture asset configured for floorType: ${o}`);const f=await r.load(y);if(!f)return void p.warn(`Floor material texture not found: ${y}`);const d=t.map(({graphics:o})=>o.getLocalBounds()),m=s(d),T=new e({texture:f,width:m.width,height:m.height});T.x=m.x,T.y=m.y,T.alpha=n,T.tileScale.set(c);const g=this.createMergedMask(t.map(({graphics:o})=>o));T.mask=g,this.addChild(T),this.floorTypeMap.set(o,T),this.floorTypeMasks.set(o,g),this.floorTypeToRooms.set(o,new Set(t.map(({roomId:o})=>o)))}createMergedMask(r){const e=new o;return r.forEach(o=>{const r=new t;r.context=o.context.clone(),e.addChild(r)}),e}clearFloorTypes(){this.floorTypeMap.forEach(o=>{try{this.removeChild(o),o.destroy()}catch(o){p.warn("Error destroying floor material:",o)}}),this.floorTypeMap.clear(),this.floorTypeMasks.forEach(o=>{try{o.destroy()}catch(o){p.warn("Error destroying floor mask:",o)}}),this.floorTypeMasks.clear(),this.floorTypeToRooms.clear()}destroy(){this.clearFloorTypes(),super.destroy()}}export{l as RoomFloorType};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Text as o,TextStyle as e}from"pixi.js";import{useAppService as
|
|
1
|
+
import{Text as o,TextStyle as e}from"pixi.js";import{useAppService as n}from"../../application/AppService.js";class t extends o{roomId;roomIndex;colorIndex;constructor(o){const t=n(),{nameLabel:i,colors:r}=t.roomConfig,l=o.colorIndex??o.index,s=r.name[l%r.name.length],m=new e({fontSize:i.fontSize,fontFamily:i.fontFamily,fontWeight:i.fontWeight,fill:s,align:"center"});super({text:o.name||"Unknown",style:m}),this.roomId=o.id,this.roomIndex=o.index,this.colorIndex=l,this.anchor.set(.5)}updateName(o){this.text=o}updateColor(o){const e=n(),{colors:t}=e.roomConfig,i=o??t.name[this.colorIndex%t.name.length];this.style.fill=i}}export{t as RoomName};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as e,Graphics as t,Text as
|
|
1
|
+
import{Container as e,Graphics as t,Text as o,TextStyle as i}from"pixi.js";import{useAppService as n}from"../../application/AppService.js";import{EnhancedSprite as s}from"../Base/EnhancedSprite.js";class r extends e{background;cleanModeIcon;suctionIcon;cisternIcon;cleanTimesIcon;orderContainer;orderBackground;orderText;bubble=null;isFolded=!1;roomId;colorIndex;constructor(r){super();const l=n(),c=l.roomConfig;this.roomId=r.id,this.colorIndex=r.colorIndex??r.index,this.background=new t;const{property:h,colors:{propertyTheme:d}}=c;c.property.foldable&&(this.bubble=new t);const a=d[this.colorIndex%d.length];this.cleanModeIcon=new s,this.cleanModeIcon.tint=a,this.cleanModeIcon.anchor.set(0,0),this.suctionIcon=new s,this.suctionIcon.tint=a,this.suctionIcon.anchor.set(0,0),this.cisternIcon=new s,this.cisternIcon.tint=a,this.cisternIcon.anchor.set(0,0),this.cleanTimesIcon=new s,this.cleanTimesIcon.tint=a,this.cleanTimesIcon.anchor.set(0,0),this.orderContainer=new e,this.orderBackground=new t,this.orderText=new o({text:"",style:new i({fontSize:h.cleanOrder.fontSize,fontFamily:h.cleanOrder.fontFamily,fontWeight:h.cleanOrder.fontWeight,fill:h.cleanOrder.color,align:"center",trim:!0})}),this.orderText.anchor.set(.5,.5),this.orderContainer.addChild(this.orderBackground),this.orderContainer.addChild(this.orderText),this.addChild(this.background),this.bubble&&this.addChild(this.bubble),this.addChild(this.cleanModeIcon),this.addChild(this.suctionIcon),this.addChild(this.cisternIcon),this.addChild(this.cleanTimesIcon),this.addChild(this.orderContainer),this.visible=l.runtimeSnapshot.showRoomProperty,this.updateProperty(r)}async updateProperty(e){await this.updateIcons(e),this.updateBackground()}getDisplayElements(e){const t=n(),{displayOrders:o}=t.roomConfig.property,{showRoomOrder:i,showRoomProperty:s}=t.runtimeSnapshot,r=e.order||0,l=i&&r>0,c=s&&o.includes("cleanMode"),h=s&&o.includes("suction"),d=s&&o.includes("cistern"),a=s&&o.includes("cleanTimes")&&e.cleanTimes>0,u={cleanMode:{element:this.cleanModeIcon,show:c,isOrder:!1},suction:{element:this.suctionIcon,show:h,isOrder:!1},cistern:{element:this.cisternIcon,show:d,isOrder:!1},cleanTimes:{element:this.cleanTimesIcon,show:a,isOrder:!1}},b=[];return l&&b.push({element:this.orderContainer,show:!0,isOrder:!0}),o.forEach(e=>{const t=u[e];t&&t.show&&b.push(t)}),{shouldShowOrder:l,shouldShowCleanMode:c,shouldShowSuction:h,shouldShowCistern:d,shouldShowCleanTimes:a,elementsToShow:b,orderValue:r}}async updateIcons(e){const t=n(),{iconWidth:o,iconHeight:i,container:s,cleanOrder:r,foldable:l,iconGap:c}=t.roomConfig.property,{propertyTheme:h}=t.roomConfig.colors,{paddingHorizontal:d,paddingVertical:a}=s,{shouldShowOrder:u,shouldShowCleanMode:b,shouldShowSuction:p,shouldShowCistern:g,shouldShowCleanTimes:m,elementsToShow:I,orderValue:C}=this.getDisplayElements(e);this.orderContainer.visible=u,this.cleanModeIcon.visible=b,this.suctionIcon.visible=p,this.cisternIcon.visible=g,this.cleanTimesIcon.visible=m,l&&this.isFolded&&(this.orderContainer.visible=!1,this.cleanModeIcon.visible=!1,this.suctionIcon.visible=!1,this.cisternIcon.visible=!1,this.cleanTimesIcon.visible=!1);const f=[];if(b&&f.push(this.cleanModeIcon.loadTextureAndSetSize(`cleanMode_${e.cleanMode}`,{width:o,height:i,sizeFixed:!1})),p&&f.push(this.suctionIcon.loadTextureAndSetSize(`fan_${e.suction}`,{width:o,height:i,sizeFixed:!1})),g&&f.push(this.cisternIcon.loadTextureAndSetSize(`water_${e.cistern}`,{width:o,height:i,sizeFixed:!1})),m){const t=e.cleanTimes||1;f.push(this.cleanTimesIcon.loadTextureAndSetSize(`cleanTimes${t}`,{width:o,height:i,sizeFixed:!1}))}await Promise.all(f),u&&(this.orderText.text=C.toString(),this.orderBackground.clear(),this.orderBackground.setFillStyle({color:h[this.colorIndex%h.length]}),this.orderBackground.circle(o/2,i/2,o/2).fill(),this.orderText.position.set(o/2,i/2));let w=d;I.forEach((e,t)=>{const{element:i,isOrder:n}=e;i.position.set(w,a),w+=o,t<I.length-1&&(w+=n?r.gapRight:c)})}updateBackground(){const e=n().roomConfig,{container:t,foldable:o}=e.property,{borderRadius:i,tailHeight:s,tailWidth:r,backgroundColor:l}=t,c=this.calculateContentWidth(),h=this.calculateContentHeight(),d=Math.min(r,c/2);if(this.background.clear(),this.bubble&&this.bubble.clear(),this.background.setFillStyle({color:l}),this.background.roundRect(0,0,c,h,i).fill(),o&&this.bubble){const e=(c-d)/2;this.bubble.setFillStyle({color:l}),this.bubble.poly([e,h-1,e+d,h-1,e+d/2,h+s]).fill()}}calculateContentWidth(){const e=n(),{iconWidth:t,container:o,cleanOrder:i,iconGap:s}=e.roomConfig.property,{paddingHorizontal:r}=o,l=e.getRoomData(this.roomId);if(!l)return 2*r;const{elementsToShow:c}=this.getDisplayElements(l);let h=r;return c.forEach((e,o)=>{const{isOrder:n}=e;h+=t,o<c.length-1&&(h+=n?i.gapRight:s)}),h+=r,h}calculateContentHeight(){const e=n().roomConfig,{iconHeight:t,container:o}=e.property;return o.paddingVertical+t+o.paddingVertical}getTotalHeight(){const e=n(),{foldable:t,container:o}=e.roomConfig.property,{tailHeight:i}=o;return this.calculateContentHeight()+(t?i:0)}getTotalWidth(){return this.calculateContentWidth()}setFolded(e){const t=n(),{foldable:o}=t.roomConfig.property;if(o)if(this.isFolded=e,e)this.background.visible=!1,this.cleanModeIcon.visible=!1,this.suctionIcon.visible=!1,this.cisternIcon.visible=!1,this.cleanTimesIcon.visible=!1,this.orderContainer.visible=!1,this.bubble&&(this.bubble.visible=!0,this.bubble.rotation=Math.PI,this.repositionFoldedBubble());else{this.background.visible=!0,this.bubble&&(this.bubble.visible=!0,this.bubble.rotation=0,this.bubble.position.set(0,0)),this.updateBackground();const e=t.getRoomData(this.roomId);e&&this.updateIcons(e)}}isFoldedState(){const e=n(),{foldable:t}=e.roomConfig.property;return!!t&&this.isFolded}repositionFoldedBubble(){const e=n(),{foldable:t}=e.roomConfig.property;if(!t||!this.bubble)return;const o=e.roomConfig,{tailHeight:i}=o.property.container,s=this.calculateContentWidth(),r=this.calculateContentHeight(),l=s/2;this.bubble.position.set(l,r+i/2)}destroy(){this.cleanModeIcon?.destroy(),this.suctionIcon?.destroy(),this.cisternIcon?.destroy(),this.cleanTimesIcon?.destroy(),super.destroy()}}export{r as RoomProperty};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as t,Graphics as o}from"pixi.js";import{useAppService as i}from"../../application/AppService.js";import{EnhancedSprite as e}from"../Base/EnhancedSprite.js";class c extends t{background;checkmarkIcon;bubble;roomId;constructor(t){super();const c=i().roomConfig;this.roomId=t.id,this.background=new o,this.bubble=new o;const{colors:{selectionIndicatorIcon:n}}=c;this.checkmarkIcon=new e,this.checkmarkIcon.tint=n[t.index%n.length],this.checkmarkIcon.anchor.set(0,0),this.addChild(this.background),this.addChild(this.bubble),this.addChild(this.checkmarkIcon),this.updateIndicator(t)}async updateIndicator(t){const o=i(),{roomSelectionMode:e,enableRoomSelection:c,selectRoomIds:n}=o.runtimeSnapshot;if(!c||"checkmark"!==e)return void(this.visible=!1);const r=n.includes(t.id);await this.showCheckmarkMode(r),this.updateBackground()}async showCheckmarkMode(t){const o=i(),{selectionIndicator:e}=o.roomConfig,{iconWidth:c,iconHeight:n}=e;if(t){this.visible=!0,this.checkmarkIcon.visible=!0,await this.checkmarkIcon.loadTextureAndSetSize("checkmark",{width:c,height:n,sizeFixed:!1});const t=e.containerWidth/2,o=e.containerHeight/2;this.checkmarkIcon.position.set(t-c/2,o-n/2)}else this.visible=!1}updateBackground(){const t=i(),{selectionIndicator:o,colors:e}=t.roomConfig,{containerWidth:c,containerHeight:n,strokeWidth:r,strokeColor:s,borderRadius:a,tailHeight:h,tailWidth:d}=o,l=t.getRoomData(this.roomId);if(!l)return;const k=e.selectionIndicatorBackground[
|
|
1
|
+
import{Container as t,Graphics as o}from"pixi.js";import{useAppService as i}from"../../application/AppService.js";import{EnhancedSprite as e}from"../Base/EnhancedSprite.js";class c extends t{background;checkmarkIcon;bubble;roomId;constructor(t){super();const c=i().roomConfig;this.roomId=t.id,this.background=new o,this.bubble=new o;const{colors:{selectionIndicatorIcon:n}}=c;this.checkmarkIcon=new e,this.checkmarkIcon.tint=n[t.index%n.length],this.checkmarkIcon.anchor.set(0,0),this.addChild(this.background),this.addChild(this.bubble),this.addChild(this.checkmarkIcon),this.updateIndicator(t)}async updateIndicator(t){const o=i(),{roomSelectionMode:e,enableRoomSelection:c,selectRoomIds:n}=o.runtimeSnapshot;if(!c||"checkmark"!==e)return void(this.visible=!1);const r=n.includes(t.id);await this.showCheckmarkMode(r),this.updateBackground()}async showCheckmarkMode(t){const o=i(),{selectionIndicator:e}=o.roomConfig,{iconWidth:c,iconHeight:n}=e;if(t){this.visible=!0,this.checkmarkIcon.visible=!0,await this.checkmarkIcon.loadTextureAndSetSize("checkmark",{width:c,height:n,sizeFixed:!1});const t=e.containerWidth/2,o=e.containerHeight/2;this.checkmarkIcon.position.set(t-c/2,o-n/2)}else this.visible=!1}updateBackground(){const t=i(),{selectionIndicator:o,colors:e}=t.roomConfig,{containerWidth:c,containerHeight:n,strokeWidth:r,strokeColor:s,borderRadius:a,tailHeight:h,tailWidth:d}=o,l=t.getRoomData(this.roomId);if(!l)return;const k=l.colorIndex??l.index,m=e.selectionIndicatorBackground[k%e.selectionIndicatorBackground.length];if(this.background.clear(),this.bubble.clear(),this.background.setFillStyle({color:m}).roundRect(0,0,c,n,a).fill().setStrokeStyle({color:s,width:r,alignment:0}).stroke(),h>0&&d>0){const t=(c-d)/2;this.bubble.setFillStyle({color:s});const o=n+r;this.bubble.poly([t,o-1,t+d,o-1,t+d/2,o+h]).fill()}}getTotalHeight(){const t=i(),{selectionIndicator:o}=t.roomConfig,{containerHeight:e,tailHeight:c,strokeWidth:n}=o;return e+n+(c>0?c:0)}getTotalWidth(){const t=i(),{selectionIndicator:o}=t.roomConfig;return o.containerWidth}destroy(){this.checkmarkIcon?.destroy(),super.destroy()}}export{c as RoomSelectionIndicator};
|
package/dist/constant/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import o from"../assets/chargingStation.png.js";import e from"../assets/robot.png.js";import t from"../assets/fan0.png.js";import i from"../assets/fan1.png.js";import r from"../assets/fan2.png.js";import s from"../assets/fan3.png.js";import n from"../assets/fan4.png.js";import a from"../assets/water0.png.js";import f from"../assets/water1.png.js";import l from"../assets/water2.png.js";import d from"../assets/water3.png.js";import c from"../assets/cleanMode0.png.js";import h from"../assets/cleanMode1.png.js";import p from"../assets/cleanMode2.png.js";import m from"../assets/cleanMode3.png.js";import g from"../assets/cleanTimes1.png.js";import b from"../assets/cleanTimes2.png.js";import S from"../assets/controlScale.png.js";import C from"../assets/controlDelete.png.js";import u from"../assets/controlRotate.png.js";import W from"../assets/controlMove.png.js";import k from"../assets/checkmark.png.js";import y from"../assets/spot.png.js";import D from"../assets/floorType1.png.js";import j from"../assets/floorType2.png.js";import x from"../assets/floorType3.png.js";import F from"../assets/carpet.png.js";import A from"../assets/sleep.json.js";import{SPECIAL_ROOM_IDS as O}from"@ray-js/robot-protocol";const w="system-ui, -apple-system, sans-serif",R=["#2563b8","#26966b","#7c3fb8","#d97706"],P={global:{containerTop:"0px",containerLeft:"0px",containerWidth:"100%",containerHeight:"100%",backgroundColor:"#f6f6f6"},map:{autoPaddingPercent:.05,adjacencyThreshold:3,obstacleColor:"#999999",freeColor:"#ebebeb"},room:{colors:{active:["#a8c8f5","#9de5c7","#d4b9f7","#ffd399"],inactive:["#d6e7fc","#d1f4e5","#ece0fb","#fff0d9"],name:R,propertyTheme:R,selectionIndicatorBackground:R,selectionIndicatorIcon:["#ffffff","#ffffff","#ffffff","#ffffff"],[O.NO_ROOM_DATA]:"#ebebeb",[O.ROOM_GAP]:"#ebebeb",[O.OBSTACLE_ROOM]:"#ebebeb",[O.UNKNOWN_ROOM]:"#ebebeb"},nameLabel:{fontSize:10,fontFamily:w,fontWeight:"500"},property:{displayOrders:["cleanMode","suction","cistern","cleanTimes"],iconWidth:12,iconHeight:12,foldable:!0,offsetX:0,offsetY:4,iconGap:0,container:{backgroundColor:"#ffffff",paddingVertical:1.5,paddingHorizontal:1.5,borderRadius:16,tailHeight:2,tailWidth:10},suction:{assets:[t,i,r,s,n]},cistern:{assets:[a,f,l,d]},cleanMode:{assets:[c,h,p,m]},cleanTimes:{assets:[g,b]},cleanOrder:{color:"#ffffff",fontFamily:w,fontWeight:"400",fontSize:8,gapRight:2}},selectionIndicator:{iconSrc:k,iconWidth:12,iconHeight:12,containerWidth:16,containerHeight:16,strokeWidth:2,strokeColor:"#ffffff",borderRadius:16,offsetY:4,offsetX:0,tailHeight:2,tailWidth:6},floorType:{assets:["",D,j,x],opacity:.1,scale:.2}},path:{lineWidthFixed:!1,incrementalThreshold:5,commonPath:{color:16777215,width:.5},transitionPath:{color:"transparent",width:.5},chargePath:{color:"transparent",width:.5}},carpet:{src:F,opacity:.5,scale:.2},robot:{icon:{sizeFixed:!1,width:8,height:8,src:e},speed:0,rotationCorrection:0,sleepAnimation:{jsonSrc:A,framePrefix:"sleep_",width:16,height:16,sizeFixed:!1,frameCount:96,offsetX:8,offsetY:-8},ringSize:1,ringColor:"rgba(255, 68, 68, 0.2)",ringStrokeWidth:1,ringStrokeColor:"#ffffff",ringStrokeDashed:!0,ringStrokeDashArray:[4,4]},chargingStation:{icon:{sizeFixed:!1,width:8,height:8,src:o},rotationCorrection:0,ringSize:1,ringColor:"rgba(255, 68, 68, 0.2)",ringStrokeWidth:1,ringStrokeColor:"#ffffff",ringStrokeDashed:!0,ringStrokeDashArray:[4,4]},interaction:{zoomRange:{min:.5,max:8},fitMinScale:1,fitMaxScale:4,enableDoubleTapZoom:!0},controls:{iconWrapperWidth:24,iconWrapperHeight:24,iconWrapperBorderRadius:16,iconWidth:12,iconHeight:12,deleteIconSrc:C,rotateIconSrc:u,scaleIconSrc:S,moveIconSrc:W,moveButtonOffset:30,textFontSize:12,textFontFamily:w,textFontWeight:"400",unitLabel:"m",forbiddenSweepZone:{minSize:1,iconWrapperFillColor:"#ff4444",strokeColor:"#ff4444",strokeWidth:2,fillColor:"rgba(255, 68, 68, 0.1)",outlineOffset:16,outlineStrokeColor:"#ff4444",outlineStrokeWidth:2,outlineDashed:!0,outlineDashArray:[4,3],outlineFillColor:"rgba(255, 68, 68, 0.05)",textColor:"#ff4444",textPosition:"bottom",textOffset:10,editing:{isDashed:!1,dashArray:[0,0]},normal:{isDashed:!1,dashArray:[0,0]}},forbiddenMopZone:{minSize:1,iconWrapperFillColor:"#fe8a07",strokeColor:"#fe8a07",strokeWidth:2,fillColor:"rgba(254, 138, 7, 0.1)",outlineOffset:16,outlineStrokeColor:"#fe8a07",outlineStrokeWidth:2,outlineDashed:!0,outlineDashArray:[4,3],outlineFillColor:"rgba(254, 138, 7, 0.05)",textColor:"#fe8a07",textPosition:"bottom",textOffset:10,editing:{isDashed:!1,dashArray:[0,0]},normal:{isDashed:!1,dashArray:[0,0]}},cleanZone:{minSize:1,iconWrapperFillColor:"#5d68fe",strokeColor:"#5d68fe",strokeWidth:2,fillColor:"rgba(93, 104, 254, 0.1)",outlineOffset:16,outlineStrokeColor:"#5d68fe",outlineStrokeWidth:2,outlineDashed:!0,outlineDashArray:[4,3],outlineFillColor:"rgba(93, 104, 254, 0.05)",textColor:"#5d68fe",textPosition:"bottom",textOffset:10,editing:{isDashed:!1,dashArray:[0,0]},normal:{isDashed:!1,dashArray:[0,0]}},virtualWall:{iconWrapperFillColor:"#ff4444",lineWidth:2,lineColor:"#ff4444",hitAreaThickness:30,outlineOffset:16,outlineStrokeColor:"#ff4444",outlineStrokeWidth:2,outlineDashed:!0,outlineDashArray:[4,3],outlineFillColor:"rgba(255, 68, 68, 0.05)",minWidth:1,textColor:"#ff4444",textOffset:10,editing:{isDashed:!1,dashArray:[0,0]},normal:{isDashed:!1,dashArray:[0,0]}},spot:{iconSrc:y,iconSize:8,size:1,strokeColor:"#5d68fe",strokeWidth:2,fillColor:"rgba(93, 104, 254, 0.1)",textColor:"#5d68fe",textPosition:"bottom",textOffset:10,editing:{isDashed:!1,dashArray:[0,0]},normal:{isDashed:!1,dashArray:[0,0]}}},divider:{lineColor:"#ff4444",dashLineWidth:2,dashLineDashArray:[4,3],solidLineWidth:2,endPointSize:12,endPointColor:"#ff4444",endPointStrokeColor:"#ffffff",endPointStrokeWidth:2,hitAreaThickness:30,resetDividerWhenOutOfRoom:!0,defaultExtension:20,defaultDirection:"horizontal"},detectedObject:{height:43,width:38,interactive:!1},heatmap:{cellSize:2,maxDistance:14,smoothIterations:10,heatmapAlpha:.8,colorGradients:["#FF3B30","#FF7A00","#FFA100","#FFD700","#99DD70","#2EC070","#40E0D0","#88D0E9"]},snapshot:{format:"png",quality:1,antialias:!0,resolution:window?.devicePixelRatio||1}},z={dividingRoomId:null,enableRoomSelection:!1,editingForbiddenSweepZoneIds:[],editingForbiddenMopZoneIds:[],editingCleanZoneIds:[],editingVirtualWallIds:[],editingSpotIds:[],roomPropertyFoldIds:[],roomSelectionMode:"checkmark",selectRoomIds:[],showRoomProperty:!1,showRoomOrder:!0,showRoomName:!0,showPath:!0,showChargingStation:!0,showRoomFloorType:!0,showCarpet:!0,showChargingStationRing:!1,showRobotRing:!1,showRobotSleepAnimation:!1};export{P as DEFAULT_CONFIG,z as DEFAULT_RUNTIME_CONFIG,w as TEXT_FONT_FAMILY};
|
package/dist/index.d.ts
CHANGED
|
@@ -58,6 +58,8 @@ export declare type AppConfig = {
|
|
|
58
58
|
map: {
|
|
59
59
|
/** 自动填充百分比 */
|
|
60
60
|
autoPaddingPercent: number
|
|
61
|
+
/** 相邻房间判断阈值 */
|
|
62
|
+
adjacencyThreshold: number
|
|
61
63
|
/** 障碍点颜色 */
|
|
62
64
|
obstacleColor: ColorSource
|
|
63
65
|
/** 自由区域颜色 */
|
|
@@ -522,6 +524,7 @@ declare class AppService {
|
|
|
522
524
|
};
|
|
523
525
|
get mapConfig(): {
|
|
524
526
|
autoPaddingPercent: number;
|
|
527
|
+
adjacencyThreshold: number;
|
|
525
528
|
obstacleColor: ColorSource;
|
|
526
529
|
freeColor: ColorSource;
|
|
527
530
|
};
|
|
@@ -1892,10 +1895,9 @@ export declare interface MapApi {
|
|
|
1892
1895
|
* 例如:房间A和B相邻,房间B和C相邻,则认为A、B、C三个房间都相邻。
|
|
1893
1896
|
*
|
|
1894
1897
|
* @param roomIds - 要检测的房间ID数组
|
|
1895
|
-
* @param threshold - 距离阈值(像素),默认为5。两个房间的边界点距离小于等于此阈值时认为相邻
|
|
1896
1898
|
* @returns 是否所有指定的房间都相邻(连通)
|
|
1897
1899
|
*/
|
|
1898
|
-
areRoomsAdjacent(roomIds: number[]
|
|
1900
|
+
areRoomsAdjacent(roomIds: number[]): boolean;
|
|
1899
1901
|
/**
|
|
1900
1902
|
* 地图截图
|
|
1901
1903
|
*
|
|
@@ -2274,7 +2276,6 @@ export declare class MapApplication extends Application implements MapApi {
|
|
|
2274
2276
|
* 例如:房间A和B相邻,房间B和C相邻,则认为A、B、C三个房间都相邻。
|
|
2275
2277
|
*
|
|
2276
2278
|
* @param roomIds - 要检测的房间ID数组
|
|
2277
|
-
* @param threshold - 距离阈值(像素),默认为3。两个房间的边界点距离小于等于此阈值时认为相邻
|
|
2278
2279
|
* @returns 是否所有指定的房间都相邻(连通)
|
|
2279
2280
|
*
|
|
2280
2281
|
* @example
|
|
@@ -2282,11 +2283,9 @@ export declare class MapApplication extends Application implements MapApi {
|
|
|
2282
2283
|
* // 判断两个房间是否相邻
|
|
2283
2284
|
* const isAdjacent = mapApi.areRoomsAdjacent([1, 2])
|
|
2284
2285
|
*
|
|
2285
|
-
* // 判断三个房间是否相邻(连通),使用自定义阈值
|
|
2286
|
-
* const isAdjacent = mapApi.areRoomsAdjacent([1, 2, 3], 8)
|
|
2287
2286
|
* ```
|
|
2288
2287
|
*/
|
|
2289
|
-
areRoomsAdjacent(roomIds: number[]
|
|
2288
|
+
areRoomsAdjacent(roomIds: number[]): boolean;
|
|
2290
2289
|
/* Excluded from this release type: areStructuredRoomsAdjacentInternal */
|
|
2291
2290
|
/* Excluded from this release type: areRasterRoomsAdjacentInternal */
|
|
2292
2291
|
/**
|
|
@@ -2641,6 +2640,7 @@ declare class MapManager {
|
|
|
2641
2640
|
private lastMapId;
|
|
2642
2641
|
private roomGeometryMap;
|
|
2643
2642
|
private rasterRoomPixelsMap;
|
|
2643
|
+
private fourColorCache;
|
|
2644
2644
|
private carpetData;
|
|
2645
2645
|
private unsubscribeFns;
|
|
2646
2646
|
constructor();
|
|
@@ -2699,6 +2699,20 @@ declare class MapManager {
|
|
|
2699
2699
|
* @returns 像素索引数组,如果不存在则返回 undefined
|
|
2700
2700
|
*/
|
|
2701
2701
|
getRasterRoomPixels(roomId: number): Uint32Array | undefined;
|
|
2702
|
+
/**
|
|
2703
|
+
* 验证颜色配置
|
|
2704
|
+
* @private
|
|
2705
|
+
*/
|
|
2706
|
+
private validateColorConfig;
|
|
2707
|
+
/**
|
|
2708
|
+
* 使用四色算法分配房间颜色
|
|
2709
|
+
* @param roomData 房间数据数组
|
|
2710
|
+
* @param colorCount 可用颜色数量
|
|
2711
|
+
* @param mapType 地图类型
|
|
2712
|
+
* @returns 房间ID到颜色索引的映射
|
|
2713
|
+
* @private
|
|
2714
|
+
*/
|
|
2715
|
+
private assignColorsUsingFourColorAlgorithm;
|
|
2702
2716
|
destroy(): void;
|
|
2703
2717
|
}
|
|
2704
2718
|
|
|
@@ -2935,6 +2949,8 @@ export declare type RasterRoomData = {
|
|
|
2935
2949
|
activeColor: string
|
|
2936
2950
|
/** 非激活状态颜色 */
|
|
2937
2951
|
inactiveColor: string
|
|
2952
|
+
/** 颜色索引(用于四色算法) */
|
|
2953
|
+
colorIndex?: number
|
|
2938
2954
|
}
|
|
2939
2955
|
|
|
2940
2956
|
declare class Ring extends Graphics {
|
|
@@ -3084,6 +3100,8 @@ export declare type Room = {
|
|
|
3084
3100
|
polyPoints: number[]
|
|
3085
3101
|
/** 中心点 */
|
|
3086
3102
|
centerPoint: Point
|
|
3103
|
+
/** 颜色索引(用于四色算法) */
|
|
3104
|
+
colorIndex?: number
|
|
3087
3105
|
}
|
|
3088
3106
|
|
|
3089
3107
|
/**
|
|
@@ -3095,6 +3113,8 @@ export declare type RoomData = RoomProperty & {
|
|
|
3095
3113
|
centerPoint: Point | null
|
|
3096
3114
|
/** 索引 */
|
|
3097
3115
|
index: number
|
|
3116
|
+
/** 颜色索引(用于四色算法) */
|
|
3117
|
+
colorIndex?: number
|
|
3098
3118
|
}
|
|
3099
3119
|
|
|
3100
3120
|
declare class RoomFill extends Container {
|