Browse Source

fix:canvas地图绘制功能

chenzhen2 2 năm trước cách đây
mục cha
commit
7709a5b4c1

+ 137 - 27
src/views/envmonitor/components/Map/CanvasBox.vue

@@ -28,11 +28,15 @@ export default defineComponent({
   components: {
     VanSearch: Search,
   },
-  setup(props) {
+  setup(props, contx) {
     let ctx: any = {};
+    let canvasImageArr: any = {};
+    let iconData: any = [];
     const proxyData = reactive({
       mapData: props.mapData, // 地图数据
+      iconData: iconData,
       parseImgUrl: parseImgUrl,
+      canvasImageArr: canvasImageArr,
       ctx: ctx,
       /**
        * 设置空间的图标
@@ -53,18 +57,32 @@ export default defineComponent({
           item.icon = "";
         }
       },
+      // 地图缩放
+      scaleCanvas(data: any) {
+        proxyData.mapData = data;
+        let removeIconArr: any = document.querySelectorAll(".load-icon") || [];
+        // removeIconArr.map((item: any) => {
+        //   item.remove();
+        // });
+        proxyData.canvasImageArr = {};
+        proxyData.initCanvas(1);
+        // proxyData.ctx.clearRect(0, 0, proxyData.mapData.width, proxyData.mapData.height);
+      },
       // canvas画图
-      initCanvas() {
+      initCanvas(type: any = 0) {
         let canvasDom: any = document.querySelector("#myCanvas");
+        // canvasDom.style.display = "none";
         let ctx: any = canvasDom.getContext("2d");
+        proxyData.ctx = ctx;
         // debugger;
         proxyData.drawDpiBegin(
           canvasDom,
           ctx,
           proxyData.mapData.width,
-          proxyData.mapData.height
+          proxyData.mapData.height,
+          type
         );
-        proxyData.ctx = ctx;
+
         let spaceList: any =
           (proxyData.mapData && proxyData.mapData.spaceList) || [];
         spaceList.map((item: any) => {
@@ -85,7 +103,6 @@ export default defineComponent({
               pointLeftArr.push(childItem.left);
               pointTopArr.push(childItem.top);
             });
-
             ctx.fill();
             ctx.closePath();
             ctx.beginPath();
@@ -101,8 +118,9 @@ export default defineComponent({
                 circleArr[0].top
               );
             }
-            ctx.closePath();
             ctx.fill();
+            ctx.closePath();
+
             let min1: any =
               proxyData.MaxAndMin(pointLeftArr)[1] -
               proxyData.MaxAndMin(pointLeftArr)[0];
@@ -114,26 +132,44 @@ export default defineComponent({
             ctx.font = "12px serif";
             ctx.textAlign = "center";
             ctx.fillStyle = item.fillColor === "#fff" ? "#000" : "#8995BA";
+            let localName: any = item.localName;
+            let drutionLef: any = localName ? item.localName["length"] * 12 : 0;
             ctx.fillText(
               item.localName,
               item.logoPointArr[0].left,
-              item.logoPointArr[0].top + 45,
-              item.width
+              item.logoPointArr[0].top,
+              50
             );
-            let localName: any = item.localName;
-            let drutionLef: any = localName ? item.localName["length"] * 12 : 0;
+
             if (item.icon) {
-              proxyData.drawIcon(ctx, item.icon, {
-                left: item.logoPointArr[0].left - drutionLef / 2 + 15,
-                top: item.logoPointArr[0].top - 15,
+              proxyData.addIcon(item, 1, {
+                left: item.logoPointArr[0].left - 50 / 2 + 15,
+                top: item.logoPointArr[0].top * 1 + 5,
               });
             }
             ctx.closePath();
           } else {
+            ctx.beginPath();
             let img: any = new Image();
             img.src = require("@/assets/svg/bg_disable.png");
-            img.onload = function () {
-              ctx.beginPath();
+            if (type == 0) {
+              img.onload = function () {
+                item.pointArr.map((item: any, index: any) => {
+                  if (index === 0) {
+                    ctx.moveTo(item.left, item.top);
+                  } else {
+                    ctx.lineTo(item.left, item.top);
+                  }
+                });
+                let pat: any = ctx.createPattern(img, "repeat");
+                ctx.fillStyle = pat;
+                ctx.fill();
+                ctx.closePath();
+                ctx.lineWidth = 2;
+                ctx.strokeStyle = "#DFE3ED";
+                ctx.stroke();
+              };
+            } else {
               item.pointArr.map((item: any, index: any) => {
                 if (index === 0) {
                   ctx.moveTo(item.left, item.top);
@@ -148,9 +184,10 @@ export default defineComponent({
               ctx.lineWidth = 2;
               ctx.strokeStyle = "#DFE3ED";
               ctx.stroke();
-            };
+            }
           }
         });
+        proxyData.drawIcon(ctx, type);
         proxyData.drawDpiEnd(canvasDom, ctx);
       },
       MaxAndMin(arr: any) {
@@ -164,16 +201,21 @@ export default defineComponent({
       },
       // 解决canvas画图模糊的问题
       // 开始画
-      drawDpiBegin(dom: any, context: any, width: any, height: any) {
+      drawDpiBegin(
+        dom: any,
+        context: any,
+        width: any,
+        height: any,
+        type: any = 0
+      ) {
         context.save();
+        context.clearRect(0, 0, width, height);
         let scaleValue = window.devicePixelRatio;
         dom.setAttribute("width", width * scaleValue);
         dom.setAttribute("height", height * scaleValue);
-
         dom.style.width = width + "px";
         dom.style.height = height + "px";
         context.scale(scaleValue, scaleValue);
-        context.clearRect(0, 0, width, height);
       },
       // 画图介绍
       drawDpiEnd(dom: any, context: any) {
@@ -220,6 +262,7 @@ export default defineComponent({
           // console.log(flag);
           if (flag) {
             console.log("点击了区域" + item.localName);
+            contx.emit("checkSpace", item);
             break;
           }
         }
@@ -273,16 +316,83 @@ export default defineComponent({
           return v1.x * v2.y - v1.y * v2.x;
         }
       },
-      // 画图标
-      drawIcon(ctx: any, url: any, iconPerstion: any) {
-        if (iconPerstion) {
+      loadAllImages(imgUrls: any) {
+        let _load: any = function (imgUrl: any) {
+          //创建img标签
           let img: any = new Image();
-          img.src = url;
-          img.onload = function () {
-            ctx.drawImage(img, iconPerstion.left, iconPerstion.top, 25, 15);
-            iconPerstion.width = 30;
-            iconPerstion.height = 30;
+          img.src = imgUrl;
+          // img.src = require("@/assets/svg/coffee.svg");
+          //跨域选项
+          img.setAttribute("crossOrigin", "Anonymous");
+          return new Promise((resolve, reject) => {
+            //文件加载完毕
+            img.onload = function () {
+              resolve(img);
+            };
+          });
+        };
+        let _loadAll: any = function (imgUrls: any) {
+          let loadedImageUrls: any = [];
+          for (let i = 0, len = imgUrls.length; i < len; i++) {
+            loadedImageUrls.push(_load(imgUrls[i]));
+          }
+          return loadedImageUrls;
+        };
+        return Promise.all(_loadAll(imgUrls));
+      },
+      // 记录需要画的图片
+      addIcon(item: any, type: any, iconPerstion: any) {
+        let key: any = item.spaceId + "" + type;
+        if (proxyData.canvasImageArr[key]) {
+          proxyData.canvasImageArr[key].iconPerstion = iconPerstion;
+        } else {
+          let obj: any = {
+            url: item.icon,
+            iconPerstion: iconPerstion,
           };
+          proxyData.canvasImageArr[key] = obj;
+        }
+      },
+      // 画图标
+      drawIcon(ctx: any, type: any = 0) {
+        let canvasImageArr: any = proxyData.canvasImageArr;
+        let imgUrlArr: any = [];
+        let perstionArr: any = [];
+
+        for (let key in canvasImageArr) {
+          let item: any = canvasImageArr[key];
+          imgUrlArr.push(item.url);
+          perstionArr.push(item.iconPerstion);
+        }
+        if (type == 0) {
+          proxyData.loadAllImages(imgUrlArr).then((res: any) => {
+            proxyData.iconData = res;
+            res.map((icon: any, index: any) => {
+              let iconPerstion: any = perstionArr[index];
+              iconPerstion.width = 25;
+              iconPerstion.height = 15;
+              ctx.drawImage(
+                icon,
+                iconPerstion.left,
+                iconPerstion.top,
+                iconPerstion.width,
+                iconPerstion.height
+              );
+            });
+          });
+        } else {
+          proxyData.iconData.map((icon: any, index: any) => {
+            let iconPerstion: any = perstionArr[index];
+            iconPerstion.width = 25;
+            iconPerstion.height = 15;
+            ctx.drawImage(
+              icon,
+              iconPerstion.left,
+              iconPerstion.top,
+              iconPerstion.width,
+              iconPerstion.height
+            );
+          });
         }
       },
       init(data: any) {

+ 41 - 19
src/views/envmonitor/components/Map/MapBox.vue

@@ -66,6 +66,7 @@
         class="canvasBox"
         ref="canvasRef"
         :mapData="mapData"
+        @checkSpace="checkSpace"
       ></canvas-box>
     </div>
 
@@ -646,6 +647,8 @@ export default defineComponent({
       formateSpecialMapData() {
         let data: any = proxyData.mapData;
         if (data) {
+          data.width = data.width * proxyData.comMapScale;
+          data.height = data.height * proxyData.comMapScale;
           let spaceList: any = data.spaceList || [];
           spaceList.map((item: any) => {
             let remark: any = item.remark;
@@ -661,16 +664,30 @@ export default defineComponent({
               item.detailPointArr = remarkObj.detailPointArr;
               item.devicePointArr = remarkObj.devicePointArr;
               proxyData.setSpaceIcon(item);
+              item.pointArr.map((dev: any) => {
+                dev.left = dev.left * proxyData.comMapScale;
+                dev.top = dev.top * proxyData.comMapScale;
+              });
+              item.logoPointArr.map((dev: any) => {
+                dev.left = dev.left * proxyData.comMapScale;
+                dev.top = (dev.top * 1 - 15) * proxyData.comMapScale;
+              });
+              item.circlePointArr.map((dev: any) => {
+                dev.left = dev.left * proxyData.comMapScale;
+                dev.top = dev.top * proxyData.comMapScale;
+              });
             }
           });
+          //  原始数据* proxyData.comMapScale
           proxyData.copyMapDaata = JSON.parse(JSON.stringify(data));
-          proxyData.formateSpecialMapScale(proxyData.comMapScale);
         }
       },
       //  canvas画的地图缩放处理
       formateSpecialMapScale(scale: any) {
         let data: any = JSON.parse(JSON.stringify(proxyData.copyMapDaata));
         if (data) {
+          data.width = data.width * scale;
+          data.height = data.height * scale;
           let spaceList: any = data.spaceList || [];
           spaceList.map((item: any) => {
             item.pointArr.map((dev: any) => {
@@ -679,13 +696,14 @@ export default defineComponent({
             });
             item.logoPointArr.map((dev: any) => {
               dev.left = dev.left * scale;
-              dev.top = (dev.top - 25) * scale;
+              dev.top = dev.top * scale;
             });
             item.circlePointArr.map((dev: any) => {
               dev.left = dev.left * scale;
-              dev.top = (dev.top - 25) * scale;
+              dev.top = dev.top * scale;
             });
           });
+          proxyData.mapData = data;
         }
       },
       // 获取空间最小宽
@@ -739,14 +757,18 @@ export default defineComponent({
       /**
        * 设置地图最外框宽和高
        */
-      setMapBoxStyle() {
+      setMapBoxStyle(type: any = 0) {
         let mapBoxEle = document.querySelector("#spaceMain");
         if (proxyData.mapData && proxyData.mapData.width) {
           mapBoxEle.style.width = proxyData.mapData.width + "px";
           mapBoxEle.style.height = proxyData.mapData.height + "px";
         }
         if (proxyData.mapType == 2) {
-          canvasRef.value.init(proxyData.mapData);
+          if (type == 0) {
+            canvasRef.value.init(proxyData.mapData);
+          } else {
+            canvasRef.value.scaleCanvas(proxyData.mapData);
+          }
         }
       },
       /**
@@ -775,12 +797,13 @@ export default defineComponent({
        * 更新地图的宽高
        */
       updateMapStyle() {
-        let data: any = JSON.parse(JSON.stringify(proxyData.copyMapDaata));
-        if (data) {
-          data.width = data.width * proxyData.displacement.scale;
-          data.height = data.height * proxyData.displacement.scale;
-          let spaceList: any = data?.spaceList ?? [];
-          if (proxyData.mapType == 1) {
+        if (proxyData.mapType == 1) {
+          // 方形地图处理
+          let data: any = JSON.parse(JSON.stringify(proxyData.copyMapDaata));
+          if (data) {
+            let spaceList: any = data?.spaceList ?? [];
+            data.width = data.width * proxyData.displacement.scale;
+            data.height = data.height * proxyData.displacement.scale;
             for (let i = 0; i < spaceList.length; i++) {
               let item = spaceList[i];
               item.width = item.width * proxyData.displacement.scale;
@@ -788,12 +811,15 @@ export default defineComponent({
               item.top = item.top * proxyData.displacement.scale;
               item.left = item.left * proxyData.displacement.scale;
             }
-          } else {
-            proxyData.formateSpecialMapScale(proxyData.displacement.scale);
+            proxyData.mapData = data;
           }
-          proxyData.mapData = data;
-          proxyData.setMapBoxStyle();
+        } else {
+          // canvas画的地图逻辑处理
+
+          proxyData.formateSpecialMapScale(proxyData.displacement.scale);
         }
+
+        proxyData.setMapBoxStyle(1);
       },
       /**
        * 更新地图的位置
@@ -1107,7 +1133,6 @@ export default defineComponent({
               } else {
                 proxyData.formateMapData();
               }
-
               // 首次进入页面的时候展示空间来源于父div
               if (searchItem) {
                 let area = proxyData.getFirstSelectSpace(searchItem);
@@ -1122,9 +1147,6 @@ export default defineComponent({
                 proxyData.setMapBoxStyle();
                 proxyData.mapScale();
                 proxyData.mapScroll();
-                if (proxyData.mapType == 2) {
-                  canvasRef.value.init(proxyData.mapData);
-                }
               });
             }
           })

+ 5 - 5
src/views/mapData/indexOld.vue

@@ -88,27 +88,27 @@ export default defineComponent({
         proxyData.spaceArr.map((item: any) => {
           item.devicePointArr.map((dev: any) => {
             dev.left = dev.left * 1;
-            dev.top = proxyData.floorObj.height - dev.top;
+            dev.top = proxyData.floorObj.height* 1 - dev.top* 1;
             // dev.top = dev.top;
           });
           item.logoPointArr.map((dev: any) => {
             dev.left = dev.left * 1;
-            dev.top = proxyData.floorObj.height - dev.top;
+            dev.top = proxyData.floorObj.height* 1 - dev.top* 1;
             // dev.top = dev.top;
           });
           item.pointArr.map((dev: any) => {
             dev.left = dev.left * 1;
-            dev.top = proxyData.floorObj.height - dev.top;
+            dev.top = proxyData.floorObj.height* 1 - dev.top* 1;
             // dev.top = dev.top;
           });
           item.circlePointArr.map((dev: any) => {
             dev.left = dev.left * 1;
-            dev.top = proxyData.floorObj.height - dev.top;
+            dev.top = proxyData.floorObj.height* 1 - dev.top* 1;
             // dev.top = dev.top;
           });
           item.detailPointArr.map((dev: any) => {
             dev.left = dev.left * 1;
-            dev.top = proxyData.floorObj.height - dev.top;
+            dev.top = proxyData.floorObj.height* 1 - dev.top* 1;
             // dev.top = dev.top;
           });
         });