九宫格视频监控Vue前端界面布局

最近做项目要用到是监控界面,需要九宫格的,之前html的时候做过类似的,现在用vue来做,感觉也不是太难,就做出来,具体效果如下:

具体代码:

<template>
  <a-row type='flex'>
    <a-col :span='5'>
      <a-collapse v-model='activeKey'>
        <a-collapse-panel key='1' header='画面分割'>
          <a-row type='flex' justify='space-between'>
            <a-col @click='splitVideo(1,1)' :span='4' class='splitClass' style='background-color: #ff7e23;'>1</a-col>
            <a-col @click='splitVideo(2,2)' :span='4' class='splitClass' style='background-color: #00d8cb;'>4</a-col>
            <a-col @click='splitVideo(2,3)' :span='4' class='splitClass' style='background-color: #681bb7;'>6</a-col>
            <a-col @click='splitVideo(2,4)' :span='4' class='splitClass' style='background-color: #02c140;'>8</a-col>
            <a-col @click='splitVideo(3,3)' :span='4' class='splitClass' style='background-color: #ff2d12;'>9</a-col>
            <a-col @click='splitVideo(3,4)' :span='4' class='splitClass' style='background-color: #57c4ff;'>12</a-col>
          </a-row>
        </a-collapse-panel>
        <a-collapse-panel key='2' header='云台控制'>
          <div class='contentBody'>
            <div style='height: 170px;'>
              <div
                style='width:166px;height:165px; float: left; margin-top: 10px;padding-left:5px;'>
                <div title='右上' class='direction' onmousedown="contr('ptz-rotate','92')"
                     onmouseup="contr('ptz-rotate','24')">
                  <img src='../../../assets/images/video/ys.png'></div>
                <div title='上' class='direction' >
                  <img src='../../../assets/images/video/s.png'></div>
                <div title='左上' class='direction'>
                  <img src='../../../assets/images/video/zs.png'></div>
                <div title='右' class='direction' >
                  <img src='../../../assets/images/video/y.png'></div>
                <div title='居中' class='direction' onmousedown='' onmouseup=''>
                  <img src='../../../assets/images/video/zj.png'></div>
                <div title='左' class='direction' >
                  <img src='../../../assets/images/video/z.png'></div>
                <div title='右下' class='direction' >
                  <img src='../../../assets/images/video/yx.png'></div>
                <div title='下' class='direction' >
                  <img src='../../../assets/images/video/x.png'></div>
                <div title='左下' class='direction' >
                  <img src='../../../assets/images/video/zx.png'></div>
              </div>
              <div
                style='width:130px;height:165px; float: left; margin-top: 10px;padding-left:15px;'>
                <div class='zoom'>
                  <img class='zoomOut' title='放大' 
                       src='../../../assets/images/video/zoomOut.png'>
                  <span style='width: 39px;text-align: center;'>变倍</span>
                  <img class='zoomOut' title='缩小' 
                       src='../../../assets/images/video/zoomIn.png'>
                </div>
                <div class='zoom'>
                  <img class='zoomOut' title='放大' 
                       src='../../../assets/images/video/jujiaoOut.png'>
                  <span style='width: 39px;text-align: center;'>聚焦</span>
                  <img class='zoomOut' title='缩小' 
                       src='../../../assets/images/video/jujiaoIn.png'>
                </div>
                <div class='zoom'>
                  <img class='zoomOut' title='放大'
                       src='../../../assets/images/video/guangquanOut.png'>
                  <span style='width: 39px;text-align: center;'>光圈</span>
                  <img class='zoomOut' title='缩小' 
                       src='../../../assets/images/video/guangquanIn.png'>
                </div>
              </div>
            </div>
          </div>
        </a-collapse-panel>
        <a-collapse-panel key='3' header='速度'>
          <a-slider v-model='speed' :min='1' :max='10' />
        </a-collapse-panel>
        <a-collapse-panel key='4' header='相机列表'>
          <a-directory-tree multiple default-expand-all @select='onSelect' @expand='onExpand'>
            <a-tree-node key='0-0' title='parent 0'>
              <a-tree-node key='0-0-0' title='leaf 0-0' is-leaf />
              <a-tree-node key='0-0-1' title='leaf 0-1' is-leaf />
            </a-tree-node>
            <a-tree-node key='0-1' title='parent 1'>
              <a-tree-node key='0-1-0' title='leaf 1-0' is-leaf />
              <a-tree-node key='0-1-1' title='leaf 1-1' is-leaf />
            </a-tree-node>
          </a-directory-tree>
        </a-collapse-panel>
      </a-collapse>
    </a-col>
    <a-col :span='19' >
      <a-row style='width: 100%;' v-for="(item,rowIndex) in rows" type='flex' :key="rowIndex">
        <a-col v-for='(item,colIndex) in cols' :span="item" :key="''+rowIndex+colIndex" @click="setCurrent(rowIndex,colIndex)" >
          <a-card size="small" :style="(rowIndex==currentIndex[0]&&colIndex==currentIndex[1])?'background-color: #5ea6f1':''" title='视频监控'>
            <a slot='extra' s href='#'>截图</a>
            <a style='margin-left: 10px;' slot='extra' s href='#'>关闭</a>
            <video></video>
          </a-card>
        </a-col>
      </a-row>

    </a-col>
  </a-row>

