|
|
<template>
|
|
|
<div
|
|
|
id="wrapper"
|
|
|
class="wrapper vue-ruler-wrapper"
|
|
|
:style="{
|
|
|
width: width + thick + 'px',
|
|
|
height: height + thick + 'px'
|
|
|
}"
|
|
|
>
|
|
|
<i
|
|
|
:class="{
|
|
|
'iconfont-bigscreen': true,
|
|
|
'icon-eye': isShowReferLine,
|
|
|
'icon-eye-close': !isShowReferLine
|
|
|
}"
|
|
|
@click="handleCornerClick"
|
|
|
/>
|
|
|
<SketchRule
|
|
|
:key="scale"
|
|
|
:lang="lang"
|
|
|
:thick="thick"
|
|
|
:scale="scale"
|
|
|
:width="width"
|
|
|
:height="height"
|
|
|
:start-x="startX"
|
|
|
:start-y="startY"
|
|
|
:shadow="shadow"
|
|
|
:hor-line-arr="[...lines.h, ...presetLines.h]"
|
|
|
:ver-line-arr="[...lines.v, ...presetLines.v]"
|
|
|
:palette="Palette"
|
|
|
:is-show-refer-line="isShowReferLine"
|
|
|
:corner-active="cornerActive"
|
|
|
@handleLine="handleLine"
|
|
|
@onCornerClick="handleCornerClick"
|
|
|
/>
|
|
|
<div
|
|
|
id="screens"
|
|
|
ref="screensRef"
|
|
|
:style="{
|
|
|
width: innerWidth + 'px',
|
|
|
height: innerHeight + 'px'
|
|
|
}"
|
|
|
@scroll="throttleScroll"
|
|
|
>
|
|
|
<div
|
|
|
ref="containerRef"
|
|
|
class="screen-container grid-bg"
|
|
|
:style="containerRefStyle"
|
|
|
>
|
|
|
<div
|
|
|
id="canvas"
|
|
|
:style="canvasStyle"
|
|
|
>
|
|
|
<slot />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
|
import SketchRule from 'vue-sketch-ruler'
|
|
|
import { mapState, mapMutations } from 'vuex'
|
|
|
import throttle from 'lodash/throttle'
|
|
|
export default {
|
|
|
components: {
|
|
|
SketchRule
|
|
|
},
|
|
|
props: {
|
|
|
width: {
|
|
|
type: Number,
|
|
|
default: 500
|
|
|
},
|
|
|
height: {
|
|
|
type: Number,
|
|
|
default: 400
|
|
|
},
|
|
|
pageWidth: {
|
|
|
type: Number,
|
|
|
default: 1920
|
|
|
},
|
|
|
pageHeight: {
|
|
|
type: Number,
|
|
|
default: 1080
|
|
|
}
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
startX: 0,
|
|
|
startY: 0,
|
|
|
lines: {
|
|
|
h: [],
|
|
|
v: []
|
|
|
},
|
|
|
thick: 20,
|
|
|
lang: 'zh-CN', // 中英文
|
|
|
isShowRuler: true, // 显示标尺
|
|
|
isShowReferLine: true, // 显示参考线
|
|
|
cornerActive: true, // 左上角激活状态
|
|
|
Palette: {
|
|
|
bgColor: 'rgba(225,225,225, 0)',
|
|
|
longfgColor: '#BABBBC',
|
|
|
shortfgColor: '#C8CDD0',
|
|
|
fontColor: '#7D8694',
|
|
|
shadowColor: 'transparent',
|
|
|
lineColor: '#0089d0',
|
|
|
borderColor: '#transparent',
|
|
|
cornerActiveColor: 'rgb(235, 86, 72, 0.6)'
|
|
|
},
|
|
|
|
|
|
containerRefStyle: {
|
|
|
width: this.width + 'px',
|
|
|
height: this.height + 'px'
|
|
|
},
|
|
|
innerHeight: 0,
|
|
|
innerWidth: 0
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
// 缩放改变的时候,改变startX,startY
|
|
|
scale (scale) {
|
|
|
// 防抖调用方法
|
|
|
this.throttleScroll()
|
|
|
},
|
|
|
pageWidth (pageWidth) {
|
|
|
if (this.fitZoom === this.zoom) {
|
|
|
this.initZoom()
|
|
|
}
|
|
|
},
|
|
|
pageHeight (pageHeight) {
|
|
|
if (this.fitZoom === this.zoom) {
|
|
|
this.initZoom()
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
...mapState('bigScreen', {
|
|
|
scale: state => state.zoom / 100,
|
|
|
fitZoom: state => state.fitZoom,
|
|
|
zoom: state => state.zoom
|
|
|
}),
|
|
|
presetLines () {
|
|
|
const presetLine = this.$store.state.bigScreen.presetLine
|
|
|
// { type: 'h', site: y || 0 },
|
|
|
const v = presetLine?.filter(p => p.type === 'h')?.map(p => p.site)
|
|
|
const h = presetLine?.filter(p => p.type === 'v')?.map(p => p.site)
|
|
|
return {
|
|
|
h,
|
|
|
v
|
|
|
}
|
|
|
},
|
|
|
shadow () {
|
|
|
return {
|
|
|
x: 0,
|
|
|
y: 0,
|
|
|
width: this.width,
|
|
|
height: this.height
|
|
|
}
|
|
|
},
|
|
|
canvasStyle () {
|
|
|
return {
|
|
|
width: this.width + 'px',
|
|
|
height: this.height + 'px',
|
|
|
transform: `scale(${this.scale})`,
|
|
|
transformOrigin: '0 0 0'
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
mounted () {
|
|
|
// 监听屏幕改变
|
|
|
this.listenSize()
|
|
|
this.initRuleHeight()
|
|
|
this.throttleScroll()
|
|
|
},
|
|
|
methods: {
|
|
|
...mapMutations('bigScreen', [
|
|
|
'changeZoom',
|
|
|
'changeFitZoom'
|
|
|
]),
|
|
|
listenSize () {
|
|
|
window.onresize = throttle(() => {
|
|
|
this.initRuleHeight()
|
|
|
}, 100)
|
|
|
},
|
|
|
initRuleHeight () {
|
|
|
setTimeout(() => {
|
|
|
const screensRect = document
|
|
|
.querySelector('.grid-wrap-box')
|
|
|
?.getBoundingClientRect()
|
|
|
if (!screensRect) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 30是grid-wrap-box的底部工具栏高度
|
|
|
this.innerHeight = screensRect.height
|
|
|
this.innerWidth = screensRect.width
|
|
|
this.diffX = this.width - screensRect.width
|
|
|
this.diffY = this.height - screensRect.height
|
|
|
|
|
|
this.containerRefStyle = {
|
|
|
width: this.diffX > 0 ? ((this.width + this.diffX + this.thick + 30) + 'px') : (this.width + 'px'),
|
|
|
height: this.diffY > 0 ? ((this.height + this.diffY + this.thick + 30) + 'px') : (this.height + 'px')
|
|
|
}
|
|
|
if (this.fitZoom === this.zoom) {
|
|
|
this.initZoom()
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
handleLine (lines) {
|
|
|
this.lines = lines
|
|
|
},
|
|
|
handleCornerClick () {
|
|
|
this.isShowReferLine = !this.isShowReferLine
|
|
|
this.cornerActive = !this.cornerActive
|
|
|
},
|
|
|
throttleScroll () {
|
|
|
throttle(() => {
|
|
|
this.handleScroll()
|
|
|
}, 100)()
|
|
|
},
|
|
|
handleScroll () {
|
|
|
const screensRect = document
|
|
|
.querySelector('#screens')
|
|
|
.getBoundingClientRect()
|
|
|
const canvasRect = document
|
|
|
.querySelector('#canvas')
|
|
|
.getBoundingClientRect()
|
|
|
|
|
|
// 标尺开始的刻度
|
|
|
const startX = (screensRect.left + this.thick - canvasRect.left) / this.scale
|
|
|
const startY = (screensRect.top + this.thick - canvasRect.top) / this.scale
|
|
|
|
|
|
this.startX = startX >> 0
|
|
|
this.startY = startY >> 0
|
|
|
|
|
|
this.$emit('changeStart', {
|
|
|
x: this.startX * this.scale + 50 - this.thick,
|
|
|
y: this.startY * this.scale + 50 - this.thick
|
|
|
})
|
|
|
},
|
|
|
// 保证画布能完整展示大屏
|
|
|
initZoom () {
|
|
|
// 横向比例
|
|
|
const xRadio = this.innerWidth / (this.pageWidth + 120)
|
|
|
// 纵向比例
|
|
|
const yRadio = this.innerHeight / (this.pageHeight + 120)
|
|
|
// 取最小的适应比例
|
|
|
const scale = Math.floor(Math.min(xRadio * 100, yRadio * 100))
|
|
|
if (scale < 100) {
|
|
|
this.changeZoom(scale)
|
|
|
this.changeFitZoom(scale)
|
|
|
} else {
|
|
|
this.changeZoom(100)
|
|
|
this.changeFitZoom(100)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
|
@import '../../BigScreenDesign/fonts/iconfont.css';
|
|
|
.wrapper {
|
|
|
box-sizing: border-box;
|
|
|
position: absolute;
|
|
|
|
|
|
.iconfont-bigscreen {
|
|
|
position: absolute;
|
|
|
left: 0;
|
|
|
top: 0;
|
|
|
font-size: 16px;
|
|
|
color: #fff;
|
|
|
z-index: 999;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#screens {
|
|
|
position: absolute;
|
|
|
overflow: scroll;
|
|
|
|
|
|
// 滚动条美化,始终在最下方和最右方
|
|
|
&::-webkit-scrollbar {
|
|
|
width: 10px;
|
|
|
height: 10px;
|
|
|
}
|
|
|
&::-webkit-scrollbar-thumb {
|
|
|
border-radius: 10px;
|
|
|
background-color: var(--bs-el-background-2) !important;
|
|
|
}
|
|
|
&::-webkit-scrollbar-track {
|
|
|
border-radius: 10px;
|
|
|
background-color: transparent !important;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.screen-container {
|
|
|
position: absolute;
|
|
|
width: 6000px;
|
|
|
height: 6000px;
|
|
|
}
|
|
|
|
|
|
.scale-value {
|
|
|
position: absolute;
|
|
|
left: 0;
|
|
|
bottom: 100%;
|
|
|
}
|
|
|
|
|
|
.button {
|
|
|
position: absolute;
|
|
|
left: 100px;
|
|
|
bottom: 100%;
|
|
|
}
|
|
|
|
|
|
.button-ch {
|
|
|
position: absolute;
|
|
|
left: 200px;
|
|
|
bottom: 100%;
|
|
|
}
|
|
|
.button-en {
|
|
|
position: absolute;
|
|
|
left: 230px;
|
|
|
bottom: 100%;
|
|
|
}
|
|
|
|
|
|
#canvas {
|
|
|
position: absolute;
|
|
|
top: 50px;
|
|
|
left: 50px;
|
|
|
}
|
|
|
::v-deep .line {
|
|
|
border-left: 1px dashed #0089d0 !important;
|
|
|
border-top: 1px dashed #0089d0 !important;
|
|
|
}
|
|
|
::v-deep.action {
|
|
|
.value {
|
|
|
background: var(--bs-el-color-primary);
|
|
|
padding: 4px;
|
|
|
color: #fff;
|
|
|
}
|
|
|
|
|
|
.del {
|
|
|
color: var(--bs-el-color-primary);
|
|
|
}
|
|
|
}
|
|
|
::v-deep .ruler, ::v-deep .corner {
|
|
|
background: var(--bs-background-1);
|
|
|
}
|
|
|
::v-deep .corner {
|
|
|
z-index: 999;
|
|
|
background: var(--bs-background-1) !important;
|
|
|
}
|
|
|
|
|
|
::v-deep .mb-ruler {
|
|
|
z-index: 998
|
|
|
}
|
|
|
.grid-bg {
|
|
|
background-color: #2a2e33 !important;
|
|
|
background-image: url(./images/canvas-bg.png);
|
|
|
background-repeat: repeat;
|
|
|
word-spacing: 10px;
|
|
|
}
|
|
|
</style>
|