@ray-js/robot-map-sdk 0.0.3-beta-7 → 0.0.3-beta-8
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/components/Heatmap/index.js +1 -1
- package/dist/components/Map/Free.js +1 -1
- package/dist/components/Map/Obstacle.js +1 -1
- package/dist/constant/config.js +1 -1
- package/dist/index.d.ts +92 -1447
- package/dist/utils/logger.js +1 -1
- package/dist-app/assets/{index-rWbtFkbX.js → index-C3rjigWj.js} +1 -1
- package/dist-app/index.html +1 -1
- package/dist-docs/404.html +2 -2
- package/dist-docs/assets/{app.C8maVmzs.js → app.BGQfBD4o.js} +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.CSdgg9Q0.js +1 -0
- package/dist-docs/assets/chunks/{VPLocalSearchBox.dmVujmrV.js → VPLocalSearchBox.YvMlJA6m.js} +1 -1
- package/dist-docs/assets/chunks/{theme.BkasJq65.js → theme.1StzhkaW.js} +2 -2
- package/dist-docs/assets/{guide_getting-started.md.CSvzbjhl.js → guide_getting-started.md.B2we0fUv.js} +1 -1
- package/dist-docs/assets/reference_config.md.h1LczQ1s.js +41 -0
- package/dist-docs/assets/reference_config.md.h1LczQ1s.lean.js +1 -0
- package/dist-docs/guide/advanced-usage.html +3 -3
- package/dist-docs/guide/concepts.html +3 -3
- package/dist-docs/guide/getting-started.html +5 -5
- package/dist-docs/hashmap.json +1 -1
- package/dist-docs/index.html +3 -3
- package/dist-docs/reference/callbacks.html +3 -3
- package/dist-docs/reference/config.html +5 -5
- package/dist-docs/reference/data.html +3 -3
- package/dist-docs/reference/methods.html +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/index.rjs.js +0 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.BEPmfEXB.js +0 -1
- package/dist-docs/assets/reference_config.md.BOXwJsHq.js +0 -41
- package/dist-docs/assets/reference_config.md.BOXwJsHq.lean.js +0 -1
- /package/dist-docs/assets/{guide_getting-started.md.CSvzbjhl.lean.js → guide_getting-started.md.B2we0fUv.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},this.scaleMin=i.x*r.scaleMin,this.scaleMax=i.x*r.scaleMax,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 x=o-l*d,m=r-c*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;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 x=r-c*d,m=l-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)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(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 +1 @@
|
|
|
1
|
-
import{Application as e,isMobile as t,Assets as a}from"pixi.js";import{Interaction as n}from"./Interaction.js";import{merge as r}from"lodash-es";import{proxy as i}from"valtio/vanilla";import{MAIN_INSTANCE_KEY as s}from"../constant/index.js";import o 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}from"../utils/algorithm.js";import{ViewportContainer as m}from"./ViewportContainer.js";import{AppContainer as l}from"./AppContainer.js";import{MapManager as g}from"../managers/MapManager.js";import{PathManager as u}from"../managers/PathManager.js";import{HeatmapManager as w}from"../managers/HeatmapManager.js";import{ControlsManager as M}from"../managers/ControlsManager.js";import{DetectedObjectManager as y}from"../managers/DetectedObjectManager.js";import{CustomElementsManager as f}from"../managers/CustomElementsManager.js";import{RoomManager as x}from"../managers/RoomManager.js";import{getOptimalAntialiasingStrategy as S}from"../utils/browser.js";import{DEFAULT_CONFIG as b,DEFAULT_RUNTIME_CONFIG as v}from"../constant/config.js";class C extends e{mapState=null;components={};managers={};config=b;runtime;scaleMin=.5;scaleMax=5;events={};instanceKey;containerElement;emitter=o();tickerState={renderReasons:new Set,renderTimer:null};pendingAsyncRender=!1;isFirstMapDraw=!0;constructor(e=s){super(),this.instanceKey=e,h.registerInstance(e,this),globalThis.__PIXI_APP__=this}async initialize(e){return h.provideAsync(this,async()=>{const{resizeTo:a,events:n,config:o,runtime:c={},...h}=e;this.config=r(this.config,o??{}),this.runtime=i(Object.assign({},v,c));const d=this.instanceKey===s;this.containerElement=a;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?a:void 0,preferWebGLVersion:2,resolution:window.devicePixelRatio||1,antialias:S(),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=n,this.initializeViewportContainer(),this.initializeInteraction(),this.initializeAppContainer(),this.managers.mapManager=new g,this.managers.heatmapManager=new w,this.managers.pathManager=new u,this.managers.controlsManager=new M,this.managers.detectedObjectManager=new y,this.managers.customElementsManager=new f,this.managers.roomsManager=new x,document.addEventListener("visibilitychange",this.onVisibilityChange)})}async drawMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawMap",e);const{size:t,resolution:a,origin:n}=e;n[0]===this.mapState?.origin.x&&n[1]===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(...n),this.managers.controlsManager.updatePositionByOrigin(...n),this.managers.detectedObjectManager.updatePositionByOrigin(...n),this.managers.customElementsManager.updatePositionByOrigin(...n)),this.mapState={id:e.id,status:1===e.status,origin:{x:n[0],y:n[1]},charger:{x:e.charger.coordinate[0],y:e.charger.coordinate[1]},chargerDirection:e.charger.angle??0,resolution:a,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:a}=e,{originX:n,originY:r}=t;n===this.mapState?.origin.x&&r===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(n,r),this.managers.controlsManager.updatePositionByOrigin(n,r),this.managers.detectedObjectManager.updatePositionByOrigin(n,r),this.managers.customElementsManager.updatePositionByOrigin(n,r)),this.mapState={id:t.id,status:t.mapStable,origin:{x:n,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(a.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:a=!0}){return h.provide(this,()=>{c.log("[Heatmap] drawHeatmap",t),this.managers.heatmapManager.draw({mapData:e,heatmapPoints:t,useGradient:a}),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,a=!0){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,r=this.getViewportBounds(),i=e.maxX-e.minX,s=e.maxY-e.minY,o=r.width,h=r.height,d=o*(1-2*n)/i,p=h*(1-2*n)/s,m=Math.min(d,p),l=Math.max(this.scaleMin,Math.min(this.scaleMax,m)),g=o/2-(e.minX+i/2)*l,u=h/2-(e.minY+s/2)*l;this.components.interaction.setPanZoom({targetPosition:{x:g,y:u},targetScale:{x:l,y:l},setCenter:!0,setScale:!0},t),a&&this.emitter.emit("cacheAsTexture",Math.ceil(this.components.interaction.targetScale.x*this.scaleMax))})}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,a=e.y+e.height/2,n=this.components.appContainer,r=n.scale.x,i=(t-n.x)/r,s=(a-n.y)/r;return{x:i-this.mapState.origin.x,y:s-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,a=(e.minY+e.maxY)/2;return{x:t-this.mapState.origin.x,y:a-this.mapState.origin.y}}getWallPointsByViewportCenter(e){const{width:t=this.config.controls.virtualWall.minWidth,direction:a="horizontal",offsetX:n=0,offsetY:r=0}=e||{},i=this.getViewportCenterPoint()||{x:0,y:0},s=this.metersToPixels(t);return p(i.x,i.y,s,a).map(e=>({x:e.x+n,y:e.y+r}))}getForbiddenSweepZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenSweepZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getForbiddenMopZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenMopZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getCleanZonePointsByViewportCenter(e){const t=this.config.controls.cleanZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getSpotPointByViewportCenter(e){const{offsetX:t=0,offsetY:a=0}=e||{},n=this.getViewportCenterPoint()||{x:0,y:0};return{x:n.x+t,y:n.y+a}}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:a,customElements:n,forbiddenSweepZones:r,forbiddenMopZones:i,virtualWalls:s,detectedObjects:o},h={}){const p=`SNAPSHOT_${d()}`;c.log(`[MapApplication] ${p} snapshot start`);const m=new C(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"),a=t(e);await m.drawMap(a)}else{const{decodeMap:t}=await import("@ray-js/robot-protocol"),a=t(e);if(!a)throw new Error("Failed to decode raster map data");await m.drawRasterMap(a)}if(t){const{decodePath:e}=await import("@ray-js/robot-protocol"),a=e(t);m.drawPath(a)}a&&a.length>0&&m.drawRoomProperty(a),r&&r.length>0&&m.drawForbiddenSweepZones(r),i&&i.length>0&&m.drawForbiddenMopZones(i),s&&s.length>0&&m.drawVirtualWalls(s),o&&o.length>0&&await m.drawDetectedObjects(o),n&&n.length>0&&await m.drawCustomElements(n);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 m(this.config,this.containerElement),this.stage.addChild(this.components.viewportContainer)}initializeAppContainer(){this.components.appContainer=new l,this.components.interaction.addChild(this.components.appContainer)}initializeInteraction(){this.components.interaction=new n,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,a){const n=this.getViewportCenterPoint()||{x:0,y:0},r=this.metersToPixels(e)/2,i=n.x+t,s=n.y+a;return[{x:i-r,y:s-r},{x:i+r,y:s-r},{x:i+r,y:s+r},{x:i-r,y:s+r}]}preloadAssets(){const e=this.config.robot.icon.src,t=this.config.chargingStation.icon.src,n=[];a.add({alias:"robot",src:e}),n.push("robot"),a.add({alias:"chargingStation",src:t}),n.push("chargingStation"),a.add({alias:"deleteIcon",src:this.config.controls.deleteIconSrc}),n.push("deleteIcon"),a.add({alias:"rotateIcon",src:this.config.controls.rotateIconSrc}),n.push("rotateIcon"),a.add({alias:"scaleIcon",src:this.config.controls.scaleIconSrc}),n.push("scaleIcon"),a.add({alias:"moveIcon",src:this.config.controls.moveIconSrc}),n.push("moveIcon"),a.add({alias:"checkmark",src:this.config.room.selectionIndicator.iconSrc}),n.push("checkmark"),a.add({alias:"spotIcon",src:this.config.controls.spot.iconSrc}),n.push("spotIcon"),this.config.room.property.cleanMode.assets.forEach((e,t)=>{const r=`cleanMode_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.suction.assets.forEach((e,t)=>{const r=`fan_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.cistern.assets.forEach((e,t)=>{const r=`water_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.cleanTimes.assets.forEach((e,t)=>{const r=`cleanTimes${t+1}`;a.add({alias:r,src:e}),n.push(r)}),a.backgroundLoad(n)}onVisibilityChange=()=>{"visible"===document.visibilityState||this.components.interaction?.clearTouches()}}export{C as MapApplication};
|
|
1
|
+
import{Application as e,isMobile as t,Assets as a}from"pixi.js";import{Interaction as n}from"./Interaction.js";import{merge as r}from"lodash-es";import{proxy as i}from"valtio/vanilla";import{MAIN_INSTANCE_KEY as s}from"../constant/index.js";import o 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}from"../utils/algorithm.js";import{ViewportContainer as m}from"./ViewportContainer.js";import{AppContainer as l}from"./AppContainer.js";import{MapManager as g}from"../managers/MapManager.js";import{PathManager as u}from"../managers/PathManager.js";import{HeatmapManager as w}from"../managers/HeatmapManager.js";import{ControlsManager as M}from"../managers/ControlsManager.js";import{DetectedObjectManager as y}from"../managers/DetectedObjectManager.js";import{CustomElementsManager as f}from"../managers/CustomElementsManager.js";import{RoomManager as x}from"../managers/RoomManager.js";import{getOptimalAntialiasingStrategy as S}from"../utils/browser.js";import{DEFAULT_CONFIG as b,DEFAULT_RUNTIME_CONFIG as v}from"../constant/config.js";class C extends e{mapState=null;components={};managers={};config=b;runtime;scaleMin=.5;scaleMax=5;events={};instanceKey;containerElement;emitter=o();tickerState={renderReasons:new Set,renderTimer:null};pendingAsyncRender=!1;isFirstMapDraw=!0;constructor(e=s){super(),this.instanceKey=e,h.registerInstance(e,this),globalThis.__PIXI_APP__=this}async initialize(e){return h.provideAsync(this,async()=>{const{resizeTo:a,events:n,config:o,runtime:c={},...h}=e;this.config=r(this.config,o??{}),this.runtime=i(Object.assign({},v,c));const d=this.instanceKey===s;this.containerElement=a;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?a:void 0,preferWebGLVersion:2,resolution:window.devicePixelRatio||1,antialias:S(),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=n,this.initializeViewportContainer(),this.initializeInteraction(),this.initializeAppContainer(),this.managers.mapManager=new g,this.managers.heatmapManager=new w,this.managers.pathManager=new u,this.managers.controlsManager=new M,this.managers.detectedObjectManager=new y,this.managers.customElementsManager=new f,this.managers.roomsManager=new x,document.addEventListener("visibilitychange",this.onVisibilityChange)})}async drawMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawMap",e);const{size:t,resolution:a,origin:n}=e;n[0]===this.mapState?.origin.x&&n[1]===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(...n),this.managers.controlsManager.updatePositionByOrigin(...n),this.managers.detectedObjectManager.updatePositionByOrigin(...n),this.managers.customElementsManager.updatePositionByOrigin(...n)),this.mapState={id:e.id,status:1===e.status,origin:{x:n[0],y:n[1]},charger:{x:e.charger.coordinate[0],y:e.charger.coordinate[1]},chargerDirection:e.charger.angle??0,resolution:a,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:a}=e,{originX:n,originY:r}=t;n===this.mapState?.origin.x&&r===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(n,r),this.managers.controlsManager.updatePositionByOrigin(n,r),this.managers.detectedObjectManager.updatePositionByOrigin(n,r),this.managers.customElementsManager.updatePositionByOrigin(n,r)),this.mapState={id:t.id,status:t.mapStable,origin:{x:n,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(a.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:a=!0}){return h.provide(this,()=>{c.log("[Heatmap] drawHeatmap",t),this.managers.heatmapManager.draw({mapData:e,heatmapPoints:t,useGradient:a}),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 a=this.config.map.autoPaddingPercent||.1,n=this.getViewportBounds(),r=e.maxX-e.minX,i=e.maxY-e.minY,s=n.width,o=n.height,h=s*(1-2*a)/r,d=o*(1-2*a)/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=s/2-(e.minX+r/2)*g,w=o/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,a=e.y+e.height/2,n=this.components.appContainer,r=n.scale.x,i=(t-n.x)/r,s=(a-n.y)/r;return{x:i-this.mapState.origin.x,y:s-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,a=(e.minY+e.maxY)/2;return{x:t-this.mapState.origin.x,y:a-this.mapState.origin.y}}getWallPointsByViewportCenter(e){const{width:t=this.config.controls.virtualWall.minWidth,direction:a="horizontal",offsetX:n=0,offsetY:r=0}=e||{},i=this.getViewportCenterPoint()||{x:0,y:0},s=this.metersToPixels(t);return p(i.x,i.y,s,a).map(e=>({x:e.x+n,y:e.y+r}))}getForbiddenSweepZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenSweepZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getForbiddenMopZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenMopZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getCleanZonePointsByViewportCenter(e){const t=this.config.controls.cleanZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getSpotPointByViewportCenter(e){const{offsetX:t=0,offsetY:a=0}=e||{},n=this.getViewportCenterPoint()||{x:0,y:0};return{x:n.x+t,y:n.y+a}}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:a,customElements:n,forbiddenSweepZones:r,forbiddenMopZones:i,virtualWalls:s,detectedObjects:o},h={}){const p=`SNAPSHOT_${d()}`;c.log(`[MapApplication] ${p} snapshot start`);const m=new C(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"),a=t(e);await m.drawMap(a)}else{const{decodeMap:t}=await import("@ray-js/robot-protocol"),a=t(e);if(!a)throw new Error("Failed to decode raster map data");await m.drawRasterMap(a)}if(t){const{decodePath:e}=await import("@ray-js/robot-protocol"),a=e(t);m.drawPath(a)}a&&a.length>0&&m.drawRoomProperty(a),r&&r.length>0&&m.drawForbiddenSweepZones(r),i&&i.length>0&&m.drawForbiddenMopZones(i),s&&s.length>0&&m.drawVirtualWalls(s),o&&o.length>0&&await m.drawDetectedObjects(o),n&&n.length>0&&await m.drawCustomElements(n);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 m(this.config,this.containerElement),this.stage.addChild(this.components.viewportContainer)}initializeAppContainer(){this.components.appContainer=new l,this.components.interaction.addChild(this.components.appContainer)}initializeInteraction(){this.components.interaction=new n,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,a){const n=this.getViewportCenterPoint()||{x:0,y:0},r=this.metersToPixels(e)/2,i=n.x+t,s=n.y+a;return[{x:i-r,y:s-r},{x:i+r,y:s-r},{x:i+r,y:s+r},{x:i-r,y:s+r}]}preloadAssets(){const e=this.config.robot.icon.src,t=this.config.chargingStation.icon.src,n=[];a.add({alias:"robot",src:e}),n.push("robot"),a.add({alias:"chargingStation",src:t}),n.push("chargingStation"),a.add({alias:"deleteIcon",src:this.config.controls.deleteIconSrc}),n.push("deleteIcon"),a.add({alias:"rotateIcon",src:this.config.controls.rotateIconSrc}),n.push("rotateIcon"),a.add({alias:"scaleIcon",src:this.config.controls.scaleIconSrc}),n.push("scaleIcon"),a.add({alias:"moveIcon",src:this.config.controls.moveIconSrc}),n.push("moveIcon"),a.add({alias:"checkmark",src:this.config.room.selectionIndicator.iconSrc}),n.push("checkmark"),a.add({alias:"spotIcon",src:this.config.controls.spot.iconSrc}),n.push("spotIcon"),this.config.room.property.cleanMode.assets.forEach((e,t)=>{const r=`cleanMode_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.suction.assets.forEach((e,t)=>{const r=`fan_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.cistern.assets.forEach((e,t)=>{const r=`water_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.cleanTimes.assets.forEach((e,t)=>{const r=`cleanTimes${t+1}`;a.add({alias:r,src:e}),n.push(r)}),a.backgroundLoad(n)}onVisibilityChange=()=>{"visible"===document.visibilityState||this.components.interaction?.clearTouches()}}export{C as MapApplication};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Container as n,Color as o,Graphics as
|
|
1
|
+
import{Container as n,Color as o,Graphics as i,Geometry as r,Shader as l,GlProgram as t,Mesh as a}from"pixi.js";import{LAYER_HEATMAP as e}from"../../application/AppContainer.js";import{useAppService as s}from"../../application/AppService.js";class c extends n{colorGradients=[];cellSize=2;constructor(){super();const n=s();n.appContainer.addToLayer(e,this);const i=n.heatMapConfig;this.colorGradients=i.colorGradients.map(n=>new o(n).toArray().slice(0,3).join(",")),this.cellSize=i.cellSize}draw(n,o=!0,i=.8){this.removeChildren();const r=o?this.gradientDrawing(n):this.gridDrawing(n);this.croppingHeatmap(r),r.alpha=i,this.addChild(r)}croppingHeatmap(n){const o=s().mapManager.roomFill.children.filter(n=>n instanceof i),r=new i;for(const n of o)r.context.instructions.push(...n.context.instructions);r.context.dirty=!0,n.setMask({mask:r}),this.addChild(r)}gridDrawing(n){const o=[],i=[],e=n.length,s=n[0].length;for(let r=0;r<e;r++)for(let l=0;l<s;l++){const t=n[r][l],a=this.cellSize/2,e=t.x-a,s=t.y-a,c=t.x+a,g=t.y+a;o.push(e,s),i.push(t.signal),o.push(c,s),i.push(t.signal),o.push(c,g),i.push(t.signal),o.push(e,s),i.push(t.signal),o.push(c,g),i.push(t.signal),o.push(e,g),i.push(t.signal)}const c=new r({attributes:{aPosition:new Float32Array(o),aSignal:new Float32Array(i)}}),g=new l({glProgram:new t({vertex:"\n in vec2 aPosition;\n in float aSignal;\n uniform mat3 uProjectionMatrix;\n uniform mat3 uWorldTransformMatrix;\n uniform mat3 uTransformMatrix;\n \n out float vSignal;\n \n void main() {\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\n vSignal = aSignal;\n }\n ",fragment:`\n precision mediump float;\n \n in float vSignal;\n \n void main() {\n vec3 color;\n \n if (vSignal > 0.875) {\n color = vec3(${this.colorGradients[0]});\n } else if (vSignal > 0.75) {\n color = vec3(${this.colorGradients[1]});\n } else if (vSignal > 0.625) {\n color = vec3(${this.colorGradients[2]});\n } else if (vSignal > 0.5) {\n color = vec3(${this.colorGradients[3]});\n } else if (vSignal > 0.375) {\n color = vec3(${this.colorGradients[4]});\n } else if (vSignal > 0.25) {\n color = vec3(${this.colorGradients[5]});\n } else if (vSignal > 0.125) {\n color = vec3(${this.colorGradients[6]});\n } else {\n color = vec3(${this.colorGradients[7]});\n }\n gl_FragColor = vec4(color, 1.0);\n }\n `})}),v=new a({geometry:c,shader:g});return v.alpha=.8,v}gradientDrawing(n){const o=[],i=[],e=n.length,s=n[0].length;for(let r=0;r<e;r++)for(let l=0;l<s;l++){const t=n[r][l],a=this.cellSize/2,c=(o,i)=>o<0||o>=e||i<0||i>=s?t.signal:n[o][i].signal,g=(c(r-1,l-1)+c(r-1,l)+c(r,l-1)+t.signal)/4,v=(c(r-1,l)+c(r-1,l+1)+t.signal+c(r,l+1))/4,p=(t.signal+c(r,l+1)+c(r+1,l)+c(r+1,l+1))/4,f=(c(r,l-1)+t.signal+c(r+1,l-1)+c(r+1,l))/4,h=t.x-a,m=t.y-a,d=t.x+a,u=t.y+a;o.push(h,m,d,m,d,u),i.push(g,v,p),o.push(h,m,d,u,h,u),i.push(g,p,f)}const c=new r({attributes:{aPosition:new Float32Array(o),aSignal:new Float32Array(i)}}),g=new l({glProgram:new t({vertex:"\n in vec2 aPosition;\n in float aSignal;\n uniform mat3 uProjectionMatrix;\n uniform mat3 uWorldTransformMatrix;\n uniform mat3 uTransformMatrix;\n \n out float vSignal;\n \n void main() {\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\n vSignal = aSignal;\n }\n ",fragment:`\n precision mediump float;\n \n in float vSignal;\n \n // 颜色插值函数\n vec3 interpolateColor(vec3 color1, vec3 color2, float t) {\n return mix(color1, color2, t);\n }\n \n void main() {\n vec3 color;\n float signal = clamp(vSignal, 0.0, 1.0);\n \n vec3 color1 = vec3(${this.colorGradients[7]});\n vec3 color2 = vec3(${this.colorGradients[6]});\n vec3 color3 = vec3(${this.colorGradients[5]});\n vec3 color4 = vec3(${this.colorGradients[4]});\n vec3 color5 = vec3(${this.colorGradients[3]});\n vec3 color6 = vec3(${this.colorGradients[2]});\n vec3 color7 = vec3(${this.colorGradients[1]});\n vec3 color8 = vec3(${this.colorGradients[0]});\n \n if (signal <= 0.125) {\n float t = signal / 0.125;\n color = interpolateColor(color1, color2, t);\n } else if (signal <= 0.25) {\n float t = (signal - 0.125) / 0.125;\n color = interpolateColor(color2, color3, t);\n } else if (signal <= 0.375) {\n float t = (signal - 0.25) / 0.125;\n color = interpolateColor(color3, color4, t);\n } else if (signal <= 0.5) {\n float t = (signal - 0.375) / 0.125;\n color = interpolateColor(color4, color5, t);\n } else if (signal <= 0.625) {\n float t = (signal - 0.5) / 0.125;\n color = interpolateColor(color5, color6, t);\n } else if (signal <= 0.75) {\n float t = (signal - 0.625) / 0.125;\n color = interpolateColor(color6, color7, t);\n } else if (signal <= 0.875) {\n float t = (signal - 0.75) / 0.125;\n color = interpolateColor(color7, color8, t);\n } else {\n color = color8;\n }\n \n gl_FragColor = vec4(color, 1.0);\n }\n `})}),v=new a({geometry:c,shader:g});return v.alpha=.8,v}}export{c as Heatmap};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Graphics as
|
|
1
|
+
import{Graphics as t}from"pixi.js";import{LAYER_FREE as o}from"../../application/AppContainer.js";import{useAppService as r}from"../../application/AppService.js";class e extends t{constructor(){super(),r().appContainer.addToLayer(o,this)}draw(t){const o=r();this.clear(),this.setFillStyle({color:o.mapConfig.freeColor});for(const o of t){const t=o.coordinates;for(let o=0;o<t.length;o+=2){const r=t[o],e=t[o+1];this.rect(r,e,1,1)}}this.fill(),this.updateCacheTexture()}destroy(t){super.destroy(t)}}export{e as Free};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Graphics as t}from"pixi.js";import{LAYER_OBSTACLE as
|
|
1
|
+
import{Graphics as t}from"pixi.js";import{LAYER_OBSTACLE as o}from"../../application/AppContainer.js";import{RASTER_CHUNK_SIZE as e}from"../../constant/index.js";import{useAppService as r}from"../../application/AppService.js";class s extends t{constructor(){super(),r().appContainer.addToLayer(o,this)}draw(t){const o=r();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 e=t[o],r=t[o+1];this.rect(e,r,1,1)}}this.fill(),this.updateCacheTexture()}drawRaster(t,o){const s=r();if(this.clear(),0!==t.length){this.setFillStyle({color:s.mapConfig.obstacleColor});for(let r=0;r<t.length;r+=e){const i=Math.min(r+e,t.length);for(let e=r;e<i;e++){const r=t[e],s=r%o,i=Math.floor(r/o);this.rect(s,i,1,1)}this.fill(),i<t.length&&this.setFillStyle({color:s.mapConfig.obstacleColor})}this.updateCacheTexture()}}destroy(t){super.destroy(t)}}export{s as Obstacle};
|
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/floorType.png.js";import j from"../assets/carpet.png.js";import
|
|
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/floorType.png.js";import j from"../assets/carpet.png.js";import x from"../assets/sleep.json.js";import{SPECIAL_ROOM_IDS as F}from"@ray-js/robot-protocol";const A="system-ui, -apple-system, sans-serif",O=["#d7bb46","#4990d7","#58a789","#749cd7","#f2646c","#91be76","#4ec7b1","#4bb3c8","#e7858a","#7fa96e","#efa667","#a3d774","#6b82d8","#75b551","#b392cd","#ed5454"],w={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:O,propertyTheme:O,selectionIndicatorBackground:O,selectionIndicatorIcon:["#ffffff"],[F.NO_ROOM_DATA]:"#ebebeb",[F.ROOM_GAP]:"#ebebeb",[F.OBSTACLE_ROOM]:"#ebebeb",[F.UNKNOWN_ROOM]:"#ebebeb"},nameLabel:{fontSize:10,fontFamily:A,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:A,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,D,D],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:j,opacity:.5,scale:.2},robot:{icon:{sizeFixed:!1,width:8,height:8,src:o},speed:0,rotationCorrection:0,sleepAnimation:{jsonSrc:x,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:A,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}},R={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{w as DEFAULT_CONFIG,R as DEFAULT_RUNTIME_CONFIG,A as TEXT_FONT_FAMILY};
|