on-site-robots-screen/src/views/home/components/control-deck.vue

377 lines
10 KiB
Vue

<template>
<!-- 机器人操控面板 -->
<div class="control-deck child-container">
<!-- 第一行 -->
<n-grid :cols="10">
<n-grid-item :span="4">
<div class="row-1-item">摄像头</div>
</n-grid-item>
<n-grid-item :span="3">
<div class="row-1-item">升降杆</div>
</n-grid-item>
<n-grid-item :span="3">
<div class="row-1-item">底盘</div>
</n-grid-item>
</n-grid>
<!-- 第二行 -->
<n-grid :cols="10">
<n-grid-item :span="4">
<div class="row-2-item">
<div>速度</div>
<div>30</div>
</div>
</n-grid-item>
<n-grid-item :span="3">
<div class="row-2-item">
<div>高度</div>
<div>
{{ currentHeight }}
</div>
</div>
</n-grid-item>
<n-grid-item :span="3">
<div class="row-2-item">
<div>速度</div>
<div>30</div>
</div>
</n-grid-item>
</n-grid>
<!-- 第三行 -->
<n-grid :cols="10">
<n-grid-item :span="4">
<div class="row-3-item-1">
<!-- 上下左右控制按钮 -->
<img class="arrow-top" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<img class="arrow-right" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<img class="arrow-bottom" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<img class="arrow-left" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<!-- 中间的按钮 -->
<div class="row-3-item-1-center">
<img
class="center-icon"
src="@/assets/home-imgs/control-2-stop.png"
alt=""
/>
</div>
<!-- 描述文字 -->
<div class="text-top description-text">正前</div>
<div class="text-bottom description-text">正后</div>
<div class="text-left description-text">正左</div>
<div class="text-right description-text">正右</div>
<!-- 增加减少按钮 -->
<div class="add-reduce-btn">
<span>缩放</span>
<img
style="margin-bottom: 2px"
src="@/assets/home-imgs/control-2-add.png"
alt=""
/>
<img src="@/assets/home-imgs/control-2-reduce.png" alt="" />
</div>
</div>
</n-grid-item>
<n-grid-item :span="3">
<div class="row-3-item-2" ref="container">
<!-- 上下滑动调节 -->
<span
class="up-down-box"
ref="draggable"
@mousedown="startDrag"
:style="{ top: currentTop + 'px' }"
/>
</div>
</n-grid-item>
<n-grid-item :span="3">
<div class="row-3-item-3">
<!-- 上下左右控制按钮 -->
<img class="arrow-top" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<img class="arrow-right" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<img class="arrow-bottom" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<img class="arrow-left" src="@/assets/home-imgs/control-2-arrow.png" alt="" />
<div class="row-3-item-1-center">
<img
class="center-icon"
src="@/assets/home-imgs/control-2-start.png"
alt=""
/>
</div>
</div>
</n-grid-item>
</n-grid>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const upDownHeight = ref(30)
const container = ref(null)
const draggable = ref(null)
const isDragging = ref(false)
const currentTop = ref(0)
const startY = ref(0)
const startTop = ref(0)
// 计算当前高度百分比(0-100)
const currentHeight = computed(() => {
if (!container.value) return 0
const containerHeight = container.value.offsetHeight
const draggableHeight = draggable.value?.offsetHeight || 0
const maxTop = containerHeight - draggableHeight - 20 // 20是底部初始偏移
// 计算百分比 (0-100)
return Math.round(100 - (currentTop.value / maxTop) * 100)
})
const startDrag = (e) => {
isDragging.value = true
startY.value = e.clientY
startTop.value = currentTop.value
document.addEventListener('mousemove', onDrag)
document.addEventListener('mouseup', stopDrag)
}
const onDrag = (e) => {
if (!isDragging.value) return
const deltaY = e.clientY - startY.value
let newTop = startTop.value + deltaY
const containerHeight = container.value.offsetHeight
const draggableHeight = draggable.value.offsetHeight
const maxTop = containerHeight - draggableHeight - 20
newTop = Math.max(0, Math.min(newTop, maxTop))
currentTop.value = newTop
}
const stopDrag = () => {
isDragging.value = false
document.removeEventListener('mousemove', onDrag)
document.removeEventListener('mouseup', stopDrag)
// 拖动结束时可以在这里使用currentHeight.value
console.log('当前高度:', currentHeight.value)
}
onMounted(() => {
const containerHeight = container.value.offsetHeight
const draggableHeight = draggable.value.offsetHeight
const maxTop = containerHeight - draggableHeight - 20
currentTop.value = maxTop * (1 - upDownHeight.value / 100)
})
</script>
<style lang="scss" scoped>
.row-1-item,
.row-2-item {
width: 100px;
margin: 0 auto;
}
.row-1-item {
height: 28px;
background: url('@/assets/home-imgs/control-1-bg.png') no-repeat center center;
background-size: 100% 100%;
line-height: 28px;
text-align: center;
}
.row-2-item {
margin-top: 6px;
display: flex;
align-items: center;
justify-content: space-around;
& div:last-child {
width: 32px;
height: 18px;
background-color: #005899;
border-radius: 6px;
font-size: 12px;
text-align: center;
line-height: 18px;
}
}
.row-3-item-1,
.row-3-item-3 {
width: 90px;
height: 90px;
margin: 40px auto 0;
position: relative;
background: url('@/assets/home-imgs/control-2-round.png') no-repeat center center;
background-size: 100% 100%;
> img {
width: 18px;
height: 20px;
cursor: pointer;
object-fit: contain;
}
.arrow-top {
position: absolute;
top: 6px;
left: 50%;
transform: translateX(-50%) rotate(-90deg);
}
.arrow-right {
position: absolute;
top: 50%;
right: 8px;
transform: translateY(-50%);
}
.arrow-bottom {
position: absolute;
bottom: 6px;
left: 50%;
transform: translateX(-50%) rotate(90deg);
}
.arrow-left {
position: absolute;
top: 50%;
left: 8px;
transform: translateY(-50%) rotate(-180deg);
}
.row-3-item-1-center {
width: 18px;
height: 18px;
position: absolute;
top: 50%;
left: 50%;
display: flex;
align-items: center;
justify-content: center;
transform: translate(-50%, -50%) rotate(45deg);
border: 2px solid #7fc0ff;
border-radius: 4px;
background-color: #2f78bf;
cursor: pointer;
> img {
width: 9px;
height: 9px;
object-fit: contain;
transform: rotate(-45deg);
}
}
// 描述文字
.description-text {
position: absolute;
font-size: 12px;
}
.text-top {
left: 50%;
top: -28px;
transform: translateX(-50%);
}
.text-bottom {
left: 50%;
bottom: -28px;
transform: translateX(-50%);
}
.text-top,
.text-bottom {
width: 36px;
height: 22px;
border: 1px solid #7fc0ff;
border-radius: 4px;
text-align: center;
line-height: 22px;
}
.text-left {
left: -28px;
top: 50%;
transform: translateY(-50%);
}
.text-right {
right: -28px;
top: 50%;
transform: translateY(-50%);
}
.text-left,
.text-right {
height: 36px;
width: 22px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #7fc0ff;
border-radius: 4px;
// 使文字竖向展示 并垂直居中
writing-mode: vertical-rl;
text-orientation: upright;
}
.add-reduce-btn {
position: absolute;
right: -58px;
top: -16px;
// height: 100px;
width: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
span {
font-size: 13px;
width: 30px;
text-align: center;
color: #7fc0ff;
}
img {
width: 20px;
height: 50px;
object-fit: contain;
cursor: pointer;
}
}
}
.row-3-item-3 {
width: 120px;
height: 120px;
margin: 32px auto 0 !important;
> img {
width: 24px;
height: 26px;
cursor: pointer;
object-fit: contain;
}
}
.row-3-item-2 {
width: 60px;
height: 120px;
margin: 32px auto 0 !important;
background: url('@/assets/home-imgs/control-2-up-down.png') no-repeat center center;
background-size: 100% 100%;
position: relative;
user-select: none;
.up-down-box {
position: absolute;
left: 50%;
width: 30px;
height: 10px;
background: url('@/assets/home-imgs/control-2-up-down-hand.png') no-repeat center center;
background-size: 100% 100%;
transform: translateX(-50%);
cursor: pointer;
touch-action: none;
}
}
</style>