| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <script setup lang="ts">
- import { ref } from 'vue'
- import { startPTZ, stopPTZ, type PTZConfig } from '@/api/ptz'
- const props = withDefaults(
- defineProps<{
- /** 摄像头配置 */
- config?: PTZConfig
- }>(),
- {
- config: () => ({
- host: '192.168.0.64',
- username: 'admin',
- password: 'Wxc767718929',
- channel: 1
- })
- }
- )
- const isMoving = ref(false)
- const currentDirection = ref<string | null>(null)
- // 开始移动
- async function handleStart(
- direction: 'UP' | 'DOWN' | 'LEFT' | 'RIGHT' | 'UP_LEFT' | 'UP_RIGHT' | 'DOWN_LEFT' | 'DOWN_RIGHT'
- ) {
- if (isMoving.value) return
- isMoving.value = true
- currentDirection.value = direction
- const result = await startPTZ(props.config, direction)
- if (!result.success) {
- console.error('PTZ 控制失败:', result.error)
- }
- }
- // 停止移动
- async function handleStop() {
- if (!isMoving.value) return
- const result = await stopPTZ(props.config)
- if (!result.success) {
- console.error('PTZ 停止失败:', result.error)
- }
- isMoving.value = false
- currentDirection.value = null
- }
- </script>
- <template>
- <div class="ptz-controller">
- <div class="ptz-grid">
- <!-- 第一行 -->
- <button class="ptz-btn corner" @mousedown="handleStart('UP_LEFT')" @mouseup="handleStop" @mouseleave="handleStop">
- <el-icon><i-ep-top-left /></el-icon>
- </button>
- <button class="ptz-btn" @mousedown="handleStart('UP')" @mouseup="handleStop" @mouseleave="handleStop">
- <el-icon><i-ep-arrow-up /></el-icon>
- </button>
- <button
- class="ptz-btn corner"
- @mousedown="handleStart('UP_RIGHT')"
- @mouseup="handleStop"
- @mouseleave="handleStop"
- >
- <el-icon><i-ep-top-right /></el-icon>
- </button>
- <!-- 第二行 -->
- <button class="ptz-btn" @mousedown="handleStart('LEFT')" @mouseup="handleStop" @mouseleave="handleStop">
- <el-icon><i-ep-arrow-left /></el-icon>
- </button>
- <div class="ptz-center">
- <el-icon v-if="isMoving" class="spinning"><i-ep-loading /></el-icon>
- <span v-else>PTZ</span>
- </div>
- <button class="ptz-btn" @mousedown="handleStart('RIGHT')" @mouseup="handleStop" @mouseleave="handleStop">
- <el-icon><i-ep-arrow-right /></el-icon>
- </button>
- <!-- 第三行 -->
- <button
- class="ptz-btn corner"
- @mousedown="handleStart('DOWN_LEFT')"
- @mouseup="handleStop"
- @mouseleave="handleStop"
- >
- <el-icon><i-ep-bottom-left /></el-icon>
- </button>
- <button class="ptz-btn" @mousedown="handleStart('DOWN')" @mouseup="handleStop" @mouseleave="handleStop">
- <el-icon><i-ep-arrow-down /></el-icon>
- </button>
- <button
- class="ptz-btn corner"
- @mousedown="handleStart('DOWN_RIGHT')"
- @mouseup="handleStop"
- @mouseleave="handleStop"
- >
- <el-icon><i-ep-bottom-right /></el-icon>
- </button>
- </div>
- </div>
- </template>
- <style scoped lang="scss">
- .ptz-controller {
- display: inline-block;
- }
- .ptz-grid {
- display: grid;
- grid-template-columns: repeat(3, 48px);
- gap: 4px;
- }
- .ptz-btn {
- width: 48px;
- height: 48px;
- border: 1px solid var(--el-border-color);
- border-radius: var(--radius-base);
- background: var(--el-bg-color);
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 20px;
- color: var(--el-text-color-primary);
- transition: all 0.2s;
- &:hover {
- background: var(--el-color-primary-light-9);
- border-color: var(--el-color-primary);
- }
- &:active {
- background: var(--el-color-primary-light-7);
- }
- &.corner {
- font-size: 16px;
- }
- }
- .ptz-center {
- width: 48px;
- height: 48px;
- border-radius: 50%;
- background: var(--el-color-primary-light-9);
- border: 2px solid var(--el-color-primary);
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 12px;
- font-weight: bold;
- color: var(--el-color-primary);
- }
- .spinning {
- animation: spin 1s linear infinite;
- }
- @keyframes spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
- }
- </style>
|