</template>

<script>
export default {
  name: 'VideoMonitor',
  data() {
    return {
      activeKey: ['1', '2', '3', '4'],
      speed: 5,
      rows:[1],
      cols:[24],
      currentIndex:[0,0],
    }
  },
  methods: {
    splitVideo(row,col) {
      this.rows=[];
      this.cols=[];
      for(let i=0;i<row;i++){
        this.rows.push(1);
      }
      for(let i=0;i<col;i++){
        this.cols.push(24/col);
      }
    },
    setCurrent(row,col){
      this.currentIndex=[row,col];
    },
    contr(code,value){

    }
  }
}
</script>

<style>
.ant-card-small > .ant-card-body{
  padding: 0px;
  background-color: white;
}
.splitClass {
  cursor: pointer;
  color: white;
  width: 30px;
  height: 30px;
  text-align: center;
  line-height: 30px;
}

.sec li {
  width: 80px;
  line-height: 35px;
  font-size: 12px;
  color: #FFFFFF;
}

.sec li.cur {
  background-color: #3374BD;
  color: #FFFFFF;
}

.rightContent {
  display: none;
  border-left: 1px solid #BDC6CF;
  border-right: 1px solid #BDC6CF;
  margin-left: -1px;
  width: 316px;
  height: 265px;
  background-color: #ffffff;
}

.contentBody {
  width: 320px;
  /*height: 225px;*/
}

.direction {
  margin-right: 1px;
  margin-bottom: 1px;
  float: right;
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background-color: RGB(69, 98, 125);
  cursor: pointer;
}

.direction img {
  width: 25px;
  margin-left: 12px;
  margin-top: 12px;
}

.zoom {
  margin-top: 14px;
  margin-bottom: 25px;
}

.zoom img {
  width: 26px;
  cursor: pointer;
}

.zoom span {
  display: inline-block;
  margin-left: 5px;
  margin-right: 5px;
  color: #444;
}

/* 设置滚动条的样式 */
::-webkit-scrollbar {
  width: 6px;
}

/* 滚动槽 */
::-webkit-scrollbar-track {
  -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.3);
  border-radius: 10px;
}

/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.1);
  -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.5);
}

::-webkit-scrollbar-thumb:window-inactive {
  background: rgba(255, 0, 0, 0.4);
}

.box-shadow-1 {
  -webkit-box-shadow: 0px 3px 3px #3E91FF;
  -moz-box-shadow: 0px 3px 3px #3E91FF;
  box-shadow: 0px 3px 3px #042F52;
}

div#rMenu {
  position: absolute;
  visibility: hidden;
  top: 0;
  background-color: #cad4e6;
  text-align: left;
  padding: 2px;
}

div#rMenu ul li {
  margin: 1px 0;
  padding: 0 5px;
  cursor: pointer;
  list-style: none outside none;
  background-color: #F1F6FE;
  line-height: 24px;
  color: #98A9C0;
  font-size: 12px;
}

div#rMenu ul li span {
  margin-left: 5px;
}

.nstSlider .leftGrip {
  background-color: #A9D0F1;
}

#video_split ul {
  width: 100%;
  float: left;
  height: 43px;
  margin-left: 10px;
}

#video_split ul li {
  width: 28px;
  padding: 6px 10px 6px 10px;
  float: left;
  text-align: center;
}

#video_split ul li img {
  width: 28px;
  height: 28px;
  cursor: pointer;
}

.messager-close, .messager-close:visited {
  margin: 0 0 0 0 !important;
}

.video {
  height: 300px;
}

.panel {
  float: left;
}

video {
  object-fit: fill;
  width: 100%;
  height: 100%;
  background-color: black;
}

video::-webkit-media-controls-enclosure {
  display: none !important;
}

video::-webkit-media-controls {
  display: none !important;
}

.selected {
  background-color: deepskyblue;
}

