|
|
@@ -0,0 +1,335 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ ref="joystickRef"
|
|
|
+ :class="[
|
|
|
+ 'joystick absolute bottom-0 right-0 origin-bottom-right transition-all',
|
|
|
+ planShow ? 'w-[300px]' : 'w-0'
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ <div class="joystick-openorclose absolute left--40px bottom-0" @click="showSwitch">
|
|
|
+ <Icon
|
|
|
+ icon="mingcute:left-fill"
|
|
|
+ color="#409fff"
|
|
|
+ width="40"
|
|
|
+ height="40"
|
|
|
+ :class="['cursor-pointer transition-all', planShow ? 'rotate-180' : 'rotate-0']"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="flex">
|
|
|
+ <div class="joystick-wrapper">
|
|
|
+ <div class="buttons grid grid-cols-3 grid-rows-3 gap-1 w-38 h-38">
|
|
|
+ <div
|
|
|
+ class="direction-button bg-#093f9d75 b-0 overflow-hidden p-2 transition duration-200 ease-in-out active:bg-blue-500 focus:outline-none"
|
|
|
+ v-for="direction in directions"
|
|
|
+ :style="{
|
|
|
+ backgroundColor: direction === 'hr' && isHR ? 'rgb(59 130 246)' : ''
|
|
|
+ }"
|
|
|
+ :key="direction"
|
|
|
+ v-on:[downEvent].stop="setPZTmove(direction, 'down')"
|
|
|
+ v-on:[upEvent].stop="setPZTmove(direction, 'up')"
|
|
|
+ >
|
|
|
+ <img class="w-full" :src="getStaticResource(`assets/images/${direction}.png`).href" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="slider-box flex-1 ml-1 w-140px">
|
|
|
+ <div class="slider-box-control h-full grid grid-cols-1 grid-rows-3 gap-1">
|
|
|
+ <div
|
|
|
+ class="h-full text-20px line-height-45px text-center bg-#093f9d75 flex flex-justify-around flex-items-center"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ src="@/assets/images/fd.png"
|
|
|
+ class="w-28px transition duration-200 ease-in-out active:bg-blue-500 focus:outline-none"
|
|
|
+ alt=""
|
|
|
+ v-on:[downEvent]="setPZTmove('fd', 'down')"
|
|
|
+ v-on:[upEvent]="setPZTmove('fd', 'up')"
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src="@/assets/images/sx.png"
|
|
|
+ class="w-28px transition duration-200 ease-in-out active:bg-blue-500 focus:outline-none"
|
|
|
+ alt=""
|
|
|
+ v-on:[downEvent]="setPZTmove('sx', 'down')"
|
|
|
+ v-on:[upEvent]="setPZTmove('sx', 'up')"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="h-full text-20px line-height-45px text-center bg-#093f9d75">
|
|
|
+ <!-- <img
|
|
|
+ src="@/assets/images/jia.png"
|
|
|
+ class="w-32px transition duration-200 ease-in-out active:bg-blue-500 focus:outline-none"
|
|
|
+ alt=""
|
|
|
+ v-on:[downEvent]="setPZTmove('jia', 'down')"
|
|
|
+ v-on:[upEvent]="setPZTmove('jia', 'up')"
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src="@/assets/images/jian.png"
|
|
|
+ class="w-32px transition duration-200 ease-in-out active:bg-blue-500 focus:outline-none"
|
|
|
+ alt=""
|
|
|
+ v-on:[downEvent]="setPZTmove('jian', 'down')"
|
|
|
+ v-on:[upEvent]="setPZTmove('jian', 'up')"
|
|
|
+ /> -->
|
|
|
+ <ul class="h-full flex flex-justify-around flex-items-center">
|
|
|
+ <li
|
|
|
+ v-for="item in listComputed"
|
|
|
+ :key="item.iCom"
|
|
|
+ @click.stop="toolsHandler(item.type)"
|
|
|
+ >
|
|
|
+ <Icon
|
|
|
+ :class="[item.class]"
|
|
|
+ :icon="item.iCom"
|
|
|
+ :color="item.color"
|
|
|
+ :width="item.w"
|
|
|
+ :height="item.h"
|
|
|
+ :style="{ marginBottom: item.type === 'lx' ? '-5px' : '' }"
|
|
|
+ />
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ <div class="px-4 place-content-center flex flex-col flex-items-center bg-#093f9d75">
|
|
|
+ <n-slider
|
|
|
+ v-model:value="sliderValue"
|
|
|
+ style="
|
|
|
+ --n-fill-color: #093f9d;
|
|
|
+ --n-fill-color-hover: #093f9d;
|
|
|
+ --n-rail-color: #093f9d;
|
|
|
+ --n-rail-color-hover: #093f9d;
|
|
|
+ --n-handle-color: #8ac5ff;
|
|
|
+ "
|
|
|
+ :min="1"
|
|
|
+ :max="7"
|
|
|
+ :tooltip="false"
|
|
|
+ />
|
|
|
+ <div class="text-12px color-#8ac5ff text-nowrap">
|
|
|
+ 步长 <span>{{ sliderValue }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+ import { NSlider } from 'naive-ui'
|
|
|
+ import { getStaticResource } from '@/utils'
|
|
|
+
|
|
|
+ const { API_PTZ_MOVE_START_POST, API_PTZ_MOVE_STOP_POST, API_LY_B_RELOGIN_POST } = useRequest()
|
|
|
+ const directions = ['lt', 't', 'tr', 'l', 'hr', 'r', 'lb', 'b', 'br']
|
|
|
+ const sliderValue = ref(7)
|
|
|
+
|
|
|
+ const downEvent = 'mousedown'
|
|
|
+ const upEvent = 'mouseup'
|
|
|
+
|
|
|
+ const planShow = ref(false)
|
|
|
+ const props = defineProps({
|
|
|
+ id: String
|
|
|
+ })
|
|
|
+ // 球机重连
|
|
|
+ const reconnect = (err, data, api) => {
|
|
|
+ if ([7].includes(err.code)) {
|
|
|
+ // dialogFn(
|
|
|
+ // 'warning',
|
|
|
+ // '警告',
|
|
|
+ // '球机网络故障,请检查网络后重连设备!',
|
|
|
+ // async () => {
|
|
|
+ // const res = await API_LY_B_RELOGIN_POST()
|
|
|
+ // reconnect(res)
|
|
|
+ // },
|
|
|
+ // () => {},
|
|
|
+ // '重连',
|
|
|
+ // '取消'
|
|
|
+ // )
|
|
|
+ } else {
|
|
|
+ api(data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const isHR = ref(false)
|
|
|
+ const setPZTmove = (direction, isKey) => {
|
|
|
+ let data = { id: 0 }
|
|
|
+ let isDownOrUp = 'down'
|
|
|
+ switch (direction) {
|
|
|
+ case 't':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 3 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 3 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'tr':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 6 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 6 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'r':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 2 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 2 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'br':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 8 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 8 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'b':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 4 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 4 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'lb':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 7 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 7 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'l':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 1 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 1 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'hr':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ isHR.value = !isHR.value
|
|
|
+ if (isHR.value) {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 1 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 1 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'lt':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 5 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 5 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'fd':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 9 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 9 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'sx':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 10 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 10 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'jia':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 11 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 11 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'jian':
|
|
|
+ if (isKey === 'down') {
|
|
|
+ Object.assign(data, { speed: sliderValue.value, direction: 12 })
|
|
|
+ isDownOrUp = 'down'
|
|
|
+ } else {
|
|
|
+ Object.assign(data, { direction: 12 })
|
|
|
+ isDownOrUp = 'up'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if (!data.direction) return
|
|
|
+ if (isDownOrUp === 'down') {
|
|
|
+ API_PTZ_MOVE_START_POST({ CameraId: props.id }, data)
|
|
|
+ } else {
|
|
|
+ API_PTZ_MOVE_STOP_POST({ CameraId: props.id }, data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const showSwitch = () => {
|
|
|
+ planShow.value = !planShow.value
|
|
|
+ }
|
|
|
+
|
|
|
+ const playerObj = inject('playerObj')
|
|
|
+
|
|
|
+ const tools = ref([
|
|
|
+ {
|
|
|
+ iCom: 'iconoir:screenshot',
|
|
|
+ label: '截图',
|
|
|
+ color: '#8ac5ff',
|
|
|
+ type: 'jt',
|
|
|
+ w: 25,
|
|
|
+ h: 25
|
|
|
+ },
|
|
|
+ {
|
|
|
+ iCom: 'uil:video',
|
|
|
+ label: '录像',
|
|
|
+ type: 'lx',
|
|
|
+ color: '#8ac5ff',
|
|
|
+ class: '',
|
|
|
+ w: 30,
|
|
|
+ h: 30
|
|
|
+ }
|
|
|
+ ])
|
|
|
+ const state = ref(false)
|
|
|
+ const toolsHandler = (type) => {
|
|
|
+ switch (type) {
|
|
|
+ case 'lx':
|
|
|
+ // switchState()
|
|
|
+ state.value = !state.value
|
|
|
+ playerObj.value.recording(state.value)
|
|
|
+ break
|
|
|
+ case 'jt':
|
|
|
+ playerObj.value.screenshot()
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const listComputed = computed(() => {
|
|
|
+ return tools.value.map((item) => {
|
|
|
+ if (item.type === 'lx') {
|
|
|
+ if (state.value) {
|
|
|
+ item.iCom = 'fad:armrecording'
|
|
|
+ item.color = 'red'
|
|
|
+ item.class = 'showhide-anim'
|
|
|
+ } else {
|
|
|
+ item.iCom = 'uil:video'
|
|
|
+ item.color = '#8ac5ff'
|
|
|
+ item.class = ''
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ })
|
|
|
+</script>
|