BigShow.vue 15 KB

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