封装一个视频组件(可模拟画中画效果)

目录

 前言:

1.效果:

 2.效果图:

3.代码实现 


 前言:

我是用的原生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>

猜你喜欢

转载自blog.csdn.net/wanghaoyingand/article/details/121332359