From 76eb78c9874ddb6b4153341dce021bc5195426ba Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Sat, 19 Apr 2025 09:55:16 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/drone/command-center-dashboard

---
 src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue |  560 +++++++++++++++++++------------------------------------
 1 files changed, 193 insertions(+), 367 deletions(-)

diff --git a/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
index 5685ca1..5371249 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
@@ -1,392 +1,218 @@
 <template>
-  <div class="instrument-content">
-    <div class="left-img" :data-text="`${attitude_pitch}°`">
-      <div class="scaleImg">
-        <p class="scale" :style="{ top: 45 + ScaleTop + 'px' }"></p>
-        <img src="../../../../assets/images/rightmapidentification.png" />
-      </div>
-    </div>
-    <div class="instrument-center">
-      <div class="compass-box" :data-text="`${prevRotate?.toFixed(2)}°`">
-        <div v-for="(item, index) in str" :key="index" class="scale"
-          :style="{ '--rotate': 30 * index - prevRotate + 'deg' }">
-          <span class="text">{{ item }}</span>
-        </div>
-      </div>
-      <div class="center-show">
-        <img src="../../../../assets/images/mapidentification.png" />
-      </div>
-      <div class="rotat-btn"></div>
-    </div>
-    <div class="right-img" :data-text="`${height}m`">
-      <div class="ident-arrow">
-        <img src="../../../../assets/images/leftmapidentification.png" />
-        <div class="arrow-box" :style="{ bottom: realHeight }">
-          <div class="arrow"></div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-<script>
-import _ from 'lodash';
-export default {
-  data () {
-    return {
-      str: ['W', 30, 33, 'N', 3, 6, 'E', 12, 15, 'S', 21, 24],
-      // 俯仰角度数
-      attitude_pitch: 0,
-      // 真空高度
-      height: 0,
-      // 旋转方向角度
-      prevRotate: 0,
-      dockHeight: 0,
-    }
-  },
-  watch: {
-    roamPoint: {
-      handler (val) {
-        // this.prevRotate = val.arrowHeading
-        // this.attitude_pitch = val.roll
-        // this.height = _.round(val.altitude,1)
-      },
-    },
-  },
-  computed: {
-    // roamPoint: vuexStateSimplify('pointsWayLine', 'roamPoint'),
-    ScaleTop () {
-      return (-this.attitude_pitch * 30) / 90
-    },
-    realHeight () {
-			return 0
-      // 无人机高度
-      const maxHeight = 240
-      // 真空高度
-      const vacuumHeight = 120
-      // 机场高度
-      const dockHeightConfig = {
-        'e3dea0f5-37f2-4d79-ae58-490af3228069': 14.7,
-        '4a574db8-4ad3-48f7-9f16-3edbcd8056e1': 54,
-        // 'f47ac10b-58cc-4372-a567-0e02b2c3d479': 81,
-      }
-      const workspaceId =
-        this.$store.state.drone.selectedWorkSpaceId ||
-        window.localStorage.getItem('bs_workspace_id')
-      const dockHeight = dockHeightConfig?.[workspaceId] || 1
+	<div class="instrument-content">
+		<div class="left-img">
+			<div class="valueBox">{{ props?.options?.pitchAngle || 0 }}°</div>
+			<img src="@/assets/images/rightmapidentification.png" alt="" />
+			<div class="triangle" :style="pitchAngleStyle"></div>
+			<div class="nameBox">俯仰角度</div>
+		</div>
 
-      let proportion = 0
-      // 处于真空高度和最大高度之间
-      if (this.height < maxHeight && this.height >= vacuumHeight) {
-        const height = this.height - vacuumHeight
-        const proport = height / maxHeight
-        proportion = Math.round(proport * 50 + 50)
-      }
-      // 小于等于真空高度计算
-      if (this.height < vacuumHeight && this.height >= dockHeight) {
-        const height = this.height - dockHeight
-        const copyVacuumHeight = vacuumHeight - dockHeight
-        const proport = height / copyVacuumHeight
-        proportion = Math.round(proport * 25 + 25)
-      }
-      // 小于机场高度计算
-      if (this.height < dockHeight && this.height >= 0) {
-        const proport = this.height / dockHeight
-        proportion = Math.round(proport * 25)
-      }
-      // 大于最大高度计算
-      if (this.height >= maxHeight) {
-        proportion = 95
-      }
-      return proportion + '%'
-      // const proportion = Math.ceil((this.height / maxHeight) * 100) || 50;
-    },
-  },
-  methods: {
-    getAngle (currentLngLat, targetLngLat) {
-      const { longitude: lng_a, latitude: lat_a } = currentLngLat
-      const { longitude: lng_b, latitude: lat_b } = targetLngLat
-      var a = ((90 - lat_b) * Math.PI) / 180
-      var b = ((90 - lat_a) * Math.PI) / 180
-      var AOC_BOC = ((lng_b - lng_a) * Math.PI) / 180
-      var cosc =
-        Math.cos(a) * Math.cos(b) +
-        Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC)
-      var sinc = Math.sqrt(1 - cosc * cosc)
-      var sinA = (Math.sin(a) * Math.sin(AOC_BOC)) / sinc
-      var A = (Math.asin(sinA) * 180) / Math.PI
-      var res = 0
-      if (lng_b > lng_a && lat_b > lat_a) res = A
-      else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A
-      else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A
-      else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A
-      else if (lng_b > lng_a && lat_b == lat_a) res = 90
-      else if (lng_b < lng_a && lat_b == lat_a) res = 270
-      else if (lng_b == lng_a && lat_b > lat_a) res = 0
-      else if (lng_b == lng_a && lat_b < lat_a) res = 180
-      return res
-    },
-  },
-}
+		<div class="instrument-center">
+			<div class="compass-box" :style="{ transform: `rotate(${props?.options?.yawAngle || 0}deg)` }">
+				<div v-for="(item, index) in str" :key="index" class="scale" :style="{ '--rotate': 30 * index + 'deg' }">
+					<span class="text">{{ item }}</span>
+				</div>
+			</div>
+			<div class="center-show">
+				<img src="@/assets/images/mapidentification.png" alt="" />
+			</div>
+		</div>
+
+		<div class="right-img">
+			<div class="valueBox">{{ props.options?.trueAltitude }}m</div>
+			<img src="@/assets/images/leftmapidentification.png" alt="" />
+			<div class="rightTriangle" :style="trueAltitudeStyle"></div>
+			<div class="nameBox">真空高度</div>
+		</div>
+	</div>
+</template>
+
+<script setup>
+const str = ['W', 30, 33, 'N', 3, 6, 'E', 12, 15, 'S', 21, 24]
+
+const props = defineProps(['options'])
+
+const pitchAngleStyle = computed(() => {
+	const pitchAngle = props?.options?.pitchAngle || 0
+	// 将 [-90, 90] 映射到 [0%, 100%]
+	const percentage = (((pitchAngle + 90) / 180) * 100).toFixed(2)
+	return {
+		bottom: `${percentage}%`,
+	}
+})
+
+const trueAltitudeStyle = computed(() => {
+	const trueAltitude = props?.options?.trueAltitude || 0
+	// 将 [-240,240] 映射到 [0%, 100%]
+	const percentage = (((trueAltitude + 240) / 480) * 100).toFixed(2)
+	return {
+		bottom: `${percentage}%`,
+	}
+})
 </script>
