制作可拖拽组件的大屏

一、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();
  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值