Browse Source

log: 主页配置方案一

sunhongyao341504 2 years ago
parent
commit
02b0001a6a

+ 1 - 1
package.json

@@ -50,7 +50,7 @@
     "element-resize-detector": "1.2.4",
     "fabric": "5.3.0",
     "flv.js": "1.6.2",
-    "html2canvas": "1.4.1",
+    "html2canvas": "1.0.0",
     "konva": "9.3.0",
     "lodash-es": "4.17.21",
     "mockjs": "1.1.0",

+ 11 - 24
pnpm-lock.yaml

@@ -63,8 +63,8 @@ dependencies:
     specifier: 1.6.2
     version: 1.6.2
   html2canvas:
-    specifier: 1.4.1
-    version: 1.4.1
+    specifier: 1.0.0
+    version: 1.0.0
   konva:
     specifier: 9.3.0
     version: 9.3.0
@@ -111,7 +111,7 @@ dependencies:
     specifier: 1.8.6
     version: 1.8.6(vue@3.3.4)
   vue-konva:
-    specifier: ^3.0.2
+    specifier: 3.0.2
     version: 3.0.2(konva@9.3.0)
   vue-router:
     specifier: 4.1.2
@@ -2387,8 +2387,8 @@ packages:
     resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
     dev: true
 
-  /base64-arraybuffer@1.0.2:
-    resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
+  /base64-arraybuffer@0.2.0:
+    resolution: {integrity: sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==}
     engines: {node: '>= 0.6.0'}
     dev: false
 
@@ -3084,10 +3084,10 @@ packages:
     engines: {node: '>=12.22'}
     dev: true
 
-  /css-line-break@2.1.0:
-    resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
+  /css-line-break@1.1.1:
+    resolution: {integrity: sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==}
     dependencies:
-      utrie: 1.0.2
+      base64-arraybuffer: 0.2.0
     dev: false
 
   /css-select@4.3.0:
@@ -4861,12 +4861,11 @@ packages:
     resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
     dev: false
 
-  /html2canvas@1.4.1:
-    resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
+  /html2canvas@1.0.0:
+    resolution: {integrity: sha512-0d/f2Aj1Brn+EeNWkuRdtnT13qu1NdvxhBMvts3ssme7jgPU7dtuwnm1P6cXvXmnDdUUerH5XdhveWvuLfqkew==}
     engines: {node: '>=8.0.0'}
     dependencies:
-      css-line-break: 2.1.0
-      text-segmentation: 1.0.3
+      css-line-break: 1.1.1
     dev: false
 
   /htmlparser2@3.10.1:
@@ -7682,12 +7681,6 @@ packages:
     engines: {node: '>=0.10'}
     dev: true
 
-  /text-segmentation@1.0.3:
-    resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
-    dependencies:
-      utrie: 1.0.2
-    dev: false
-
   /text-table@0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
     dev: true
@@ -8027,12 +8020,6 @@ packages:
     engines: {node: '>= 0.4.0'}
     dev: true
 
-  /utrie@1.0.2:
-    resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
-    dependencies:
-      base64-arraybuffer: 1.0.2
-    dev: false
-
   /v8-compile-cache-lib@3.0.1:
     resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
     dev: true

File diff suppressed because it is too large
+ 23 - 0
src/assets/test/1.svg


File diff suppressed because it is too large
+ 25 - 0
src/assets/test/2.svg


src/views/page-config/component/mapContainer/LabelItem.vue → src/views/page-config/component/mapContainer/LabelItem1.vue


File diff suppressed because it is too large
+ 22 - 14
src/views/page-config/component/mapContainer/LabelPoint.vue


File diff suppressed because it is too large
+ 111 - 0
src/views/page-config/component/mapContainer/LabelRect.vue


+ 92 - 17
src/views/page-config/component/mapContainer/MapContainer.vue

@@ -1,9 +1,22 @@
 <template>
   <div>
-    <v-stage :config="stageSize">
+    <v-stage
+      :config="stageSize"
+      @mousedown="handleStageMouseDown"
+      @touchstart="handleStageMouseDown"
+    >
       <v-layer ref="layerRef">
         <v-image :config="bgConfig" />
-        <v-image :config="pointConfig" />
+        <v-group
+          v-for="item in showShops"
+          :key="item.id"
+          :config="getGroupConfig(item)"
+          @transformend="handleTransformEnd"
+        >
+          <v-image :config="getPointConfig(item)" />
+          <v-image :config="getRectConfig(item)" />
+        </v-group>
+        <v-transformer ref="transformerRef" />
       </v-layer>
     </v-stage>
   </div>
