Explorar o código

完成预览功能

louhangfei %!s(int64=2) %!d(string=hai) anos
pai
achega
f10c278535

+ 73 - 0
src/views/map-config/mini-map/MapBase/CameraPreview.vue

@@ -0,0 +1,73 @@
+<template>
+  <div>
+    <div style="overflow: auto; position: relative">
+      <canvas width="400" height="400" ref="canvasRef" style="border: 1px solid #ccc"></canvas>
+      <DefaultCameraIcon :position="favPosition" />
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { fabric } from 'fabric';
+  import { onMounted, ref, watch } from 'vue';
+  import cameraImg from '@/assets/camera/camera.png';
+  import { CameraImage, MapData, isCanvas } from './types';
+  import DefaultCameraIcon from './DefaultCameraIcon.vue';
+  import { getFavPositionByCamera } from './utils';
+
+  const props = defineProps<{ json: MapData }>();
+
+  let canvas;
+  const canvasRef = ref<HTMLCanvasElement>();
+
+  const favPosition = ref<{ left: number; top: number } | null>(null);
+
+  const createMap = () => {
+    if (!canvasRef.value) return;
+    canvas = new fabric.Canvas(canvasRef.value, {
+      fireRightClick: true, // 启用右键,button的数字为3
+      stopContextMenu: true, // 禁止默认右键菜单
+    });
+    canvas.selectable = false;
+    window.cvs = canvas;
+  };
+
+  onMounted(() => {
+    createMap();
+  });
+
+  watch(
+    () => props.json,
+    () => {
+      const json = props.json;
+      console.log('props.json', props.json);
+      if (json) {
+        const { width, height } = json.backgroundImage;
+        canvas?.setWidth(width);
+        canvas?.setHeight(height);
+        const objects = json.objects.map((item) => {
+          return {
+            ...item,
+            src: cameraImg,
+            selectable: false,
+            hasControls: false,
+            hasBoards: false,
+          };
+        });
+        canvas?.loadFromJSON({ ...json, objects }, () => {
+          const defaultCamera = getCameraById(json.defaultCameraId);
+          if (defaultCamera) {
+            favPosition.value = getFavPositionByCamera(defaultCamera);
+          }
+        });
+      }
+    },
+    { deep: true },
+  );
+
+  const getCameraById = (cameraId: string) => {
+    return canvas
+      ?.getObjects()
+      .find((x) => (x as CameraImage).cameraId === cameraId) as CameraImage;
+  };
+</script>
+<style scoped></style>

+ 1 - 0
src/views/map-config/mini-map/MapBase/types.ts

@@ -10,6 +10,7 @@ export interface MapData {
     angle: number;
   };
   objects: CameraImgObject[];
+  defaultCameraId: string;
 }
 
 export interface CameraImgObject {

+ 4 - 2
src/views/map-config/mini-map/MapBase/utils.ts

@@ -1,10 +1,12 @@
+import { fabric } from 'fabric';
 export function getRandomPosition() {
   return 100 + Math.floor(Math.random() * 30);
 }
 
 /** 根据camera位置得到fav icon的位置 */
-export function getFavPositionByCamera(position: { left?: number; top?: number }) {
-  return { left: position.left || 0, top: position.top || 0 };
+export function getFavPositionByCamera(target?: fabric.Object | null) {
+  if (!target || !target.oCoords) return null;
+  return { left: target.oCoords?.tr.x, top: target.oCoords?.tr.y };
 }
 
 export function createSelectedPositionHash(target) {

+ 11 - 18
src/views/map-config/mini-map/MiniMapConfig.vue

@@ -87,6 +87,8 @@
           />
           <DefaultCameraIcon :position="favPosition" />
         </div>
+
+        <CameraPreview :json="cameraJSON" />
       </div>
     </div>
   </div>
@@ -109,6 +111,7 @@
   import { CameraImage } from './MapBase/types';
   import { createSelectedPositionHash, getFavPositionByCamera } from './MapBase/utils';
   import SelectedCameraToolbar from './components/SelectedCameraToolbar.vue';
+  import CameraPreview from './MapBase/CameraPreview.vue';
 
   const miniMap = useMiniMap();
   const globSetting = useGlobSetting();
@@ -128,18 +131,13 @@
     rightSelectedCamera.value = e.target;
   };
 
-  const defaultCameraId = computed(() => defaultCamera.value?.cameraId);
-
   const handleMoving = (e) => {
     const target = e.transform.target;
     selectedPositionHash.value = createSelectedPositionHash(target);
     console.log('moving', target.cameraId);
     console.log(' defaultCamera.value?.cameraId', defaultCamera.value?.cameraId);
     if (target?.cameraId === defaultCamera.value?.cameraId) {
-      favPosition.value = getFavPositionByCamera({
-        left: target.oCoords.tr.x,
-        top: target.oCoords.tr.y,
-      });
+      favPosition.value = getFavPositionByCamera(target);
     }
   };
 
@@ -147,10 +145,7 @@
     const target = e.transform.target;
     selectedPositionHash.value = createSelectedPositionHash(target);
     if (target.cameraId === defaultCamera.value?.cameraId) {
-      favPosition.value = getFavPositionByCamera({
-        left: target.oCoords.tr.x,
-        top: target.oCoords.tr.y,
-      });
+      favPosition.value = getFavPositionByCamera(target);
     }
   };
 
@@ -179,16 +174,15 @@
 
   const renderMap = () => {
     map.renderCamera();
-    favPosition.value = getFavPositionByCamera({
-      left: defaultCamera.value?.oCoords?.tr.x,
-      top: defaultCamera.value?.oCoords?.tr.y,
-    });
+    favPosition.value = getFavPositionByCamera(defaultCamera.value);
   };
 
   const changeShop = (code: string) => {
     getShopContent(code);
   };
 
+  const cameraJSON = ref();
+
   const getShopContent = (code: string) => {
     getShowCameras(code);
     getMapLayout(code).then((res) => {
@@ -197,6 +191,8 @@
         defaultCamera.value = null;
         return;
       }
+      cameraJSON.value = res;
+
       map.loadFromJSON(res).then(() => {
         console.log('loadFromJSON', res);
         if (res.defaultCameraId) {
@@ -295,10 +291,7 @@
       favPosition.value = null;
       return;
     }
-    favPosition.value = getFavPositionByCamera({
-      left: defaultCamera.value?.oCoords?.tr.x,
-      top: defaultCamera.value?.oCoords?.tr.y,
-    });
+    favPosition.value = getFavPositionByCamera(defaultCamera.value);
   });
 </script>