| | |
| | | Vue.component('map-canvas', { |
| | | template: ` |
| | | <div style="width: 100%; height: 100%; position: relative;"> |
| | | <div ref="pixiView"></div> |
| | | <div ref="pixiView" style="position: absolute; inset: 0;"></div> |
| | | <div v-show="shelfTooltip.visible" |
| | | :style="shelfTooltipStyle()"> |
| | | {{ shelfTooltip.text }} |
| | |
| | | mapRowHeights: [], |
| | | mapColOffsets: [], |
| | | mapColWidths: [], |
| | | mapRowColOffsets: [], |
| | | mapRowColWidths: [], |
| | | mapRowShelfCells: [], |
| | | hoveredShelfCell: null, |
| | | hoverPointer: { x: 0, y: 0 }, |
| | | hoverRaf: null, |
| | |
| | | item: null |
| | | }, |
| | | shelfTooltipMinScale: 0.4, |
| | | containerResizeObserver: null, |
| | | timer: null, |
| | | adjustLabelTimer: null, |
| | | isSwitchingFloor: false |
| | |
| | | mounted() { |
| | | this.currentLev = this.lev || 1; |
| | | this.createMap(); |
| | | this.startContainerResizeObserve(); |
| | | this.loadMapTransformConfig(); |
| | | this.loadLocList(); |
| | | this.connectWs(); |
| | |
| | | |
| | | if (this.hoverRaf) { cancelAnimationFrame(this.hoverRaf); this.hoverRaf = null; } |
| | | if (this.pixiApp) { this.pixiApp.destroy(true, { children: true }); } |
| | | if (this.containerResizeObserver) { this.containerResizeObserver.disconnect(); this.containerResizeObserver = null; } |
| | | window.removeEventListener('resize', this.resizeToContainer); |
| | | if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; } |
| | | if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) { try { this.ws.close(); } catch (e) {} } |
| | |
| | | }); |
| | | //*******************FPS******************* |
| | | }, |
| | | startContainerResizeObserve() { |
| | | if (typeof ResizeObserver === 'undefined' || !this.$el) { return; } |
| | | this.containerResizeObserver = new ResizeObserver(() => { |
| | | this.resizeToContainer(); |
| | | }); |
| | | this.containerResizeObserver.observe(this.$el); |
| | | }, |
| | | getViewportSize() { |
| | | if (!this.pixiApp || !this.pixiApp.renderer) { return { width: 0, height: 0 }; } |
| | | const screen = this.pixiApp.renderer.screen; |
| | | if (screen && screen.width > 0 && screen.height > 0) { |
| | | return { width: screen.width, height: screen.height }; |
| | | } |
| | | const rect = this.pixiApp.view ? this.pixiApp.view.getBoundingClientRect() : null; |
| | | return { width: rect ? rect.width : 0, height: rect ? rect.height : 0 }; |
| | | }, |
| | | resizeToContainer() { |
| | | const w = this.$el.clientWidth || 0; |
| | | const h = this.$el.clientHeight || 0; |
| | | if (w > 0 && h > 0 && this.pixiApp) { |
| | | const vw = this.pixiApp.renderer && this.pixiApp.renderer.screen ? this.pixiApp.renderer.screen.width : 0; |
| | | const vh = this.pixiApp.renderer && this.pixiApp.renderer.screen ? this.pixiApp.renderer.screen.height : 0; |
| | | if (vw === w && vh === h) { return; } |
| | | this.pixiApp.renderer.resize(w, h); |
| | | if (this.mapContentSize && this.mapContentSize.width > 0 && this.mapContentSize.height > 0) { |
| | | this.applyMapTransform(true); |
| | | } |
| | | } |
| | | }, |
| | | getMap() { |
| | |
| | | if (!map || !Array.isArray(map)) { return; } |
| | | this.mapRowOffsets = Array.isArray(rowOffsets) ? rowOffsets.slice() : []; |
| | | this.mapRowHeights = Array.isArray(rowHeights) ? rowHeights.slice() : []; |
| | | const rowColOffsets = []; |
| | | const rowColWidths = []; |
| | | const rowShelfCells = new Array(map.length); |
| | | let maxCols = 0; |
| | | for (let r = 0; r < map.length; r++) { |
| | | const row = map[r]; |
| | | if (row && row.length > maxCols) { maxCols = row.length; } |
| | | rowShelfCells[r] = []; |
| | | } |
| | | const colWidths = new Array(maxCols); |
| | | for (let c = 0; c < maxCols; c++) { |
| | | let w = null; |
| | | for (let r = 0; r < map.length; r++) { |
| | | const cell = map[r] && map[r][c]; |
| | | if (!cell || cell.type === 'merge' || cell.isMergedPart) { continue; } |
| | | if (cell.width != null && cell.width > 0) { |
| | | const span = cell.colSpan || 1; |
| | | w = cell.width / span; |
| | | break; |
| | | if (!cell) { continue; } |
| | | if (cell.cellWidth != null && cell.cellWidth !== '') { |
| | | const base = Number(cell.cellWidth); |
| | | if (isFinite(base) && base > 0) { w = base / 40; break; } |
| | | } |
| | | } |
| | | colWidths[c] = w || 25; |
| | | colWidths[c] = (w && isFinite(w) && w > 0) ? w : 25; |
| | | } |
| | | const colOffsets = new Array(maxCols); |
| | | let xCursor = 0; |
| | |
| | | colOffsets[c] = xCursor; |
| | | xCursor += colWidths[c]; |
| | | } |
| | | for (let r = 0; r < map.length; r++) { |
| | | const row = map[r]; |
| | | if (!row || row.length === 0) { |
| | | rowColOffsets[r] = []; |
| | | rowColWidths[r] = []; |
| | | continue; |
| | | } |
| | | const widths = new Array(row.length); |
| | | for (let c = 0; c < row.length; c++) { |
| | | const cell = row[c]; |
| | | let w = null; |
| | | if (cell && cell.cellWidth != null && cell.cellWidth !== '') { |
| | | const base = Number(cell.cellWidth); |
| | | if (isFinite(base) && base > 0) { w = base / 40; } |
| | | } |
| | | widths[c] = (w && isFinite(w) && w > 0) ? w : 25; |
| | | } |
| | | const offsets = new Array(row.length); |
| | | let x = 0; |
| | | for (let c = 0; c < row.length; c++) { |
| | | offsets[c] = x; |
| | | x += widths[c]; |
| | | } |
| | | rowColOffsets[r] = offsets; |
| | | rowColWidths[r] = widths; |
| | | } |
| | | this.mapColWidths = colWidths; |
| | | this.mapColOffsets = colOffsets; |
| | | this.mapRowColOffsets = rowColOffsets; |
| | | this.mapRowColWidths = rowColWidths; |
| | | this.mapRowShelfCells = rowShelfCells; |
| | | |
| | | for (let r = 0; r < map.length; r++) { |
| | | const row = map[r]; |
| | | if (!row) { continue; } |
| | | for (let c = 0; c < row.length; c++) { |
| | | const cell = row[c]; |
| | | if (!cell || cell.type !== 'shelf') { continue; } |
| | | const startRow = this.findIndexByOffsets(this.mapRowOffsets, this.mapRowHeights, cell.posY + 0.01); |
| | | const endRow = this.findIndexByOffsets(this.mapRowOffsets, this.mapRowHeights, cell.posY + cell.height - 0.01); |
| | | if (startRow < 0) { continue; } |
| | | const last = endRow >= 0 ? endRow : startRow; |
| | | for (let rr = startRow; rr <= last; rr++) { |
| | | if (!rowShelfCells[rr]) { rowShelfCells[rr] = []; } |
| | | rowShelfCells[rr].push(cell); |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | findIndexByOffsets(offsets, sizes, value) { |
| | | if (!offsets || !sizes || offsets.length === 0) { return -1; } |
| | |
| | | const local = this.mapRoot.toLocal(new PIXI.Point(globalPos.x, globalPos.y)); |
| | | const rowIndex = this.findIndexByOffsets(this.mapRowOffsets, this.mapRowHeights, local.y); |
| | | if (rowIndex < 0) { if (this.hoveredShelfCell) { this.hoveredShelfCell = null; this.hideShelfTooltip(); } return; } |
| | | const colIndex = this.findIndexByOffsets(this.mapColOffsets, this.mapColWidths, local.x); |
| | | if (colIndex < 0) { if (this.hoveredShelfCell) { this.hoveredShelfCell = null; this.hideShelfTooltip(); } return; } |
| | | const cell = this.resolveMergedCell(this.map, rowIndex, colIndex); |
| | | let cell = null; |
| | | if (this.mapRowShelfCells && this.mapRowShelfCells[rowIndex]) { |
| | | const list = this.mapRowShelfCells[rowIndex]; |
| | | for (let i = 0; i < list.length; i++) { |
| | | const it = list[i]; |
| | | if (!it) { continue; } |
| | | if (local.x >= it.posX && local.x < it.posX + it.width && |
| | | local.y >= it.posY && local.y < it.posY + it.height) { |
| | | cell = it; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (!cell || cell.type !== 'shelf') { if (this.hoveredShelfCell) { this.hoveredShelfCell = null; this.hideShelfTooltip(); } return; } |
| | | if (this.hoveredShelfCell !== cell) { |
| | | this.hoveredShelfCell = cell; |
| | |
| | | adjustLabelScale() { |
| | | const s = this.pixiApp && this.pixiApp.stage ? Math.abs(this.pixiApp.stage.scale.x || 1) : 1; |
| | | const minPx = 14; |
| | | const vw = this.pixiApp.view.width; |
| | | const vh = this.pixiApp.view.height; |
| | | const viewport = this.getViewportSize(); |
| | | const vw = viewport.width; |
| | | const vh = viewport.height; |
| | | const margin = 50; |
| | | const mirrorSign = this.mapMirrorX ? -1 : 1; |
| | | const inverseRotation = -((this.mapRotation % 360) * Math.PI / 180); |
| | |
| | | const contentW = size.width || 0; |
| | | const contentH = size.height || 0; |
| | | if (contentW <= 0 || contentH <= 0) { return; } |
| | | const vw = this.pixiApp.view.width; |
| | | const vh = this.pixiApp.view.height; |
| | | 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 = this.mapContentSize.width || contentW; |
| | |
| | | } |
| | | } |
| | | }); |
| | | |
| | | |
| | | |
| | | |