BigShow.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <!--大屏显示组件-->
  2. <template>
  3. <div>
  4. <draggable
  5. v-for="(item,index) in currentBigshow"
  6. element="div"
  7. v-model="signalPreList"
  8. :options="dragOptions2"
  9. @change="log"
  10. :class="['split_screen', splitScreenStatus === 0 ? 'split_screen_one' : splitScreenStatus === 1 ? 'split_screen_four' : splitScreenStatus === 2 ? 'split_screen_nine' : 'split_screen_sixteen']"
  11. :style="{
  12. float:'left',
  13. width:item.Width*bigScale + 'px',
  14. height:item.Height*bigScale + 'px',
  15. left:item.Left*bigScale+'px',
  16. top:item.Top*bigScale+'px',
  17. zIndex:item.ZIndex,
  18. display:item.IsVisibility ? 'black' : 'none',
  19. }"
  20. id="bigscreen"
  21. >
  22. <VueDragResize
  23. v-for="itemV in signalPreList" :key="itemV.Id" class="sitem"
  24. :w="item.Width*bigScale/itemV.splitScreenStatus" :h="item.Height*bigScale/itemV.splitScreenStatus" :parentLimitation="false"
  25. :x="itemV.left" :y="itemV.top"
  26. @dragstop="(obj) => dragStop(obj,itemV)"
  27. @resizestop="(obj) => reSizeSignal(obj,itemV)"
  28. >
  29. <div ref="signal">
  30. {{itemV.deviceID}}
  31. <!--<video-player
  32. ref="videoPlayer"
  33. :options="playerOptions"
  34. :playsinline="true"
  35. >
  36. </video-player>-->
  37. <div class="closeBtn" @click.stop="closeSignal(itemV)">×</div>
  38. </div>
  39. </VueDragResize>
  40. <div v-for="itemD in bindList" :key="itemD" class="sitem2">
  41. {{itemD}}
  42. </div>
  43. </draggable>
  44. </div>
  45. </template>
  46. <script>
  47. import {mapState} from 'vuex'
  48. import draggable from 'vuedraggable'
  49. import VueDragResize from 'vue-drag-resize'
  50. import '../assets/less/splitscreen.less'
  51. import {elePosition, getElementLeft, getElementTop, getStaticFile, guId} from "../../utils/tools"
  52. import {reqRefreshView} from "../api"
  53. import VideoPlayer from "./player.vue"
  54. export default {
  55. data() {
  56. return {
  57. isDragging: false, // 是否可拖动标志
  58. bindList:[], // 拼接屏的数量
  59. streamWindows:[], // 传递出去的信号源位置信息
  60. bigScreenJson:[], // 大屏配置json文件
  61. currentBigshow:[], // 当前大屏
  62. playerOptions: { // rtmp视频流配置
  63. sources: [
  64. {
  65. "src": "rtmp://58.200.131.2:1935/livetv/hunantv",
  66. "type": "rtmp/flv"
  67. }
  68. ],
  69. techOrder: ['flash'],
  70. autoplay: true,
  71. controls: false,
  72. fluid:true,
  73. aspectRatio: '200:93',
  74. preload: 'auto',
  75. notSupportedMessage: '此视频暂无法播放,请稍后再试',
  76. },
  77. screenPosition:{}, // 大屏在视口中的位置
  78. newIndex: 1, // 开窗拖到第几个格子中
  79. }
  80. },
  81. components: {
  82. draggable,
  83. VueDragResize,
  84. "video-player": VideoPlayer
  85. },
  86. async beforeCreate() {
  87. this.bigScreenJson = await getStaticFile('EnityBigScreen.Data')
  88. this.currentBigshow = this.bigScreenJson.filter(item => item.IsVisibility === true)
  89. const num = this.currentBigshow[0].BindList.length
  90. for(let i=0;i<num;i++){
  91. this.$data.bindList.push(i+1)
  92. }
  93. this.$store.dispatch('splitScreen', Math.sqrt(num)-1)
  94. },
  95. updated() {
  96. // 获取大屏在视口中的位置
  97. const screenDiv = document.getElementById('bigscreen')
  98. this.screenPosition = {
  99. top:getElementTop(screenDiv),
  100. left:getElementLeft(screenDiv)
  101. }
  102. },
  103. methods: {
  104. // 改变信号源
  105. log() {
  106. this.newIndex = this.$store.state.positionNum
  107. },
  108. // 大屏开窗接口提交
  109. reqRefreshBigScreen(arr) {
  110. const streamWindows = []
  111. setTimeout(async () => {
  112. const elementArr = this.$refs.signal ? this.$refs.signal.filter(item => item.clientWidth !== 0) : []
  113. if(elementArr){
  114. elementArr.forEach((item,index) => {
  115. // 获取元素绝对位置的横坐标和纵坐标
  116. const left = getElementLeft(item)
  117. const top = getElementTop(item)
  118. streamWindows.push({
  119. left,
  120. top,
  121. width:arr[index].width,
  122. height:arr[index].height,
  123. id:0,
  124. sourceId:arr[index].sourceId,
  125. widthScale:arr[index].width/(this.currentBigshow[0].Width*this.$store.state.bigScale),
  126. heightScale:arr[index].height/(this.currentBigshow[0].Height*this.$store.state.bigScale),
  127. orginRect:{}
  128. })
  129. })
  130. const data = {
  131. bigScreenId:this.currentBigshow[0].ID,
  132. streamWindows
  133. }
  134. this.streamWindows = streamWindows
  135. // 调用大屏开窗接口
  136. await reqRefreshView(data)
  137. }
  138. })
  139. },
  140. // 拖动结束
  141. dragStop(obj,item) {
  142. /*const arr = this.$store.state.signalPreList.filter(a => a.Id !== item.Id)
  143. item.top = this.screenPosition.top + obj.top
  144. item.left = this.screenPosition.left + obj.left
  145. this.$store.dispatch('updateSignalPreList',[...arr,item])*/
  146. const arr2 = this.$store.state.signalPreList
  147. this.reqRefreshBigScreen(arr2)
  148. },
  149. // 放大缩小信号源(缩放结束事件)
  150. async reSizeSignal(obj,itemV) {
  151. const arr = this.$data.streamWindows
  152. // 找出当前改动的信号源
  153. const currentItem = arr.filter(item => item.sourceId === itemV.sourceId)
  154. currentItem[0].width = obj.width
  155. currentItem[0].height = obj.height
  156. currentItem[0].widthScale = obj.width/(this.currentBigshow[0].Width*this.$store.state.bigScale)
  157. currentItem[0].heightScale = obj.height/(this.currentBigshow[0].Height*this.$store.state.bigScale)
  158. const otherItems = arr.filter(item => item.sourceId !== itemV.sourceId)
  159. const newStreamWindows = [...currentItem,...otherItems]
  160. this.streamWindows = newStreamWindows
  161. this.reqRefreshBigScreen(newStreamWindows)
  162. },
  163. // 关闭信号源
  164. closeSignal(signal) {
  165. const signalPreList = this.$store.state.signalPreList
  166. const newSignalPreList = signalPreList.filter(item => item.Id !== signal.Id)
  167. this.$store.dispatch('updateSignalPreList',newSignalPreList)
  168. }
  169. },
  170. computed: {
  171. ...mapState(['splitScreenStatus', 'bigScale','positionNum']),
  172. signalPreList: {
  173. get() {
  174. return this.$store.state.signalPreList
  175. },
  176. set(arr) {
  177. let len = arr.length
  178. if(len>0){
  179. // 对监视的信号源数组进行深度克隆,解决赋加Id一样的问题
  180. const arr2 = []
  181. arr.forEach(item => {arr2.push(JSON.parse(JSON.stringify(item)))})
  182. // 删除数据的最后一项,重新赋值再添加
  183. arr2.pop()
  184. // 给新增的信号源进行赋值
  185. const signalObj = arr[len-1]
  186. signalObj.Id = guId()
  187. signalObj.splitScreenStatus = this.$store.state.splitScreenStatus + 1
  188. signalObj.width = this.currentBigshow[0].Width * this.$store.state.bigScale / (this.$store.state.splitScreenStatus+1)
  189. signalObj.height = this.currentBigshow[0].Height * this.$store.state.bigScale / (this.$store.state.splitScreenStatus+1)
  190. signalObj.widthScale = signalObj.width / (this.currentBigshow[0].Width * this.$store.state.bigScale)
  191. signalObj.heightScale = signalObj.height / (this.currentBigshow[0].Height * this.$store.state.bigScale)
  192. signalObj.isFixed = true // 是否使用固定定位
  193. this.$store.dispatch('updateSignalPreList', [...arr2,signalObj])
  194. // 添加定时器是为了得到最新的newIndex
  195. setTimeout(() => {
  196. let width = this.currentBigshow[0].Width*this.$store.state.bigScale/(signalObj.splitScreenStatus)
  197. let height = this.currentBigshow[0].Height*this.$store.state.bigScale/(signalObj.splitScreenStatus)
  198. const res = elePosition(width,height,this.newIndex,this.screenPosition.top,this.screenPosition.left,this.$store.state.splitScreenStatus+1)
  199. signalObj.top = res.top - this.screenPosition.top
  200. signalObj.left = res.left - this.screenPosition.left
  201. this.$store.dispatch('updateSignalPreList', [...arr2,signalObj])
  202. })
  203. }else {
  204. this.$store.dispatch('updateSignalPreList', arr)
  205. }
  206. }
  207. },
  208. dragOptions1() {
  209. return {
  210. animation: 0,
  211. group: {
  212. name: "description",
  213. pull: 'clone',
  214. put: false
  215. },
  216. ghostClass: "ghost",
  217. }
  218. },
  219. dragOptions2() {
  220. return {
  221. animation: 0,
  222. group: "description",
  223. disabled:false,
  224. sort:false,
  225. }
  226. },
  227. player() {
  228. return this.$refs.videoPlayer.player
  229. }
  230. },
  231. watch: {
  232. // 监视大屏中的信号源,只要变动,就调用回调函数
  233. signalPreList: function (arr) {
  234. this.reqRefreshBigScreen(arr)
  235. },
  236. // 监视分屏的状态
  237. splitScreenStatus: function(num) {
  238. this.$data.bindList = []
  239. for (let i=0;i<(num+1)*(num+1);i++){
  240. this.$data.bindList.push(i+1)
  241. }
  242. this.reqRefreshBigScreen(this.$data.streamWindows)
  243. }
  244. }
  245. }
  246. </script>