前言:
我是用的原生js写的这个功能,因此这个组件在vue、react、jquery等框架中均可使用,例如,我就是用在基于nuxt.js框架+typescript项目中的,用来做点击某按钮,弹出视频,模拟画中画效果。
1.效果:
1.在页面中可以随意拖拽
2.可以用鼠标动态控制大小,且宽高是按比例放大或缩小
3.点击右上角可以关闭视频
4.点击按钮打开时,自动播放
5.全凭遮罩效果及控制视频弹出位置
ps:处理bug完毕,关闭时声音关不掉。
2.效果图:
3.代码实现
封装组件名为 video.vue
建议:封装为组件后,可以通过vuex传值来控制视频的打开和关闭。
强烈警告:用v-if而不要使用v-show控制此组件的显示隐藏!!!
【如果用v-if不能拖动或者放大缩小,可以用v-show,然后可以设置一个控制音量的小图标,点击的时候让muted为false,高级浏览器默认自动播放时不能有声音,可以通过muted控制】
<template> <div> <div id="div2" ref="div2" v-show="open"> <div style="width: 100%; height: 100%; overflow: hidden"> <div id="close" @click="close">x</div> <h2 id="h2"></h2> <video id="sonVideo" preload="auto" width="100%" height="100%" autoplay :muted="shengyin"> <source src="写你的视频地址,我的就不贴了,可以随意找个视频的地址 " /> </video> <div id="right"></div> <div id="div1"></div> <div id="bottom"></div> <div id="left"></div> </div> </div> <!-- <div id="zhezhao"></div> 遮罩功能可以用 --> </div> </template> <script> export default { data () { return { open: false, shengyin:false //声音控制 } }, methods: { close () { this.open = false } }, mounted () { // window.onload=function(){ this.$nextTick(() => { // window.onload=function(){ var oDiv = document.getElementById("div1") var oDiv2 = document.getElementById("div2") var zhezhao = document.getElementById("zhezhao") var h2 = document.getElementById("h2") var right = document.getElementById("right") var bottom = document.getElementById("bottom") var sClose = document.getElementById("close") var sonVideo = document.getElementById("sonVideo") var mouseStart = {} var divStart = {} var rightStart = {} var bottomStart = {} if(right){ //右边鼠标按下 right.onmousedown = function (ev) { var oEvent = ev || event //e.XX mouseStart.x = oEvent.clientX //鼠标的x坐标--起始位置 mouseStart.y = oEvent.clientY //鼠标的y坐标 rightStart.x = right.offsetLeft //元素(div)到浏览器边框的距离 if (right.setCapture) //多用于容器对象,效果是对指定的对象设置鼠标捕获。 // 所谓鼠标捕获,是指对鼠标事件( ondblclick, onmouseout)进行捕捉, // 使在容器内的子对象的鼠标事件均由容器对象触发,因此,只能在容器对象的鼠标事件函数中进行处理。 // 当参数为true时,对鼠标进行捕捉,相反,不捕捉。 // 与这个函数对应,releaseCapture方法释放鼠标捕获,并触发onlosecapture事件。 { right.onmousemove = doDrag1 //鼠标移动时,拖拽 right.onmouseup = stopDrag1 //鼠标抬起时,停止拖拽 right.setCapture() } else { document.addEventListener("mousemove", doDrag1, true) document.addEventListener("mouseup", stopDrag1, true) } } } function doDrag1 (ev) { // clientX、clientY //点击位置距离当前body可视区域的x,y坐标 var oEvent = ev || event var l = oEvent.clientX - mouseStart.x + rightStart.x var w = l + oDiv.offsetWidth if (w < oDiv.offsetWidth) { w = oDiv.offsetWidth } else if (w > document.documentElement.clientWidth - oDiv2.offsetLeft) { w = document.documentElement.clientWidth - oDiv2.offsetLeft - 2 } oDiv2.style.width = w + "px" oDiv2.style.height = w * 0.56 + "px" }; function stopDrag1 () { if (right.releaseCapture) { right.onmousemove = null right.onmouseup = null right.releaseCapture() } else { document.removeEventListener("mousemove", doDrag1, true) document.removeEventListener("mouseup", stopDrag1, true) } }; if(bottom){ //底部边框按下 bottom.onmousedown = function (ev) { var oEvent = ev || event mouseStart.x = oEvent.clientX mouseStart.y = oEvent.clientY bottomStart.y = bottom.offsetTop if (bottom.setCapture) { bottom.onmousemove = doDrag2 bottom.onmouseup = stopDrag2 bottom.setCapture() } else { document.addEventListener("mousemove", doDrag2, true) document.addEventListener("mouseup", stopDrag2, true) } } } function doDrag2 (ev) { var oEvent = ev || event var t = oEvent.clientY - mouseStart.y + bottomStart.y var h = t + oDiv.offsetHeight if (h < oDiv.offsetHeight) { h = oDiv.offsetHeight } else if (h > document.documentElement.clientHeight - oDiv2.offsetTop) { h = document.documentElement.clientHeight - oDiv2.offsetTop - 2 } oDiv2.style.height = h + "px" oDiv2.style.width = h * 1.56 + "px" }; function stopDrag2 () { if (bottom.releaseCapture) { bottom.onmousemove = null bottom.onmouseup = null bottom.releaseCapture() } else { document.removeEventListener("mousemove", doDrag2, true) document.removeEventListener("mouseup", stopDrag2, true) } }; if(oDiv){ //大盒子按下 oDiv.onmousedown = function (ev) { var oEvent = ev || event mouseStart.x = oEvent.clientX mouseStart.y = oEvent.clientY divStart.x = oDiv.offsetLeft divStart.y = oDiv.offsetTop if (oDiv.setCapture) { oDiv.onmousemove = doDrag oDiv.onmouseup = stopDrag oDiv.setCapture() } else { document.addEventListener("mousemove", doDrag, true) document.addEventListener("mouseup", stopDrag, true) } zhezhao.style.display = "block" } } function doDrag (ev) { var oEvent = ev || event var l = oEvent.clientX - mouseStart.x + divStart.x var t = oEvent.clientY - mouseStart.y + divStart.y var w = l + oDiv.offsetWidth var h = t + oDiv.offsetHeight if (w < oDiv.offsetWidth) { w = oDiv.offsetWidth } else if (w > document.documentElement.clientWidth - oDiv2.offsetLeft) { w = document.documentElement.clientWidth - oDiv2.offsetLeft - 2 } if (h < oDiv.offsetHeight) { h = oDiv.offsetHeight } else if (h > document.documentElement.clientHeight - oDiv2.offsetTop) { h = document.documentElement.clientHeight - oDiv2.offsetTop - 2 } oDiv2.style.width = w + "px" oDiv2.style.height = h + "px" }; function stopDrag () { if (oDiv.releaseCapture) { oDiv.onmousemove = null oDiv.onmouseup = null oDiv.releaseCapture() } else { document.removeEventListener("mousemove", doDrag, true) document.removeEventListener("mouseup", stopDrag, true) } zhezhao.style.display = "none" }; if(h2){ //h2上边按下 h2.onmousedown = function (ev) { var oEvent = ev || event mouseStart.x = oEvent.clientX mouseStart.y = oEvent.clientY divStart.x = oDiv2.offsetLeft divStart.y = oDiv2.offsetTop if (h2.setCapture) { h2.onmousemove = doDrag3 h2.onmouseup = stopDrag3 h2.setCapture() } else { document.addEventListener("mousemove", doDrag3, true) document.addEventListener("mouseup", stopDrag3, true) } // zhezhao.style.display = "block" } } function doDrag3 (ev) { var oEvent = ev || event var l = oEvent.clientX - mouseStart.x + divStart.x var t = oEvent.clientY - mouseStart.y + divStart.y if (l < 0) { l = 0 } else if (l > document.documentElement.clientWidth - oDiv2.offsetWidth) { l = document.documentElement.clientWidth - oDiv2.offsetWidth } if (t < 0) { t = 0 } else if (t > document.documentElement.clientHeight - oDiv2.offsetHeight) { t = document.documentElement.clientHeight - oDiv2.offsetHeight } oDiv2.style.left = l + "px" oDiv2.style.top = t + "px" }; function stopDrag3 () { if (h2.releaseCapture) { h2.onmousemove = null h2.onmouseup = null h2.releaseCapture() } else { document.removeEventListener("mousemove", doDrag3, true) document.removeEventListener("mouseup", stopDrag3, true) } // zhezhao.style.display = "none" } //关闭窗口 if(sClose){ sClose.onmousedown = function (ev) { (ev || event).cancelBubble = true } sClose.onclick = function () { // console.log(window.$nuxt); // oDiv2.style.display="none"; console.log(sonVideo.muted,'sonVideo.mounted'); sonVideo.muted = true // }; // } } } }) }, } </script> <style scoped> * { margin: 0; padding: 0; } /* #zhezhao{ width:100%; height:100%; background:#f00; filter:alpha(opacity:0); opacity:0; z-index:9999; position:absolute; top:0; left:0; display:none; } */ #div2 { width: 762px; min-width: 500px; min-height: 280px; height: 429px; display: block; overflow: hidden; position: fixed; top: 30%; /* 控制视频出现的位置 */ left: 30%; background: #eeeeee; z-index: 999999; padding: 0 15px 20px; /* border:20px solid #f00; */ } #div1 { width: 15px; height: 15px; background: rgba(rgb(240, 234, 234), alpha); position: absolute; right: 0px; bottom: 0px; cursor: nw-resize; overflow: hidden; font-size: 12px; text-align: center; line-height: 15px; color: #ffffff; float: right; z-index: 3; } #right { /*右边的可以拖动的框 */ width: 15px; height: 100%; background: #ffffff; float: right; position: absolute; right: 0; top: 0; cursor: e-resize; overflow: hidden; /* filter: alpha(opacity: 0); */ opacity: 1; z-index: 1; } #left { /*左边的可以拖动的框 */ width: 15px; height: 100%; background: #ffffff; float: left; position: absolute; left: 0; top: 0; cursor: e-resize; overflow: hidden; /* filter: alpha(opacity: 0); */ opacity: 1; z-index: 1; } /* 最底下的绿色的 */ #bottom { width: 100%; height: 15px; background: #ffffff; position: absolute; left: 0; bottom: 0; cursor: n-resize; overflow: hidden; /* filter: alpha(opacity: 0); */ opacity: 1; z-index: 1; } #div2 p { padding: 10px; line-height: 24px; font-size: 13px; text-indent: 24px; color: #996600; } #div2 h2 { width: 100%; height: 25px; line-height: 25px; font-size: 14px; background: #fff; color: #ffffff; text-indent: 15px; cursor: move; overflow: hidden; position: relative; z-index: 9999; } #close { position: absolute; top: 0; right: 0; z-index: 999999; line-height: 25px; font-weight: normal; cursor: pointer; display: block; background-color:red ; text-align: center; width:30px; height: 25px; color: #fff; } </style>