簡述:在前端開發中,彈框和實時視頻播放是常見的需求。這里來簡單記錄一下,如何使用Vue.js和Element UI實現一個可拖動的彈框,并在其中播放實時視頻。同時,確保在拖拽彈框時,底層元素仍然可以操作。這里來記錄一下
一、項目初始化,以Vue項目為例
首先,確保你的項目已經安裝了Element UI。如果沒有安裝,可以使用以下命令進行安裝并注冊:
npm install element-ui
// 或者
cnpm install element-ui
二、創建Vue組件
這里我們創建一個包含實時視頻播放功能的彈框組件。這個組件將使用Element UI的el-dialog
組件,并添加拖動功能,同時添加CSS代碼。確保在拖拽時底層元素可以操作。
1. 彈框組件
<template><!-- 彈出框 --><el-dialogtitle="實時視頻播放":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,使用 currentStylereturn (dom, attr) => dom.currentStyle[attr];} else {// 對于現代瀏覽器,使用 getComputedStylereturn (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-dialogtitle="實時視頻播放":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.jsexport 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,使用 currentStylereturn (dom, attr) => dom.currentStyle[attr];} else {// 對于現代瀏覽器,使用 getComputedStylereturn (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視頻流播放https://blog.csdn.net/weixin_65793170/article/details/140049511?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22140049511%22%2C%22source%22%3A%22weixin_65793170%22%7D
五. Cesium在項目中使用的詳細介紹,請看以下
Cesium在項目中的使用https://blog.csdn.net/weixin_65793170/article/details/131204332
六. 小結
通過以上步驟,我們實現了一個可拖動的彈框,并在其中播放實時視頻。我們使用了Vue.js和Element UI,并通過自定義混入實現了拖拽功能。同時,通過設置pointer-events
屬性,確保在拖拽彈框時底層元素仍然可以操作。