首页 前端知识 CesiumJS第3篇,前端使用Vue和Element实现可拖动弹框效果,并使用mixins混入特性实现,不影响底层元素操作(Cesium上可拖拽的实时视频播放弹框,底层元素可以正常操作)

CesiumJS第3篇,前端使用Vue和Element实现可拖动弹框效果,并使用mixins混入特性实现,不影响底层元素操作(Cesium上可拖拽的实时视频播放弹框,底层元素可以正常操作)

2024-08-10 22:08:56 前端知识 前端哥 621 766 我要收藏

前言

在前端开发中,弹框和实时视频播放是常见的需求。这里来简单记录一下,如何使用Vue.js和Element UI实现一个可拖动的弹框,并使用mixins混入特性,在组件中播放实时视频。同时,确保在拖拽弹框时,底层元素仍然可以操作。这里来记录一下


Cesium ~ 第 3 篇    ——    Cesium上可拖拽的实时视频弹框

一、项目初始化,以Vue项目为例

首先,确保你的项目已经安装了Element UI。如果没有安装,可以使用以下命令进行安装并注册:

npm install element-ui

// 或者

cnpm install element-ui


二、创建Vue组件

这里我们创建一个包含实时视频播放功能的弹框组件。这个组件将使用Element UI的el-dialog组件,并添加拖动功能,同时添加CSS代码。确保在拖拽时底层元素可以操作。

1. 弹框组件

<template>
  <!-- 弹出框 -->
  <el-dialog
    title="实时视频播放"
    :visible.sync="dialogVisible"
    width="30%"
    :before-close="handleClose"
    :modal="false"
    :close-on-click-modal="false"
    class="cesium_dialog"
  >
    <flvVue :Url="rtsp1" v-if="dialogVisible"></flvVue>
    <span slot="footer" class="dialog-footer"> </span>
  </el-dialog>
</template>

<script>

export default {

  data() {
    return {
      dialogVisible: false, // 弹框显示状态
      rtsp1: 'rtsp://your-stream-url' // 实时视频流地址
    };
  },

  methods: {
    // 打开弹框事件
    DialogOpen(RtspUrl) {
      this.dialogVisible = true; // 显示弹框
    },
    // 关闭弹框事件
    handleClose() {
      this.dialogVisible = false; // 关闭弹框
    }
  },

};};
</script>

<style>
/* 在你的 CSS 文件或 <style> 标签中添加 */
::v-deep .el-dialog__wrapper {
  pointer-events: none !important; /* 禁用遮罩层的点击事件 */
}
::v-deep .el-dialog__wrapper .el-dialog {
  pointer-events: auto !important; /* 允许对话框内的元素交互 */
  margin-top: 20vh !important; /* 设置弹框距顶部的距离 */
}
</style>

2. 拖拽功能的实现

创建一个draggable.js文件,用于实现弹框的拖拽功能:

// src/mixins/draggable.js
export default {
  mounted() {
    // 获取对话框的头部元素
    const dialogHeaderEl = this.$el.querySelector('.el-dialog__header');
    // 获取整个对话框元素
    const dragDom = this.$el.querySelector('.el-dialog');
    // 设置头部的光标为移动样式,表示可以拖动
    dialogHeaderEl.style.cursor = 'move';

    // 函数用于获取元素的计算样式
    const getStyle = (function () {
      if (window.document.currentStyle) {
        // 对于旧版 IE,使用 currentStyle
        return (dom, attr) => dom.currentStyle[attr];
      } else {
        // 对于现代浏览器,使用 getComputedStyle
        return (dom, attr) => getComputedStyle(dom, false)[attr];
      }
    })();

    // 鼠标按下事件处理程序
    dialogHeaderEl.onmousedown = (e) => {
      // 计算鼠标点击点相对于对话框头部的偏移量
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
      const disY = e.clientY - dialogHeaderEl.offsetTop;

      // 获取对话框的宽度和高度
      const dragDomWidth = dragDom.offsetWidth;
      const dragDomHeight = dragDom.offsetHeight;

      // 获取浏览器窗口的宽度和高度
      const screenWidth = document.body.clientWidth;
      const screenHeight = document.body.clientHeight;

      // 计算对话框拖动的边界
      const minDragDomLeft = dragDom.offsetLeft; // 左边界
      // 右边界
      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; 
      const minDragDomTop = dragDom.offsetTop; // 上边界
      // 下边界
      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight; 

      // 获取对话框当前位置的样式(左和上),处理 px 或百分比单位
      let styL = getStyle(dragDom, 'left');
      let styT = getStyle(dragDom, 'top');

      // 处理百分比单位,将其转换为绝对像素值
      if (styL.includes('%')) {
        styL = +document.body.clientWidth * (+styL.replace(/%/g, '') / 100);
        styT = +document.body.clientHeight * (+styT.replace(/%/g, '') / 100);
      } else {
        // 处理 px 单位
        styL = +styL.replace(/px/g, '');
        styT = +styT.replace(/px/g, '');
      }

      // 鼠标移动事件处理程序
      document.onmousemove = function (e) {
        // 计算新的位置
        let left = e.clientX - disX;
        let top = e.clientY - disY;

        // 边界处理:防止对话框拖动超出边界
        if (-left > minDragDomLeft) {
          left = -minDragDomLeft;
        } else if (left > maxDragDomLeft) {
          left = maxDragDomLeft;
        }

        if (-top > minDragDomTop) {
          top = -minDragDomTop;
        } else if (top > maxDragDomTop) {
          top = maxDragDomTop;
        }

        // 更新对话框的位置
        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
      };

      // 鼠标释放事件处理程序
      document.onmouseup = function () {
        // 解除鼠标移动和释放事件的绑定
        document.onmousemove = null;
        document.onmouseup = null;
      };

    };
  }
};};

