一、screenfull
1. 实现全屏功能
① 在 < script > 中导入全屏插件:
import screenfull from "screenfull";
② 定义初始化方法,在mounted使用:
init() {
if (screenfull.isEnabled) {
screenfull.on("change", this.change);
}
}
③ 切换全屏时,会触发的方法:
change() {
this.isFullscreen = screenfull.isFullscreen;
}
④ 点击全屏按钮,实现全屏切换:
<el-button
@click="handleFullScreen()"
>全屏</el-button
>
handleFullScreen() {
screenfull.toggle(this.$refs["screenWrap"]); // screenWrap是需要展示组件的ref名称
}
2. 解决问题:el-popover在全屏状态下,不显示
问题原因:
el-popover默认将弹窗放在body中,要想办法挂载在父元素 而不是body上;
解决思路:
根据官方文档,只要修改el-popover放入到父级div即可
在< el-popover > 添加属性:
:append-to-body="false"
:popper-append-to-body="false"
3. 解决问题:全屏状态导致的指标块位置偏移
一、插件使用
// 引入插件
import VueDragResize from "vue-drag-resize";
// ① 给父元素 div 进行定位;
// ② 给子元素 VueDragResize 进行定位 position: absolute;
// ③ isResizable 是否可以拖动大小 位置;
<VueDragResize
style="position: absolute"
v-for="(item, index) in canvasData"
:key="index"
:isActive="true"
:w="item.width !== null ? Number(item.w ? item.w : item.width) : 50"
:h="item.height !== null ? Number(item.h ? item.h : item.height) : 50"
:x="
item.xaxis !== null ? Number(item.x ? item.x : item.xaxis) : 5 * index
"
:y="
item.yaxis !== null ? Number(item.y ? item.y : item.yaxis) : 5 * index
"
:minw="20"
:minh="20"
:parentW="width"
:parentH="height"
:parentLimitation="true"
parent=".父元素名"
:isResizable="isResizable"
:isDraggable="isResizable"
v-on:dragstop="resize($event, index)"
>
</VueDragResize>
二、问题解决
解决思路:
先获取到画布宽高->再进行坐标值计算->最后进行指标块渲染
① 全屏时,获取画布宽高:
// 重置画布宽高 需要延迟50ms 不然画布大小还未更新
resizeWH() {
var p = new Promise((resolve, reject) => {
setTimeout(() => {
this.width = this.$refs.canvas.offsetWidth;
this.height = this.$refs.canvas.offsetHeight;
resolve();
}, 50);
});
return p;
},
② 计算坐标值
这里需要保存几个值:
(1)width_c:全屏前的画布宽度;
(2)height_c:全屏前的画布高度;
(3)item.x:全屏后才有的字段,用于保存全屏后计算好的x坐标(非全屏时,值为null);
(4)item.y:全屏后才有的字段,用于保存全屏后计算好的x坐标(非全屏时,值为null);
注意点:如果不放大宽高,则需要计算比例时减去设备宽高;
this.resizeWH().then(() => {
setTimeout(() => {
// 全屏时重新计算设备块的x y值
let temp = JSON.parse(JSON.stringify(this.canvasData));
temp.forEach((item) => {
// 整个屏幕全屏
if (this.isFullscreen) {
// x放大(缩小)倍数 = 现在的宽度 - 设备宽度 / 原来的宽度 - 设备宽度
const scaleX =
(this.width - item.width) / (this.width_c - item.width);
// Y放大(缩小)倍数 = 现在的高度 - 设备高度 / 原来的高度 - 设备高度
const scaleY =
(this.height - item.height) / (this.height_c - item.height);
item.x = Number(scaleX * item.xaxis); // 现在的x值 = 原来的x值 * x放大(缩小)倍数
item.y = Number(scaleY * item.yaxis); // 现在的y值 = 原来的y值 * y放大(缩小)倍数
} else {
item.x = null;
item.y = null;
}
});
this.canvasData = temp;
this.$forceUpdate();
}, 0);
});
③ resize渲染:
// 改变设备块属性
resize(newRect, index) {
// 如果不是全屏 才可以进行设备块拖动/重新赋值
if (!this.isFullscreen) {
this.canvasData[index].width = newRect.width;
this.canvasData[index].height = newRect.height;
this.canvasData[index].xaxis = newRect.left;
this.canvasData[index].yaxis = newRect.top;
}
},
二、vueDragResize
1. 解决问题:指标块刚开始不能拖拽大小
问题原因:当前指标块没有被选中,需要先点击选中后才能进行自定义拖动;
2. 解决问题:VueDragResize自定义的大小不够小
问题原因:默认是50;
解决思路:设置minX、minY可调整为自定义值;
三、dataV
1. 解决问题:不能拿到地图div大小,从而限制拖动范围
问题原因:datav里的 div 打印不出 ref 值 / 获取不到 dom 元素;
解决思路:将div抽离成子组件,与datav进行分离;在子组件中再通过ref获取到当前值;
2. dataV的滚动表格:添加悬浮框
解决思路:利用自带的@mouseover方法,获得到当前hover的item进行判断;
<el-popover
placement="top"
trigger="hover"
width="250"
:append-to-body="false"
:popper-append-to-body="false"
:content="table.content"
v-model="table.visible"
>
<dv-scroll-board
slot="reference"
:config="config"
@mouseover="mouseover"
/>
</el-popover>
四、设备分辨率/屏幕大小
1. 不同设备进行切换,导致的指标块坐标偏差
解决思路:
① 后端保存 designCanvasX designCanvasY(设计稿画布宽高);
② (现在使用者的屏幕宽高 / 设计者初始的屏幕宽高 = 放大/缩小的比例) * 原先设备块的x y w h
③ 这里注意的是:
要对原坐标进行遍历,获得其放大/缩小倍数后的坐标值/宽高值;
x y w h都需要等比例放大,否则有可能还是会有偏差存在
const ratioX = this.width / this.designCanvasX; // 屏幕宽度比例
const ratioY = this.height / this.designCanvasY; // 屏幕高度比例
const data = JSON.parse(JSON.stringify(this.canvasData));
data.forEach((item, index) => {
// 如果设备块宽度小于20,则设为20,否则按实际值
item.width =
(item.width !== null ? item.width : 50) * ratioX < 20
? 20
: (item.width !== null ? item.width : 50) * ratioX;
// 如果设备块高度小于20,则设为20,否则按实际值
item.height =
(item.height !== null ? item.height : 50) * ratioY < 20
? 20
: (item.height !== null ? item.height : 50) * ratioY;
// 如果设备块x 大于 画布宽度,则设为画布宽度,否则按实际值
item.xaxis = (item.xaxis !== null ? item.xaxis : 5 * index) * ratioX;
// 如果设备块y 大于 画布高度,则设为画布宽度,否则按实际值
item.yaxis = (item.yaxis !== null ? item.yaxis : 5 * index) * ratioY;
this.canvasData = data;
this.$forceUpdate();