|
@@ -1,16 +1,11 @@
|
|
|
<template>
|
|
|
<div class="detection-area-view">
|
|
|
- <canvas ref="canvasRef" width="400" height="400"></canvas>
|
|
|
+ <canvas ref="canvasRef" width="500" height="500"></canvas>
|
|
|
|
|
|
<div class="overlay-layer">
|
|
|
<template v-if="mode === 'view'">
|
|
|
<div class="furniture-container" :class="{ 'clip-overflow': mode === 'view' }">
|
|
|
- <div
|
|
|
- v-for="item in furnitureItems"
|
|
|
- :key="item.nanoid"
|
|
|
- class="furniture-item"
|
|
|
- :style="getFurnitureStyle(item)"
|
|
|
- >
|
|
|
+ <div v-for="item in localFurnitureItems" :key="item.nanoid" class="furniture-item">
|
|
|
<div class="furniture-rotated-container" :style="getRotatedContainerStyle(item)">
|
|
|
<furnitureIcon :icon="item.type" :width="item.width" :height="item.length" />
|
|
|
</div>
|
|
@@ -50,9 +45,10 @@ import {
|
|
|
type CanvasRect,
|
|
|
type RadarPosition,
|
|
|
type RadarFurniture,
|
|
|
+ rotateRect,
|
|
|
} from '@/utils/coordTransform'
|
|
|
import radarUrl from '@/assets/furnitures/radar.png'
|
|
|
-import type { FurnitureItem, LocalFurnitureItem } from '@/api/room/types'
|
|
|
+import type { LocalFurnitureItem } from '@/api/room/types'
|
|
|
|
|
|
defineOptions({ name: 'DetectionAreaView' })
|
|
|
|
|
@@ -81,8 +77,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
})
|
|
|
|
|
|
// 画布配置常量
|
|
|
-const CANVAS_SIZE = 400 // 画布尺寸(像素)
|
|
|
-const RADAR_RANGE = 400 // 雷达检测范围(厘米)
|
|
|
+const CANVAS_SIZE = 500 // 画布尺寸(像素)
|
|
|
+const RADAR_RANGE = 500 // 雷达检测范围(厘米)
|
|
|
|
|
|
// Canvas 相关引用
|
|
|
const canvasRef = ref<HTMLCanvasElement | null>(null)
|
|
@@ -111,6 +107,44 @@ const device = {
|
|
|
size: 20, // 设备图标尺寸
|
|
|
}
|
|
|
|
|
|
+const localFurnitureItems = computed(() => {
|
|
|
+ return props.furnitureItems.map((item) => {
|
|
|
+ const itemConvert = convert_furniture_r2c(
|
|
|
+ {
|
|
|
+ x: item.x,
|
|
|
+ y: item.y,
|
|
|
+ width: item.width,
|
|
|
+ height: item.length,
|
|
|
+ },
|
|
|
+ radarPosition
|
|
|
+ )
|
|
|
+ const rotatedRect = rotateRect(
|
|
|
+ {
|
|
|
+ left: itemConvert.left,
|
|
|
+ top: itemConvert.top,
|
|
|
+ width: item.width,
|
|
|
+ height: item.length,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ x: CANVAS_SIZE / 2,
|
|
|
+ y: CANVAS_SIZE / 2,
|
|
|
+ },
|
|
|
+ props.direction
|
|
|
+ )
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ left: rotatedRect.left,
|
|
|
+ top: rotatedRect.top,
|
|
|
+ width: rotatedRect.width,
|
|
|
+ length: rotatedRect.height,
|
|
|
+ }
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+watch(localFurnitureItems, (newItems) => {
|
|
|
+ console.log('🔥🔥🔥🔥🔥🔥🔥🔥🔥localFurnitureItems', newItems)
|
|
|
+})
|
|
|
+
|
|
|
/**
|
|
|
* 计算旋转后的边界框(基于左上角基准)
|
|
|
*/
|
|
@@ -180,35 +214,13 @@ const geoToPixel = (geoX: number, geoY: number): { x: number; y: number } => {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取家具容器样式 - 基于左上角定位
|
|
|
- */
|
|
|
-const getFurnitureStyle = (item: FurnitureItem) => {
|
|
|
- // 获取家具左上角的像素坐标
|
|
|
- const pixelPos = geoToPixel(item?.x || 0, item?.y || 0)
|
|
|
- const boundingBox = calculateBoundingBox(item.width, item.length, item.rotate || 0)
|
|
|
-
|
|
|
- const cssObj = {
|
|
|
- position: 'absolute',
|
|
|
- left: `${pixelPos.x}px`,
|
|
|
- top: `${pixelPos.y}px`,
|
|
|
- width: `${boundingBox.width}px`,
|
|
|
- height: `${boundingBox.height}px`,
|
|
|
- pointerEvents: props.mode === 'edit' ? 'auto' : 'none',
|
|
|
- } as CSSProperties
|
|
|
-
|
|
|
- return cssObj
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
* 获取旋转容器样式 - 调整位置使内容在边界框中正确显示
|
|
|
*/
|
|
|
-const getRotatedContainerStyle = (item: FurnitureItem) => {
|
|
|
- const boundingBox = calculateBoundingBox(item.width, item.length, item.rotate || 0)
|
|
|
-
|
|
|
+const getRotatedContainerStyle = (item: LocalFurnitureItem) => {
|
|
|
const cssObj = {
|
|
|
position: 'absolute',
|
|
|
- left: `${-boundingBox.left}px`,
|
|
|
- top: `${-boundingBox.top}px`,
|
|
|
+ left: `${item.left}px`,
|
|
|
+ top: `${item.top}px`,
|
|
|
width: `${item.width}px`,
|
|
|
height: `${item.length}px`,
|
|
|
transform: `rotate(${item.rotate || 0}deg)`,
|
|
@@ -251,11 +263,11 @@ const convertAreaByDirection = (
|
|
|
case 0: // 设备朝东:保持原始坐标系(x轴朝右)
|
|
|
return [xStart, xEnd, yStart, yEnd]
|
|
|
case 90: // 设备朝南:y轴反向
|
|
|
- return [xStart, xEnd, -yEnd, -yStart]
|
|
|
+ return [yEnd, yStart, -xEnd, -xStart]
|
|
|
case 180: // 设备朝西:x轴反向
|
|
|
return [-xEnd, -xStart, -yEnd, -yStart]
|
|
|
case 270: // 设备朝北:x轴反向,y轴反向
|
|
|
- return [-xEnd, -xStart, yStart, yEnd]
|
|
|
+ return [-yEnd, -yStart, xStart, xEnd]
|
|
|
default: // 其他角度使用任意角度转换
|
|
|
return convertAreaForArbitraryAngle(area, direction)
|
|
|
}
|
|
@@ -600,8 +612,8 @@ defineExpose({
|
|
|
.detection-area-view {
|
|
|
position: relative;
|
|
|
display: inline-block;
|
|
|
- width: 400px;
|
|
|
- height: 400px;
|
|
|
+ width: 500px;
|
|
|
+ height: 500px;
|
|
|
|
|
|
canvas {
|
|
|
border: 1px solid #ddd;
|
|
@@ -613,8 +625,8 @@ defineExpose({
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
- width: 400px;
|
|
|
- height: 400px;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
pointer-events: auto;
|
|
|
|
|
|
.furniture-container {
|