Browse Source

路口详情:摄像头视频弹窗改为按方向层叠布局,尺寸/位置自适应右侧控制区

画安 3 weeks ago
parent
commit
a5dcd9853c
1 changed files with 24 additions and 18 deletions
  1. 24 18
      src/components/ui/IntersectionMapVideos.vue

+ 24 - 18
src/components/ui/IntersectionMapVideos.vue

@@ -579,8 +579,10 @@ export default {
       });
     },
 
-    /** 把 dir 映射成 .detail-panel-right 内的 2×2 单元格,返回设计坐标系下的 position/width/height。
-     *  N→左上, E→右上, W→左下, S→右下,与画面方位一致。 */
+    /** 摄像头视频弹窗在 .detail-panel-right 内的位置/尺寸:
+     *  - 尺寸:取右侧面板的 70% × 70%,单窗口下封顶(避免太大),多窗口下自然缩小贴合面板
+     *  - 位置:按方向 N→0、E→1、S→2、W→3 做层叠偏移(cascade),右下方向逐个偏移 STEP 像素
+     *  - 偏移量被夹紧到 (面板宽-弹窗宽, 面板高-弹窗高) 之内,保证不溢出右侧控制方式区 */
     _calcCameraDialogRect(dir) {
       const DESIGN_WIDTH = 1920;
       const scale = window.innerWidth / DESIGN_WIDTH;
@@ -590,28 +592,32 @@ export default {
       const rect = rightPanel.getBoundingClientRect();
       if (!(rect.width > 0 && rect.height > 0)) return null;
 
-      const DIR_TO_CELL = {
-        N: { col: 0, row: 0 },
-        E: { col: 1, row: 0 },
-        W: { col: 0, row: 1 },
-        S: { col: 1, row: 1 },
-      };
-      const GAP = 4;       // 单元格间距(设计像素)
+      const DIR_TO_IDX = { N: 0, E: 1, S: 2, W: 3 };
+      const STEP = 18;          // 层叠步进(设计像素)
+      const MAX_W = 420;        // 单窗口大尺寸下弹窗宽度封顶
+      const MAX_H = 300;
 
-      // 单元尺寸严格按右侧面板的 1/2 切分,不加最小兜底
-      // —— 多窗口下面板可能只剩 ~300×200 设计像素,加 MIN 反而让 4 弹窗溢出
       const wDesign = rect.width / scale;
       const hDesign = rect.height / scale;
-      const cellW = Math.max(40, Math.floor((wDesign - GAP) / 2));
-      const cellH = Math.max(40, Math.floor((hDesign - GAP) / 2));
-      const cell = DIR_TO_CELL[dir] || { col: 0, row: 0 };
+
+      // 弹窗本体尺寸:取面板 70%,但不超过 MAX,也不小于面板(多窗口)
+      const W = Math.max(40, Math.min(MAX_W, Math.floor(wDesign * 0.7)));
+      const H = Math.max(40, Math.min(MAX_H, Math.floor(hDesign * 0.7)));
+
+      // 层叠偏移:每个方向独立索引,超出最大可偏移距离则夹紧到边界
+      const idx = DIR_TO_IDX[dir] !== undefined ? DIR_TO_IDX[dir] : 0;
+      const maxOffsetX = Math.max(0, wDesign - W);
+      const maxOffsetY = Math.max(0, hDesign - H);
+      const offsetX = Math.min(idx * STEP, maxOffsetX);
+      const offsetY = Math.min(idx * STEP, maxOffsetY);
+
       return {
         position: {
-          x: rect.left / scale + cell.col * (cellW + GAP),
-          y: rect.top / scale + cell.row * (cellH + GAP),
+          x: rect.left / scale + offsetX,
+          y: rect.top / scale + offsetY,
         },
-        width: cellW,
-        height: cellH,
+        width: W,
+        height: H,
       };
     },