@ray-js/robot-map-sdk 0.0.3-beta-10 → 0.0.3-beta-11
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/Interaction.js +1 -1
- package/dist/application/MapApplication.js +1 -1
- package/dist/assets/floorType1.png.js +1 -0
- package/dist/assets/floorType2.png.js +1 -0
- package/dist/components/Map/Free.js +1 -1
- package/dist/components/Map/Obstacle.js +1 -1
- package/dist/components/Path/index.js +1 -1
- package/dist/components/RoomFloorType/index.js +1 -1
- package/dist/components/RoomInfo/RoomProperty.js +1 -1
- package/dist/components/RoomInfo/RoomSelectionIndicator.js +1 -1
- package/dist/components/RoomInfo/index.js +1 -1
- package/dist/constant/config.js +1 -1
- package/dist/index.rjs.js +1 -1
- package/dist/managers/RoomManager.js +1 -1
- package/dist-app/assets/{index-zPCor596.js → index-BZrSlwsu.js} +1 -1
- package/dist-app/index.html +1 -1
- package/dist-docs/404.html +2 -2
- package/dist-docs/assets/{app.CWzbsird.js → app.DQX-KXAE.js} +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.DFhlA73m.js +1 -0
- package/dist-docs/assets/chunks/{VPLocalSearchBox.C1dzEhbA.js → VPLocalSearchBox.DMOz5xxA.js} +1 -1
- package/dist-docs/assets/chunks/{theme.Dh1LIHtb.js → theme.BNIQfRMl.js} +2 -2
- package/dist-docs/assets/{guide_advanced-usage.md.ChUH15VJ.js → guide_advanced-usage.md.DUawnQ9c.js} +6 -6
- package/dist-docs/assets/{guide_advanced-usage.md.ChUH15VJ.lean.js → guide_advanced-usage.md.DUawnQ9c.lean.js} +1 -1
- package/dist-docs/assets/{guide_getting-started.md.9TA9iDUN.js → guide_getting-started.md.pCYbkwjy.js} +1 -1
- package/dist-docs/guide/advanced-usage.html +9 -9
- 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 +3 -3
- package/dist-docs/reference/data.html +3 -3
- package/dist-docs/reference/methods.html +3 -3
- 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.DRAHC9Wk.js +0 -1
- /package/dist/assets/{floorType.png.js → floorType3.png.js} +0 -0
- /package/dist-docs/assets/{guide_getting-started.md.9TA9iDUN.lean.js → guide_getting-started.md.pCYbkwjy.lean.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as t,Graphics as i}from"pixi.js";import{easeInOutCubic as e}from"../utils/index.js";import{getDistance as s}from"../utils/algorithm.js";import{Logger as n}from"../utils/logger.js";import{throttle as a,debounce as o}from"lodash-es";import{useAppService as h}from"./AppService.js";class r extends t{dragStart=null;initialTouchDistance=null;initialScale=null;activeTouches=new Map;firstTouchId=null;secondTouchId=null;zoomFactor=.8;scaleMin=.2;scaleMax=5;originalPosition={x:0,y:0};targetPosition={x:0,y:0};centerPosition={x:0,y:0};originalScale={x:1,y:1};targetScale={x:1,y:1};defaultScale={x:1,y:1};transitionDuration=500;transitionStartTime=null;initialPinchCenter=null;isGestureValid=!0;lastTapTime=0;doubleTapDelay=300;doubleTapZoomFactor=1.5;lastTapPosition=null;tapDistanceThreshold=20;tapDetectionEnabled=!0;isGestureHijacked=!1;hijackedPointerId=null;isHijackPaused=!1;interactionGraphics;viewportBounds;boundResetAnimation;debouncedStopWheelRender;interactionState={isInteracting:!1,isAnimating:!1,interactionTimer:null,renderReasons:new Set};throttledAntiScale;constructor(){super();const t=h().getApp();this.viewportBounds=t.getViewportBounds(),this.eventMode="static",this.interactionGraphics=new i,this.interactionGraphics.rect(this.viewportBounds.x,this.viewportBounds.y,this.viewportBounds.width,this.viewportBounds.height).fill({color:"#ffffff",alpha:0}),this.addChild(this.interactionGraphics),this.scaleMax=t.scaleMax,this.scaleMin=t.scaleMin,this.centerPosition={x:Math.round(this.viewportBounds.x+this.viewportBounds.width/2),y:Math.round(this.viewportBounds.y+this.viewportBounds.height/2)},this.originalPosition={x:Math.round(this.viewportBounds.width/2),y:Math.round(this.viewportBounds.height/2)},this.targetPosition={x:Math.round(this.viewportBounds.width/2),y:Math.round(this.viewportBounds.height/2)},this.throttledAntiScale=a(t=>{h().emitter.emit("antiScale",t)},16,{leading:!0,trailing:!0}),this.boundResetAnimation=this.resetAnimation.bind(this),this.debouncedStopWheelRender=o(()=>{t.stopRender("wheel")},300),this.setupInteraction()}setupInteraction(){this.on("pointerdown",t=>this.onPointerDown(t)),this.on("pointerup",t=>this.onPointerUp(t)),this.on("pointerupoutside",t=>this.onPointerUp(t)),this.on("pointermove",t=>this.onPointerMove(t)),this.on("wheel",t=>this.onWheel(t)),h().emitter.on("gestureHijackStart",this.handleGestureHijacked),document.addEventListener("pointercancel",()=>{this.clearTouches()})}resetPan(t){const i=h(),e=i.getApp(),s=i.appContainer;null!==this.transitionStartTime&&(e.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null);const n=this.centerPosition.x-t.x*s.scale.x,a=this.centerPosition.y-t.y*s.scale.y;this.originalPosition={x:s.x,y:s.y},this.targetPosition={x:n,y:a},this.originalScale={x:s.scale.x,y:s.scale.y},this.targetScale={x:s.scale.x,y:s.scale.y};const o=(r=Math.sqrt((s.x-n)**2+(s.y-a)**2),Math.pow(Math.min(1,r/1e3),.5));var r;this.transitionDuration=500+1e3*Math.min(1,Math.pow(o,2)),this.transitionStartTime=e.ticker.lastTime,e.ticker.add(this.boundResetAnimation)}setPanZoom({targetPosition:t,targetScale:i,setCenter:e=!1,setScale:s=!1}={},a=!0){const o=h(),r=o.getApp(),l=o.appContainer;if(e&&t&&(this.centerPosition={x:t.x,y:t.y},n.debug("[Interaction] Set center position:",this.centerPosition)),s&&i&&(this.defaultScale={x:i.x,y:i.y},n.debug("[Interaction] Set scale:",this.defaultScale)),this.originalPosition={x:l.x,y:l.y},this.originalScale={x:l.scale.x,y:l.scale.y},this.targetPosition=t||{x:this.centerPosition.x,y:this.centerPosition.y},this.targetScale=i||this.defaultScale,!a)return l.position.set(this.targetPosition.x,this.targetPosition.y),l.scale.set(this.targetScale.x,this.targetScale.y),this.antiScale(this.targetScale.x),void(null!==this.transitionStartTime&&(r.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null));var c,u,d;const p=.8*(c=Math.sqrt((l.x-this.targetPosition.x)**2+(l.y-this.targetPosition.y)**2),Math.pow(Math.min(1,c/1e3),.5))+.2*(u=l.scale.x,d=this.targetScale.x,Math.pow(Math.min(1,Math.abs(u-d)/Math.abs(-.8)),.5));this.transitionDuration=500+1e3*Math.min(1,Math.pow(p,2)),null!==this.transitionStartTime&&(r.ticker.remove(this.boundResetAnimation),this.interactionState.isAnimating=!1,r.stopRender("animation")),this.interactionState.isAnimating=!0,r.requestRender("animation",!0),this.transitionStartTime=r.ticker.lastTime,r.ticker.add(this.boundResetAnimation)}clearTouches(){const t=h().getApp();this.activeTouches.clear(),this.firstTouchId=null,this.secondTouchId=null,this.dragStart=null,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.isGestureValid=!0,null!==this.transitionStartTime&&(t.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null),this.interactionState.isInteracting=!1,t.stopRender("interaction")}checkEventListeners(){return{wheel:this.listenerCount("wheel"),pointerdown:this.listenerCount("pointerdown"),pointerup:this.listenerCount("pointerup"),pointerupoutside:this.listenerCount("pointerupoutside"),pointermove:this.listenerCount("pointermove")}}destroy(){this.checkEventListeners(),this.interactionState.interactionTimer&&clearTimeout(this.interactionState.interactionTimer),this.interactionState.renderReasons.clear(),this.interactionState.isInteracting=!1,this.interactionState.isAnimating=!1,this.debouncedStopWheelRender.cancel(),h().emitter.off("gestureHijackStart",this.handleGestureHijacked),super.destroy()}handleGestureHijacked=t=>{this.isGestureHijacked=!0,this.hijackedPointerId=t.pointerId,this.isHijackPaused=!1,this.clearTouches(),this.activeTouches.set(t.pointerId,{x:t.global.x,y:t.global.y}),this.firstTouchId=t.pointerId,this.dragStart={x:t.global.x,y:t.global.y}};exitGestureHijacked(){null===this.hijackedPointerId||this.isHijackPaused||(this.activeTouches.delete(this.hijackedPointerId),this.firstTouchId===this.hijackedPointerId&&(this.firstTouchId=null,this.dragStart=null),this.secondTouchId===this.hijackedPointerId&&(this.secondTouchId=null)),this.isGestureHijacked=!1,this.hijackedPointerId=null,this.isHijackPaused=!1}pauseGestureHijack(){this.isHijackPaused=!0}resumeGestureHijack(){this.isHijackPaused=!1}antiScale(t){this.throttledAntiScale(t)}resetAnimation(){const t=h(),i=t.getApp(),s=t.appContainer;if(null===this.transitionStartTime)return;const{targetPosition:n,targetScale:a}=this,o=i.ticker.lastTime,r=Math.min(1,(o-this.transitionStartTime)/this.transitionDuration);if(r>=1)s.position.set(n.x,n.y),s.scale.set(a.x,a.y),this.antiScale(a.x),i.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null,this.interactionState.isAnimating=!1,i.stopRender("animation");else{const t=e(r),i=this.originalPosition.x+(n.x-this.originalPosition.x)*t,o=this.originalPosition.y+(n.y-this.originalPosition.y)*t,h=this.originalScale.x+(a.x-this.originalScale.x)*t,l=this.originalScale.y+(a.y-this.originalScale.y)*t;s.position.set(i,o),s.scale.set(h,l),this.antiScale(h)}}onWheel(t){const i=h();if(this.isGestureHijacked)return void n.warn("⚠️ [onWheel] 被手势劫持阻止执行",{isGestureHijacked:this.isGestureHijacked,hijackedPointerId:this.hijackedPointerId,isHijackPaused:this.isHijackPaused});i.getApp().requestRender("wheel",!0),this.debouncedStopWheelRender();const{scaleMin:e,scaleMax:s}=this,a=i.appContainer;t.preventDefault();const o=t.clientX,r=t.clientY,l=(o-a.x)/a.scale.x,c=(r-a.y)/a.scale.y,u=t.deltaY>0?.95:1.05;let d=a.scale.x*u,p=a.scale.y*u;if(d=Math.max(e,Math.min(s,d)),p=Math.max(e,Math.min(s,p)),d===a.scale.x&&p===a.scale.y)return;const m=o-l*d,x=r-c*p;try{a.scale.set(d,p),a.position.set(m,x),this.antiScale(d)}catch(t){n.error("❌ [onWheel] 应用缩放时发生错误:",t)}}onPointerDown(t){const i=h();this.interactionState.isInteracting=!0,i.getApp().requestRender("interaction",!0),this.isGestureHijacked&&(t.pointerId===this.hijackedPointerId||this.isHijackPaused||this.pauseGestureHijack());const e=i.getApp(),s=i.appContainer;if(null!==this.transitionStartTime&&(e.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null),this.activeTouches.has(t.pointerId-2)&&this.activeTouches.delete(t.pointerId-2),0===this.activeTouches.size&&(this.isGestureValid=!0,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.dragStart=null,this.firstTouchId=null,this.secondTouchId=null),this.activeTouches.has(t.pointerId)&&1===this.activeTouches.size&&(this.isGestureValid=!0),this.activeTouches.set(t.pointerId,{x:t.global.x,y:t.global.y}),1===this.activeTouches.size)this.firstTouchId=t.pointerId,this.dragStart={x:t.global.x,y:t.global.y};else if(2===this.activeTouches.size){const i=Array.from(this.activeTouches.keys());this.secondTouchId=i.find(t=>t!==this.firstTouchId)||t.pointerId,this.setInitialScaleAndDistance(s),this.tapDetectionEnabled=!1}}onPointerUp(t){const i=h();if(this.isGestureHijacked){if(t.pointerId===this.hijackedPointerId)return i.emitter.emit("gestureHijackPointerUp",t),void this.exitGestureHijacked();this.isHijackPaused}if(!this.activeTouches.has(t.pointerId))return;const e=null!==this.initialTouchDistance&&null!==this.initialScale;this.activeTouches.delete(t.pointerId),e&&1===this.activeTouches.size&&(this.isGestureValid=!1,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null),t.pointerId===this.firstTouchId?(this.firstTouchId=null,this.dragStart=null,0===this.activeTouches.size&&this.tapDetectionEnabled&&this.detectDoubleTap(t)):t.pointerId===this.secondTouchId&&(this.secondTouchId=null),this.isGestureHijacked&&this.isHijackPaused&&1===this.activeTouches.size&&Array.from(this.activeTouches.keys())[0]===this.hijackedPointerId&&this.resumeGestureHijack(),0===this.activeTouches.size&&(this.isGestureValid=!0,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.firstTouchId=null,this.secondTouchId=null,this.dragStart=null,this.tapDetectionEnabled=!0,this.interactionState.isInteracting=!1,i.getApp().stopRender("interaction"))}detectDoubleTap(t){const i=h(),{interactionConfig:e}=i;if(!e.enableDoubleTapZoom)return;const n=performance.now(),a={x:t.global.x,y:t.global.y};n-this.lastTapTime<this.doubleTapDelay&&this.lastTapPosition&&s(a,this.lastTapPosition)<this.tapDistanceThreshold?(this.handleDoubleTap(a),this.lastTapTime=0,this.lastTapPosition=null):(this.lastTapTime=n,this.lastTapPosition=a)}handleDoubleTap(t){const i=h(),e=i.getApp(),s=i.appContainer,{scaleMin:n,scaleMax:a,doubleTapZoomFactor:o}=this,r=t.x,l=t.y,c=(r-s.x)/s.scale.x,u=(l-s.y)/s.scale.y;let d=s.scale.x*o,p=s.scale.y*o;d=Math.max(n,Math.min(a,d)),p=Math.max(n,Math.min(a,p)),this.originalPosition={x:s.x,y:s.y},this.originalScale={x:s.scale.x,y:s.scale.y};const m=r-c*d,x=l-u*p;this.targetPosition={x:m,y:x},this.targetScale={x:d,y:p},this.interactionState.isAnimating=!0,e.requestRender("animation",!0),this.transitionDuration=300,this.transitionStartTime=e.ticker.lastTime,e.ticker.add(this.boundResetAnimation)}onPointerMove(t){if(this.isGestureHijacked&&!this.isHijackPaused)return t.pointerId===this.hijackedPointerId?(this.activeTouches.set(t.pointerId,{x:t.global.x,y:t.global.y}),void h().emitter.emit("gestureHijackPointerMove",t)):void 0;this.activeTouches.has(t.pointerId)&&this.isGestureValid&&(this.activeTouches.set(t.pointerId,{x:t.global.x,y:t.global.y}),2===this.activeTouches.size&&null!==this.initialTouchDistance&&null!==this.initialScale&&this.applyPinchZoom(),1!==this.activeTouches.size||null===this.initialTouchDistance&&null===this.initialScale||(this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.secondTouchId=null),1===this.activeTouches.size&&t.pointerId===this.firstTouchId&&null!==this.dragStart&&this.applyPan(t))}applyPan(t){const i=h(),e=this.activeTouches.get(t.pointerId),s=i.appContainer,{x:n,y:a}=this.dragStart;s.position.set(s.x+e.x-n,s.y+e.y-a),this.dragStart={x:e.x,y:e.y}}applyPinchZoom(){const t=h().appContainer,i=Array.from(this.activeTouches.values());if(i.length<2||!this.initialTouchDistance||!this.initialScale||!this.initialPinchCenter)return;const e=s(i[0],i[1]),n={x:(i[0].x+i[1].x)/2,y:(i[0].y+i[1].y)/2},a=(n.x-t.position.x)/t.scale.x,o=(n.y-t.position.y)/t.scale.y,r=(e/this.initialTouchDistance)**this.zoomFactor,l=Math.max(this.scaleMin,Math.min(this.scaleMax,this.initialScale.x*r)),c=Math.max(this.scaleMin,Math.min(this.scaleMax,this.initialScale.y*r));t.scale.set(l,c);let u=n.x-a*l,d=n.y-o*c;u+=n.x-this.initialPinchCenter.x,d+=n.y-this.initialPinchCenter.y,t.position.set(u,d),this.antiScale(l),this.initialPinchCenter=n}setInitialScaleAndDistance(t){const i=Array.from(this.activeTouches.values());i.length<2||(this.initialTouchDistance=s(i[0],i[1]),this.initialScale={x:t.scale.x,y:t.scale.y},this.initialPinchCenter={x:(i[0].x+i[1].x)/2,y:(i[0].y+i[1].y)/2})}}export{r as Interaction};
|
|
1
|
+
import{Container as t,Graphics as i}from"pixi.js";import{easeInOutCubic as e}from"../utils/index.js";import{getDistance as s}from"../utils/algorithm.js";import{Logger as n}from"../utils/logger.js";import{throttle as a,debounce as o}from"lodash-es";import{useAppService as h}from"./AppService.js";class r extends t{dragStart=null;initialTouchDistance=null;initialScale=null;activeTouches=new Map;firstTouchId=null;secondTouchId=null;zoomFactor=.8;scaleMin=.2;scaleMax=5;originalPosition={x:0,y:0};targetPosition={x:0,y:0};centerPosition={x:0,y:0};originalScale={x:1,y:1};targetScale={x:1,y:1};defaultScale={x:1,y:1};transitionDuration=500;transitionStartTime=null;initialPinchCenter=null;isGestureValid=!0;lastTapTime=0;doubleTapDelay=300;doubleTapZoomFactor=1.5;lastTapPosition=null;tapDistanceThreshold=20;tapDetectionEnabled=!0;isGestureHijacked=!1;hijackedPointerId=null;isHijackPaused=!1;interactionGraphics;viewportBounds;boundResetAnimation;debouncedStopWheelRender;interactionState={isInteracting:!1,isAnimating:!1,interactionTimer:null,renderReasons:new Set};throttledAntiScale;constructor(){super();const t=h().getApp();this.viewportBounds=t.getViewportBounds(),this.eventMode="static",this.interactionGraphics=new i,this.interactionGraphics.rect(0,0,this.viewportBounds.width,this.viewportBounds.height).fill({color:"#ffffff",alpha:0}),this.addChild(this.interactionGraphics),this.scaleMax=t.scaleMax,this.scaleMin=t.scaleMin,this.centerPosition={x:Math.round(this.viewportBounds.width/2),y:Math.round(this.viewportBounds.height/2)},this.originalPosition={x:Math.round(this.viewportBounds.width/2),y:Math.round(this.viewportBounds.height/2)},this.targetPosition={x:Math.round(this.viewportBounds.width/2),y:Math.round(this.viewportBounds.height/2)},this.throttledAntiScale=a(t=>{h().emitter.emit("antiScale",t)},16,{leading:!0,trailing:!0}),this.boundResetAnimation=this.resetAnimation.bind(this),this.debouncedStopWheelRender=o(()=>{t.stopRender("wheel")},300),this.setupInteraction()}setupInteraction(){this.on("pointerdown",t=>this.onPointerDown(t)),this.on("pointerup",t=>this.onPointerUp(t)),this.on("pointerupoutside",t=>this.onPointerUp(t)),this.on("pointermove",t=>this.onPointerMove(t)),this.on("wheel",t=>this.onWheel(t)),h().emitter.on("gestureHijackStart",this.handleGestureHijacked),document.addEventListener("pointercancel",()=>{this.clearTouches()})}resetPan(t){const i=h(),e=i.getApp(),s=i.appContainer;null!==this.transitionStartTime&&(e.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null);const n=this.centerPosition.x-t.x*s.scale.x,a=this.centerPosition.y-t.y*s.scale.y;this.originalPosition={x:s.x,y:s.y},this.targetPosition={x:n,y:a},this.originalScale={x:s.scale.x,y:s.scale.y},this.targetScale={x:s.scale.x,y:s.scale.y};const o=(r=Math.sqrt((s.x-n)**2+(s.y-a)**2),Math.pow(Math.min(1,r/1e3),.5));var r;this.transitionDuration=500+1e3*Math.min(1,Math.pow(o,2)),this.transitionStartTime=e.ticker.lastTime,e.ticker.add(this.boundResetAnimation)}setPanZoom({targetPosition:t,targetScale:i,setCenter:e=!1,setScale:s=!1}={},a=!0){const o=h(),r=o.getApp(),c=o.appContainer;if(e&&t&&(this.centerPosition={x:t.x,y:t.y},n.debug("[Interaction] Set center position:",this.centerPosition)),s&&i&&(this.defaultScale={x:i.x,y:i.y},n.debug("[Interaction] Set scale:",this.defaultScale)),this.originalPosition={x:c.x,y:c.y},this.originalScale={x:c.scale.x,y:c.scale.y},this.targetPosition=t||{x:this.centerPosition.x,y:this.centerPosition.y},this.targetScale=i||this.defaultScale,!a)return c.position.set(this.targetPosition.x,this.targetPosition.y),c.scale.set(this.targetScale.x,this.targetScale.y),this.antiScale(this.targetScale.x),void(null!==this.transitionStartTime&&(r.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null));var l,u,d;const p=.8*(l=Math.sqrt((c.x-this.targetPosition.x)**2+(c.y-this.targetPosition.y)**2),Math.pow(Math.min(1,l/1e3),.5))+.2*(u=c.scale.x,d=this.targetScale.x,Math.pow(Math.min(1,Math.abs(u-d)/Math.abs(-.8)),.5));this.transitionDuration=500+1e3*Math.min(1,Math.pow(p,2)),null!==this.transitionStartTime&&(r.ticker.remove(this.boundResetAnimation),this.interactionState.isAnimating=!1,r.stopRender("animation")),this.interactionState.isAnimating=!0,r.requestRender("animation",!0),this.transitionStartTime=r.ticker.lastTime,r.ticker.add(this.boundResetAnimation)}clearTouches(){const t=h().getApp();this.activeTouches.clear(),this.firstTouchId=null,this.secondTouchId=null,this.dragStart=null,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.isGestureValid=!0,null!==this.transitionStartTime&&(t.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null),this.interactionState.isInteracting=!1,t.stopRender("interaction")}checkEventListeners(){return{wheel:this.listenerCount("wheel"),pointerdown:this.listenerCount("pointerdown"),pointerup:this.listenerCount("pointerup"),pointerupoutside:this.listenerCount("pointerupoutside"),pointermove:this.listenerCount("pointermove")}}destroy(){this.checkEventListeners(),this.interactionState.interactionTimer&&clearTimeout(this.interactionState.interactionTimer),this.interactionState.renderReasons.clear(),this.interactionState.isInteracting=!1,this.interactionState.isAnimating=!1,this.debouncedStopWheelRender.cancel(),h().emitter.off("gestureHijackStart",this.handleGestureHijacked),super.destroy()}handleGestureHijacked=t=>{this.isGestureHijacked=!0,this.hijackedPointerId=t.pointerId,this.isHijackPaused=!1,this.clearTouches();const i=t.global.x-this.viewportBounds.x,e=t.global.y-this.viewportBounds.y;this.activeTouches.set(t.pointerId,{x:i,y:e}),this.firstTouchId=t.pointerId,this.dragStart={x:i,y:e}};exitGestureHijacked(){null===this.hijackedPointerId||this.isHijackPaused||(this.activeTouches.delete(this.hijackedPointerId),this.firstTouchId===this.hijackedPointerId&&(this.firstTouchId=null,this.dragStart=null),this.secondTouchId===this.hijackedPointerId&&(this.secondTouchId=null)),this.isGestureHijacked=!1,this.hijackedPointerId=null,this.isHijackPaused=!1}pauseGestureHijack(){this.isHijackPaused=!0}resumeGestureHijack(){this.isHijackPaused=!1}antiScale(t){this.throttledAntiScale(t)}resetAnimation(){const t=h(),i=t.getApp(),s=t.appContainer;if(null===this.transitionStartTime)return;const{targetPosition:n,targetScale:a}=this,o=i.ticker.lastTime,r=Math.min(1,(o-this.transitionStartTime)/this.transitionDuration);if(r>=1)s.position.set(n.x,n.y),s.scale.set(a.x,a.y),this.antiScale(a.x),i.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null,this.interactionState.isAnimating=!1,i.stopRender("animation");else{const t=e(r),i=this.originalPosition.x+(n.x-this.originalPosition.x)*t,o=this.originalPosition.y+(n.y-this.originalPosition.y)*t,h=this.originalScale.x+(a.x-this.originalScale.x)*t,c=this.originalScale.y+(a.y-this.originalScale.y)*t;s.position.set(i,o),s.scale.set(h,c),this.antiScale(h)}}onWheel(t){const i=h();if(this.isGestureHijacked)return void n.warn("⚠️ [onWheel] 被手势劫持阻止执行",{isGestureHijacked:this.isGestureHijacked,hijackedPointerId:this.hijackedPointerId,isHijackPaused:this.isHijackPaused});i.getApp().requestRender("wheel",!0),this.debouncedStopWheelRender();const{scaleMin:e,scaleMax:s}=this,a=i.appContainer;t.preventDefault();const o=t.global.x-this.viewportBounds.x,r=t.global.y-this.viewportBounds.y,c=(o-a.x)/a.scale.x,l=(r-a.y)/a.scale.y,u=t.deltaY>0?.95:1.05;let d=a.scale.x*u,p=a.scale.y*u;if(d=Math.max(e,Math.min(s,d)),p=Math.max(e,Math.min(s,p)),d===a.scale.x&&p===a.scale.y)return;const x=o-c*d,m=r-l*p;try{a.scale.set(d,p),a.position.set(x,m),this.antiScale(d)}catch(t){n.error("❌ [onWheel] 应用缩放时发生错误:",t)}}onPointerDown(t){const i=h();this.interactionState.isInteracting=!0,i.getApp().requestRender("interaction",!0),this.isGestureHijacked&&(t.pointerId===this.hijackedPointerId||this.isHijackPaused||this.pauseGestureHijack());const e=i.getApp(),s=i.appContainer;null!==this.transitionStartTime&&(e.ticker.remove(this.boundResetAnimation),this.transitionStartTime=null),this.activeTouches.has(t.pointerId-2)&&this.activeTouches.delete(t.pointerId-2),0===this.activeTouches.size&&(this.isGestureValid=!0,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.dragStart=null,this.firstTouchId=null,this.secondTouchId=null),this.activeTouches.has(t.pointerId)&&1===this.activeTouches.size&&(this.isGestureValid=!0);const n=t.global.x-this.viewportBounds.x,a=t.global.y-this.viewportBounds.y;if(this.activeTouches.set(t.pointerId,{x:n,y:a}),1===this.activeTouches.size)this.firstTouchId=t.pointerId,this.dragStart={x:n,y:a};else if(2===this.activeTouches.size){const i=Array.from(this.activeTouches.keys());this.secondTouchId=i.find(t=>t!==this.firstTouchId)||t.pointerId,this.setInitialScaleAndDistance(s),this.tapDetectionEnabled=!1}}onPointerUp(t){const i=h();if(this.isGestureHijacked){if(t.pointerId===this.hijackedPointerId)return i.emitter.emit("gestureHijackPointerUp",t),void this.exitGestureHijacked();this.isHijackPaused}if(!this.activeTouches.has(t.pointerId))return;const e=null!==this.initialTouchDistance&&null!==this.initialScale;this.activeTouches.delete(t.pointerId),e&&1===this.activeTouches.size&&(this.isGestureValid=!1,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null),t.pointerId===this.firstTouchId?(this.firstTouchId=null,this.dragStart=null,0===this.activeTouches.size&&this.tapDetectionEnabled&&this.detectDoubleTap(t)):t.pointerId===this.secondTouchId&&(this.secondTouchId=null),this.isGestureHijacked&&this.isHijackPaused&&1===this.activeTouches.size&&Array.from(this.activeTouches.keys())[0]===this.hijackedPointerId&&this.resumeGestureHijack(),0===this.activeTouches.size&&(this.isGestureValid=!0,this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.firstTouchId=null,this.secondTouchId=null,this.dragStart=null,this.tapDetectionEnabled=!0,this.interactionState.isInteracting=!1,i.getApp().stopRender("interaction"))}detectDoubleTap(t){const i=h(),{interactionConfig:e}=i;if(!e.enableDoubleTapZoom)return;const n=performance.now(),a={x:t.global.x-this.viewportBounds.x,y:t.global.y-this.viewportBounds.y};n-this.lastTapTime<this.doubleTapDelay&&this.lastTapPosition&&s(a,this.lastTapPosition)<this.tapDistanceThreshold?(this.handleDoubleTap(a),this.lastTapTime=0,this.lastTapPosition=null):(this.lastTapTime=n,this.lastTapPosition=a)}handleDoubleTap(t){const i=h(),e=i.getApp(),s=i.appContainer,{scaleMin:n,scaleMax:a,doubleTapZoomFactor:o}=this,r=t.x,c=t.y,l=(r-s.x)/s.scale.x,u=(c-s.y)/s.scale.y;let d=s.scale.x*o,p=s.scale.y*o;d=Math.max(n,Math.min(a,d)),p=Math.max(n,Math.min(a,p)),this.originalPosition={x:s.x,y:s.y},this.originalScale={x:s.scale.x,y:s.scale.y};const x=r-l*d,m=c-u*p;this.targetPosition={x:x,y:m},this.targetScale={x:d,y:p},this.interactionState.isAnimating=!0,e.requestRender("animation",!0),this.transitionDuration=300,this.transitionStartTime=e.ticker.lastTime,e.ticker.add(this.boundResetAnimation)}onPointerMove(t){if(this.isGestureHijacked&&!this.isHijackPaused){if(t.pointerId===this.hijackedPointerId){const i=t.global.x-this.viewportBounds.x,e=t.global.y-this.viewportBounds.y;return this.activeTouches.set(t.pointerId,{x:i,y:e}),void h().emitter.emit("gestureHijackPointerMove",t)}return}if(!this.activeTouches.has(t.pointerId)||!this.isGestureValid)return;const i=t.global.x-this.viewportBounds.x,e=t.global.y-this.viewportBounds.y;this.activeTouches.set(t.pointerId,{x:i,y:e}),2===this.activeTouches.size&&null!==this.initialTouchDistance&&null!==this.initialScale&&this.applyPinchZoom(),1!==this.activeTouches.size||null===this.initialTouchDistance&&null===this.initialScale||(this.initialTouchDistance=null,this.initialScale=null,this.initialPinchCenter=null,this.secondTouchId=null),1===this.activeTouches.size&&t.pointerId===this.firstTouchId&&null!==this.dragStart&&this.applyPan(t)}applyPan(t){const i=h(),e=this.activeTouches.get(t.pointerId),s=i.appContainer,{x:n,y:a}=this.dragStart;s.position.set(s.x+e.x-n,s.y+e.y-a),this.dragStart={x:e.x,y:e.y}}applyPinchZoom(){const t=h().appContainer,i=Array.from(this.activeTouches.values());if(i.length<2||!this.initialTouchDistance||!this.initialScale||!this.initialPinchCenter)return;const e=s(i[0],i[1]),n={x:(i[0].x+i[1].x)/2,y:(i[0].y+i[1].y)/2},a=(n.x-t.position.x)/t.scale.x,o=(n.y-t.position.y)/t.scale.y,r=(e/this.initialTouchDistance)**this.zoomFactor,c=Math.max(this.scaleMin,Math.min(this.scaleMax,this.initialScale.x*r)),l=Math.max(this.scaleMin,Math.min(this.scaleMax,this.initialScale.y*r));t.scale.set(c,l);let u=n.x-a*c,d=n.y-o*l;u+=n.x-this.initialPinchCenter.x,d+=n.y-this.initialPinchCenter.y,t.position.set(u,d),this.antiScale(c),this.initialPinchCenter=n}setInitialScaleAndDistance(t){const i=Array.from(this.activeTouches.values());i.length<2||(this.initialTouchDistance=s(i[0],i[1]),this.initialScale={x:t.scale.x,y:t.scale.y},this.initialPinchCenter={x:(i[0].x+i[1].x)/2,y:(i[0].y+i[1].y)/2})}}export{r as Interaction};
|
|
@@ -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)}),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,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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const A="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAwAgMAAACTeJdcAAAACVBMVEUAAAAAAAAAAACDY+nAAAAAAnRSTlMAgJsrThgAAAAiSURBVDjLY2hgwA5GJUYliJBYhQMwOAwWF45KDEUJXOkKAA7xNyG+w0wTAAAAAElFTkSuQmCC";export{A as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const A="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAABgAgMAAAAm4hnjAAAACVBMVEUAAAAAAAAAAACDY+nAAAAAAnRSTlMAgJsrThgAAAAjSURBVDjLY1gFBg4MQMAExGBqlDPKoS0HkuoGjXNGOcOVAwDBxwm1N3ts8gAAAABJRU5ErkJggg==";export{A as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Graphics as
|
|
1
|
+
import{Graphics as o}from"pixi.js";import{LAYER_FREE as t}from"../../application/AppContainer.js";import{useAppService as r}from"../../application/AppService.js";class s extends o{constructor(){super(),r().appContainer.addToLayer(t,this)}draw(o){const t=r();this.clear(),this.setFillStyle({color:t.mapConfig.freeColor});for(const t of o){const o=t.coordinates;for(let t=0;t<o.length;t+=2){const r=o[t],s=o[t+1];this.rect(r,s,1,1)}}this.fill()}destroy(o){super.destroy(o)}}export{s as Free};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Graphics as t}from"pixi.js";import{LAYER_OBSTACLE as o}from"../../application/AppContainer.js";import{RASTER_CHUNK_SIZE as
|
|
1
|
+
import{Graphics as t}from"pixi.js";import{LAYER_OBSTACLE as o}from"../../application/AppContainer.js";import{RASTER_CHUNK_SIZE as r}from"../../constant/index.js";import{useAppService as s}from"../../application/AppService.js";class e extends t{constructor(){super(),s().appContainer.addToLayer(o,this)}draw(t){const o=s();this.clear(),this.setFillStyle({color:o.mapConfig.obstacleColor});for(const o of t){const t=o.coordinates;for(let o=0;o<t.length;o+=2){const r=t[o],s=t[o+1];this.rect(r,s,1,1)}}this.fill()}drawRaster(t,o){const e=s();if(this.clear(),0!==t.length){this.setFillStyle({color:e.mapConfig.obstacleColor});for(let s=0;s<t.length;s+=r){const l=Math.min(s+r,t.length);for(let r=s;r<l;r++){const s=t[r],e=s%o,l=Math.floor(s/o);this.rect(e,l,1,1)}this.fill(),l<t.length&&this.setFillStyle({color:e.mapConfig.obstacleColor})}}}destroy(t){super.destroy(t)}}export{e as Obstacle};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as t,Graphics as i}from"pixi.js";import{throttle as o}from"lodash-es";import{LAYER_PATH as a}from"../../application/AppContainer.js";import{Logger as s}from"../../utils/logger.js";import{useAppService as e}from"../../application/AppService.js";class h extends t{commonPath;chargePath;transitionsPath;mopPath;pathData=null;lastPointCount=0;lastDrawnPosition=null;isRealTimeDrawing=!1;throttledUpdateLineWidth;throttledHandleRobotPosition;constructor(){super({isRenderGroup:!0});const t=e();t.appContainer.addToLayer(a,this),this.eventMode="none",this.commonPath=new i,this.chargePath=new i,this.transitionsPath=new i,this.mopPath=new i,this.addChild(this.commonPath),this.addChild(this.chargePath),this.addChild(this.transitionsPath),this.addChild(this.mopPath),this.visible=t.runtimeSnapshot.showPath,this.chargePath.visible=!1,this.transitionsPath.visible=!1,this.mopPath.visible=!1,this.throttledUpdateLineWidth=o(this.updateLineWidth
|
|
1
|
+
import{Container as t,Graphics as i}from"pixi.js";import{throttle as o}from"lodash-es";import{LAYER_PATH as a}from"../../application/AppContainer.js";import{Logger as s}from"../../utils/logger.js";import{useAppService as e}from"../../application/AppService.js";class h extends t{commonPath;chargePath;transitionsPath;mopPath;pathData=null;lastPointCount=0;lastDrawnPosition=null;isRealTimeDrawing=!1;throttledUpdateLineWidth;throttledHandleRobotPosition;constructor(){super({isRenderGroup:!0});const t=e();t.appContainer.addToLayer(a,this),this.eventMode="none",this.commonPath=new i,this.chargePath=new i,this.transitionsPath=new i,this.mopPath=new i,this.addChild(this.commonPath),this.addChild(this.chargePath),this.addChild(this.transitionsPath),this.addChild(this.mopPath),this.visible=t.runtimeSnapshot.showPath,this.chargePath.visible=!1,this.transitionsPath.visible=!1,this.mopPath.visible=!1,this.throttledUpdateLineWidth=o(()=>{this.updateLineWidth()},50,{leading:!0,trailing:!0}),this.throttledHandleRobotPosition=o(this.handleRobotPositionUpdate.bind(this),0),this.registerEventListeners()}registerEventListeners(){const{emitter:t}=e();t.on("antiScale",this.throttledUpdateLineWidth),t.on("robotPositionUpdate",this.throttledHandleRobotPosition),t.on("robotAnimationComplete",this.handleRobotAnimationComplete)}handleRobotAnimationComplete=()=>{this.isRealTimeDrawing&&this.stopRealTimeDrawing()};handleRobotPositionUpdate(t){if(!this.isRealTimeDrawing||!this.lastDrawnPosition)return;let i;switch(t.pathType||"common"){case"common":default:i=this.commonPath;break;case"charge":i=this.chargePath;break;case"transitions":i=this.transitionsPath;break;case"mop":i=this.mopPath}i.moveTo(this.lastDrawnPosition.x,this.lastDrawnPosition.y),i.lineTo(t.x,t.y),i.stroke(),this.lastDrawnPosition={x:t.x,y:t.y}}updateLineWidth(){const t=e();this.pathData&&t.pathConfig.lineWidthFixed&&this.redrawPaths(this.pathData)}redrawPaths(t){const{pathPoints:i}=t;i&&0!==i.length&&(this.commonPath.clear(),this.chargePath.clear(),this.transitionsPath.clear(),this.mopPath.clear(),this.setupPathStyles(),this.drawPathSegments(i),this.commonPath.stroke(),this.chargePath.stroke(),this.transitionsPath.stroke(),this.mopPath.stroke())}setupPathStyles(){const t=e(),i=t.pathConfig,o=o=>i.lineWidthFixed?t.getApp().toFixedSize(o):o;this.commonPath.setStrokeStyle({width:o(i.commonPath.width),color:i.commonPath.color,join:"round",cap:"round"}),this.chargePath.setStrokeStyle({width:o(i.chargePath.width),color:i.chargePath.color,join:"round",cap:"round"}),this.transitionsPath.setStrokeStyle({width:o(i.transitionPath.width),color:i.transitionPath.color,join:"round",cap:"round"}),this.mopPath.setStrokeStyle({width:0,color:0,alpha:0,join:"round",cap:"round"})}drawPathSegments(t){let i=null,o=null;for(let a=0;a<t.length;a++){const s=t[a],e=s.type||"common";let h;switch(e){case"common":default:h=this.commonPath;break;case"charge":h=this.chargePath;break;case"transitions":h=this.transitionsPath;break;case"mop":h=this.mopPath}0===a||e!==i?h.moveTo(s.x,s.y):h===o&&h.lineTo(s.x,s.y),i=e,o=h}}updatePositionByOrigin(t,i){this.position.set(t,i)}drawFull(t){s.debug("[Path] Draw Full Path",t),this.pathData=t,this.redrawPaths(t),this.lastPointCount=t.pathPoints?.length||0}drawIncremental(t){const i=e(),o=this.lastPointCount,a=t.pathPoints?.slice(o)||[];if(a.length>0)if(this.setupPathStyles(),s.debug("[Path] Draw Incremental Path",a),i.robotConfig.speed>0){if(this.isRealTimeDrawing=!0,o>0&&this.pathData?.pathPoints){const t=this.pathData.pathPoints[o-1];this.lastDrawnPosition={x:t.x,y:t.y}}}else this.drawNewPathSegments(a,o,t.pathPoints,this.pathData?.pathPoints);this.pathData=t,this.lastPointCount=t.pathPoints?.length||0}drawNewPathSegments(t,i,o,a){if(!o||0===t.length)return;let s=null;i>0&&(a&&a[i-1]?s=a[i-1]:o[i-1]&&(s=o[i-1]));let e=null,h=null,n=!1;for(let i=0;i<t.length;i++){const o=t[i],a=o.type||"common";let r;switch(a){case"common":default:r=this.commonPath;break;case"charge":r=this.chargePath;break;case"transitions":r=this.transitionsPath;break;case"mop":r=this.mopPath}a!==e||0===i?(h&&n&&h.stroke(),e=a,h=r,n=!0,s&&0===i&&s.type===a?(r.moveTo(s.x,s.y),r.lineTo(o.x,o.y)):r.moveTo(o.x,o.y)):r.lineTo(o.x,o.y)}h&&n&&h.stroke()}stopRealTimeDrawing(){this.isRealTimeDrawing=!1,this.lastDrawnPosition=null}destroy(t){const{emitter:i}=e();i.off("antiScale",this.throttledUpdateLineWidth),i.off("robotPositionUpdate",this.throttledHandleRobotPosition),i.off("robotAnimationComplete",this.handleRobotAnimationComplete),this.stopRealTimeDrawing(),super.destroy(t)}}export{h as Path};
|
|
@@ -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="floorType"+o%l.length;if(!h)return void p.warn(`No texture asset configured for floorType: ${o}`);const y=await r.load(h);if(!y)return void p.warn(`Floor material texture not found: ${h}`);const f=t.map(({graphics:o})=>o.getLocalBounds()),d=s(f),m=new e({texture:y,width:d.width,height:d.height});m.x=d.x,m.y=d.y,m.alpha=n,m.tileScale.set(c);const T=this.createMergedMask(t.map(({graphics:o})=>o));m.mask=T,this.addChild(m),this.floorTypeMap.set(o,m),this.floorTypeMasks.set(o,T),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{Container as e,Graphics as t,Text as i,TextStyle as o}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;constructor(r){super();const l=n(),c=l.roomConfig;this.roomId=r.id,this.background=new t;const{property:h,colors:{propertyTheme:d}}=c;c.property.foldable&&(this.bubble=new t);const a=d[r.index%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 i({text:"",style:new o({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:i
|
|
1
|
+
import{Container as e,Graphics as t,Text as i,TextStyle as o}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;constructor(r){super();const l=n(),c=l.roomConfig;this.roomId=r.id,this.background=new t;const{property:h,colors:{propertyTheme:d}}=c;c.property.foldable&&(this.bubble=new t);const a=d[r.index%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 i({text:"",style:new o({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:i}=t.roomConfig.property,{showRoomOrder:o,showRoomProperty:s}=t.runtimeSnapshot,r=e.order||0,l=o&&r>0,c=s&&i.includes("cleanMode"),h=s&&i.includes("suction"),d=s&&i.includes("cistern"),a=s&&i.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}),i.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:i,iconHeight:o,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:i,height:o,sizeFixed:!1})),p&&f.push(this.suctionIcon.loadTextureAndSetSize(`fan_${e.suction}`,{width:i,height:o,sizeFixed:!1})),g&&f.push(this.cisternIcon.loadTextureAndSetSize(`water_${e.cistern}`,{width:i,height:o,sizeFixed:!1})),m){const t=e.cleanTimes||1;f.push(this.cleanTimesIcon.loadTextureAndSetSize(`cleanTimes${t}`,{width:i,height:o,sizeFixed:!1}))}await Promise.all(f),u&&(this.orderText.text=C.toString(),this.orderBackground.clear(),this.orderBackground.setFillStyle({color:h[e.index%h.length]}),this.orderBackground.circle(i/2,o/2,i/2).fill(),this.orderText.position.set(i/2,o/2));let w=d;I.forEach((e,t)=>{const{element:o,isOrder:n}=e;o.position.set(w,a),w+=i,t<I.length-1&&(w+=n?r.gapRight:c)})}updateBackground(){const e=n().roomConfig,{container:t,foldable:i}=e.property,{borderRadius:o,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,o).fill(),i&&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:i,cleanOrder:o,iconGap:s}=e.roomConfig.property,{paddingHorizontal:r}=i,l=e.getRoomData(this.roomId);if(!l)return 2*r;const{elementsToShow:c}=this.getDisplayElements(l);let h=r;return c.forEach((e,i)=>{const{isOrder:n}=e;h+=t,i<c.length-1&&(h+=n?o.gapRight:s)}),h+=r,h}calculateContentHeight(){const e=n().roomConfig,{iconHeight:t,container:i}=e.property;return i.paddingVertical+t+i.paddingVertical}getTotalHeight(){const e=n(),{foldable:t,container:i}=e.roomConfig.property,{tailHeight:o}=i;return this.calculateContentHeight()+(t?o:0)}getTotalWidth(){return this.calculateContentWidth()}setFolded(e){const t=n(),{foldable:i}=t.roomConfig.property;if(i)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 i=e.roomConfig,{tailHeight:o}=i.property.container,s=this.calculateContentWidth(),r=this.calculateContentHeight(),l=s/2;this.bubble.position.set(l,r+o/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[l.index%e.selectionIndicatorBackground.length];if(this.background.clear(),this.bubble.clear(),this.background.setFillStyle({color:k}).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}}export{c as RoomSelectionIndicator};
|
|
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[l.index%e.selectionIndicatorBackground.length];if(this.background.clear(),this.bubble.clear(),this.background.setFillStyle({color:k}).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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RoomName as o}from"./RoomName.js";import{RoomProperty as t}from"./RoomProperty.js";import{RoomSelectionIndicator as i}from"./RoomSelectionIndicator.js";import{ClickHandler as e}from"../../mixins/ClickHandler.js";import{FixedSizeContainer as r}from"../Base/FixedSizeContainer.js";import{useAppService as s}from"../../application/AppService.js";class n extends r{roomId;roomName;roomProperty=null;roomSelectionIndicator=null;clickHandler=null;constructor(t){super();const i=s();this.enableRenderGroup(),this.roomId=t.id,t.centerPoint&&this.position.set(t.centerPoint.x,t.centerPoint.y),this.roomName=new o(t),this.roomName.visible=i.runtimeSnapshot.showRoomName,this.createRoomProperty(t),this.createRoomSelectionIndicator(t),this.updateLayout(),this.clickHandler=new e(this,{onClick:()=>{i.events?.onClickRoomProperties?.(t)}})}shouldShowRoomProperty(){const o=s(),{showRoomOrder:t,showRoomProperty:i,
|
|
1
|
+
import{RoomName as o}from"./RoomName.js";import{RoomProperty as t}from"./RoomProperty.js";import{RoomSelectionIndicator as i}from"./RoomSelectionIndicator.js";import{ClickHandler as e}from"../../mixins/ClickHandler.js";import{FixedSizeContainer as r}from"../Base/FixedSizeContainer.js";import{useAppService as s}from"../../application/AppService.js";class n extends r{roomId;roomName;roomProperty=null;roomSelectionIndicator=null;clickHandler=null;constructor(t){super();const i=s();this.enableRenderGroup(),this.roomId=t.id,t.centerPoint&&this.position.set(t.centerPoint.x,t.centerPoint.y),this.roomName=new o(t),this.roomName.visible=i.runtimeSnapshot.showRoomName,this.createRoomProperty(t),this.createRoomSelectionIndicator(t),this.updateLayout(),this.clickHandler=new e(this,{onClick:()=>{i.events?.onClickRoomProperties?.(t)}})}shouldShowRoomProperty(){const o=s(),{showRoomOrder:t,showRoomProperty:i,selectRoomIds:e,enableRoomSelection:r,roomSelectionMode:n}=o.runtimeSnapshot,m=o.getRoomData(this.roomId);if(!m)return!1;if(r&&"checkmark"===n&&e.includes(this.roomId))return!1;const a=t&&(m.order||0)>0,c=i&&(m.suction&&o.roomConfig.property.displayOrders.includes("suction")||m.cistern&&o.roomConfig.property.displayOrders.includes("cistern")||m.cleanTimes>0&&o.roomConfig.property.displayOrders.includes("cleanTimes"));return a||c}shouldShowRoomSelectionIndicator(){const o=s(),{enableRoomSelection:t,roomSelectionMode:i}=o.runtimeSnapshot;return t&&"checkmark"===i}updateRoomPropertyVisibility(){const o=s();if(this.roomProperty){if(this.shouldShowRoomProperty()){this.roomProperty.visible=!0;const t=o.runtimeSnapshot.roomPropertyFoldIds.includes(this.roomId);this.roomProperty.setFolded(t);const i=o.getRoomData(this.roomId);i&&this.roomProperty.updateProperty(i)}else this.roomProperty.visible=!1;this.updateLayout()}}async updateRoomSelectionIndicatorVisibility(){const o=s();if(this.roomSelectionIndicator){if(this.shouldShowRoomSelectionIndicator()){const t=o.getRoomData(this.roomId);t&&await this.roomSelectionIndicator.updateIndicator(t)}else this.roomSelectionIndicator.visible=!1;this.updateLayout()}}async createRoomProperty(o){const i=s();this.roomProperty&&(this.removeChild(this.roomProperty),this.roomProperty.destroy()),this.roomProperty=new t(o),await this.roomProperty.updateProperty(o),this.addChild(this.roomProperty),this.addChild(this.roomName),this.roomName.visible=i.runtimeSnapshot.showRoomName,this.updateRoomPropertyVisibility()}async createRoomSelectionIndicator(o){this.roomSelectionIndicator&&(this.removeChild(this.roomSelectionIndicator),this.roomSelectionIndicator.destroy()),this.roomSelectionIndicator=new i(o),this.addChild(this.roomSelectionIndicator),await this.updateRoomSelectionIndicatorVisibility()}updateLayout(){const o=s(),{property:{offsetY:t,offsetX:i},selectionIndicator:{offsetY:e,offsetX:r}}=o.roomConfig,n=this.roomProperty?.visible||!1,m=this.roomName.visible,a=this.roomSelectionIndicator?.visible||!1;if(n&&this.roomProperty)if(this.roomProperty.isFoldedState())this.roomProperty.position.set(i,-t);else{const o=this.roomProperty.getTotalHeight(),e=this.roomProperty.getTotalWidth();m?(this.roomProperty.position.set(-e/2+i,-t-o),this.roomName.position.set(0,0)):this.roomProperty.position.set(-e/2+i,-o/2-t)}if(a&&this.roomSelectionIndicator){const o=this.roomSelectionIndicator.getTotalHeight(),t=this.roomSelectionIndicator.getTotalWidth();m?(this.roomSelectionIndicator.position.set(-t/2+r,-e-o),this.roomName.position.set(0,0)):this.roomSelectionIndicator.position.set(-t/2+r,-o/2-e)}!m||n||a||this.roomName.position.set(0,0)}updateName(o){this.roomName.updateName(o)}updateRoomNameVisibility(o){this.roomName.visible=o,this.updateLayout()}updatePosition(o){this.position.set(o.x,o.y)}destroy(){this.clickHandler?.destroy(),this.clickHandler=null,this.roomProperty?.destroy(),this.roomProperty=null,this.roomSelectionIndicator?.destroy(),this.roomSelectionIndicator=null,this.roomName?.destroy(),super.destroy()}}export{n as RoomInfo};
|
package/dist/constant/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"../assets/chargingStation.png.js";import o 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 a from"../assets/fan4.png.js";import n 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/
|
|
1
|
+
import e from"../assets/chargingStation.png.js";import o 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 a from"../assets/fan4.png.js";import n 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=["#d7bb46","#4990d7","#58a789","#749cd7","#f2646c","#91be76","#4ec7b1","#4bb3c8","#e7858a","#7fa96e","#efa667","#a3d774","#6b82d8","#75b551","#b392cd","#ed5454"],P={global:{containerTop:"0px",containerLeft:"0px",containerWidth:"100%",containerHeight:"100%",backgroundColor:"#f6f6f6"},map:{autoPaddingPercent:.05,obstacleColor:"#999999",freeColor:"#ebebeb"},room:{colors:{active:["#fae9a3","#a6d0fa","#9ce3c8","#d1e2fa","#fed8da","#d4f0c3","#a1f3e4","#a0e5f3","#fee6e8","#c1e5b1","#fee9d7","#e4fad1","#c8d3fa","#b8ea9c","#f0e5f9","#fdc4c4"],inactive:["#fef5d2","#d5e9fe","#c0f2df","#e7f0fe","#fef0f1","#f0fbe9","#ccfbf3","#caf3fc","#fff3f4","#def5d4","#fef1e6","#f2fee7","#e6ebfe","#d5f7c2","#f3e9fb","#fee2e2"],name:R,propertyTheme:R,selectionIndicatorBackground:R,selectionIndicatorIcon:["#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,a]},cistern:{assets:[n,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:o},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:e},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:20,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:20,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:20,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:20,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};
|