index.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <template>
  2. <div
  3. class="radarArea"
  4. :style="{
  5. width: `${width}px`,
  6. height: `${length}px`,
  7. }"
  8. >
  9. <furniture-icon
  10. v-for="(item, index) in localFurnitureItems"
  11. :key="`furniture-${index}-${item.type}`"
  12. :icon="item.type"
  13. :width="item.width"
  14. :height="item.length"
  15. :style="{
  16. left: `${item.left}px`,
  17. top: `${item.top}px`,
  18. position: 'absolute',
  19. rotate: `${item.rotate}deg`,
  20. cursor: 'default',
  21. pointerEvents: 'none',
  22. }"
  23. :draggable="false"
  24. />
  25. <slot></slot>
  26. </div>
  27. </template>
  28. <script setup lang="ts">
  29. import { ref } from 'vue'
  30. import { getOriginPosition } from '@/utils'
  31. defineOptions({
  32. name: 'BaseAreaViewer',
  33. })
  34. /**
  35. * 组件Props定义(明确类型约束,提高可维护性)
  36. */
  37. interface FurnitureItem {
  38. name: string
  39. type: string
  40. width: number
  41. length: number
  42. left: number
  43. top: number
  44. rotate: number
  45. x?: number
  46. y?: number
  47. }
  48. const props = withDefaults(
  49. defineProps<{
  50. width: number
  51. length: number
  52. furnitureItems: FurnitureItem[]
  53. ranges?: number[]
  54. }>(),
  55. {
  56. furnitureItems: () => [],
  57. }
  58. )
  59. const { originOffsetX, originOffsetY, radarX, radarY, radarWidth, radarHeight } = getOriginPosition(
  60. props?.ranges ?? [],
  61. [0, 0]
  62. )
  63. const localFurnitureItems = ref<FurnitureItem[]>([
  64. {
  65. name: '雷达',
  66. type: 'radar',
  67. width: radarWidth,
  68. length: radarHeight,
  69. top: radarY,
  70. left: radarX,
  71. x: originOffsetX,
  72. y: originOffsetY,
  73. rotate: 0,
  74. },
  75. ...props.furnitureItems,
  76. ])
  77. </script>
  78. <style scoped lang="less">
  79. .radarArea {
  80. position: relative;
  81. background-image:
  82. linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
  83. linear-gradient(to right, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
  84. background-size: 20px 20px;
  85. border: 1px solid rgba(0, 0, 0, 0.8);
  86. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  87. overflow: hidden;
  88. flex-shrink: 0;
  89. }
  90. /* 目标点样式(从原代码提取并优化) */
  91. .target-dot {
  92. &__number {
  93. color: #fff;
  94. font-size: 12px;
  95. font-weight: 600;
  96. position: absolute;
  97. left: 50%;
  98. top: 50%;
  99. transform: translate(-50%, -50%);
  100. pointer-events: none;
  101. }
  102. }
  103. </style>