#
Junjie
9 小时以前 58dc3b44e29e52de145ca95569fa34c0ad48a06a
src/main/webapp/views/locMap/locMap.html
@@ -59,9 +59,9 @@
  >
    <div v-if="drawerLocNoData!=null">
      <div style="margin: 10px;">
        <div style="margin-top: 5px;">排:{{drawerLocNoData.row}}</div>
        <div style="margin-top: 5px;">列:{{drawerLocNoData.bay}}</div>
        <div style="margin-top: 5px;">层:{{drawerLocNoData.lev}}</div>
<!--        <div style="margin-top: 5px;">排:{{drawerLocNoData.row}}</div>-->
<!--        <div style="margin-top: 5px;">列:{{drawerLocNoData.bay}}</div>-->
<!--        <div style="margin-top: 5px;">层:{{drawerLocNoData.lev}}</div>-->
        <div style="margin-top: 5px;">库位号:{{drawerLocNoData.locNo}}</div>
        <div style="margin-top: 5px;">库位状态:{{drawerLocNoData.locSts}}</div>
      </div>
@@ -101,7 +101,12 @@
  let pixiStageList = [];
  let pixiStaMap = new Map();
  let objectsContainer;
  let objectsContainer3;
  let tracksGraphics;
  let mapRoot;
  let mapContentSize = { width: 0, height: 0 };
  let graphics0;
  let graphicsF;
  let graphics3;
  let graphics4;
  let graphics5;