+
 <style lang="scss" scoped>
 .instrument-content {
-  height: 100%;
-  width: 100%;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  position: relative;
-  transform: translateY(20px);
+	height: 100%;
+	width: 100%;
+	display: flex;
+	gap: 0 30px;
+	justify-content: center;
+	align-items: center;
+	position: relative;
 
-  .left-img,
-  .right-img {
-    position: relative;
-    height: 100%;
-    display: flex;
-    align-items: center;
-    width: 40px;
+	.left-img,
+	.right-img {
+		position: relative;
+		width: 9px;
+		height: 127px;
 
-    img {
-      height: 100px;
-    }
-  }
+		img {
+			width: 100%;
+			height: 100%;
+		}
 
-  .left-img {
-    .text {
-      position: absolute;
-      left: 0px;
-      top: 50px;
-      width: 60px;
-      text-align: center;
-    }
+		.triangle {
+			width: 0px;
+			height: 0px;
+			margin: auto;
+			border: 6px solid transparent;
+			border-left-color: #0fff7b;
+			position: absolute;
+			left: -10px;
 
-    .scaleImg {
-      position: relative;
-      width: 100%;
-      height: 100px;
+			transform: translateY(50%);
+		}
 
-      img {
-        margin-left: 25px;
-      }
+		.rightTriangle {
+			width: 0px;
+			height: 0px;
+			margin: auto;
+			border: 6px solid transparent;
+			border-left-color: #0fff7b;
+			position: absolute;
+			right: -10px;
+			transform: translateY(50%) rotate(180deg);
+		}
 
-      .scale {
-        width: 10px;
-        height: 10px;
-        background-color: #1fa3f6;
-        position: absolute;
-        margin-left: 10px;
+		.valueBox {
+			position: absolute;
+			top: -20px;
+			left: 50%;
+			transform: translateX(-50%);
+		}
 
-        &::before {
-          content: '';
-          position: absolute;
-          width: 0;
-          height: 0;
-          top: 0px;
-          left: 10px;
-          border-top: solid 5px transparent;
-          border-left: solid 5px #1fa3f6;
-          border-bottom: solid 5px transparent;
-        }
-      }
-    }
+		.nameBox {
+			position: absolute;
+			bottom: -20px;
+			left: 50%;
+			width: auto;
+			transform: translateX(-50%);
+			font-family: Segoe UI, Segoe UI;
+			font-weight: 400;
+			font-size: 12px;
+			white-space: nowrap;
+			color: #ffffff;
+		}
+	}
 
-    &::before {
-      content: attr(data-text);
-      position: absolute;
-      right: 0px;
-      top: 50px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
+	.instrument-center {
+		position: relative;
 
-    &::after {
-      content: '俯仰角度';
-      position: absolute;
-      right: 0px;
-      text-align: right;
-      bottom: 30px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
-  }
+		.compass-box {
+			width: 180px;
+			height: 180px;
+			border-radius: 50%;
+			position: relative;
+			border: 30px solid rgba($color: #323931, $alpha: 0.5);
+			box-shadow: 0 2px 12px 0 #158aff;
+			user-select: none;
 
-  .right-img {
-    &::before {
-      content: attr(data-text);
-      position: absolute;
-      left: 0px;
-      top: 50px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
+			.scale {
+				width: 135%;
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				font-weight: bold;
+				color: #c1c3c4;
+				text-align: left;
+				transform: translate(-50%, -50%) rotate(var(--rotate));
 
-    &::after {
-      content: '真空高度';
-      position: absolute;
-      left: 0px;
-      bottom: 30px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
+				&:nth-child(3n - 2) {
+					color: #fff;
+					font-weight: bolder;
+					font-size: 20px;
+				}
+			}
 
-    .ident-arrow {
-      position: relative;
+			.scale {
+				.text {
+					display: inline-block;
+					// rotate: -90deg;
+					transform: rotate(-90deg);
+					-ms-transform: rotate(-90deg);
+					-moz-transform: rotate(-90deg);
+					-webkit-transform: rotate(-90deg);
+					-o-transform: rotate(-90deg);
+				}
+			}
+		}
 
-      .arrow-box {
-        position: absolute;
-        bottom: 0;
-        left: 20px;
+		.rotat-btn {
+			width: 16px;
+			height: 16px;
+			background-color: rgba($color: #1fa3f6, $alpha: 1);
+			position: absolute;
+			top: 10px;
+			left: 50%;
+			transform: translateX(-50%);
 
-        .arrow {
-          position: relative;
-          width: 10px;
-          height: 10px;
-          background-color: #1fa3f6;
+			&::before {
+				content: '';
+				display: block;
+				width: 0;
+				height: 0;
+				border-left: 8px solid transparent;
+				border-right: 8px solid transparent;
+				border-bottom: 8px solid #1fa3f6;
+				position: absolute;
+				bottom: 100%;
+			}
+		}
 
-          &::before {
-            content: '';
-            position: absolute;
-            left: -9px;
-            top: 0;
+		.center-show {
+			width: 30px;
+			height: 40px;
+			position: absolute;
+			left: 50%;
+			top: 50%;
+			transform: translate(-50%, -50%);
 
-            border: 5px solid transparent {
-              right: solid 5px #1fa3f6;
-            }
-          }
-        }
-      }
-    }
-  }
+			img {
+				width: 100%;
+				height: 100%;
+				transform: rotate(var(--rotate));
+				transition: all 0.5s linear;
+			}
+		}
 
-  .instrument-center {
-    position: relative;
+		&::after {
+			content: '';
+			position: absolute;
+			width: 40px;
+			top: 50%;
+			left: 0;
+			z-index: 99;
+		}
 
-    .compass-box {
-      width: 180px;
-      height: 180px;
-      border-radius: 50%;
-      position: relative;
-      border: 30px solid rgba($color: #323931, $alpha: 0.5);
-      box-shadow: 0 2px 12px 0 #158aff;
-      user-select: none;
-      transform: none !important;
-
-      .scale {
-        width: 135%;
-        position: absolute;
-        top: 50%;
-        left: 50%;
-        font-weight: bold;
-        color: #c1c3c4;
-        text-align: left;
-        transform: translate(-50%, -50%) rotate(var(--rotate));
-
-        &:nth-child(3n - 2) {
-          color: #fff;
-          font-weight: bolder;
-          font-size: 20px;
-        }
-      }
-
-      .scale {
-        .text {
-          display: inline-block;
-          // rotate: -90deg;
-          transform: rotate(-90deg);
-          -ms-transform: rotate(-90deg);
-          -moz-transform: rotate(-90deg);
-          -webkit-transform: rotate(-90deg);
-          -o-transform: rotate(-90deg);
-        }
-      }
-
-      &::before {
-        content: '';
-        position: absolute;
-        top: -45px;
-        left: 50%;
-        transform: translateX(-50%);
-        width: 7px;
-        height: 15px;
-        background: #00ee8b;
-        margin: 0 auto;
-        box-shadow: 0 0 4px rgba(0, 0, 0, 0.5), -1px -1px 0 rgba(0, 0, 0, 0.5),
-          1px -1px 0 rgba(0, 0, 0, 0.5), -1px 1px 0 rgba(0, 0, 0, 0.5),
-          1px 1px 0 rgba(0, 0, 0, 0.5);
-      }
-
-      &::after {
-        content: attr(data-text);
-        position: absolute;
-        top: -60px;
-        font-size: 16px;
-        line-height: 16px;
-        font-weight: 600;
-        color: #00ee8b;
-        left: 50%;
-        transform: translateX(-50%);
-      }
-    }
-
-    .rotat-btn {
-      width: 16px;
-      height: 16px;
-      background-color: rgba($color: #1fa3f6, $alpha: 1);
-      position: absolute;
-      top: 10px;
-      left: 50%;
-      transform: translateX(-50%);
-
-      &::before {
-        content: '';
-        display: block;
-        width: 0;
-        height: 0;
-        border-left: 8px solid transparent;
-        border-right: 8px solid transparent;
-        border-bottom: 8px solid #1fa3f6;
-        position: absolute;
-        bottom: 100%;
-      }
-    }
-
-    .center-show {
-      width: 30px;
-      height: 40px;
-      position: absolute;
-      left: 50%;
-      top: 50%;
-      transform: translate(-50%, -50%);
-
-      img {
-        width: 100%;
-        height: 100%;
-        transform: rotate(var(--rotate));
-        transition: all 0.5s linear;
-      }
-    }
-
-    &::after {
-      content: '';
-      position: absolute;
-      width: 40px;
-      top: 50%;
-      left: 0;
-      z-index: 99;
-    }
-
-    &::before {
-      content: '';
-      position: absolute;
-      width: 40px;
-      top: 50%;
-      right: 0;
-      z-index: 99;
-    }
-  }
+		&::before {
+			content: '';
+			position: absolute;
+			width: 40px;
+			top: 50%;
+			right: 0;
+			z-index: 99;
+		}
+	}
 }
 </style>

--
Gitblit v1.9.3