Commit 1a9f821daaef2a37b12b6690139a9c3b085aa7fb

Authored by fengwotao
1 parent 04531a78

perf(external/Composes): 修改摄像头排布

1 <template> 1 <template>
2 - <video 2 + <div class="go-content-box" :style="{ width: w + 'px', height: h + 'px' }">
  3 + <video
3 crossOrigin="anonymous" 4 crossOrigin="anonymous"
4 - :id="`my-player${index}`"  
5 - ref="videoRef"  
6 - class="video-js my-video vjs-theme-city vjs-big-play-centered"  
7 - >  
8 - <source :src="sourceSrc" />  
9 - </video> 5 + :id="`my-player${index}`" ref="videoRef" class="video-js my-video vjs-theme-city vjs-big-play-centered">
  6 + <source :src="sourceSrc" />
  7 + </video>
  8 + </div>
10 </template> 9 </template>
11 <script setup lang="ts"> 10 <script setup lang="ts">
12 import { onMounted, ref, onUnmounted, watch } from 'vue' 11 import { onMounted, ref, onUnmounted, watch } from 'vue'
@@ -98,8 +97,14 @@ defineExpose({ @@ -98,8 +97,14 @@ defineExpose({
98 </script> 97 </script>
99 98
100 <style lang="scss" scoped> 99 <style lang="scss" scoped>
101 -.my-video {  
102 - width: 100%;  
103 - height: 100%; 100 +.go-content-box {
  101 + display: flex;
  102 + align-items: center;
  103 + justify-content: center;
  104 + .my-video {
  105 + width: 100% !important;
  106 + height: 100% !important;
  107 + position: relative;
  108 + }
104 } 109 }
105 </style> 110 </style>
src/packages/components/external/Composes/Mores/Camera/components/CameraItem2.vue renamed from src/packages/components/external/Composes/Mores/Camera/components/CameraItem1.vue
1 <template> 1 <template>
2 - <div class="go-content-box" :style="{ width: w + 'px', height: h + 'px' }">  
3 - <video 2 + <video
4 crossOrigin="anonymous" 3 crossOrigin="anonymous"
5 - :id="`my-player${index}`" ref="videoRef" class="video-js my-video vjs-theme-city vjs-big-play-centered">  
6 - <source :src="sourceSrc" />  
7 - </video>  
8 - </div> 4 + :id="`my-player${index}`"
  5 + ref="videoRef"
  6 + class="video-js my-video vjs-theme-city vjs-big-play-centered"
  7 + >
  8 + <source :src="sourceSrc" />
  9 + </video>
9 </template> 10 </template>
10 <script setup lang="ts"> 11 <script setup lang="ts">
11 import { onMounted, ref, onUnmounted, watch } from 'vue' 12 import { onMounted, ref, onUnmounted, watch } from 'vue'
@@ -97,14 +98,8 @@ defineExpose({ @@ -97,14 +98,8 @@ defineExpose({
97 </script> 98 </script>
98 99
99 <style lang="scss" scoped> 100 <style lang="scss" scoped>
100 -.go-content-box {  
101 - display: flex;  
102 - align-items: center;  
103 - justify-content: center;  
104 - .my-video {  
105 - width: 100% !important;  
106 - height: 100% !important;  
107 - position: relative;  
108 - } 101 +.my-video {
  102 + width: 100%;
  103 + height: 100%;
109 } 104 }
110 </style> 105 </style>
1 <template> 1 <template>
2 <div class="banner-box" ref="root"> 2 <div class="banner-box" ref="root">
3 - <n-grid x-gap="12" :y-gap="12" :cols="computedCols">  
4 - <n-gi v-for="(item, index) in option.dataset" :key="index + item">  
5 - <div class="camera-container">  
6 - <CameraItem  
7 - ref="cameraRef"  
8 - :name="item.name"  
9 - :avatar="item.avatar"  
10 - :key="item + index"  
11 - :sourceSrc="item.url"  
12 - :index="index"  
13 - />  
14 - </div>  
15 - </n-gi>  
16 - </n-grid> 3 + <div class="wrapper">
  4 + <div
  5 + v-for="(item, index) in option.dataset"
  6 + :key="index + item"
  7 + :class="item.className"
  8 + :style="item.sty"
  9 + >
  10 + <CameraItem
  11 + ref="cameraRef"
  12 + :name="item.name"
  13 + :avatar="item.avatar"
  14 + :key="item + index"
  15 + :sourceSrc="item.url"
  16 + :w="w"
  17 + :h="h"
  18 + :index="index"
  19 + />
  20 + <span class="video-title">{{ item.name }}</span>
  21 + </div>
  22 + </div>
  23 + <a href="javascript:;" class="left" @click="changeSlide('left')"></a>
  24 + <a href="javascript:;" class="right" @click="changeSlide('right')"></a>
17 </div> 25 </div>
18 </template> 26 </template>
19 <script setup lang="ts"> 27 <script setup lang="ts">
20 -import { PropType, toRefs, watch, shallowReactive, ref, computed } from 'vue' 28 +import { PropType, watch, toRefs, shallowReactive, onMounted, ref } from 'vue'
21 import { CreateComponentType } from '@/packages/index.d' 29 import { CreateComponentType } from '@/packages/index.d'
22 import 'video.js/dist/video-js.min.css' 30 import 'video.js/dist/video-js.min.css'
23 import { option as configOption } from './config' 31 import { option as configOption } from './config'
@@ -30,34 +38,68 @@ const props = defineProps({ @@ -30,34 +38,68 @@ const props = defineProps({
30 } 38 }
31 }) 39 })
32 40
33 -const { h } = toRefs(props.chartConfig.attr)  
34 -  
35 -const responsiveComputeValue = ref(0) 41 +const { w, h } = toRefs(props.chartConfig.attr)
36 42
37 const option = shallowReactive({ 43 const option = shallowReactive({
38 dataset: configOption.dataset 44 dataset: configOption.dataset
39 }) 45 })
40 46
41 -const computedCols = computed(() => {  
42 - if (option.dataset.length <= 1) return 1  
43 - if (option.dataset.length <= 4) return 2  
44 - return 3  
45 -})  
46 -  
47 const cameraRef = ref<InstanceType<typeof CameraItem>>() 47 const cameraRef = ref<InstanceType<typeof CameraItem>>()
48 48
49 -const responsive = (value: number) => {  
50 - responsiveComputeValue.value = value  
51 - if (option.dataset.length <= 2) responsiveComputeValue.value = value  
52 - if (option.dataset.length > 2 && option.dataset.length <= 4) responsiveComputeValue.value = value / 2.03  
53 - if (option.dataset.length > 4 && option.dataset.length <= 9) responsiveComputeValue.value = value / 3.1 49 +let initial = ref(0)
  50 +
  51 +let interval = ref(2500)
  52 +
  53 +const computedFunc = (initial: number, source: any) => {
  54 + if (initial < 0) initial = 0
  55 + if (Array.isArray(source)) {
  56 + let len = source.length,
  57 + temp1 = initial - 2 < 0 ? initial - 2 + len : initial - 2,
  58 + temp2 = initial - 1 < 0 ? initial - 1 + len : initial - 1,
  59 + temp3 = initial,
  60 + temp4 = initial + 1 >= len ? initial + 1 - len : initial + 1,
  61 + temp5 = initial + 2 >= len ? initial + 2 - len : initial + 2
  62 + return source?.map((item: any, index: number) => {
  63 + let transform = `translateX(-50%) scale(0.7)`,
  64 + zIndex = 0,
  65 + className = 'slide'
  66 + switch (index) {
  67 + case temp3:
  68 + transform = `translateX(-50%) scale(1)`
  69 + className = ['slide', 'activate'] as any
  70 + zIndex = 300
  71 + break
  72 + case temp1:
  73 + transform = `translateX(-80%) scale(0.7)`
  74 + zIndex = 100
  75 + break
  76 + case temp5:
  77 + transform = `translateX(100%) scale(0.7)`
  78 + zIndex = 100
  79 + break
  80 + case temp2:
  81 + transform = `translateX(-100%) scale(0.85)`
  82 + zIndex = 200
  83 + break
  84 + case temp4:
  85 + transform = `translateX(58%) scale(0.85)`
  86 + zIndex = 200
  87 + break
  88 + }
  89 + item.sty = {
  90 + transform,
  91 + zIndex
  92 + }
  93 + item.className = className
  94 + return item
  95 + })
  96 + }
54 } 97 }
55 98
56 watch( 99 watch(
57 () => props.chartConfig.option.dataset, 100 () => props.chartConfig.option.dataset,
58 newData => { 101 newData => {
59 option.dataset = newData 102 option.dataset = newData
60 - responsive(h.value)  
61 }, 103 },
62 { 104 {
63 immediate: true, 105 immediate: true,
@@ -65,19 +107,101 @@ watch( @@ -65,19 +107,101 @@ watch(
65 } 107 }
66 ) 108 )
67 109
  110 +option.dataset = computedFunc(initial.value, option.dataset)
  111 +
68 watch( 112 watch(
69 - () => h.value,  
70 - newData => responsive(newData),  
71 - {  
72 - immediate: true 113 + () => initial.value,
  114 + newV => {
  115 + option.dataset = computedFunc(newV, option.dataset)
73 } 116 }
74 ) 117 )
  118 +
  119 +// 处理自动轮播
  120 +let timer: any = null
  121 +
  122 +const autoPlay = () => {
  123 + timer = setInterval(() => {
  124 + initial.value++
  125 + if (initial.value >= option.dataset.length) {
  126 + initial.value = 0
  127 + }
  128 + }, interval.value)
  129 +}
  130 +
  131 +// 鼠标移入移除效果
  132 +let root = ref(null)
  133 +
  134 +onMounted(() => {
  135 + clearInterval(timer)
  136 + autoPlay()
  137 + const box: any = root.value
  138 + box.onmouseenter = () => clearInterval(timer)
  139 + box.onmouseleave = () => autoPlay()
  140 +})
  141 +
  142 +// 点击左右按钮切换图片
  143 +function changeVideo(dir: string) {
  144 + if (dir === 'left') {
  145 + clearInterval(timer)
  146 + initial.value++
  147 + initial.value >= option.dataset.length ? (initial.value = 0) : false
  148 + return
  149 + }
  150 + initial.value--
  151 + initial.value < 0 ? (initial.value = option.dataset.length - 1) : false
  152 +}
  153 +
  154 +// 左右切换图片设置防抖效果
  155 +function changeSlide(dir: string) {
  156 + changeVideo(dir)
  157 +}
75 </script> 158 </script>
76 159
77 <style lang="scss" scoped> 160 <style lang="scss" scoped>
78 .banner-box { 161 .banner-box {
79 - .camera-container {  
80 - height: v-bind('`${responsiveComputeValue}px`'); 162 + .wrapper {
  163 + height: 100%;
  164 + display: flex;
  165 + overflow: hidden;
  166 + .slide {
  167 + width: 20%;
  168 + height: 100%;
  169 + position: absolute;
  170 + left: 10%;
  171 + transform: translateX(-50%);
  172 + transition: 0.5s;
  173 + box-shadow: 0 0 4px black;
  174 + .video-title {
  175 + width: v-bind('w+"px"');
  176 + font-size: 30px;
  177 + color: white;
  178 + position: absolute;
  179 + bottom: 6%;
  180 + left: 10%;
  181 + z-index: 999;
  182 + }
  183 + }
  184 + }
  185 + .arrow {
  186 + position: absolute;
  187 + top: 50%;
  188 + transform: translateY(-50%);
  189 + z-index: 9;
  190 + width: 50px;
  191 + height: 50px;
  192 + background-size: contain;
  193 + background-color: white;
  194 + opacity: 0.5;
  195 + }
  196 + a.left {
  197 + @extend .arrow;
  198 + background-image: url(./static/left.svg);
  199 + left: 0px;
  200 + }
  201 + a.right {
  202 + @extend .arrow;
  203 + background-image: url(./static/right.svg);
  204 + right: 0px;
81 } 205 }
82 } 206 }
83 </style> 207 </style>
  1 +<template>
  2 + <div class="banner-box" ref="root">
  3 + <n-grid x-gap="12" :y-gap="12" :cols="computedCols">
  4 + <n-gi v-for="(item, index) in option.dataset" :key="index + item">
  5 + <div class="camera-container">
  6 + <CameraItem
  7 + ref="cameraRef"
  8 + :name="item.name"
  9 + :avatar="item.avatar"
  10 + :key="item + index"
  11 + :sourceSrc="item.url"
  12 + :index="index"
  13 + />
  14 + </div>
  15 + </n-gi>
  16 + </n-grid>
  17 + </div>
  18 +</template>
  19 +<script setup lang="ts">
  20 +import { PropType, toRefs, watch, shallowReactive, ref, computed } from 'vue'
  21 +import { CreateComponentType } from '@/packages/index.d'
  22 +import 'video.js/dist/video-js.min.css'
  23 +import { option as configOption } from './config'
  24 +import { CameraItem } from './components'
  25 +
  26 +const props = defineProps({
  27 + chartConfig: {
  28 + type: Object as PropType<CreateComponentType>,
  29 + required: true
  30 + }
  31 +})
  32 +
  33 +const { h } = toRefs(props.chartConfig.attr)
  34 +
  35 +const responsiveComputeValue = ref(0)
  36 +
  37 +const option = shallowReactive({
  38 + dataset: configOption.dataset
  39 +})
  40 +
  41 +const computedCols = computed(() => {
  42 + if (option.dataset.length <= 1) return 1
  43 + if (option.dataset.length <= 4) return 2
  44 + return 3
  45 +})
  46 +
  47 +const cameraRef = ref<InstanceType<typeof CameraItem>>()
  48 +
  49 +const responsive = (value: number) => {
  50 + responsiveComputeValue.value = value
  51 + if (option.dataset.length <= 2) responsiveComputeValue.value = value
  52 + if (option.dataset.length > 2 && option.dataset.length <= 4) responsiveComputeValue.value = value / 2.03
  53 + if (option.dataset.length > 4 && option.dataset.length <= 9) responsiveComputeValue.value = value / 3.1
  54 +}
  55 +
  56 +watch(
  57 + () => props.chartConfig.option.dataset,
  58 + newData => {
  59 + option.dataset = newData
  60 + responsive(h.value)
  61 + },
  62 + {
  63 + immediate: true,
  64 + deep: true
  65 + }
  66 +)
  67 +
  68 +watch(
  69 + () => h.value,
  70 + newData => responsive(newData),
  71 + {
  72 + immediate: true
  73 + }
  74 +)
  75 +</script>
  76 +
  77 +<style lang="scss" scoped>
  78 +.banner-box {
  79 + .camera-container {
  80 + height: v-bind('`${responsiveComputeValue}px`');
  81 + }
  82 +}
  83 +</style>
1 -<template>  
2 - <div class="banner-box" ref="root">  
3 - <div class="wrapper">  
4 - <div  
5 - v-for="(item, index) in option.dataset"  
6 - :key="index + item"  
7 - :class="item.className"  
8 - :style="item.sty"  
9 - >  
10 - <CameraItem  
11 - ref="cameraRef"  
12 - :name="item.name"  
13 - :avatar="item.avatar"  
14 - :key="item + index"  
15 - :sourceSrc="item.url"  
16 - :w="w"  
17 - :h="h"  
18 - :index="index"  
19 - />  
20 - <span class="video-title">{{ item.name }}</span>  
21 - </div>  
22 - </div>  
23 - <a href="javascript:;" class="left" @click="changeSlide('left')"></a>  
24 - <a href="javascript:;" class="right" @click="changeSlide('right')"></a>  
25 - </div>  
26 -</template>  
27 -<script setup lang="ts">  
28 -import { PropType, watch, toRefs, shallowReactive, onMounted, ref } from 'vue'  
29 -import { CreateComponentType } from '@/packages/index.d'  
30 -import 'video.js/dist/video-js.min.css'  
31 -import { option as configOption } from './config'  
32 -import { CameraItem } from './components'  
33 -  
34 -const props = defineProps({  
35 - chartConfig: {  
36 - type: Object as PropType<CreateComponentType>,  
37 - required: true  
38 - }  
39 -})  
40 -  
41 -const { w, h } = toRefs(props.chartConfig.attr)  
42 -  
43 -const option = shallowReactive({  
44 - dataset: configOption.dataset  
45 -})  
46 -  
47 -const cameraRef = ref<InstanceType<typeof CameraItem>>()  
48 -  
49 -let initial = ref(0)  
50 -  
51 -let interval = ref(2500)  
52 -  
53 -const computedFunc = (initial: number, source: any) => {  
54 - if (initial < 0) initial = 0  
55 - if (Array.isArray(source)) {  
56 - let len = source.length,  
57 - temp1 = initial - 2 < 0 ? initial - 2 + len : initial - 2,  
58 - temp2 = initial - 1 < 0 ? initial - 1 + len : initial - 1,  
59 - temp3 = initial,  
60 - temp4 = initial + 1 >= len ? initial + 1 - len : initial + 1,  
61 - temp5 = initial + 2 >= len ? initial + 2 - len : initial + 2  
62 - return source?.map((item: any, index: number) => {  
63 - let transform = `translateX(-50%) scale(0.7)`,  
64 - zIndex = 0,  
65 - className = 'slide'  
66 - switch (index) {  
67 - case temp3:  
68 - transform = `translateX(-50%) scale(1)`  
69 - className = ['slide', 'activate'] as any  
70 - zIndex = 300  
71 - break  
72 - case temp1:  
73 - transform = `translateX(-80%) scale(0.7)`  
74 - zIndex = 100  
75 - break  
76 - case temp5:  
77 - transform = `translateX(100%) scale(0.7)`  
78 - zIndex = 100  
79 - break  
80 - case temp2:  
81 - transform = `translateX(-100%) scale(0.85)`  
82 - zIndex = 200  
83 - break  
84 - case temp4:  
85 - transform = `translateX(58%) scale(0.85)`  
86 - zIndex = 200  
87 - break  
88 - }  
89 - item.sty = {  
90 - transform,  
91 - zIndex  
92 - }  
93 - item.className = className  
94 - return item  
95 - })  
96 - }  
97 -}  
98 -  
99 -watch(  
100 - () => props.chartConfig.option.dataset,  
101 - newData => {  
102 - option.dataset = newData  
103 - },  
104 - {  
105 - immediate: true,  
106 - deep: true  
107 - }  
108 -)  
109 -  
110 -option.dataset = computedFunc(initial.value, option.dataset)  
111 -  
112 -watch(  
113 - () => initial.value,  
114 - newV => {  
115 - option.dataset = computedFunc(newV, option.dataset)  
116 - }  
117 -)  
118 -  
119 -// 处理自动轮播  
120 -let timer: any = null  
121 -  
122 -const autoPlay = () => {  
123 - timer = setInterval(() => {  
124 - initial.value++  
125 - if (initial.value >= option.dataset.length) {  
126 - initial.value = 0  
127 - }  
128 - }, interval.value)  
129 -}  
130 -  
131 -// 鼠标移入移除效果  
132 -let root = ref(null)  
133 -  
134 -onMounted(() => {  
135 - clearInterval(timer)  
136 - autoPlay()  
137 - const box: any = root.value  
138 - box.onmouseenter = () => clearInterval(timer)  
139 - box.onmouseleave = () => autoPlay()  
140 -})  
141 -  
142 -// 点击左右按钮切换图片  
143 -function changeVideo(dir: string) {  
144 - if (dir === 'left') {  
145 - clearInterval(timer)  
146 - initial.value++  
147 - initial.value >= option.dataset.length ? (initial.value = 0) : false  
148 - return  
149 - }  
150 - initial.value--  
151 - initial.value < 0 ? (initial.value = option.dataset.length - 1) : false  
152 -}  
153 -  
154 -// 左右切换图片设置防抖效果  
155 -function changeSlide(dir: string) {  
156 - changeVideo(dir)  
157 -}  
158 -</script>  
159 -  
160 -<style lang="scss" scoped>  
161 -.banner-box {  
162 - .wrapper {  
163 - height: 100%;  
164 - display: flex;  
165 - overflow: hidden;  
166 - .slide {  
167 - width: 20%;  
168 - height: 100%;  
169 - position: absolute;  
170 - left: 10%;  
171 - transform: translateX(-50%);  
172 - transition: 0.5s;  
173 - box-shadow: 0 0 4px black;  
174 - .video-title {  
175 - width: v-bind('w+"px"');  
176 - font-size: 30px;  
177 - color: white;  
178 - position: absolute;  
179 - bottom: 6%;  
180 - left: 10%;  
181 - z-index: 999;  
182 - }  
183 - }  
184 - }  
185 - .arrow {  
186 - position: absolute;  
187 - top: 50%;  
188 - transform: translateY(-50%);  
189 - z-index: 9;  
190 - width: 50px;  
191 - height: 50px;  
192 - background-size: contain;  
193 - background-color: white;  
194 - opacity: 0.5;  
195 - }  
196 - a.left {  
197 - @extend .arrow;  
198 - background-image: url(./static/left.svg);  
199 - left: 0px;  
200 - }  
201 - a.right {  
202 - @extend .arrow;  
203 - background-image: url(./static/right.svg);  
204 - right: 0px;  
205 - }  
206 -}  
207 -</style>