@@ -125,6 +130,12 @@
      currentLevStaList: [],//当前楼层站点list
      drawerSta: false,
      drawerStaData: null,
      mapRotation: 0,
      mapMirrorX: false,
      mapConfigCodes: {
        rotate: 'map_canvas_rotation',
        mirror: 'map_canvas_mirror_x'
      }
    },
    mounted() {
      this.init()
@@ -157,6 +168,7 @@
        ws.onclose = this.webSocketClose
        this.loadMapTransformConfig()
        this.initLev()//初始化楼层信息
        setTimeout(() => {
          that.getMap(this.currentLev)
@@ -205,6 +217,7 @@
      },
      changeFloor(lev) {
        this.currentLev = lev
        this.loadMapTransformConfig()
        this.reloadMap = true
        this.getMap(lev)
      },
@@ -229,13 +242,18 @@
        graphics67 = pixiApp.renderer.generateTexture(getContainer(67));
        graphicsLock = pixiApp.renderer.generateTexture(getContainer(-999));
        mapRoot = new PIXI.Container();
        pixiApp.stage.addChild(mapRoot);
        // 创建一个容器来管理大批量的显示对象
        objectsContainer = new PIXI.Container();
        pixiApp.stage.addChild(objectsContainer);
        mapRoot.addChild(objectsContainer);
        tracksGraphics = new PIXI.Graphics();
        mapRoot.addChild(tracksGraphics);
        // 创建一个容器来管理大批量的显示对象
        objectsContainer3 = new PIXI.Container();
        pixiApp.stage.addChild(objectsContainer3);
        mapRoot.addChild(objectsContainer3);
        //*******************拖动画布*******************
        let stageOriginalPos;
@@ -285,16 +303,22 @@
        pixiApp.view.addEventListener('wheel', (event) => {
          event.stopPropagation();
          event.preventDefault();
          const sx = event.clientX;
          const sy = event.clientY;
          const oldZoom = pixiApp.stage.scale.x;
          const rect = pixiApp.view.getBoundingClientRect();
          const sx = event.clientX - rect.left;
          const sy = event.clientY - rect.top;
          const oldZoomX = pixiApp.stage.scale.x || 1;
          const oldZoomY = pixiApp.stage.scale.y || 1;
          const oldZoomAbs = Math.abs(oldZoomX) || 1;
          const delta = event.deltaY;
          let newZoom = oldZoom * 0.999 ** delta;
          const worldX = (sx - pixiApp.stage.position.x) / oldZoom;
          const worldY = (sy - pixiApp.stage.position.y) / oldZoom;
          const newPosX = sx - worldX * newZoom;
          const newPosY = sy - worldY * newZoom;
          pixiApp.stage.setTransform(newPosX, newPosY, newZoom, newZoom, 0, 0, 0, 0, 0);
          let newZoomAbs = oldZoomAbs * 0.999 ** delta;
          const mirrorX = this.mapMirrorX ? -1 : 1;
          const newZoomX = mirrorX * newZoomAbs;
          const newZoomY = newZoomAbs;
          const worldX = (sx - pixiApp.stage.position.x) / oldZoomX;
          const worldY = (sy - pixiApp.stage.position.y) / oldZoomY;
          const newPosX = sx - worldX * newZoomX;
          const newPosY = sy - worldY * newZoomY;
          pixiApp.stage.setTransform(newPosX, newPosY, newZoomX, newZoomY, 0, 0, 0, 0, 0);
        });
        //*******************缩放画布*******************
@@ -328,6 +352,7 @@
          pixiStageList = [map.length]//初始化列表
          pixiStaMap = new Map();//重置
          objectsContainer.removeChildren()
          if (tracksGraphics) { tracksGraphics.clear(); }
          map.forEach((item,index) => {
            pixiStageList[index] = [item.length]
            for (let idx = 0; idx < item.length; idx++) {
@@ -388,21 +413,160 @@
          });
          const b1 = objectsContainer.getLocalBounds();
          const minX = Math.min(b1.x);
          const minY = Math.min(b1.y);
          const maxX = Math.max(b1.x + b1.width);
          const maxY = Math.max(b1.y + b1.height);
          const minX = b1.x;
          const minY = b1.y;
          const maxX = b1.x + b1.width;
          const maxY = b1.y + b1.height;
          const contentW = Math.max(0, maxX - minX);
          const contentH = Math.max(0, maxY - minY);
          const vw = pixiApp.view.width;
          const vh = pixiApp.view.height;
          let scale = Math.min(vw / contentW, vh / contentH) * 0.95;
          if (!isFinite(scale) || scale <= 0) { scale = 1; }
          const posX = (vw - contentW * scale) / 2 - minX * scale;
          const posY = (vh - contentH * scale) / 2 - minY * scale;
          pixiApp.stage.setTransform(posX, posY, scale, scale, 0, 0, 0, 0, 0);
          mapContentSize = { width: contentW, height: contentH };
          this.drawTracks(map);
          this.applyMapTransform(true);
        }
        this.map = map;
      },
      isTrackCell(cell) {
        if (!cell) { return false; }
        const type = cell.type ? String(cell.type).toLowerCase() : '';
        if (type === 'track' || type === 'crn' || type === 'dualcrn' || type === 'rgv') { return true; }
        if (cell.trackSiteNo != null) { return true; }
        const v = parseInt(cell.value, 10);
        if (v === 3 || v === 9) { return true; }
        if (cell.value != null) {
          try {
            const obj = (typeof cell.value === 'string') ? JSON.parse(cell.value) : cell.value;
            if (obj && (obj.trackSiteNo != null || (obj.deviceNo != null && (type === 'crn' || type === 'dualcrn' || type === 'rgv')))) {
              return true;
            }
          } catch (e) {}
        }
        return false;
      },
      drawTracks(map) {
        if (!tracksGraphics || !Array.isArray(map)) { return; }
        tracksGraphics.clear();
        const railColor = 0x6c727a;
        const railWidth = Math.max(1, Math.round(Math.min(width, height) * 0.08));
        tracksGraphics.lineStyle(railWidth, railColor, 1);
        for (let r = 0; r < map.length; r++) {
          const row = map[r];
          if (!Array.isArray(row)) { continue; }
          for (let c = 0; c < row.length; c++) {
            const cell = row[c];
            if (!this.isTrackCell(cell)) { continue; }
            const cx = c * width + width / 2;
            const cy = r * height + height / 2;
            const up = (r - 1 >= 0 && Array.isArray(map[r - 1])) ? map[r - 1][c] : null;
            const right = (c + 1 < row.length) ? row[c + 1] : null;
            const down = (r + 1 < map.length && Array.isArray(map[r + 1])) ? map[r + 1][c] : null;
            const left = (c - 1 >= 0) ? row[c - 1] : null;
            const hasN = this.isTrackCell(up);
            const hasE = this.isTrackCell(right);
            const hasS = this.isTrackCell(down);
            const hasW = this.isTrackCell(left);
            const seg = Math.min(width, height) * 0.5;
            let drew = false;
            if (hasN) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx, cy - seg); drew = true; }
            if (hasE) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx + seg, cy); drew = true; }
            if (hasS) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx, cy + seg); drew = true; }
            if (hasW) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx - seg, cy); drew = true; }
            if (!drew) {
              tracksGraphics.moveTo(cx - seg * 0.4, cy);
              tracksGraphics.lineTo(cx + seg * 0.4, cy);
            }
          }
        }
      },
      parseRotation(value) {
        const num = parseInt(value, 10);
        if (!isFinite(num)) { return 0; }
        const rot = ((num % 360) + 360) % 360;
        return (rot === 90 || rot === 180 || rot === 270) ? rot : 0;
      },
      parseMirror(value) {
        if (value === true || value === false) { return value; }
        if (value == null) { return false; }
        const str = String(value).toLowerCase();
        return str === '1' || str === 'true' || str === 'y';
      },
      loadMapTransformConfig() {
        if (!window.$ || typeof baseUrl === 'undefined') { return; }
        $.ajax({
          url: baseUrl + "/config/listAll/auth",
          headers: { 'token': localStorage.getItem('token') },
          dataType: 'json',
          method: 'GET',
          success: (res) => {
            if (!res || res.code !== 200 || !Array.isArray(res.data)) {
              if (res && res.code === 403) { parent.location.href = baseUrl + "/login"; }
              return;
            }
            const byCode = {};
            res.data.forEach((item) => {
              if (item && item.code) { byCode[item.code] = item; }
            });
            const rotateCfg = byCode[this.mapConfigCodes.rotate];
            const mirrorCfg = byCode[this.mapConfigCodes.mirror];
            if (rotateCfg && rotateCfg.value != null) {
              this.mapRotation = this.parseRotation(rotateCfg.value);
            }
            if (mirrorCfg && mirrorCfg.value != null) {
              this.mapMirrorX = this.parseMirror(mirrorCfg.value);
            }
            if (mapContentSize && mapContentSize.width > 0 && mapContentSize.height > 0) {
              this.applyMapTransform(true);
            }
          }
        });
      },
      getViewportSize() {
        if (!pixiApp || !pixiApp.renderer) { return { width: 0, height: 0 }; }
        const screen = pixiApp.renderer.screen;
        if (screen && screen.width > 0 && screen.height > 0) {
          return { width: screen.width, height: screen.height };
        }
        const rect = pixiApp.view ? pixiApp.view.getBoundingClientRect() : null;
        return { width: rect ? rect.width : 0, height: rect ? rect.height : 0 };
      },
      getTransformedContentSize() {
        const size = mapContentSize || { width: 0, height: 0 };
        const w = size.width || 0;
        const h = size.height || 0;
        const rot = ((this.mapRotation % 360) + 360) % 360;
        const swap = rot === 90 || rot === 270;
        return { width: swap ? h : w, height: swap ? w : h };
      },
      fitStageToContent() {
        if (!pixiApp || !mapContentSize) { return; }
        const size = this.getTransformedContentSize();
        const contentW = size.width || 0;
        const contentH = size.height || 0;
        if (contentW <= 0 || contentH <= 0) { return; }
        const viewport = this.getViewportSize();
        const vw = viewport.width;
        const vh = viewport.height;
        let scale = Math.min(vw / contentW, vh / contentH) * 0.95;
        if (!isFinite(scale) || scale <= 0) { scale = 1; }
        const baseW = mapContentSize.width || contentW;
        const baseH = mapContentSize.height || contentH;
        const mirrorX = this.mapMirrorX ? -1 : 1;
        const scaleX = scale * mirrorX;
        const scaleY = scale;
        const posX = (vw / 2) - (baseW / 2) * scaleX;
        const posY = (vh / 2) - (baseH / 2) * scaleY;
        pixiApp.stage.setTransform(posX, posY, scaleX, scaleY, 0, 0, 0, 0, 0);
      },
      applyMapTransform(fitToView) {
        if (!mapRoot || !mapContentSize) { return; }
        const contentW = mapContentSize.width || 0;
        const contentH = mapContentSize.height || 0;
        if (contentW <= 0 || contentH <= 0) { return; }
        mapRoot.pivot.set(contentW / 2, contentH / 2);
        mapRoot.position.set(contentW / 2, contentH / 2);
        mapRoot.rotation = (this.mapRotation % 360) * Math.PI / 180;
        mapRoot.scale.set(1, 1);
        if (fitToView) { this.fitStageToContent(); }
      },
      rightEvent(x, y, e) {
        this.drawerLocNo = true
@@ -520,12 +684,16 @@
      sprite = new PIXI.Sprite(graphics0);
    }
    sprite.position.set(x, y);
    sprite.interactive = true; // 必须要设置才能接收事件
    sprite.buttonMode = true; // 让光标在hover时变为手型指针
    sprite.on('pointerdown', (e) => {
      pointerDownEvent(e)
    })
    const type = item && item.type ? String(item.type).toLowerCase() : '';
    const numVal = parseInt(value, 10);
    const isTrackCell = numVal === 3 || numVal === 9 || type === 'track' || type === 'crn' || type === 'dualcrn' || type === 'rgv';
    if (!isTrackCell) {
      sprite.interactive = true; // 必须要设置才能接收事件
      sprite.buttonMode = true; // 让光标在hover时变为手型指针
      sprite.on('pointerdown', (e) => {
        pointerDownEvent(e)
      })
    }
    return sprite;
  }
@@ -542,4 +710,4 @@
</script>
</body>
</html>
</html>