Commit 771ef12d8e8b1c7df786f768f4533d367223e9dd
Merge branch 'ft' into 'main_dev'
pref: 修改摄像头和大标题 See merge request yunteng/thingskit-view!41
Showing
8 changed files
with
365 additions
and
97 deletions
1 | <template> | 1 | <template> |
2 | <div class="go-text-box"> | 2 | <div class="go-text-box"> |
3 | - <n-grid :style="{'background-image': 'url('+option.configOption.bgSrc+')'}" class="go-n-grid" :x-gap="12" :y-gap="3" | ||
4 | - :cols="3" layout-shift-disabled> | 3 | + <n-grid |
4 | + :style="{ 'background-image': 'url(' + option.configOption.bgSrc + ')', height: h + 'px' }" | ||
5 | + class="go-n-grid" | ||
6 | + :x-gap="12" | ||
7 | + :y-gap="3" | ||
8 | + :cols="3" | ||
9 | + layout-shift-disabled | ||
10 | + > | ||
5 | <n-grid-item> | 11 | <n-grid-item> |
6 | <!-- 占位--> | 12 | <!-- 占位--> |
7 | <div></div> | 13 | <div></div> |
8 | </n-grid-item> | 14 | </n-grid-item> |
9 | <n-grid-item> | 15 | <n-grid-item> |
10 | <span | 16 | <span |
11 | - style="position:relative" | ||
12 | - :style="{ top:option.configOption.y+'px',marginLeft:option.configOption.x+'px',color: option.configOption.textColor, fontSize: option.configOption.fontSize + 'px' }">{{ | ||
13 | - option.configOption.dataset | ||
14 | - }}</span> | 17 | + style="position: relative" |
18 | + :style="{ | ||
19 | + top: option.configOption.y + 'px', | ||
20 | + marginLeft: option.configOption.x + 'px', | ||
21 | + color: option.configOption.textColor, | ||
22 | + fontSize: option.configOption.fontSize + 'px' | ||
23 | + }" | ||
24 | + >{{ option.configOption.dataset }}</span | ||
25 | + > | ||
15 | </n-grid-item> | 26 | </n-grid-item> |
16 | <n-grid-item> | 27 | <n-grid-item> |
17 | - <span style="position:relative" v-if="option.configOption.showRight" | ||
18 | - :style="{ top:option.configOption.yT+'px',marginLeft:option.configOption.xT+'px',color: option.configOption.textRightSizeColor, fontSize: option.configOption.textRightFontSize + 'px' }">{{ | ||
19 | - newData | ||
20 | - }}</span> | 28 | + <span |
29 | + style="position: relative" | ||
30 | + v-if="option.configOption.showRight" | ||
31 | + :style="{ | ||
32 | + top: option.configOption.yT + 'px', | ||
33 | + marginLeft: option.configOption.xT + 'px', | ||
34 | + color: option.configOption.textRightSizeColor, | ||
35 | + fontSize: option.configOption.textRightFontSize + 'px' | ||
36 | + }" | ||
37 | + >{{ newData }}</span | ||
38 | + > | ||
21 | </n-grid-item> | 39 | </n-grid-item> |
22 | </n-grid> | 40 | </n-grid> |
23 | </div> | 41 | </div> |
24 | </template> | 42 | </template> |
25 | <script setup lang="ts"> | 43 | <script setup lang="ts"> |
26 | -import {PropType, toRefs, shallowReactive, watch, onMounted, onUnmounted, ref} from 'vue' | ||
27 | -import {CreateComponentType} from '@/packages/index.d' | ||
28 | -import {useChartDataFetch} from '@/hooks' | ||
29 | -import {useChartEditStore} from '@/store/modules/chartEditStore/chartEditStore' | ||
30 | -import {option as configOption} from './config' | 44 | +import { PropType, toRefs, shallowReactive, watch, onMounted, onUnmounted, ref } from 'vue' |
45 | +import { CreateComponentType } from '@/packages/index.d' | ||
46 | +import { useChartDataFetch } from '@/hooks' | ||
47 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
48 | +import { option as configOption } from './config' | ||
31 | 49 | ||
32 | const props = defineProps({ | 50 | const props = defineProps({ |
33 | chartConfig: { | 51 | chartConfig: { |
@@ -47,42 +65,40 @@ let nowData = ref('08:00:00') | @@ -47,42 +65,40 @@ let nowData = ref('08:00:00') | ||
47 | let newData = ref('2021-2-3 08:00:00') | 65 | let newData = ref('2021-2-3 08:00:00') |
48 | 66 | ||
49 | let timer: any = null | 67 | let timer: any = null |
68 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
50 | 69 | ||
51 | //修改默认宽高 | 70 | //修改默认宽高 |
52 | -props.chartConfig.attr.w=1920 | ||
53 | -props.chartConfig.attr.h=180 | ||
54 | - | 71 | +props.chartConfig.attr.w = 1920 |
72 | +props.chartConfig.attr.h = 100 | ||
55 | 73 | ||
56 | watch( | 74 | watch( |
57 | - () => props.chartConfig.option, | ||
58 | - (newData: any) => { | ||
59 | - option.configOption = newData | ||
60 | - }, | ||
61 | - { | ||
62 | - immediate: true, | ||
63 | - deep: false | ||
64 | - } | 75 | + () => props.chartConfig.option, |
76 | + (newData: any) => { | ||
77 | + option.configOption = newData | ||
78 | + }, | ||
79 | + { | ||
80 | + immediate: true, | ||
81 | + deep: false | ||
82 | + } | ||
65 | ) | 83 | ) |
66 | 84 | ||
67 | useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | 85 | useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { |
68 | option.configOption = newData | 86 | option.configOption = newData |
69 | }) | 87 | }) |
70 | 88 | ||
71 | - | ||
72 | //TODO待封装 这里和原作者时间通用获取当前时间代码一样 | 89 | //TODO待封装 这里和原作者时间通用获取当前时间代码一样 |
73 | onMounted(() => { | 90 | onMounted(() => { |
74 | -//格式化当前时间 | 91 | + //格式化当前时间 |
75 | timer = setInterval(() => { | 92 | timer = setInterval(() => { |
76 | - const | ||
77 | - weeks = { | ||
78 | - "0": '星期日', | ||
79 | - "1": '星期一', | ||
80 | - "2": '星期二', | ||
81 | - "3": '星期三', | ||
82 | - "4": '星期四', | ||
83 | - "5": '星期五', | ||
84 | - "6": '星期六', | ||
85 | - } as any | 93 | + const weeks = { |
94 | + '0': '星期日', | ||
95 | + '1': '星期一', | ||
96 | + '2': '星期二', | ||
97 | + '3': '星期三', | ||
98 | + '4': '星期四', | ||
99 | + '5': '星期五', | ||
100 | + '6': '星期六' | ||
101 | + } as any | ||
86 | const datetime = new Date() | 102 | const datetime = new Date() |
87 | const year = datetime.getFullYear() | 103 | const year = datetime.getFullYear() |
88 | const month = datetime.getMonth() + 1 < 10 ? '0' + (datetime.getMonth() + 1) : datetime.getMonth() + 1 | 104 | const month = datetime.getMonth() + 1 < 10 ? '0' + (datetime.getMonth() + 1) : datetime.getMonth() + 1 |
@@ -90,7 +106,7 @@ onMounted(() => { | @@ -90,7 +106,7 @@ onMounted(() => { | ||
90 | const hh = datetime.getHours() // 时 | 106 | const hh = datetime.getHours() // 时 |
91 | const mm = datetime.getMinutes() // 分 | 107 | const mm = datetime.getMinutes() // 分 |
92 | const ss = datetime.getSeconds() // 分 | 108 | const ss = datetime.getSeconds() // 分 |
93 | - let weekIndex = datetime.getDay(); | 109 | + let weekIndex = datetime.getDay() |
94 | let time = '' | 110 | let time = '' |
95 | if (hh < 10) time += '0' | 111 | if (hh < 10) time += '0' |
96 | time += hh + ':' | 112 | time += hh + ':' |
@@ -106,14 +122,15 @@ onMounted(() => { | @@ -106,14 +122,15 @@ onMounted(() => { | ||
106 | onUnmounted(() => { | 122 | onUnmounted(() => { |
107 | clearInterval(timer) | 123 | clearInterval(timer) |
108 | }) | 124 | }) |
109 | - | ||
110 | </script> | 125 | </script> |
111 | 126 | ||
112 | <style lang="scss" scoped> | 127 | <style lang="scss" scoped> |
113 | @include go('text-box') { | 128 | @include go('text-box') { |
129 | + width: v-bind('w+"px"'); | ||
130 | + height: v-bind('h+"px"'); | ||
114 | display: flex; | 131 | display: flex; |
115 | - align-items: center; | ||
116 | - justify-content: center; | 132 | + align-items: start; |
133 | + justify-content: start; | ||
117 | .n-gradient-text { | 134 | .n-gradient-text { |
118 | white-space: initial; | 135 | white-space: initial; |
119 | } | 136 | } |
1 | +<template> | ||
2 | + <div class="go-content-box" :style="{ width: w + 'px', height: h + 'px' }"> | ||
3 | + <video :id="`my-player${index}`" ref="videoRef" class="video-js my-video vjs-theme-city vjs-big-play-centered"> | ||
4 | + <source :src="sourceSrc" /> | ||
5 | + </video> | ||
6 | + </div> | ||
7 | +</template> | ||
8 | +<script setup lang="ts"> | ||
9 | +import { onMounted, ref, onUnmounted, watch } from 'vue' | ||
10 | +import videojs from 'video.js' | ||
11 | +import type { VideoJsPlayerOptions } from 'video.js' | ||
12 | +import 'video.js/dist/video-js.min.css' | ||
13 | + | ||
14 | +const props = defineProps({ | ||
15 | + sourceSrc: { | ||
16 | + type: String | ||
17 | + }, | ||
18 | + w: { | ||
19 | + type: Number, | ||
20 | + default: 300 | ||
21 | + }, | ||
22 | + h: { | ||
23 | + type: Number, | ||
24 | + default: 300 | ||
25 | + }, | ||
26 | + index: { | ||
27 | + type: Number | ||
28 | + } | ||
29 | +}) | ||
30 | + | ||
31 | +// video标签 | ||
32 | +const videoRef = ref<HTMLElement | null>(null) | ||
33 | + | ||
34 | +// video实例对象 | ||
35 | +let videoPlayer: videojs.Player | null = null | ||
36 | + | ||
37 | +//options配置 | ||
38 | +const options: VideoJsPlayerOptions = { | ||
39 | + language: 'zh-CN', // 设置语言 | ||
40 | + controls: true, // 是否显示控制条 | ||
41 | + preload: 'auto', // 预加载 | ||
42 | + autoplay: true, // 是否自动播放 | ||
43 | + fluid: false, // 自适应宽高 | ||
44 | + src: props.sourceSrc, // 要嵌入的视频源的源 URL | ||
45 | + muted: true, | ||
46 | + userActions: { | ||
47 | + hotkeys: true | ||
48 | + } | ||
49 | +} | ||
50 | + | ||
51 | +// 初始化videojs | ||
52 | +const initVideo = () => { | ||
53 | + if (videoRef.value) { | ||
54 | + // 创建 video 实例 | ||
55 | + videoPlayer = videojs(videoRef.value, options) | ||
56 | + } | ||
57 | +} | ||
58 | + | ||
59 | +watch( | ||
60 | + () => props.sourceSrc, | ||
61 | + (newData: any) => { | ||
62 | + // props.sourceSrc = newData | ||
63 | + videoPlayer?.src(newData) as any | ||
64 | + videoPlayer?.play() | ||
65 | + }, | ||
66 | + { | ||
67 | + immediate: true | ||
68 | + } | ||
69 | +) | ||
70 | + | ||
71 | +onMounted(() => { | ||
72 | + initVideo() | ||
73 | +}) | ||
74 | + | ||
75 | +onUnmounted(() => { | ||
76 | + handleVideoDispose() | ||
77 | +}) | ||
78 | + | ||
79 | +//播放 | ||
80 | +const handleVideoPlay = () => videoPlayer?.play() | ||
81 | + | ||
82 | +const handleVideoDispose = () => videoPlayer?.dispose() && videoPlayer?.pause() | ||
83 | +//暂停 | ||
84 | +defineExpose({ | ||
85 | + handleVideoPlay, | ||
86 | + handleVideoDispose | ||
87 | +}) | ||
88 | +</script> | ||
89 | + | ||
90 | +<style lang="scss" scoped> | ||
91 | +.go-content-box { | ||
92 | + display: flex; | ||
93 | + align-items: center; | ||
94 | + justify-content: center; | ||
95 | + .my-video { | ||
96 | + width: 100% !important; | ||
97 | + height: 100% !important; | ||
98 | + position: relative; | ||
99 | + } | ||
100 | +} | ||
101 | +</style> |
@@ -4,7 +4,36 @@ import { CameraConfig } from './index' | @@ -4,7 +4,36 @@ import { CameraConfig } from './index' | ||
4 | import cloneDeep from 'lodash/cloneDeep' | 4 | import cloneDeep from 'lodash/cloneDeep' |
5 | 5 | ||
6 | export const option = { | 6 | export const option = { |
7 | - dataset: '' | 7 | + dataset: [ |
8 | + { | ||
9 | + url: 'https://vcsplay.scjtonline.cn:8094/live/HD_664c01b9-4b67-11eb-bf78-3cd2e55e0a36.m3u8?auth_key=1681457689-0-0-a797d264f2889a388c52ff188fedf7dc' | ||
10 | + }, | ||
11 | + { | ||
12 | + url: 'https://vcsplay.scjtonline.cn:8196/live/HD_c53fd3cb-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457668-0-0-7ef56e21fddd9ffb9740cbe499a1824c' | ||
13 | + }, | ||
14 | + { | ||
15 | + url: 'https://vcsplay.scjtonline.cn:8199/live/HD_53713154-1371-489a-a929-015cca5569fc.m3u8?auth_key=1681441451-0-0-4f1ebdcf28a71b7631c0028c099923c9' | ||
16 | + }, | ||
17 | + { | ||
18 | + url: 'https://vcsplay.scjtonline.cn:8195/live/HD_c54034ca-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457640-0-0-3a53b856ac19c09273986e8281f3d727' | ||
19 | + }, | ||
20 | + { | ||
21 | + url: 'https://vcsplay.scjtonline.cn:8094/live/HD_664c01b9-4b67-11eb-bf78-3cd2e55e0a36.m3u8?auth_key=1681457689-0-0-a797d264f2889a388c52ff188fedf7dc' | ||
22 | + }, | ||
23 | + { | ||
24 | + url: 'https://vcsplay.scjtonline.cn:8196/live/HD_c53fd3cb-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457668-0-0-7ef56e21fddd9ffb9740cbe499a1824c' | ||
25 | + }, | ||
26 | + { | ||
27 | + url: 'https://vcsplay.scjtonline.cn:8199/live/HD_53713154-1371-489a-a929-015cca5569fc.m3u8?auth_key=1681441451-0-0-4f1ebdcf28a71b7631c0028c099923c9' | ||
28 | + }, | ||
29 | + { | ||
30 | + url: 'https://vcsplay.scjtonline.cn:8195/live/HD_c54034ca-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457640-0-0-3a53b856ac19c09273986e8281f3d727' | ||
31 | + } | ||
32 | + ] as any, | ||
33 | + // 自动播放的间隔(ms) | ||
34 | + interval: 5000, | ||
35 | + autoplay: true, | ||
36 | + effect: 'slide' | ||
8 | } | 37 | } |
9 | 38 | ||
10 | export default class Config extends PublicConfigClass implements CreateComponentType { | 39 | export default class Config extends PublicConfigClass implements CreateComponentType { |
1 | <template> | 1 | <template> |
2 | - <CollapseItem name="配置" :expanded="true"> | 2 | + <CollapseItem name="播放器配置" :expanded="true"> |
3 | <setting-item-box name="源地址" :alone="true"> | 3 | <setting-item-box name="源地址" :alone="true"> |
4 | + <setting-item v-for="(item, index) in optionData.dataset" :key="index"> | ||
5 | + <n-input-group> | ||
6 | + <n-input v-model:value="item.url" size="small" placeholder="请输入源地址"></n-input> | ||
7 | + <n-button ghost @click="optionData.dataset.splice(index, 1)"> - </n-button> | ||
8 | + </n-input-group> | ||
9 | + </setting-item> | ||
4 | <setting-item> | 10 | <setting-item> |
5 | - <n-input v-model:value="optionData.dataset" size="small"></n-input> | 11 | + <n-button v-if="optionData.dataset.length < 5" size="small" @click="optionData.dataset.push({ url: '' })"> |
12 | + + | ||
13 | + </n-button> | ||
6 | </setting-item> | 14 | </setting-item> |
7 | </setting-item-box> | 15 | </setting-item-box> |
8 | </CollapseItem> | 16 | </CollapseItem> |
1 | <template> | 1 | <template> |
2 | - <div class="go-content-box" :style="{ width: w + 'px', height: h + 'px' }"> | ||
3 | - <video id="my-player" ref="videoRef" class="video-js my-video vjs-theme-city vjs-big-play-centered"> | ||
4 | - <source :src="dataset" /> | ||
5 | - </video> | 2 | + <div class="banner-box" ref="root"> |
3 | + <div class="wrapper"> | ||
4 | + <div v-for="(item, index) in option.dataset" :key="index + item" :class="item.className" :style="item.sty"> | ||
5 | + <CameraItem ref="cameraRef" :key="item + index" :sourceSrc="item.url" :w="w" :h="h" :index="index" /> | ||
6 | + </div> | ||
7 | + </div> | ||
8 | + <a href="javascript:;" class="left" @click="changeSlide('left')"></a> | ||
9 | + <a href="javascript:;" class="right" @click="changeSlide('right')"></a> | ||
6 | </div> | 10 | </div> |
7 | </template> | 11 | </template> |
8 | <script setup lang="ts"> | 12 | <script setup lang="ts"> |
9 | -import { PropType, onMounted, ref, watch, toRefs, onUnmounted } from 'vue' | 13 | +import { PropType, watch, toRefs, shallowReactive, onMounted, ref } from 'vue' |
10 | import { CreateComponentType } from '@/packages/index.d' | 14 | import { CreateComponentType } from '@/packages/index.d' |
11 | -import videojs from 'video.js' | ||
12 | -import type { VideoJsPlayerOptions } from 'video.js' | ||
13 | import 'video.js/dist/video-js.min.css' | 15 | import 'video.js/dist/video-js.min.css' |
16 | +import { option as configOption } from './config' | ||
17 | +import CameraItem from './cameraItem.vue' | ||
14 | 18 | ||
15 | const props = defineProps({ | 19 | const props = defineProps({ |
16 | chartConfig: { | 20 | chartConfig: { |
@@ -21,66 +25,165 @@ const props = defineProps({ | @@ -21,66 +25,165 @@ const props = defineProps({ | ||
21 | 25 | ||
22 | const { w, h } = toRefs(props.chartConfig.attr) | 26 | const { w, h } = toRefs(props.chartConfig.attr) |
23 | 27 | ||
24 | -const { dataset } = toRefs(props.chartConfig.option) | 28 | +const option = shallowReactive({ |
29 | + dataset: configOption.dataset | ||
30 | +}) | ||
25 | 31 | ||
26 | -// video标签 | ||
27 | -const videoRef = ref<HTMLElement | null>(null) | 32 | +const cameraRef = ref<InstanceType<typeof CameraItem>>() |
28 | 33 | ||
29 | -// video实例对象 | ||
30 | -let videoPlayer: videojs.Player | null = null | 34 | +let initial = ref(0) |
31 | 35 | ||
32 | -//options配置 | ||
33 | -const options: VideoJsPlayerOptions = { | ||
34 | - language: 'zh-CN', // 设置语言 | ||
35 | - controls: true, // 是否显示控制条 | ||
36 | - preload: 'auto', // 预加载 | ||
37 | - autoplay: true, // 是否自动播放 | ||
38 | - fluid: false, // 自适应宽高 | ||
39 | - src: dataset?.value, // 要嵌入的视频源的源 URL | ||
40 | - muted:true, | ||
41 | - userActions: { | ||
42 | - hotkeys: true | ||
43 | - } | ||
44 | -} | 36 | +let interval = ref(4000) |
45 | 37 | ||
46 | -// 初始化videojs | ||
47 | -const initVideo = () => { | ||
48 | - if (videoRef.value) { | ||
49 | - // 创建 video 实例 | ||
50 | - videoPlayer = videojs(videoRef.value, options) | ||
51 | - } | 38 | +const computedFunc = (initial: number, source: any) => { |
39 | + if (initial < 0) initial = 0 | ||
40 | + let len = source.length, | ||
41 | + temp1 = initial - 2 < 0 ? initial - 2 + len : initial - 2, | ||
42 | + temp2 = initial - 1 < 0 ? initial - 1 + len : initial - 1, | ||
43 | + temp3 = initial, | ||
44 | + temp4 = initial + 1 >= len ? initial + 1 - len : initial + 1, | ||
45 | + temp5 = initial + 2 >= len ? initial + 2 - len : initial + 2 | ||
46 | + return source.map((item: any, index: number) => { | ||
47 | + let transform = `translate(-50%, -50%) scale(0.7)`, | ||
48 | + zIndex = 0, | ||
49 | + className = 'slide' | ||
50 | + switch (index) { | ||
51 | + case temp3: | ||
52 | + transform = `translate(-50%, -50%) scale(1)` | ||
53 | + className = ['slide', 'activate'] as any | ||
54 | + zIndex = 3 | ||
55 | + break | ||
56 | + case temp1: | ||
57 | + transform = `translate(-80%, -50%) scale(0.7)` | ||
58 | + zIndex = 1 | ||
59 | + break | ||
60 | + case temp5: | ||
61 | + transform = `translate(100%, -50%) scale(0.7)` | ||
62 | + zIndex = 1 | ||
63 | + break | ||
64 | + case temp2: | ||
65 | + transform = `translate(-100%, -50%) scale(0.85)` | ||
66 | + zIndex = 2 | ||
67 | + break | ||
68 | + case temp4: | ||
69 | + transform = `translate(58%, -50%) scale(0.85)` | ||
70 | + zIndex = 2 | ||
71 | + break | ||
72 | + } | ||
73 | + item.sty = { | ||
74 | + transform, | ||
75 | + zIndex | ||
76 | + } | ||
77 | + item.className = className | ||
78 | + return item | ||
79 | + }) | ||
52 | } | 80 | } |
53 | 81 | ||
54 | -onMounted(() => { | ||
55 | - initVideo() | ||
56 | -}) | ||
57 | - | ||
58 | -onUnmounted(() => { | ||
59 | - videoPlayer?.dispose() | ||
60 | -}) | ||
61 | - | ||
62 | watch( | 82 | watch( |
63 | () => props.chartConfig.option.dataset, | 83 | () => props.chartConfig.option.dataset, |
64 | newData => { | 84 | newData => { |
65 | - props.chartConfig.option.dataset = newData | ||
66 | - videoPlayer?.src(newData) | ||
67 | - videoPlayer?.play() | 85 | + option.dataset = newData |
86 | + console.log(option.dataset) | ||
68 | }, | 87 | }, |
69 | { | 88 | { |
70 | - immediate: true | 89 | + immediate: true, |
90 | + deep: true | ||
71 | } | 91 | } |
72 | ) | 92 | ) |
93 | +option.dataset = computedFunc(initial.value, option.dataset) | ||
94 | + | ||
95 | +watch( | ||
96 | + () => initial.value, | ||
97 | + newV => { | ||
98 | + option.dataset = computedFunc(newV, option.dataset) | ||
99 | + } | ||
100 | +) | ||
101 | +// 处理自动轮播 | ||
102 | +let timer: any = null | ||
103 | + | ||
104 | +const autoPlay = () => { | ||
105 | + timer = setInterval(() => { | ||
106 | + initial.value++ | ||
107 | + if (initial.value >= option.dataset.length) { | ||
108 | + initial.value = 0 | ||
109 | + } | ||
110 | + }, interval.value) | ||
111 | +} | ||
112 | + | ||
113 | +// 鼠标移入移除效果 | ||
114 | +let root = ref(null) | ||
115 | + | ||
116 | +onMounted(() => { | ||
117 | + clearInterval(timer) | ||
118 | + autoPlay() | ||
119 | + const box: any = root.value | ||
120 | + box.onmouseenter = () => clearInterval(timer) | ||
121 | + box.onmouseleave = () => autoPlay() | ||
122 | +}) | ||
123 | + | ||
124 | +// 点击左右按钮切换图片 | ||
125 | +function changeVideo(dir: string) { | ||
126 | + if (dir === 'left') { | ||
127 | + // cameraRef.value?.handleVideoPlay() | ||
128 | + clearInterval(timer) | ||
129 | + initial.value++ | ||
130 | + initial.value >= option.dataset.length ? (initial.value = 0) : false | ||
131 | + return | ||
132 | + } | ||
133 | + // cameraRef.value?.handleVideoDispose() | ||
134 | + initial.value-- | ||
135 | + initial.value < 0 ? (initial.value = option.dataset.length - 1) : false | ||
136 | +} | ||
137 | + | ||
138 | +// 左右切换图片设置防抖效果 | ||
139 | +function changeSlide(dir: string) { | ||
140 | + changeVideo(dir) | ||
141 | +} | ||
73 | </script> | 142 | </script> |
74 | 143 | ||
75 | <style lang="scss" scoped> | 144 | <style lang="scss" scoped> |
76 | -.go-content-box { | ||
77 | - display: flex; | ||
78 | - align-items: center; | ||
79 | - justify-content: center; | ||
80 | - .my-video { | ||
81 | - width: 100% !important; | ||
82 | - height: 100% !important; | 145 | +.banner-box { |
146 | + width: 100%; | ||
147 | + height: 100%; | ||
148 | + // position: absolute; | ||
149 | + top: 50%; | ||
150 | + left: 50%; | ||
151 | + transform: translate(-50%, -50%); | ||
152 | + .wrapper { | ||
153 | + width: 100%; | ||
154 | + height: 100%; | ||
83 | position: relative; | 155 | position: relative; |
156 | + .slide { | ||
157 | + width: 20%; | ||
158 | + height: 100%; | ||
159 | + position: absolute; | ||
160 | + top: 50%; | ||
161 | + left: 10%; | ||
162 | + transform: translate(-50%, -50%); | ||
163 | + transition: 0.5s; | ||
164 | + box-shadow: 0 0 4px black; | ||
165 | + } | ||
166 | + } | ||
167 | + .arrow { | ||
168 | + position: absolute; | ||
169 | + top: 50%; | ||
170 | + transform: translateY(-50%); | ||
171 | + z-index: 9; | ||
172 | + width: 50px; | ||
173 | + height: 50px; | ||
174 | + background-size: contain; | ||
175 | + background-color: white; | ||
176 | + opacity: 0.5; | ||
177 | + } | ||
178 | + a.left { | ||
179 | + @extend .arrow; | ||
180 | + background-image: url(./left.svg); | ||
181 | + left: 0px; | ||
182 | + } | ||
183 | + a.right { | ||
184 | + @extend .arrow; | ||
185 | + background-image: url(./right.svg); | ||
186 | + right: 0px; | ||
84 | } | 187 | } |
85 | } | 188 | } |
86 | </style> | 189 | </style> |
1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g fill="none"><path d="M10.26 3.2a.75.75 0 0 1 .04 1.06L6.773 8l3.527 3.74a.75.75 0 1 1-1.1 1.02l-4-4.25a.75.75 0 0 1 0-1.02l4-4.25a.75.75 0 0 1 1.06-.04z" fill="currentColor"></path></g></svg> |
1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g fill="none"><path d="M5.74 3.2a.75.75 0 0 0-.04 1.06L9.227 8L5.7 11.74a.75.75 0 1 0 1.1 1.02l4-4.25a.75.75 0 0 0 0-1.02l-4-4.25a.75.75 0 0 0-1.06-.04z" fill="currentColor"></path></g></svg> |
@@ -208,8 +208,16 @@ defineExpose({ | @@ -208,8 +208,16 @@ defineExpose({ | ||
208 | :disabled="true" /> | 208 | :disabled="true" /> |
209 | 209 | ||
210 | </SettingItemBox> | 210 | </SettingItemBox> |
211 | - | ||
212 | - <SettingItemBox v-if="requestContentTypeRef === RequestContentTypeEnum.WEB_SOCKET"> | 211 | + <!-- |
212 | + /** | ||
213 | + * ft 修改 | ||
214 | + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯 | ||
215 | + * 源代码 无 | ||
216 | + * 修改后代码 新增一句:item-right-style="{ gridTemplateColumns: '7fr 1fr' }" | ||
217 | + * 优化普通和websocket表格长度不一样样式问题 | ||
218 | + */ | ||
219 | + --> | ||
220 | + <SettingItemBox v-if="requestContentTypeRef === RequestContentTypeEnum.WEB_SOCKET" :item-right-style="{ gridTemplateColumns: '7fr 1fr' }"> | ||
213 | <NCard v-if="requestParamsTypeRef === RequestParamsTypeEnum.PARAMS" class="dynamic-form"> | 221 | <NCard v-if="requestParamsTypeRef === RequestParamsTypeEnum.PARAMS" class="dynamic-form"> |
214 | <NScrollbar style="max-height: 400px; box-sizing: border-box;"> | 222 | <NScrollbar style="max-height: 400px; box-sizing: border-box;"> |
215 | <DynamicForm ref="socketDynamicFormEl" :paramsItemList="getSelectedInterfaceParams" /> | 223 | <DynamicForm ref="socketDynamicFormEl" :paramsItemList="getSelectedInterfaceParams" /> |