cuiqian2004
2025-10-17 68ce9382090846dc3a03a057a18a7d09f30e45e5
pages/map/js/ctx.js
@@ -468,12 +468,18 @@
         cantainerEl.addEventListener('touchend', function(e) {
            //   _this.canvas._onMouseUp(e);
            //   console.log('touchend:');
            e.preventDefault(); // 阻止默认行为
            _this.touchPoint = {
               x: 0,
               y: 0
            };
            if (_this.pressObjTimer) {
               clearTimeout(_this.pressObjTimer);
               _this.pressObjTimer = null
            }
            const activeObj = _this.canvas.getActiveObject()
            if (!activeObj) {
               // 处理结束事件
@@ -488,16 +494,13 @@
               //    _this.canvas.discardActiveObject();
               // }
            }
            if (this.pressObjTimer) {
               clearTimeout(this.pressObjTimer);
               this.pressObjTimer = null
            }
         });
         cantainerEl.addEventListener('touchcancel', function(e) {
            //   console.log('touchcancel:');
            if (this.pressObjTimer) {
               clearTimeout(this.pressObjTimer);
               this.pressObjTimer = null
            if (_this.pressObjTimer) {
               clearTimeout(_this.pressObjTimer);
               _this.pressObjTimer = null
            }
         })
@@ -522,6 +525,7 @@
               const list = _this.canvas.getActiveObjects()
               if (list.length === 1) {
                  if (!_this.objEditing) {
                     this.pressObjTimer = setTimeout(function() {
                        const zoom = _this.canvas.getZoom();
@@ -569,6 +573,7 @@
                           });
                        }
                     }, 1000); //
                  }
                  let activeObj = list[0]
                  if (activeObj.eleType == "region_pt_add") {
@@ -812,7 +817,10 @@
            if (obj instanceof fabric.Path || obj instanceof fabric.Line) {
               if (this.isPointOnStroke(obj, pointer, 1)) {
                  if (objActive != obj) {
                     if (this.pressObjTimer) {
                        clearTimeout(this.pressObjTimer);
                        this.pressObjTimer = null
                     }
                     this.canvas.discardActiveObject()
                     this.canvas.setActiveObject(obj);
                     this.canvas.requestRenderAll();
@@ -822,7 +830,10 @@
               pointerList2.unshift(obj)
            } else {
               if (objActive != obj) {
                  if (this.pressObjTimer) {
                     clearTimeout(this.pressObjTimer);
                     this.pressObjTimer = null
                  }
                  this.canvas.discardActiveObject()
                  this.canvas.setActiveObject(obj);
                  this.canvas.requestRenderAll();
@@ -835,7 +846,10 @@
            if (pointerList2.length == 1) {
               const obj = pointerList2[0];
               if (objActive != obj) {
                  if (this.pressObjTimer) {
                     clearTimeout(this.pressObjTimer);
                     this.pressObjTimer = null
                  }
                  this.canvas.discardActiveObject()
                  this.canvas.setActiveObject(obj);
                  this.canvas.requestRenderAll();
@@ -848,7 +862,10 @@
               const obj = pointerList[i];
               if (this.isPointOnStroke(obj, pointer, 2)) {
                  if (objActive != obj) {
                     if (this.pressObjTimer) {
                        clearTimeout(this.pressObjTimer);
                        this.pressObjTimer = null
                     }
                     this.canvas.discardActiveObject()
                     this.canvas.setActiveObject(obj);
                     this.canvas.requestRenderAll();
@@ -862,7 +879,10 @@
            if (pointerList2.length == 1) {
               const obj = pointerList2[0];
               if (objActive != obj) {
                  if (this.pressObjTimer) {
                     clearTimeout(this.pressObjTimer);
                     this.pressObjTimer = null
                  }
                  this.canvas.discardActiveObject()
                  this.canvas.setActiveObject(obj);
                  this.canvas.requestRenderAll();
@@ -875,7 +895,10 @@
               const obj = pointerList[i];
               if (this.isPointOnStroke(obj, pointer, 3)) {
                  if (objActive != obj) {
                     if (this.pressObjTimer) {
                        clearTimeout(this.pressObjTimer);
                        this.pressObjTimer = null
                     }
                     this.canvas.discardActiveObject()
                     this.canvas.setActiveObject(obj);
                     this.canvas.requestRenderAll();
@@ -889,7 +912,10 @@
            if (pointerList2.length == 1) {
               const obj = pointerList2[0];
               if (objActive != obj) {
                  if (this.pressObjTimer) {
                     clearTimeout(this.pressObjTimer);
                     this.pressObjTimer = null
                  }
                  this.canvas.discardActiveObject()
                  this.canvas.setActiveObject(obj);
                  this.canvas.requestRenderAll();
@@ -902,7 +928,10 @@
               const obj = pointerList[i];
               if (this.isPointOnStroke(obj, pointer, 4)) {
                  if (objActive != obj) {
                     if (this.pressObjTimer) {
                        clearTimeout(this.pressObjTimer);
                        this.pressObjTimer = null
                     }
                     this.canvas.discardActiveObject()
                     this.canvas.setActiveObject(obj);
                     this.canvas.requestRenderAll();
@@ -916,7 +945,10 @@
            const obj = pointerList2[pointerList2.length - 1];
            if (objActive != obj) {
               if (this.pressObjTimer) {
                  clearTimeout(this.pressObjTimer);
                  this.pressObjTimer = null
               }
               this.canvas.discardActiveObject()
               this.canvas.setActiveObject(obj);
               this.canvas.requestRenderAll();
@@ -1202,7 +1234,7 @@
               _this.$ownerInstance.callMethod('receiveRenderData', {
                  method: "set_backgroud_progress",
                  type: "error",
                  msg:err
                  msg: err
               });
               console.error("图片加载失败", err)
               reject(new Error('图片加载失败'));
@@ -1236,6 +1268,7 @@
         }
      },
      clearObjects() {
         if (!this.canvas) return;
         this.canvas.discardActiveObject()
         const objects = this.canvas.getObjects()
@@ -1251,6 +1284,8 @@
         this.objEditing = null;
         this.editObject = null;
         this.drawingObj = null;
         this.objAgvLaser = null
         this.objAgvLaserLine = null
         if (this.pressObjTimer) {
            clearTimeout(this.pressObjTimer);
            this.pressObjTimer = null;
@@ -1370,6 +1405,8 @@
                     // _this.canvas.renderAll()
                     _this.workSpace = wsGroup
                     const scale = _this.eleWidth / (4 * 84)
                     _this.setZoomAuto(scale); //
                  }
                  //_this.checkMemoryUsage()
                  resolve()
@@ -1391,7 +1428,7 @@
                     strokeLineCap: 'butt',
                     fill: "rgba(255,255,255,0)",
                  })
                  let wsGroup = new fabric.Group([ rect], {
                  let wsGroup = new fabric.Group([rect], {
                     id: "workspace",
                     eleType: "workspace",
                     selectable: false,
@@ -1400,11 +1437,13 @@
                     top: 0,
                     width: _this.mapInfo.img_x,
                     height: _this.mapInfo.img_y,
                  });
                  _this.clearObjects()
                  _this.canvas.add(wsGroup)
                  _this.workSpace = wsGroup
                  const scale = _this.eleWidth / (4 * 84)
                  _this.setZoomAuto(scale); //
                  resolve()
               })
@@ -1539,11 +1578,13 @@
                  clearTimeout(this.pressObjTimer);
                  this.pressObjTimer = null
               }
            }
            if (Math.abs(deltaX) > 20 || Math.abs(deltaY) > 20) {
               this.$ownerInstance.callMethod('receiveRenderData', {
                  method: "cancel_positioning_agv",
               });
            }
            // 移动视口
            const vpt = this.canvas.viewportTransform;
            this.canvas.relativePan(new fabric.Point(deltaX, deltaY));
@@ -1773,9 +1814,7 @@
         }
         //console.log(scale, scaleAuto)
         this.setZoomAuto(scale, center)
         this.$ownerInstance.callMethod('receiveRenderData', {
            method: "cancel_positioning_agv",
         });
         //   console.log('多点移动 - 距离:', distance, '角度:', angle);
         // 多点移动逻辑
      },
@@ -1886,7 +1925,7 @@
            const left = _this.getXOnImg(info.x) // * scale
            const top = _this.getYOnImg(info.y) //* scale
            const angle = info.angle * 180 / Math.PI
            const angle = -(info.angle * 180 / Math.PI)
            fabric.loadSVGFromURL(svg).then(
               ({
                  objects,
@@ -2018,7 +2057,8 @@
            this.canvas.remove(this.curTeachingObj)
            this.curTeachingObj = null
         }
         if (teachingData.lenght === 0)
            return
         posArr.forEach((item) => {
            const curIndex = pos_list.findIndex((item2) => item2.x === item.x && item2.y === item.y)
            if (curIndex < 0) {
@@ -2026,9 +2066,6 @@
            }
         })
         let path2 = ""
         const theta = 20;
         let headlen = 10;
         var main_road = teachingData.main_road || 0
         const len = pos_list.length
         let fromX = 0,
@@ -2042,45 +2079,18 @@
               y: this.getYOnImg(pt.y)
            }
            if (index > 0) {
               if ((index % 50 == 0 || index == len - 1 || index % 50 == 1)) {
                  if (index % 50 == 0 || index == len - 1) {
                     toX = pt2.x
                     toY = pt2.y
                     path2 += ` L${pt2.x} ${pt2.y}`
                     // 计算各角度和对应的P2,P3坐标
                     let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,
                        angle1 = ((angle + theta) * Math.PI) / 180,
                        angle2 = ((angle - theta) * Math.PI) / 180,
                        topX = headlen * Math.cos(angle1),
                        topY = headlen * Math.sin(angle1),
                        botX = headlen * Math.cos(angle2),
                        botY = headlen * Math.sin(angle2);
                     let arrowX = fromX - topX,
                        arrowY = fromY - topY;
                     arrowX = toX + topX;
                     arrowY = toY + topY;
                     path2 += " L " + arrowX + " " + arrowY;
                     arrowX = toX + botX;
                     arrowY = toY + botY;
                     path2 += " M " + arrowX + " " + arrowY;
                     path2 += " L " + toX + " " + toY;
                  }
               } else {
                  path2 += ` L${pt2.x} ${pt2.y}`
               }
               path2 += ` L${pt2.x} ${pt2.y}`
            } else {
               path2 = `M${pt2.x} ${pt2.y}`
            }
            fromX = pt2.x
            fromY = pt2.y
         }
         let strokeWidth = 1
         let stroke = "#95DE64"
         let strokeWidth = 5
         let stroke = "#69C0FF"
         if (main_road == 1) {
            stroke = "#69C0FF"
         }
         const objPath = new fabric.Path(
            path2, {
               id: "current_teaching",
@@ -2116,7 +2126,7 @@
         const theta = 20;
         let headlen = 10;
         var main_road = 1
         var main_road = teachingData.main_road
         const len = pos_list.length
         let fromX = 0,
@@ -2132,77 +2142,12 @@
               y: this.getYOnImg(pt.y)
            }
            if (index > 0) {
               if ((type == "public_teaching") && (index % 50 == 0 || index == len - 1 || index % 50 == 1)) {
                  if (index % 50 == 1 || index == len - 1) {
                     if (teachingData.bidirection == 1 && index < len - 1) { //- 1
                        toY = fromY
                        toX = fromX
                        fromX = pt2.x
                        fromY = pt2.y
                        let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,
                           angle1 = ((angle + theta) * Math.PI) / 180,
                           angle2 = ((angle - theta) * Math.PI) / 180,
                           topX = headlen * Math.cos(angle1),
                           topY = headlen * Math.sin(angle1),
                           botX = headlen * Math.cos(angle2),
                           botY = headlen * Math.sin(angle2);
                        let arrowX = fromX - topX,
                           arrowY = fromY - topY;
                        arrowX = toX + topX;
                        arrowY = toY + topY;
                        let path3 = " L " + arrowX + " " + arrowY;
                        arrowX = toX + botX;
                        arrowY = toY + botY;
                        path3 += " M " + arrowX + " " + arrowY;
                        path3 += " L " + toX + " " + toY;
                        path2 += path3
                        fromY = toY
                        fromX = toX
                     }
                  }
                  if (index % 50 == 0 || index == len - 1) {
                     toX = pt2.x
                     toY = pt2.y
                     // if (fromX == toX && fromY == toY) {
                     //    if (index - 2 >= 0) {
                     //       const pt3 = pos_list[index - 2]
                     //       fromX = this.getXOnImg(pt3.x),
                     //          fromY = this.getYOnImg(pt3.y)
                     //    } else {
                     //       continue;
                     //    }
                     // }
                     path2 += ` L${pt2.x} ${pt2.y}`
                     // 计算各角度和对应的P2,P3坐标
                     let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,
                        angle1 = ((angle + theta) * Math.PI) / 180,
                        angle2 = ((angle - theta) * Math.PI) / 180,
                        topX = headlen * Math.cos(angle1),
                        topY = headlen * Math.sin(angle1),
                        botX = headlen * Math.cos(angle2),
                        botY = headlen * Math.sin(angle2);
                     let arrowX = fromX - topX,
                        arrowY = fromY - topY;
                     arrowX = toX + topX;
                     arrowY = toY + topY;
                     path2 += " L " + arrowX + " " + arrowY;
                     arrowX = toX + botX;
                     arrowY = toY + botY;
                     path2 += " M " + arrowX + " " + arrowY;
                     path2 += " L " + toX + " " + toY;
                  }
                  //   console.log(`箭头 L${pt2.x} ${pt2.y}`)
               } else {
                  //   console.log(`点 L${pt2.x} ${pt2.y} ${index} == ${len-1}`)
                  path2 += ` L${pt2.x} ${pt2.y}`
               }
               path2 += ` L${pt2.x} ${pt2.y}`
            } else {
               main_road = pt.main_road
               if (main_road == 1) {
                  headlen = 15
               }
               if (main_road === undefined)
                  main_road = pt.main_road
               path2 = `M${pt2.x} ${pt2.y}`
            }
            fromX = pt2.x
@@ -2213,15 +2158,25 @@
         // console.log("addTeachingPath",path2)
         // path2 += " Z"
         let strokeWidth = 1
         let stroke = "#95DE64"
         let strokeWidth = 1.5
         let stroke = "#69C0FF"
         if (type == "station_teaching") {
            stroke = "#69C0FF"
         } else {
            if (main_road == 1) {
               stroke = "#69C0FF"
               //stroke = "#69C0FF"
               if (teachingData.bidirection == 1) {
                  stroke = "#ffaa00"
               }
               strokeWidth = 3
            } else {
               if (teachingData.bidirection == 1) {
                  stroke = "#FF00FF"
               }
            }
         }
         teachingData.main_road = main_road
         let list = this.canvas.getObjects() || []
         list = list.filter((a) => a.eleType == "station_teaching" || a.eleType == "public_teaching")
         let lenTeaching = list.length
@@ -2256,6 +2211,7 @@
         return objPath
      },
      isObjectFullyContained(outerObj, innerObj) {
         const outer = outerObj.getBoundingRect(true, true);
         const inner = innerObj.getBoundingRect(true, true);
@@ -2310,7 +2266,7 @@
         let id = ""
         if (teachingMode.mode == "Public") {
            eleType = "public_teaching"
            id = `public_teaching_${teachingMode.name}`
            id = `public_teaching_${teachingMode.name}_${teachingMode.edge_name}`
         } else if (teachingMode.mode == "Stations") {
            eleType = "station_teaching"
            id = `station_teaching_${teachingMode.src_dst}`
@@ -2461,7 +2417,7 @@
            //   const scale = this.getAutoScale()
            const left = _this.getXOnImg(info.x) // * scale
            const top = _this.getYOnImg(info.y) //* scale
            const angle = info.angle * 180 / Math.PI
            const angle = -(info.angle * 180 / Math.PI) + 90
            if (obj) {
               obj.set({
                  left,
@@ -3028,53 +2984,102 @@
         this.canvas.remove(obj)
      },
      updateAgvLaser(param) {
         const angle = param.angle - Math.PI / 2 // * 180 / Math.PI
         const angle = -param.angle //- Math.PI / 2 // * 180 / Math.PI
         const pt = {
            x: this.getXOnImg(param.x),
            y: this.getYOnImg(param.y)
         }
         if (this.objAgvLaser) {
            this.objAgvLaser.set({stroke: "#00ff00",   rx: 2,
            ry:2})
         }
         let ellipse = new fabric.Ellipse({
            id: "agv_laser",
            eleType: "agv_laser",
            left: pt.x,
            top: pt.y,
            rx: 2,
            ry: 2,
            stroke: "#00aa00",
            rx: 3,
            ry: 3,
            stroke: "#ff0000",
            strokeWidth: 1,
            fill: "#00aa00",
            fill: "#00ff00",
            originX: "center",
            originY: "center",
            selectable: false,
            hasControls: true,
            lockRotation: true,
            lockScalingX: true,
            lockScalingY: true,
            lockMovementX: true,
            lockMovementY: true,
            hasControls: false,
         });
         this.canvas.add(ellipse)
         const offX = 20 * Math.cos(angle)
         const offY = 20 * Math.sin(angle)
         if (this.objAgvLaser) {
            this.canvas.remove(this.objAgvLaser)
         this.objAgvLaser = ellipse
         if (this.objAgvLaserLine) {
            this.canvas.remove(this.objAgvLaserLine)
         }
         const line = new fabric.Line([pt.x, pt.y, pt.x + offX,
            pt.y + offY
         ], {
            id: "agv_laser_angle",
            eleType: "agv_laser_angle",
            stroke: "#00aa00",
            strokeWidth: 2,
            lockRotation: true,
            lockScalingX: true,
            lockScalingY: true,
            lockMovementX: true,
            lockMovementY: true,
            stroke: "#00ff00",
            strokeWidth: 1,
            selectable: false,
            hasControls: false,
         });
         this.objAgvLaser = line
         this.objAgvLaserLine = line
         this.canvas.add(line)
      },
      addTrajectoryPoint(list) {
         const objs = []
         let right = 0
         let bottom = 0
         let left = this.mapInfo.img_x
         let top = this.mapInfo.img_y
         for (let i in list) {
            const pt = list[i]
            const pt2 = {
               x: this.getXOnImg(pt[0]),
               y: this.getYOnImg(pt[1])
            }
            let ellipse = new fabric.Ellipse({
               left: pt2.x,
               top: pt2.y,
               rx: 2,
               ry: 2,
               stroke: "#00ff00",
               strokeWidth: 1,
               fill: "#00ff00",
               originX: "center",
               originY: "center",
            });
            objs.push(ellipse)
            if (left > pt2.x-2) {
               left = pt2.x-2
            }
            if (top > pt2.y-2) {
               top = pt2.y-2
            }
            if (right < pt2.x + 2) {
               right = pt2.x + 2
            }
            if (bottom < pt2.y + 2) {
               bottom = pt2.y + 2
            }
         }
         const groupObj = new fabric.Group(objs, {
            id: `trajectory_point_group`,
            eleType: "trajectory_point_group",
            left,
            top,
            width: right - left,
            height: bottom - top,
            selectable: false,
            hasControls: true,
         })
         this.canvas.add(groupObj)
      },
      updateLaserPoint(param) {
@@ -3116,7 +3121,7 @@
               top: pt2.y,
               width: 1,
               height: 1,
               fill: "#F5222D",
               fill: "#ff00ff",
               originX: "left",
               originY: "top",
               // selectable: false,
@@ -3325,7 +3330,7 @@
                     } else {
                        //   _this.canvas.remove(list[curIndex])
                        const curStationObj = list[curIndex]
                        const angle = station.angle * 180 / Math.PI
                        const angle = -station.angle * 180 / Math.PI
                        //const scale = this.getAutoScale()
                        const left = this.getXOnImg(station.x) //* scale
                        const top = this.getYOnImg(station.y) //* scale
@@ -3360,6 +3365,7 @@
               } else if (item.method == "remove_station") {
                  const stationList = item.param || []
                  this.canvas.discardActiveObject()
                  let list = _this.canvas.getObjects() || []
                  list = list.filter((a) => a.eleType == "station")
@@ -3536,6 +3542,7 @@
                  _this.showTeachingPath(_this.showTeachPathFlag ? true : false)
               } else if (item.method == "clear_teaching_path") {
                  this.canvas.discardActiveObject()
                  let list = _this.canvas.getObjects() || []
                  list = list.filter((a) => a.eleType == "public_teaching" || a.eleType ==
                     "station_teaching")
@@ -3548,7 +3555,7 @@
                  const show = item.param?.show || false
                  for (let i2 in teachingPathList) {
                     const teachingPath = teachingPathList[i2]
                     const id = `public_teaching_${teachingPath.name}`
                     const id = `public_teaching_${teachingPath.name}_${teachingPath.edge_name}`
                     const obj = await this.addTeachingPath(teachingPath, id, "public_teaching",
                        show)
                     obj.set({
@@ -3575,10 +3582,11 @@
                  _this.showTeachingPath(item.param.show)
               } else if (item.method == "remove_teaching_path") {
                  this.canvas.discardActiveObject()
                  let list = _this.canvas.getObjects() || []
                  if (item.param.mode == "Public") {
                     list = list.filter((a) => a.eleType == "public_teaching")
                     const id = `public_teaching_${item.param.name}`
                     const id = `public_teaching_${item.param.name}_${item.param.edge_name}`
                     const curIndex = list.findIndex((a) => a.id == id)
                     if (curIndex > -1) {
@@ -3600,6 +3608,38 @@
                  const teachingMode = item.param
                  _this.showEditTeachingPath(teachingMode)
               } else if (item.method == "update_teaching") {
                  let list = _this.canvas.getObjects() || []
                  list = list.filter((a) => a.eleType == "public_teaching")
                  const id = `public_teaching_${item.param.name}_${item.param.edge_name}`
                  const curIndex = list.findIndex((a) => a.id == id)
                  if (curIndex > -1) {
                     const obj = list[curIndex]
                     let strokeWidth = 1.5
                     let stroke = "#69C0FF"
                     if (item.param.main_road == 1) {
                        //stroke = "#69C0FF"
                        if (item.param.bidirection == 1) {
                           stroke = "#ffaa00"
                        }
                        strokeWidth = 3
                     } else {
                        if (item.param.bidirection == 1) {
                           stroke = "#FF00FF"
                        }
                     }
                     obj.set({
                        strokeWidth,
                        stroke
                     })
                  }
               } else if (item.method == "set_selectable") {
                  if (item.param)
                     _this.setAllObjectSelectable(true)
@@ -3648,6 +3688,7 @@
                  }
               } else if (item.method == "remove_wall") {
                  const wallList = item.param || []
                  this.canvas.discardActiveObject()
                  let list = _this.canvas.getObjects() || []
                  list = list.filter((a) => a.eleType == "virtual_wall")
                  for (let i2 in wallList) {
@@ -3659,6 +3700,7 @@
                  }
               } else if (item.method == "remove_region") {
                  const regionList = item.param || []
                  this.canvas.discardActiveObject()
                  let list = _this.canvas.getObjects() || []
                  list = list.filter((a) => a.eleType == "region")
                  for (let i2 in regionList) {
@@ -3672,7 +3714,10 @@
                  this.updateAgvLaser(item.param || {})
               } else if (item.method == "point_cloud") {
                  this.updateLaserPoint(item.param || {})
               } else if (item.method == "point_trajectory") {
                  this.addTrajectoryPoint(item.param || [])
               }
            }
            if (_this.canvas)
               _this.canvas.renderAll()