VideoMonitor.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <template>
  2. <div class="video-monitor-page">
  3. <ScreenHeader />
  4. <div class="page-body">
  5. <div class="video-left">
  6. <BuildingNav @node-click="handleNodeClick" />
  7. </div>
  8. <div class="video-right">
  9. <div class="video-breadcrumb">{{ breadcrumb }}</div>
  10. <VideoGrid />
  11. </div>
  12. </div>
  13. </div>
  14. </template>
  15. <script>
  16. import ScreenHeader from '@/components/Header.vue'
  17. import BuildingNav from '@/components/VideoMonitor/BuildingNav.vue'
  18. import VideoGrid from '@/components/VideoMonitor/VideoGrid.vue'
  19. export default {
  20. name: 'VideoMonitor',
  21. components: { ScreenHeader, BuildingNav, VideoGrid },
  22. data() {
  23. return {
  24. breadcrumb: '安科院院区 → 科研楼A → 3层'
  25. }
  26. },
  27. methods: {
  28. handleNodeClick(data) {
  29. console.log('选中节点:', data.label)
  30. }
  31. }
  32. }
  33. </script>
  34. <style lang="scss" scoped>
  35. .video-monitor-page {
  36. width: 1920px;
  37. height: 1080px;
  38. display: flex;
  39. flex-direction: column;
  40. overflow: hidden;
  41. }
  42. .page-body {
  43. flex: 1;
  44. display: flex;
  45. gap: 14px;
  46. padding: 14px;
  47. overflow: hidden;
  48. }
  49. .video-left {
  50. width: 300px;
  51. flex-shrink: 0;
  52. position: relative;
  53. &::after {
  54. content: '';
  55. position: absolute;
  56. left: 0;
  57. top: -100%;
  58. width: 1px;
  59. height: 60%;
  60. background: linear-gradient(180deg, transparent, rgba(72,215,255,0.7), rgba(72,215,255,0.9), rgba(72,215,255,0.7), transparent);
  61. animation: sidebarScan 5s linear infinite;
  62. pointer-events: none;
  63. z-index: 3;
  64. }
  65. &::before {
  66. content: '';
  67. position: absolute;
  68. left: 0;
  69. top: 10%;
  70. bottom: 10%;
  71. width: 2px;
  72. background: linear-gradient(180deg, transparent, $accent, transparent);
  73. opacity: 0.4;
  74. animation: sidebarEdgeGlow 3s ease-in-out infinite;
  75. z-index: 3;
  76. pointer-events: none;
  77. }
  78. }
  79. @keyframes sidebarScan {
  80. 0% { top: -60%; }
  81. 100% { top: 160%; }
  82. }
  83. @keyframes sidebarEdgeGlow {
  84. 0%, 100% { opacity: 0.25; }
  85. 50% { opacity: 0.7; box-shadow: 0 0 12px $accent; }
  86. }
  87. .video-right {
  88. flex: 1;
  89. display: flex;
  90. flex-direction: column;
  91. min-width: 0;
  92. position: relative;
  93. &::before {
  94. content: '';
  95. position: absolute;
  96. top: 0; left: 0; right: 0; bottom: 0;
  97. pointer-events: none;
  98. z-index: 0;
  99. background-image:
  100. radial-gradient(1px 1px at 10% 20%, rgba(72,215,255,0.3) 50%, transparent 100%),
  101. radial-gradient(1px 1px at 75% 80%, rgba(72,215,255,0.3) 50%, transparent 100%),
  102. radial-gradient(1px 1px at 90% 40%, rgba(72,215,255,0.25) 50%, transparent 100%);
  103. animation: videoParticles 12s ease-in-out infinite alternate;
  104. }
  105. }
  106. @keyframes videoParticles {
  107. 0% { opacity: 0.3; }
  108. 50% { opacity: 0.7; }
  109. 100% { opacity: 0.3; transform: translateY(-10px); }
  110. }
  111. .video-breadcrumb {
  112. font-size: 14px;
  113. color: $text-secondary;
  114. margin-bottom: 10px;
  115. padding: 4px 0;
  116. border-bottom: 1px solid rgba(72,215,255,0.1);
  117. position: relative;
  118. z-index: 1;
  119. overflow: hidden;
  120. &::before {
  121. content: '';
  122. position: absolute;
  123. bottom: 0;
  124. left: -80px;
  125. width: 80px;
  126. height: 1px;
  127. background: linear-gradient(90deg, transparent, $accent, transparent);
  128. animation: breadcrumbFlow 5s linear infinite;
  129. pointer-events: none;
  130. }
  131. }
  132. @keyframes breadcrumbFlow {
  133. 0% { left: -80px; }
  134. 100% { left: calc(100% + 80px); }
  135. }
  136. </style>