1、通过循环画出页面座位图
<div id="zoomDiv" ref="zoomDiv" style="width:100%;height:480px;overflow-x: auto;overflow-y: auto;" @scroll="zoomDiv">
<div id="zoomImg" v-if="seatForm" v-loading="loading" style="display: flex;" @wheel="zoomImg">
<div v-if="seatForm.form && seatForm.form.length > 0" style="display: table; margin: 0 auto; min-height: 472px; position: relative;">
<div v-for="item in seatForm.form" :key="item.index" style="display: flex;">
<div v-for="i in item" :key="i.id">
<div :class="['signSymbol', 'signSymbol' + i.sign]">
{{ i.sign }}
</div>
</div>
</div>
</div>
</div>
2、画出右下角的预览图
<div class="right-bottom-block">
<div style="position: relative;">
<img id="imgLoop" :src="imgPhoto" style="width: 100%;" />
<div class="loop" :style="{width: loopWidth + 'px', height: loopHeight + 'px',marginLeft: loopLeft + 'px', marginTop: loopTop + 'px'}"></div>
</div>
</div>
3、编写对应js方法
watch: {
seatList: {
handler (newVal, oldVal) {
if (this.seatList && !stringBlank(this.seatList.height)) {
this.seatForm = JSON.parse(JSON.stringify(this.seatList))
this.loading = false
if (stringBlank(oldVal) || stringBlank(oldVal.height)) {
this.refreshZoom()
}
}
},
immediate: true,
deep: true
}
},
computed: {
realWidth () {
return this.zoomWidth * this.zoom
},
realHeight () {
return this.zoomHeight * this.zoom
},
zoomMultiple () {
return Math.floor(this.realWidth / 150 * 100) / 100
},
loopWidthOriginal () {
return Math.floor(this.realWidth / this.zoomMultiple)
},
loopHeightOriginal () {
return Math.floor(this.realHeight / this.zoomMultiple)
},
widthMultiple () {
return Math.floor(this.zoomWidthOriginal / this.realWidth * 100) / 100
},
heightMultiple () {
return Math.floor(this.zoomHeightOriginal / this.realHeight * 100) / 100
},
loopWidth () {
return this.loopWidthOriginal * this.widthMultiple
},
loopHeight () {
return this.loopHeightOriginal * this.heightMultiple
},
loopLeft () {
return Math.floor(this.loopWidth * this.scrollLeft / this.widthMultiple / this.realWidth * 10) / 10
},
loopTop () {
return Math.floor(this.loopHeight * this.scrollTop / this.heightMultiple / this.realHeight * 10) / 10
}
},
mounted () {
const element = this.$refs.zoomDiv
element.addEventListener('wheel', this.preventDefaultWheel)
},
beforeDestroy () {
const element = this.$refs.zoomDiv
element.removeEventListener('wheel', this.preventDefaultWheel)
},
methods: {
preventDefaultWheel (event) {
event.preventDefault()
event.stopPropagation()
},
refreshZoom () {
if (this.seatForm.table.zoom) {
this.zoom = this.seatForm.table.zoom
}
if (this.seatForm.table.zoomMax) {
this.zoomMax = this.seatForm.table.zoomMax
}
if (this.seatForm.table.zoomMin) {
this.zoomMin = this.seatForm.table.zoomMin
}
document.getElementById('zoomImg').style.zoom = this.zoom
this.$nextTick(() => {
this.makePicture()
})
},
zoomDiv () {
const scrollContainer = this.$refs.zoomDiv
this.scrollTop = scrollContainer.scrollTop
this.scrollLeft = scrollContainer.scrollLeft
},
zoomImg (e) {
let zoomImg = document.getElementById('zoomImg')
if (e.wheelDelta < 0) {
this.zoom -= 0.05
} else {
this.zoom += 0.05
}
if (this.zoom >= this.zoomMax) {
this.zoom = this.zoomMax
}
if (this.zoom <= this.zoomMin) {
this.zoom = this.zoomMin
}
zoomImg.style.zoom = this.zoom
},
makePicture () {
let zoomImg = document.getElementById('zoomImg')
this.zoomWidth = zoomImg.offsetWidth
this.zoomHeight = zoomImg.offsetHeight
this.zoomWidthOriginal = this.zoomWidth * this.zoom
this.zoomHeightOriginal = this.zoomHeight * this.zoom
if (this.zoomHeightOriginal > 480) {
this.zoomHeightOriginal = 480
}
this.$nextTick(() => {
html2canvas(zoomImg, {backgroundColor: '#c8c8c8'}).then(canvas => {
const imgData = canvas.toDataURL('image/png')
this.imgPhoto = imgData
})
})
this.loading = false
},
}
4、对应CSS样式
.loop {
position: absolute;
top: 0px;
left: -1px;
border: 2px solid #ee3846;
border-radius: 5px;
opacity: 0.8;
}
.right-bottom-block {
border: 1px solid #e5e5e5;
border-radius: 0px;
position: absolute;
bottom: 0px;
right: 50px;
width: 150px;
}
样式如下