@@ -12,46 +25,108 @@
 <script setup lang="ts">
   import { computed, ref } from 'vue';
   import { storeToRefs } from 'pinia';
-  import useMapEditor from '../../stores/useMapEditor';
+  import useMapEditor, { MapWorkShopInfoItem } from '../../stores/useMapEditor';
   import { useGlobSetting } from '@/hooks/setting';
-  import urlJoin from 'url-join';
   import Konva from 'konva';
 
   const mapEditor = useMapEditor();
-  const { mapWidth, mapHeight, bgImg, showShops, bgImage, pointImage } = storeToRefs(mapEditor);
+  const { mapWidth, mapHeight, bgImg, showShops, bgImage } = storeToRefs(mapEditor);
 
   const globSetting = useGlobSetting();
 
   const layerRef = ref<Konva.Layer>();
+  const transformerRef = ref<Konva.Transformer>();
+
+  let selectedShape = -1;
 
   const stageSize = computed(() => {
     return {
-      width: mapWidth.value,
-      height: mapHeight.value,
+      // width: mapWidth.value,
+      // height: mapHeight.value,
+      width: 1920,
+      height: 1080,
     };
   });
 
   const bgConfig = computed(() => {
     return {
-      width: mapWidth.value,
-      height: mapHeight.value,
+      width: 1920,
+      height: 1080,
       image: bgImage.value,
       name: 'bg',
     };
   });
 
-  const pointConfig = computed(() => {
+  const getGroupConfig = (shop: MapWorkShopInfoItem) => {
     return {
-      x: 50,
-      y: 0,
-      width: 100,
-      height: 100,
-      image: pointImage.value,
+      x: shop.x,
+      y: shop.y,
+      id: shop.id,
+      draggable: true,
+      name: 'group',
+    };
+  };
+
+  const getPointConfig = (shop: MapWorkShopInfoItem) => {
+    return {
+      width: 32,
+      height: 39,
+      image: shop.pointSvg,
       name: 'pointSvg',
     };
-  });
+  };
+
+  const getRectConfig = (shop: MapWorkShopInfoItem) => {
+    return {
+      x: 53,
+      y: 6,
+      width: 160,
+      height: 38,
+      image: shop.rectSvg,
+      name: 'pointSvg',
+    };
+  };
+
+  const handleStageMouseDown = (e) => {
+    console.log(e);
+
+    if (e.target.attrs.name === 'bg') {
+      selectedShape = -1;
+      updateTransformer();
+    }
+
+    if (e.target.parent.attrs.name === 'group') {
+      console.log(e.target.parent.id());
+
+      if (e.target.parent.id() === selectedShape) {
+        return;
+      }
+      selectedShape = e.target.parent.id();
+      console.log(selectedShape);
+
+      const transformerNode = transformerRef.value!.getNode();
+      (transformerNode as Konva.Transformer).nodes([e.target.parent!]);
+
+      // updateTransformer();
+    }
+  };
+
+  const handleTransformEnd = (e) => {};
+
+  const updateTransformer = () => {
+    const transformerNode = transformerRef.value!.getNode();
+    const layer = layerRef.value!.getNode().getLayer();
+    console.log(layer);
+
+    if (selectedShape >= 0) {
+      const selectedNode = layer.findOne('#' + selectedShape);
+      console.log(selectedNode);
 
-  const getRealImgUrl = () => urlJoin(globSetting.imgUrl!, bgImg.value);
+      (transformerNode as Konva.Transformer).nodes([selectedNode!]);
+    } else {
+      (transformerNode as Konva.Transformer).nodes([]);
+    }
+  };
 </script>
 
 <style scoped></style>

+ 58 - 21
src/views/page-config/stores/useMapEditor.ts

@@ -5,6 +5,7 @@ import { cloneDeep } from 'lodash-es';
 import { useGlobSetting } from '@/hooks/setting';
 import urlJoin from 'url-join';
 import LabelPoint from '../component/mapContainer/LabelPoint.vue';
