| | |
| | | > |
| | | <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> |
| | |
| | | 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; |
| | |
| | | currentLevStaList: [],//当前楼层站点list |
| | | drawerSta: false, |
| | | drawerStaData: null, |
| | | mapRotation: 0, |
| | | mapMirrorX: false, |
| | | mapConfigCodes: { |
| | | rotate: 'map_canvas_rotation', |
| | | mirror: 'map_canvas_mirror_x' |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | |
| | | ws.onclose = this.webSocketClose |
| | | |
| | | |
| | | this.loadMapTransformConfig() |
| | | this.initLev()//初始化楼层信息 |
| | | setTimeout(() => { |
| | | that.getMap(this.currentLev) |
| | |
| | | }, |
| | | changeFloor(lev) { |
| | | this.currentLev = lev |
| | | this.loadMapTransformConfig() |
| | | this.reloadMap = true |
| | | this.getMap(lev) |
| | | }, |
| | |
| | | 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; |
| | |
| | | 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); |
| | | |
| | | }); |
| | | //*******************缩放画布******************* |
| | |
| | | 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++) { |
| | |
| | | }); |
| | | |
| | | 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 |
| | |
| | | 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; |
| | | } |
| | |
| | | |
| | | </script> |
| | | </body> |
| | | </html> |
| | | </html> |