3. 整合拖拽功能

draggable.js文件混入到你的Vue组件中,使得弹框可以实现拖动功能,同时确保拖拽时底层元素仍然可以操作。

import draggable from "@/utils/hs/draggable.js"; // 引入拖拽功能

export default {

  // 混入拖拽功能
  mixins: [draggable],

  data() {
    return {
      ......
    };
  },
  methods: {
      ......
  },

};};


三、完整代码

1. Vue

<template>
  <!-- 弹出框 -->
  <el-dialog
    title="实时视频播放"
    :visible.sync="dialogVisible"
    width="30%"
    :before-close="handleClose"
    :modal="false"
    :close-on-click-modal="false"
    class="cesium_dialog"
  >
    <flvVue :Url="rtsp1" v-if="dialogVisible"></flvVue>
    <span slot="footer" class="dialog-footer"> </span>
  </el-dialog>
</template>

<script>
import draggable from "@/utils/hs/draggable.js"; // 引入拖拽功能

export default {

  // 混入拖拽功能
  mixins: [draggable],

  data() {
    return {
      dialogVisible: false,
      rtsp1: 'rtsp://your-stream-url'
    };
  },

  methods: {
    DialogOpen(RtspUrl) {
      this.dialogVisible = true;
    },
    handleClose() {
      this.dialogVisible = false;
    }
  },

};};
</script>

<style>
/* 在你的 CSS 文件或 <style> 标签中添加 */
::v-deep .el-dialog__wrapper {
  pointer-events: none !important; /* 禁用遮罩层的点击事件 */
}
::v-deep .el-dialog__wrapper .el-dialog {
  pointer-events: auto !important; /* 允许对话框内的元素交互 */
  margin-top: 20vh !important; /* 设置弹框距顶部的距离 */
}
</style>

2. JS

// src/mixins/draggable.js

export default {
  mounted() {
    // 获取对话框的头部元素
    const dialogHeaderEl = this.$el.querySelector('.el-dialog__header');
    // 获取整个对话框元素
    const dragDom = this.$el.querySelector('.el-dialog');
    // 设置头部的光标为移动样式,表示可以拖动
    dialogHeaderEl.style.cursor = 'move';

    // 函数用于获取元素的计算样式
    const getStyle = (function () {
      if (window.document.currentStyle) {
        // 对于旧版 IE,使用 currentStyle
        return (dom, attr) => dom.currentStyle[attr];
      } else {
        // 对于现代浏览器,使用 getComputedStyle
        return (dom, attr) => getComputedStyle(dom, false)[attr];
      }
    })();

    // 鼠标按下事件处理程序
    dialogHeaderEl.onmousedown = (e) => {
      // 计算鼠标点击点相对于对话框头部的偏移量
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
      const disY = e.clientY - dialogHeaderEl.offsetTop;

      // 获取对话框的宽度和高度
      const dragDomWidth = dragDom.offsetWidth;
      const dragDomHeight = dragDom.offsetHeight;

      // 获取浏览器窗口的宽度和高度
      const screenWidth = document.body.clientWidth;
      const screenHeight = document.body.clientHeight;

      // 计算对话框拖动的边界
      const minDragDomLeft = dragDom.offsetLeft; // 左边界
      // 右边界
      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
      const minDragDomTop = dragDom.offsetTop; // 上边界
      // 下边界
      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight; 
      // 获取对话框当前位置的样式(左和上),处理 px 或百分比单位
      let styL = getStyle(dragDom, 'left');
      let styT = getStyle(dragDom, 'top');

      // 处理百分比单位,将其转换为绝对像素值
      if (styL.includes('%')) {
        styL = +document.body.clientWidth * (+styL.replace(/%/g, '') / 100);
        styT = +document.body.clientHeight * (+styT.replace(/%/g, '') / 100);
      } else {
        // 处理 px 单位
        styL = +styL.replace(/px/g, '');
        styT = +styT.replace(/px/g, '');
      }

      // 鼠标移动事件处理程序
      document.onmousemove = function (e) {
        // 计算新的位置
        let left = e.clientX - disX;
        let top = e.clientY - disY;

        // 边界处理:防止对话框拖动超出边界
        if (-left > minDragDomLeft) {
          left = -minDragDomLeft;
        } else if (left > maxDragDomLeft) {
          left = maxDragDomLeft;
        }

        if (-top > minDragDomTop) {
          top = -minDragDomTop;
        } else if (top > maxDragDomTop) {
          top = maxDragDomTop;
        }

        // 更新对话框的位置
        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
      };

      // 鼠标释放事件处理程序
      document.onmouseup = function () {
        // 解除鼠标移动和释放事件的绑定
        document.onmousemove = null;
        document.onmouseup = null;
      };
    };
  }
};};


四. 请求RTSP视频流播放,请看

前端请求RTSP视频流播放icon-default.png?t=N7T8https://blog.csdn.net/weixin_65793170/article/details/140049511?csdn_share_tail={"type":"blog","rType":"article","rId":"140049511","source":"weixin_65793170"}


五. Cesium在项目中使用的详细介绍,请看以下

Cesium在项目中的使用icon-default.png?t=N7T8https://blog.csdn.net/weixin_65793170/article/details/131204332


六. 小结

通过以上步骤,我们实现了一个可拖动的弹框,并在其中播放实时视频。我们使用了Vue.js和Element UI,并通过自定义混入实现了拖拽功能。同时,通过设置pointer-events属性,确保在拖拽弹框时底层元素仍然可以操作。

创作不易,感觉有用,就一键三连😄点赞、收藏加关注,感谢(●'◡'●)

转载请注明出处或者链接地址:https://www.qianduange.cn//article/15221.html
标签
web3webgl
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!