+import LabelRect from '../component/mapContainer/LabelRect.vue';
 import emptyImg from '@/assets/images/table/table-empty.png';
 
 export enum LabelPositionEnum {
@@ -22,6 +23,9 @@ export type EditStyle = {
   fontSize: number;
   fontColor: string;
   posType: LabelPositionEnum;
+
+  pointSvg?: HTMLImageElement;
+  rectSvg?: HTMLImageElement;
 };
 
 export type MapWorkShopInfoItem = WorkShopInfoItem & EditStyle;
@@ -36,11 +40,8 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
   const showShops = ref<MapWorkShopInfoItem[]>([]);
   const activeShop = ref<MapWorkShopInfoItem>({} as MapWorkShopInfoItem);
 
-  let tempDiv: HTMLDivElement;
-
   /** konva elements refs */
   const bgImage = ref<HTMLImageElement>(new Image());
-  const pointImage = ref<HTMLImageElement>(new Image());
 
   const addBg = () => {
     const imgUrl = urlJoin(globSetting.imgUrl!, bgImg.value);
@@ -53,11 +54,11 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     bgImage.value.src = emptyImg;
   };
 
-  const addShop = (shop: MapWorkShopInfoItem) => {
-    activeShop.value = shop;
-    addedShops.value.push(cloneDeep(shop));
-    showShops.value.push(cloneDeep(shop));
-  };
+  // const addShop = (shop: MapWorkShopInfoItem) => {
+  //   activeShop.value = shop;
+  //   addedShops.value.push(cloneDeep(shop));
+  //   showShops.value.push(cloneDeep(shop));
+  // };
 
   const toJson = () => {
     const layout = {
@@ -90,13 +91,57 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     activeShop.value = {} as MapWorkShopInfoItem;
   };
 
-  const getPointSvg = (url: string) => {
+  const getSvgImages = (shop: MapWorkShopInfoItem): MapWorkShopInfoItem => {
+    let hasPoint = false;
+    let hasRect = false;
+
+    const tempDiv = document.createElement('div') as HTMLDivElement;
+    tempDiv.setAttribute('style', `position: absolute; left: -3000px; top: 0px;`);
+    const parentEl = document.getElementById('shopEditContainer') as HTMLDivElement;
+    parentEl.append(tempDiv);
+
     const svgImg = new Image();
     svgImg.onload = () => {
-      pointImage.value = svgImg;
-      // tempDiv?.remove();
+      hasPoint = true;
+      if (hasRect) {
+        // tempDiv?.remove();
+      }
+      addedShops.value.find((item) => item.id === shop.id)!.pointSvg = svgImg;
+      showShops.value.find((item) => item.id === shop.id)!.pointSvg = svgImg;
+    };
+    const pointSvg = h(LabelPoint, {
+      color: shop.bgColor,
+      getSvg: (url: string) => {
+        svgImg.src = url;
+      },
+    });
+    render(pointSvg, tempDiv);
+
+    const rectImg = new Image();
+    rectImg.onload = () => {
+      hasRect = true;
+      if (hasPoint) {
+        // tempDiv?.remove();
+      }
+      addedShops.value.find((item) => item.id === shop.id)!.rectSvg = rectImg;
+      showShops.value.find((item) => item.id === shop.id)!.rectSvg = rectImg;
     };
-    svgImg.src = url;
+    shop.name = 'ARJ21部装车间';
+    const rectSvg = h(LabelRect, {
+      shop,
+      getSvg: (url: string) => {
+        rectImg.src = url;
+      },
+    });
+    render(rectSvg, tempDiv);
+
+    return { ...shop };
+  };
+
+  const addShop = (shop: MapWorkShopInfoItem) => {
+    activeShop.value = getSvgImages(shop);
+    addedShops.value.push(cloneDeep(activeShop.value));
+    showShops.value.push(cloneDeep(activeShop.value));
   };
 
   const resetMap = () => {
@@ -108,14 +153,7 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     activeShop.value = {} as MapWorkShopInfoItem;
   };
 
-  onMounted(() => {
-    tempDiv = document.createElement('div') as HTMLDivElement;
-    tempDiv.setAttribute('style', `position: absolute; left: -3000px; top: 0px;`);
-    const pointSvg = h(LabelPoint, { color: 'red', getSvg: getPointSvg });
-    render(pointSvg, tempDiv);
-    const parentEl = document.getElementById('shopEditContainer') as HTMLDivElement;
-    parentEl.append(tempDiv);
-  });
+  onMounted(() => {});
 
   return {
     bgImg,
@@ -125,7 +163,6 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     showShops,
     activeShop,
     bgImage,
-    pointImage,
     addShop,
     addBg,
     toJson,