BigShow.vue 14 KB

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