div#rMenu {
  position: absolute;
  visibility: hidden;
  top: 0;
  text-align: left;
  padding: 4px;
}

div#rMenu a {
  padding: 3px 15px 3px 15px;
  background-color: #cad4e6;
  vertical-align: middle;
}



</style>

具体页面还需要优化,整体的结构布局已经出来,希望对你有帮助!

如果其他问题或者合作,可以发邮件探讨:mxgsa@qq.com   

实现九宫格拖动播放视频需要使用 Vue 和一些第三方插件。以下是一个简单的实现步骤: 1. 安装 vue-grid-layout 插件,该插件可以帮助我们实现可拖动的九宫格布局。 ``` npm install vue-grid-layout --save ``` 2. 在 Vue 组件中引入 vue-grid-layout,并初始化网格布局。具体可以参考 vue-grid-layout 文档。 ```html <template> <vue-grid-layout :layout="layout" :col-num="3" :row-height="100" :is-draggable="true" :is-resizable="false"> <div v-for="(video, index) in videos" :key="index" :data-grid="{x: video.x, y: video.y, w: video.w, h: video.h}"> <video :src="video.src" controls></video> </div> </vue-grid-layout> </template> <script> import VueGridLayout from 'vue-grid-layout' export default { components: { VueGridLayout, }, data() { return { layout: [], videos: [ { src: 'video1.mp4', x: 0, y: 0, w: 1, h: 1 }, { src: 'video2.mp4', x: 1, y: 0, w: 1, h: 1 }, { src: 'video3.mp4', x: 2, y: 0, w: 1, h: 1 }, { src: 'video4.mp4', x: 0, y: 1, w: 1, h: 1 }, { src: 'video5.mp4', x: 1, y: 1, w: 1, h: 1 }, { src: 'video6.mp4', x: 2, y: 1, w: 1, h: 1 }, { src: 'video7.mp4', x: 0, y: 2, w: 1, h: 1 }, { src: 'video8.mp4', x: 1, y: 2, w: 1, h: 1 }, { src: 'video9.mp4', x: 2, y: 2, w: 1, h: 1 }, ], } }, created() { // 初始化九宫格布局 this.layout = this.videos.map(video => { return { x: video.x, y: video.y, w: video.w, h: video.h, i: String(this.videos.indexOf(video)) } }) }, } </script> ``` 3. 在 video 标签中添加 controls 属性,可以在视频上添加默认的播放控件。 4. 在组件中处理视频的播放暂停事件。可以使用 videojs 插件,该插件提供了丰富的视频控制 API。 ```html <template> <vue-grid-layout :layout="layout" :col-num="3" :row-height="100" :is-draggable="true" :is-resizable="false"> <div v-for="(video, index) in videos" :key="index" :data-grid="{x: video.x, y: video.y, w: video.w, h: video.h}"> <video ref="videoPlayer" :src="video.src" controls></video> </div> </vue-grid-layout> </template> <script> import VueGridLayout from 'vue-grid-layout' import videojs from 'video.js' export default { components: { VueGridLayout, }, data() { return { layout: [], videos: [ { src: 'video1.mp4', x: 0, y: 0, w: 1, h: 1 }, { src: 'video2.mp4', x: 1, y: 0, w: 1, h: 1 }, { src: 'video3.mp4', x: 2, y: 0, w: 1, h: 1 }, { src: 'video4.mp4', x: 0, y: 1, w: 1, h: 1 }, { src: 'video5.mp4', x: 1, y: 1, w: 1, h: 1 }, { src: 'video6.mp4', x: 2, y: 1, w: 1, h: 1 }, { src: 'video7.mp4', x: 0, y: 2, w: 1, h: 1 }, { src: 'video8.mp4', x: 1, y: 2, w: 1, h: 1 }, { src: 'video9.mp4', x: 2, y: 2, w: 1, h: 1 }, ], } }, created() { // 初始化九宫格布局 this.layout = this.videos.map(video => { return { x: video.x, y: video.y, w: video.w, h: video.h, i: String(this.videos.indexOf(video)) } }) }, mounted() { // 初始化视频播放器 this.videos.forEach((video, index) => { const videoPlayer = videojs(this.$refs[`videoPlayer${index}`], {}, function onPlayerReady() { videoPlayer.on('play', () => { console.log('Video is playing') }) videoPlayer.on('pause', () => { console.log('Video is paused') }) }) }) }, } </script> ``` 注意:上述代码中的 `videojs` 插件需要单独安装。 ``` npm install video.js --save ``` 以上就是使用 Vue 和第三方插件实现九宫格拖动播放视频的基本步骤。当然,您可以根据自己的需求进行扩展和优化。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值