You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
10 KiB
329 lines
10 KiB
<template>
|
|
<div class="venue-preview">
|
|
<!-- v-show="currentMarkData && currentMarkData.signPoint" -->
|
|
<div v-show="currentMarkData && currentMarkData.signPoint">
|
|
<canvas :id="`canvasPreview${currentMarkData && currentMarkData.id}`" :width="width" :height="height" />
|
|
</div>
|
|
<img v-if="currentMarkData && !currentMarkData.signPoint" :src="imageUrl" :onerror="defaultImg" alt="">
|
|
<div id="tooltip" class="tooltip-style">
|
|
<!-- <div class="tooltip-top">
|
|
<h4>区域名称</h4>
|
|
<span class="update-time">2024-11-28 09:46</span>
|
|
</div>
|
|
<ul>
|
|
<li><p>在架</p><span><i>15000</i>册</span></li>
|
|
<li><p>错架</p><span><i>300</i>层</span> <span class="percentage">(2.00%)</span></li>
|
|
<li><p>错序</p><span><i>0</i>层</span><span class="percentage">(0.00%)</span></li>
|
|
</ul> -->
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import defaultImg from '@/assets/images/system/default-img.jpg'
|
|
import { fabric } from 'fabric'
|
|
import { mapGetters } from 'vuex'
|
|
export default {
|
|
name: 'Mark',
|
|
props: {
|
|
currentMarkData: {
|
|
type: Object,
|
|
require: true,
|
|
default: function() {
|
|
return {}
|
|
}
|
|
},
|
|
imageUrl: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
pagePreview: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
defaultImg: defaultImg,
|
|
canvasPreview: {},
|
|
width: 1200,
|
|
height: 600,
|
|
drawWidth: 2,
|
|
tooltipInfo: null
|
|
}
|
|
},
|
|
computed: {
|
|
...mapGetters([
|
|
'user',
|
|
'baseApi'
|
|
])
|
|
},
|
|
watch: {
|
|
width() {
|
|
this.canvasPreview.setWidth(this.width)
|
|
},
|
|
height() {
|
|
this.canvasPreview.setHeight(this.height)
|
|
},
|
|
currentMarkData: {
|
|
handler(newVal, oldVal) {
|
|
// 检查 newVal 是否为 null 或 undefined
|
|
if (!newVal) {
|
|
console.log('newVal-null')
|
|
return
|
|
}
|
|
},
|
|
deep: true
|
|
},
|
|
imageUrl(newVal, oldVal) {
|
|
if (newVal !== oldVal) {
|
|
console.log('imageUrl', newVal)
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
},
|
|
beforeDestroy() {
|
|
// if (this.canvasPreview) {
|
|
// this.canvasPreview.clear()
|
|
// this.canvasPreview.dispose()
|
|
// }
|
|
},
|
|
methods: {
|
|
initCanvasPreview(drawinfo, tabIndex) {
|
|
if (!this.currentMarkData) {
|
|
console.error('currentMarkData-null')
|
|
return
|
|
}
|
|
|
|
const canvasId = `canvasPreview${this.currentMarkData.id}`
|
|
this.canvasPreview = new fabric.Canvas(canvasId, {
|
|
skipTargetFind: false,
|
|
selectable: false,
|
|
selection: false
|
|
})
|
|
|
|
this.$nextTick(() => {
|
|
this.canvasPreview.selectionColor = 'rgba(0,0,0,0.05)'
|
|
this.loadDrawPreview(drawinfo, tabIndex)
|
|
this.canvasPreview.on('mouse:wheel', this.mouse)
|
|
})
|
|
},
|
|
// 鼠标滚轮放大缩小
|
|
mouse(e) {
|
|
if (undefined === e) return
|
|
let zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + this.canvasPreview.getZoom()
|
|
zoom = Math.max(0.8, zoom)
|
|
// 最小为原来的1/10
|
|
zoom = Math.min(3, zoom)
|
|
// 最大是原来的3倍
|
|
const zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY)
|
|
this.canvasPreview.zoomToPoint(zoomPoint, zoom)
|
|
},
|
|
// 回显详情信息
|
|
loadDrawPreview(drawinfo, tabIndex) {
|
|
const self = this
|
|
const pointGroup = drawinfo.pointInfo
|
|
const imgInfo = drawinfo.imgInfo
|
|
imgInfo.src = self.imageUrl
|
|
|
|
// 加载底图
|
|
fabric.util.enlivenObjects([imgInfo], objects => {
|
|
objects.forEach(o => {
|
|
o.selectable = false
|
|
o.hasControls = false
|
|
o.centeredScaling = false
|
|
self.canvasPreview.add(o)
|
|
})
|
|
// 处理多边形绘制回显操作
|
|
pointGroup.forEach(async(item, index) => {
|
|
if (item.pointInfo !== '') {
|
|
const polygon = new fabric.Polygon(item.pointInfo, {
|
|
id: item.id,
|
|
name: item.name,
|
|
floorId: item.floorId,
|
|
rowType: item.rowType,
|
|
toward: item.toward,
|
|
floorName: item.floorName,
|
|
regionName: item.regionName,
|
|
stroke: 'rgba(196,43, 1, 1)',
|
|
strokeWidth: self.drawWidth,
|
|
fill: 'rgba(196,43, 1, 0.3)',
|
|
opacity: 1,
|
|
selectable: false,
|
|
hasBorders: false,
|
|
hasControls: false,
|
|
originX: 'left', // 设置原点为左上角
|
|
originY: 'top' // 设置原点为左上角
|
|
})
|
|
self.canvasPreview.add(polygon)
|
|
|
|
let lastClickTime = 0
|
|
const doubleClickInterval = 300
|
|
polygon.on('mousedown', function(e) {
|
|
const currentTime = new Date().getTime()
|
|
const timeDiff = currentTime - lastClickTime
|
|
|
|
if (timeDiff <= doubleClickInterval) {
|
|
console.log('双击事件', e)
|
|
lastClickTime = 0
|
|
const toReigonsData = {
|
|
id: e.target.id,
|
|
name: e.target.name,
|
|
floorId: e.target.floorId,
|
|
rowType: e.target.rowType,
|
|
toward: e.target.toward,
|
|
regionName: e.target.regionName,
|
|
floorName: e.target.floorName
|
|
}
|
|
if (self.pagePreview === 'floor') {
|
|
self.handleToRegions(toReigonsData, tabIndex)
|
|
} else if (self.pagePreview === 'region') {
|
|
self.handleToShelfs(toReigonsData, tabIndex)
|
|
}
|
|
} else {
|
|
lastClickTime = currentTime
|
|
}
|
|
})
|
|
|
|
polygon.on('mouseover', function(e) {
|
|
console.log('e', e)
|
|
console.log('e.target', e.target)
|
|
console.log('e.target.name', e.target.name)
|
|
|
|
this.tooltipInfo = {
|
|
'id': e.target.id,
|
|
'name': e.target.name
|
|
}
|
|
console.log('this.tooltipInfo', this.tooltipInfo)
|
|
// this.set({ opacity: 0.3, hoverCursor: 'pointer' })
|
|
|
|
if (self.pagePreview === 'floor') {
|
|
document.getElementById('tooltip').innerHTML =
|
|
`<div class="tooltip-top">
|
|
<h4>${this.tooltipInfo.name}</h4>
|
|
<span class="update-time">2024-11-28 09:46</span>
|
|
</div>
|
|
<ul>
|
|
<li><p>在架</p><span><i>15000</i>册</span></li>
|
|
<li><p>错架</p><span><i>300</i>层</span> <span class="percentage">(2.00%)</span></li>
|
|
<li><p>错序</p><span><i>0</i>层</span><span class="percentage">(0.00%)</span></li>
|
|
</ul>`
|
|
} else if (self.pagePreview === 'region') {
|
|
document.getElementById('tooltip').innerHTML =
|
|
`<div class="tooltip-top">
|
|
<h4>书架概况</h4>
|
|
<span class="update-time">2024-11-28 09:46</span>
|
|
</div>
|
|
<ul>
|
|
<li><p>书架</p><span><i>${this.tooltipInfo.name}</i></span></li>
|
|
<li><p>规则</p><span><i>双面6*8</i></span></li>
|
|
<li><p>在架</p><span><i>15000</i>册</span></li>
|
|
<li><p>错架</p><span><i>300</i>层</span> <span class="percentage">(2.00%)</span></li>
|
|
<li><p>错序</p><span><i>0</i>层</span><span class="percentage">(0.00%)</span></li>
|
|
</ul>`
|
|
}
|
|
|
|
var rectLeft = e.target.left + e.target.width - 100
|
|
var rectTop = e.target.top + e.target.height - 40
|
|
document.getElementById('tooltip').style.left = rectLeft + 'px'
|
|
document.getElementById('tooltip').style.top = rectTop + 'px'
|
|
document.getElementById('tooltip').style.display = 'block'
|
|
self.canvasPreview.renderAll()
|
|
})
|
|
|
|
polygon.on('mouseout', function() {
|
|
this.set({ opacity: 1 })
|
|
document.getElementById('tooltip').style.display = 'none'
|
|
self.canvasPreview.renderAll()
|
|
})
|
|
}
|
|
})
|
|
// 计算画布的中心点
|
|
const centerX = self.canvasPreview.width / 2
|
|
const centerY = self.canvasPreview.height / 2
|
|
const centerPoint = new fabric.Point(centerX, centerY)
|
|
|
|
// 设置画布的缩放比例为最小值并居中显示
|
|
self.canvasPreview.zoomToPoint(centerPoint, 0.8)
|
|
self.canvasPreview.renderAll()
|
|
|
|
setTimeout(() => {
|
|
self.$parent.prewLoading = false
|
|
}, 500)
|
|
})
|
|
},
|
|
handleToRegions(data, tabIndex) {
|
|
this.$router.push({ path: '/dataScreening/regions' })
|
|
localStorage.setItem('dataScreenFloor', JSON.stringify(data))
|
|
localStorage.setItem('dataScreenFloorTableIndex', tabIndex)
|
|
},
|
|
handleToShelfs(data, tabIndex) {
|
|
this.$router.push({ path: '/dataScreening/shelf' })
|
|
localStorage.setItem('dataScreenRegion', JSON.stringify(data))
|
|
localStorage.setItem('dataScreenRegionTableIndex', tabIndex)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style>
|
|
.tooltip-style{
|
|
display:none;
|
|
position:absolute;
|
|
width: 300px;
|
|
background:rgba(0,0,0,.6);
|
|
color: #fff;
|
|
border-radius: 6px;
|
|
}
|
|
.tooltip-top{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
padding: 0 10px;
|
|
border-bottom: 1px solid #fff;
|
|
}
|
|
.tooltip-top span{
|
|
font-size: 12px;
|
|
|
|
}
|
|
#tooltip ul{
|
|
padding: 10px;
|
|
}
|
|
#tooltip ul li{
|
|
display: flex;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
line-height: 36px;
|
|
font-style: normal;
|
|
}
|
|
|
|
#tooltip ul li p{
|
|
width: 80px;
|
|
font-weight: bold;
|
|
text-align: right;
|
|
}
|
|
#tooltip ul li span{
|
|
width: 100px;
|
|
display: block;
|
|
text-align: right;
|
|
}
|
|
#tooltip ul li i{
|
|
font-style: normal;
|
|
font-weight: bold;
|
|
padding: 0 10px;
|
|
color: #0348f3;
|
|
}
|
|
#tooltip ul li span.percentage{
|
|
width: auto;
|
|
}
|
|
</style>
|
|
<style lang="scss" scoped>
|
|
#expImg{
|
|
display: none;
|
|
}
|
|
.venue-preview{
|
|
background-color: #e8f2ff;
|
|
}
|
|
</style>
|