| | |
| | | import { |
| | | Base64 |
| | | } from '../../../comm/base64.js'; |
| | | import { |
| | | hasSelfIntersection |
| | | } from '../../../comm/line.js'; |
| | | import { |
| | | hexToRGBA, |
| | | } from '../../../comm/utils.js'; |
| | | import { |
| | | throttle |
| | | } from 'lodash-es'; |
| | | import { |
| | | debounce |
| | | } from "lodash-es"; |
| | | import { |
| | | Result |
| | | } from "ant-design-vue"; |
| | | |
| | | // import okIcon from '../../../static/images/confirm.svg'; |
| | | // import cancelIcon from '../../../static/images/remove.svg'; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | |
| | | agvObj: null, |
| | | initFlag: false, |
| | | editMode: false, |
| | | |
| | | objEditing: null, |
| | | onOjectMoving: debounce(this.objectMoving, 200), |
| | | mapInfo: { |
| | | proportion: 1, |
| | | img_proportion: 1, |
| | | max_x: 1, |
| | | max_y: 1, |
| | | min_x: 0, |
| | | min_y: 0, |
| | | img_x: 1, |
| | | img_y: 1 |
| | | }, |
| | | pressObjTimer: 0 |
| | | |
| | | } |
| | | }, |
| | |
| | | transparentCorners: false, |
| | | cornerStyle: 'circle', |
| | | borderScaleFactor: 2, |
| | | padding: 10, |
| | | padding: 5, |
| | | |
| | | }); |
| | | this.canvasId = `canvas_${uuidv4()}` |
| | |
| | | stopContextMenu: true, // 禁止长按菜单 |
| | | fireRightClick: true, |
| | | fireMiddleClick: true, |
| | | targetFindTolerance: 15, // 增大触摸容差 |
| | | isTouchSupported: true |
| | | targetFindTolerance: 10, // 增大触摸容差 |
| | | isTouchSupported: true, |
| | | enableRetinaScaling: true, |
| | | renderOnAddRemove: false, |
| | | imageSmoothingEnabled: true |
| | | }) |
| | | this.canvas.clear() |
| | | this.eleWidth = cantainerEl.clientWidth |
| | |
| | | height: this.eleHeight, |
| | | selectable: false, |
| | | hasControls: false, |
| | | fill: "#FFFFFF" |
| | | fill: "#FFFFFF20" |
| | | }) |
| | | this.canvas.add(this.workSpace) |
| | | this.patchFabricForUniApp(this.canvas) |
| | |
| | | return this; |
| | | }; |
| | | }, |
| | | createDeleteControl(obj) { |
| | | // 创建删除按钮的图片元素 |
| | | const _this = this |
| | | const deleteIcon = |
| | | "data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='595.275px' height='595.275px' viewBox='200 215 230 470' xml:space='preserve'%3E%3Ccircle style='fill:%23F44336;' cx='299.76' cy='439.067' r='218.516'/%3E%3Cg%3E%3Crect x='267.162' y='307.978' transform='matrix(0.7071 -0.7071 0.7071 0.7071 -222.6202 340.6915)' style='fill:white;' width='65.545' height='262.18'/%3E%3Crect x='266.988' y='308.153' transform='matrix(0.7071 0.7071 -0.7071 0.7071 398.3889 -83.3116)' style='fill:white;' width='65.544' height='262.179'/%3E%3C/g%3E%3C/svg%3E"; |
| | | const deleteImg = document.createElement('img'); |
| | | deleteImg.src = deleteIcon; |
| | | // 添加自定义删除控件到所有对象的原型上 |
| | | // console.log("controls", JSON.stringify(fabric.Object.prototype)) |
| | | obj.controls.deleteControl = new fabric.Control({ |
| | | x: 0.5, |
| | | y: 0, |
| | | offsetY: 0, |
| | | offsetX: 36, |
| | | mouseDownHandler: _this.deleteObject, // 触摸事件处理器 |
| | | render: (ctx, left, top, styleOverride, fabricObject) => { |
| | | |
| | | if (fabricObject.lockRemove) { |
| | | return; |
| | | } |
| | | if (fabricObject.canvas?.skipTargetFind) { |
| | | return; |
| | | } |
| | | const size = this.cornerSize || 36; |
| | | // drawImg(ctx, left, top, imgDelete, 24, 24, fabricObject.angle); |
| | | ctx.save(); |
| | | ctx.translate(left, top); |
| | | ctx.drawImage(deleteImg, -size / 2, -size / 2, size, size); |
| | | ctx.restore(); |
| | | }, |
| | | cornerSize: 36, |
| | | withConnection: false, |
| | | actionName: 'delete', // 动作名称 |
| | | pointerStyle: 'pointer' // 指针样式 |
| | | }); |
| | | }, |
| | | deleteObject(eventData, transform, x, y) { |
| | | console.log("") |
| | | const target = transform.target; |
| | | const canvas = target.canvas; |
| | | |
| | | canvas.remove(target); |
| | | canvas.requestRenderAll(); |
| | | }, |
| | | editCancelObject(eventData, transform, x, y) { |
| | | const target = transform.target; |
| | | const canvas = target.canvas; |
| | | this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "edit_finish", |
| | | cmd: "cancel", |
| | | type: target.eleType, |
| | | data: target.data, |
| | | station: target.data, |
| | | }); |
| | | target.set({ |
| | | lockEdit: true |
| | | }) |
| | | |
| | | this.canvas.requestRenderAll() |
| | | }, |
| | | editOkObject(eventData, transform, x, y) { |
| | |
| | | this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "edit_finish", |
| | | cmd: "ok", |
| | | type: target.eleType, |
| | | data: target.data, |
| | | station: target.data, |
| | | }); |
| | | target.set({ |
| | | lockEdit: true |
| | | }) |
| | | this.canvas.requestRenderAll() |
| | | }, |
| | | |
| | | closeOkCancelControl() { |
| | | let list = this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "cmd") |
| | | list.forEach((obj) => { |
| | | this.canvas.remove(obj) |
| | | }) |
| | | this.objEditing = null |
| | | |
| | | }, |
| | | createOkCancelControl(obj) { |
| | | // 创建删除按钮的图片元素 |
| | | const _this = this |
| | | const cancelImg = document.createElement('img'); |
| | | cancelImg.src = "static/images/remove.svg" |
| | | const okImg = document.createElement('img'); |
| | | okImg.src = "static/images/confirm.svg" |
| | | // 添加自定义删除控件到所有对象的原型上 |
| | | // console.log("controls", JSON.stringify(fabric.Object.prototype)) |
| | | obj.controls.cancelControl = new fabric.Control({ |
| | | x: -0.5, |
| | | y: 0, |
| | | offsetY: 0, |
| | | offsetX: -32, |
| | | mouseDownHandler: _this.editCancelObject, // 触摸事件处理器 |
| | | render: (ctx, left, top, styleOverride, fabricObject) => { |
| | | var scale = this.canvas.getZoom() |
| | | if (scale < 1) { |
| | | scale = 1 |
| | | } |
| | | var scale2 = 1 |
| | | var offset = 50 |
| | | |
| | | if (fabricObject.lockEdit) { |
| | | return; |
| | | } |
| | | if (fabricObject.canvas?.skipTargetFind) { |
| | | return; |
| | | } |
| | | const size = this.cornerSize || 32; |
| | | // drawImg(ctx, left, top, imgDelete, 24, 24, fabricObject.angle); |
| | | ctx.save(); |
| | | ctx.translate(left, top); |
| | | ctx.drawImage(cancelImg, -size / 2, -size / 2, size, size); |
| | | ctx.restore(); |
| | | }, |
| | | cornerSize: 32, |
| | | withConnection: false, |
| | | actionName: 'delete', // 动作名称 |
| | | pointerStyle: 'pointer' // 指针样式 |
| | | }); |
| | | obj.controls.okControl = new fabric.Control({ |
| | | x: 0.5, |
| | | y: 0, |
| | | offsetY: 0, |
| | | offsetX: 32, |
| | | mouseDownHandler: _this.editOkObject, // 触摸事件处理器 |
| | | render: (ctx, left, top, styleOverride, fabricObject) => { |
| | | //if (obj.eleType == "station" || obj.eleType == "edit_teaching") { |
| | | scale2 = 1 / scale |
| | | |
| | | if (fabricObject.lockEdit) { |
| | | return; |
| | | } |
| | | if (fabricObject.canvas?.skipTargetFind) { |
| | | return; |
| | | } |
| | | const size = this.cornerSize || 32; |
| | | // drawImg(ctx, left, top, imgDelete, 24, 24, fabricObject.angle); |
| | | ctx.save(); |
| | | ctx.translate(left, top); |
| | | ctx.drawImage(okImg, -size / 2, -size / 2, size, size); |
| | | ctx.restore(); |
| | | }, |
| | | cornerSize: 32, |
| | | withConnection: false, |
| | | actionName: 'delete', // 动作名称 |
| | | pointerStyle: 'pointer' // 指针样式 |
| | | //} |
| | | offset = 50 / scale |
| | | this.objEditing = obj |
| | | let list = this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "cmd") |
| | | if (list.length > 0) { |
| | | let left = obj.left - offset |
| | | let top = obj.top + obj.height / 2 |
| | | if (obj.originX == "center") { |
| | | left = obj.left - obj.width / 2 - offset |
| | | } |
| | | if (obj.originX == "center") { |
| | | top = obj.top |
| | | } |
| | | |
| | | let curIndex = list.findIndex((a) => a.id == "cancel") |
| | | if (curIndex > -1) { |
| | | list[curIndex].set({ |
| | | left, |
| | | top, |
| | | mainObj: obj, |
| | | scaleX: scale2, |
| | | scaleY: scale2 |
| | | }) |
| | | list[curIndex].setCoords() |
| | | this.canvas.bringObjectToFront(list[curIndex]); |
| | | } |
| | | left = obj.left + obj.width + offset |
| | | if (obj.originX == "center") { |
| | | left = obj.left + obj.width / 2 + offset |
| | | } |
| | | curIndex = list.findIndex((a) => a.id == "ok") |
| | | if (curIndex > -1) { |
| | | list[curIndex].set({ |
| | | left, |
| | | top, |
| | | mainObj: obj, |
| | | scaleX: scale2, |
| | | scaleY: scale2 |
| | | }) |
| | | list[curIndex].setCoords() |
| | | this.canvas.bringObjectToFront(list[curIndex]); |
| | | } |
| | | return |
| | | } |
| | | let objList = [] |
| | | let ellipse = new fabric.Ellipse({ |
| | | left: -15, |
| | | top: -15, |
| | | rx: 15, |
| | | ry: 15, |
| | | stroke: "#F5222D", |
| | | strokeWidth: 1, |
| | | fill: "#F5222D", |
| | | |
| | | }); |
| | | objList.push(ellipse) |
| | | let line = new fabric.Line([-6, -6, 6, 6], { |
| | | stroke: "white", |
| | | strokeWidth: 3, |
| | | }); |
| | | objList.push(line) |
| | | line = new fabric.Line([6, -6, -6, 6], { |
| | | stroke: "white", |
| | | strokeWidth: 3, |
| | | }); |
| | | objList.push(line) |
| | | let left = obj.left - offset |
| | | let top = obj.top + obj.height / 2 |
| | | if (obj.originX == "center") { |
| | | left = obj.left - obj.width / 2 - offset |
| | | } |
| | | if (obj.originY == "center") { |
| | | top = obj.top |
| | | } |
| | | let objGroup = new fabric.Group(objList, { |
| | | id: `cancel`, |
| | | eleType: "cmd", |
| | | left, |
| | | top, |
| | | width: 30, |
| | | height: 30, |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | mainObj: obj, |
| | | scaleX: scale2, |
| | | scaleY: scale2 |
| | | }); |
| | | this.canvas.add(objGroup) |
| | | |
| | | objList = [] |
| | | ellipse = new fabric.Ellipse({ |
| | | left: -15, |
| | | top: -15, |
| | | rx: 15, |
| | | ry: 15, |
| | | stroke: "#52C41A", |
| | | strokeWidth: 1, |
| | | fill: "#52C41A", |
| | | }); |
| | | objList.push(ellipse) |
| | | line = new fabric.Line([-8, -2, -2, 5], { |
| | | stroke: "white", |
| | | strokeWidth: 3, |
| | | }); |
| | | objList.push(line) |
| | | line = new fabric.Line([-3, 6, 9, -5], { |
| | | stroke: "white", |
| | | strokeWidth: 3, |
| | | }); |
| | | objList.push(line) |
| | | left = obj.left + obj.width + offset |
| | | if (obj.originX == "center") { |
| | | left = obj.left + obj.width / 2 + offset |
| | | } |
| | | objGroup = new fabric.Group(objList, { |
| | | id: `ok`, |
| | | eleType: "cmd", |
| | | left, |
| | | top, |
| | | width: 30, |
| | | height: 30, |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | scaleX: scale2, |
| | | scaleY: scale2, |
| | | mainObj: obj |
| | | }); |
| | | this.canvas.add(objGroup) |
| | | |
| | | }, |
| | | addObject(obj) { |
| | | obj.set({ |
| | | lockEdit: true |
| | | }) |
| | | this.canvas.add(obj) |
| | | this.createOkCancelControl(obj) |
| | | }, |
| | | |
| | | canvasEventListener() { |
| | | const _this = this |
| | | |
| | |
| | | _this.canvas.on("selection:updated", function(e) { |
| | | console.log("selection:updated", e); |
| | | const activeObj = _this.canvas.getActiveObject(); |
| | | |
| | | activeObj.set({ |
| | | borderColor: '#1890ff', |
| | | borderScaleFactor: 3, |
| | | padding: 5, |
| | | padding: 3, |
| | | borderDashArray: [5, 5], //5px 实线和5px 间隔 |
| | | }); |
| | | _this.canvas.requestRenderAll(); |
| | |
| | | |
| | | }); |
| | | _this.canvas.on("selection:cleared", function(e) { |
| | | console.log("selection:cleared", e); |
| | | // console.log("selection:cleared", e); |
| | | |
| | | //_this.selectionChangeCanvas(); |
| | | }); |
| | |
| | | e.target.isRemoved = true; |
| | | } |
| | | }); |
| | | _this.canvas.on("transform", function(e) { |
| | | _this.onScaleChange() |
| | | }); |
| | | |
| | | _this.canvas.on("object:modified", function(e) { |
| | | // console.log("object:modified", e.target); |
| | | if (e?.target.eleType == "station") { |
| | | const obj = e.target |
| | | obj.data.x = obj.left |
| | | obj.data.y = obj.top |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "update_station", |
| | | station: obj.data, |
| | | |
| | | }); |
| | | } |
| | | |
| | | // _this.resizetCanvas(); |
| | | }); |
| | | _this.canvas.on("object:moving", function(e) { |
| | | // console.log("object:modified", e.target); |
| | | console.log("object:moving", e.target); |
| | | _this.onOjectMoving(e.target) |
| | | |
| | | }); |
| | | |
| | | var pressObjTimer |
| | | |
| | | cantainerEl.addEventListener('touchstart', function(e) { |
| | | console.log('touchstart:', e); |
| | | // console.log('touchstart:', e.touches.length); |
| | | e.preventDefault(); // 阻止默认行为 |
| | | _this.canvas.fire('touch:start', { |
| | | e: e |
| | | }); |
| | | // _this.canvas._onMouseDown(e); |
| | | _this.pointerSelectObject(e) |
| | | if (!_this.canvas.getActiveObject()) { |
| | | // 根据触摸点数量判断交互类型 |
| | | if (e.touches.length === 1) { |
| | | |
| | | |
| | | _this.handleSingleTouch(e.touches[0]); |
| | | } else if (e.touches.length >= 2) { |
| | | |
| | | |
| | | _this.handleMultiTouch(e.touches); |
| | | } |
| | | } else { |
| | | if (e.touches.length === 1) { |
| | | const touch = e.touches[0] |
| | | this.lastPosX = touch.clientX; |
| | | this.lastPosY = touch.clientY; |
| | | _this.lastPosX = touch.clientX; |
| | | _this.lastPosY = touch.clientY; |
| | | |
| | | const list = _this.canvas.getActiveObjects() |
| | | if (list.length === 1) { |
| | | pressObjTimer = setTimeout(function() { |
| | | console.log("edit_station", list[0].eleType) |
| | | if (list[0].eleType == "station") { |
| | | _this.setAllObjectSelectable(false) |
| | | if (!_this.objEditing) { |
| | | this.pressObjTimer = setTimeout(function() { |
| | | |
| | | list[0].set({ |
| | | selectable: true |
| | | }) |
| | | const zoom = _this.canvas.getZoom(); |
| | | let deltaX = list[0].left * zoom |
| | | let deltaY = list[0].top * zoom |
| | | const vpt = _this.canvas.viewportTransform; |
| | | if (list[0].eleType == "station") { |
| | | _this.setAllObjectSelectable(false) |
| | | |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "edit_station", |
| | | station: list[0].data, |
| | | view: { |
| | | x: vpt[4] + deltaX, |
| | | y: vpt[5] + deltaY, |
| | | // x: e.touches[0].clientX, |
| | | // y: e.touches[0].clientY, |
| | | width: list[0].width * zoom, |
| | | height: list[0].height * zoom |
| | | } |
| | | }); |
| | | list[0].set({ |
| | | selectable: true |
| | | }) |
| | | |
| | | let deltaX = list[0].left * zoom |
| | | let deltaY = list[0].top * zoom |
| | | const scale = zoom < 1 ? zoom : 1 |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "edit_station", |
| | | station: list[0].data, |
| | | view: { |
| | | x: vpt[4] + deltaX, |
| | | y: vpt[5] + deltaY, |
| | | // x: e.touches[0].clientX, |
| | | // y: e.touches[0].clientY, |
| | | width: list[0].width * scale, |
| | | height: list[0].height * scale |
| | | } |
| | | }); |
| | | } else if (list[0].eleType == "public_teaching") { |
| | | const pt = _this.canvas.getPointer(touch); // ← 关键 |
| | | // 2. pointer 就是画布坐标 |
| | | |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "select_teaching_path", |
| | | data: list[0].data, |
| | | type: "public", |
| | | point: pt |
| | | |
| | | |
| | | }); |
| | | } else if (list[0].eleType == "station_teaching") { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "select_teaching_path", |
| | | data: list[0].data, |
| | | type: "station", |
| | | point: pt |
| | | }); |
| | | } |
| | | }, 1000); // |
| | | } |
| | | let activeObj = list[0] |
| | | if (activeObj.eleType == "region_pt_add") { |
| | | const data = activeObj.mainObj?.data |
| | | |
| | | data.path.push({ |
| | | x: _this.getActualXFromImg(activeObj.left), |
| | | y: _this.getActualYFromImg(activeObj.top) |
| | | }) |
| | | _this.updateRegion(activeObj.mainObj, data) |
| | | } else if (activeObj.eleType == "cmd") { |
| | | let data = activeObj.mainObj.data |
| | | if (activeObj.mainObj.eleType == "edit_teaching") { |
| | | |
| | | let left = _this.getActualXFromImg(activeObj.left) |
| | | let top = _this.getActualYFromImg(activeObj.top) |
| | | let right = _this.getActualXFromImg(activeObj.left + activeObj.width) |
| | | let bottom = _this.getActualYFromImg(activeObj.top + activeObj.height) |
| | | data = [ |
| | | [left, top], |
| | | [left, bottom], |
| | | [right, bottom], |
| | | [right, top] |
| | | ] |
| | | console.log(data) |
| | | } |
| | | }, 3000); // |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "edit_finish", |
| | | cmd: activeObj.id, |
| | | type: activeObj.mainObj.eleType, |
| | | data: data, |
| | | }); |
| | | if (activeObj.id == "ok") { |
| | | if (activeObj.mainObj.eleType == "region") { |
| | | _this.addRegionFinish(activeObj.mainObj) |
| | | } else if (activeObj.mainObj.eleType == "virtual_wall") { |
| | | _this.addVirtualWallFinish(activeObj.mainObj) |
| | | } |
| | | |
| | | } |
| | | if (activeObj.mainObj.eleType == "edit_teaching") { |
| | | let list = _this.canvas.getObjects() || [] |
| | | for (let i2 in list) { |
| | | const obj = list[i2] |
| | | obj.set({ |
| | | opacity: 1 |
| | | }) |
| | | } |
| | | if (activeObj.mainObj?.mainObj) { |
| | | activeObj.mainObj.mainObj.set({ |
| | | selectable: true |
| | | }) |
| | | } |
| | | const ptObjs = activeObj.mainObj.ptObjs || [] |
| | | _this.canvas.remove(activeObj.mainObj) |
| | | for (let i2 in ptObjs) { |
| | | const obj = ptObjs[i2] |
| | | _this.canvas.remove(obj) |
| | | } |
| | | } |
| | | if (activeObj.mainObj.eleType == "station") { |
| | | |
| | | _this.setAllObjectSelectable(true) |
| | | activeObj.mainObj.tipObj.set({ |
| | | left: activeObj.mainObj.left, |
| | | top: activeObj.mainObj.top - activeObj.mainObj.height / 2 - |
| | | activeObj.mainObj |
| | | .tipObj.height / 2, |
| | | visible: true |
| | | }) |
| | | activeObj.mainObj.tipObj.setCoords() |
| | | } |
| | | _this.closeOkCancelControl() |
| | | |
| | | _this.canvas.requestRenderAll() |
| | | } |
| | | // else if (activeObj.eleType == "station") { |
| | | // _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | // method: "select_station", |
| | | // data: activeObj.data, |
| | | // select: activeObj.mark ? false : true |
| | | // }); |
| | | // } |
| | | } |
| | | } else if (e.touches.length >= 2) { |
| | | _this.handleMultiTouch(e.touches); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | cantainerEl.addEventListener('touchmove', function(e) { |
| | | // _this.canvas._onMouseMove(e); |
| | | // console.log('touchmove:', e.touches.length); |
| | | e.preventDefault(); // 阻止默认行为 |
| | | // 处理移动 |
| | | if (!_this.canvas.getActiveObject()) { |
| | | const list = _this.canvas.getActiveObjects() |
| | | if (list.length == 0) { |
| | | if (e.touches.length === 1) { |
| | | _this.handleSingleTouchMove(e.touches[0]); |
| | | } else if (e.touches.length >= 2) { |
| | |
| | | } |
| | | } else { |
| | | if (e.touches.length === 1) { |
| | | const touch = e.touches[0] |
| | | const deltaX = touch.clientX - this.lastPosX; |
| | | const deltaY = touch.clientY - this.lastPosY; |
| | | if (Math.abs(deltaX) > 20) |
| | | clearTimeout(pressObjTimer); |
| | | if (list.length > 1 || list[0].lockMovementX) { |
| | | if (list[0].lockMovementX) { |
| | | _this.canvas.discardActiveObject(); |
| | | } |
| | | _this.handleSingleTouchMove(e.touches[0]); |
| | | } else { |
| | | const touch = e.touches[0] |
| | | const deltaX = touch.clientX - this.lastPosX; |
| | | const deltaY = touch.clientY - this.lastPosY; |
| | | if (Math.abs(deltaX) > 20) |
| | | clearTimeout(this.pressObjTimer); |
| | | } |
| | | |
| | | } else if (e.touches.length >= 2) { |
| | | _this.canvas.discardActiveObject(); |
| | | _this.handleMultiTouchMove(e.touches); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | cantainerEl.addEventListener('touchend', function(e) { |
| | | // _this.canvas._onMouseUp(e); |
| | | // console.log('touchend:'); |
| | | e.preventDefault(); // 阻止默认行为 |
| | | _this.touchPoint = { |
| | | x: 0, |
| | | y: 0 |
| | | }; |
| | | if (!_this.canvas.getActiveObject()) { |
| | | const activeObj = _this.canvas.getActiveObject() |
| | | if (!activeObj) { |
| | | // 处理结束事件 |
| | | if (e.touches.length === 0) { |
| | | _this.handleTouchEnd(); |
| | | } |
| | | if (_this.editObject) { |
| | | _this.canvas.setActiveObject(_this.editObject) |
| | | } |
| | | // if (_this.editObject) { |
| | | // _this.canvas.setActiveObject(_this.editObject) |
| | | // } |
| | | } else { |
| | | clearTimeout(pressObjTimer); |
| | | // if (activeObj.lockMovementX) { |
| | | // _this.canvas.discardActiveObject(); |
| | | // } |
| | | } |
| | | |
| | | |
| | | if (this.pressObjTimer) { |
| | | clearTimeout(this.pressObjTimer); |
| | | this.pressObjTimer = null |
| | | } |
| | | }); |
| | | cantainerEl.addEventListener('touchcancel', function(e) { |
| | | if (_this.canvas.getActiveObject()) { |
| | | // 处理结束事件 |
| | | clearTimeout(pressObjTimer); |
| | | } else { |
| | | if (_this.editObject) { |
| | | _this.canvas.setActiveObject(_this.editObject) |
| | | } |
| | | // console.log('touchcancel:'); |
| | | if (this.pressObjTimer) { |
| | | clearTimeout(this.pressObjTimer); |
| | | this.pressObjTimer = null |
| | | } |
| | | // const activeObj = _this.canvas.getActiveObject() |
| | | // if (activeObj) { |
| | | // if (activeObj.lockMovementX) { |
| | | // _this.canvas.discardActiveObject(); |
| | | // } |
| | | // } |
| | | }) |
| | | |
| | | }, |
| | | onSelectionChanage() { |
| | | const _this = this |
| | | const list = _this.canvas.getActiveObjects() |
| | | if (list.length === 1) { |
| | | if (list[0].eleType == "station") { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "selected_change", |
| | | type: list[0].eleType, |
| | | param: list[0].data |
| | | }); |
| | | } else if (list[0].eleType == "agv") { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "selected_change", |
| | | type: list[0].eleType, |
| | | param: list[0].data |
| | | }); |
| | | } else if (list[0].eleType == "agv_line") { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "selected_change", |
| | | type: list[0].eleType, |
| | | param: list[0].data |
| | | }); |
| | | } else { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "selected_change", |
| | | type: "" |
| | | }); |
| | | // 计算点到线段的距离 |
| | | pointToSegmentDistance(px, py, x1, y1, x2, y2) { |
| | | const A = px - x1; |
| | | const B = py - y1; |
| | | const C = x2 - x1; |
| | | const D = y2 - y1; |
| | | |
| | | const dot = A * C + B * D; |
| | | const lenSq = C * C + D * D; |
| | | let param = -1; |
| | | if (lenSq !== 0) param = dot / lenSq; |
| | | |
| | | let xx, yy; |
| | | if (param < 0) { |
| | | xx = x1; |
| | | yy = y1; |
| | | } else if (param > 1) { |
| | | xx = x2; |
| | | yy = y2; |
| | | } else { |
| | | xx = x1 + param * C; |
| | | yy = y1 + param * D; |
| | | } |
| | | |
| | | const dx = px - xx; |
| | | const dy = py - yy; |
| | | return Math.sqrt(dx * dx + dy * dy); |
| | | }, |
| | | |
| | | // 获取 Path 的所有线段 |
| | | getPathSegments(path) { |
| | | const segs = []; |
| | | const pts = path.path; |
| | | let lastX = 0, |
| | | lastY = 0; |
| | | |
| | | for (let i = 0; i < pts.length; i++) { |
| | | const cmd = pts[i]; |
| | | if (cmd[0] === 'M') { |
| | | lastX = cmd[1]; |
| | | lastY = cmd[2]; |
| | | } else if (cmd[0] === 'L') { |
| | | const x = cmd[1]; |
| | | const y = cmd[2]; |
| | | segs.push([lastX, lastY, x, y]); |
| | | lastX = x; |
| | | lastY = y; |
| | | } |
| | | } |
| | | return segs; |
| | | }, |
| | | |
| | | // 判断点是否在 Path 或 Line 的边框上 |
| | | isPointOnStroke(obj, pointer, tolerance = 5) { |
| | | if (obj instanceof fabric.Line) { |
| | | const dist = this.pointToSegmentDistance( |
| | | pointer.x, pointer.y, |
| | | obj.x1, obj.y1, obj.x2, obj.y2 |
| | | ); |
| | | return dist <= tolerance; |
| | | } |
| | | |
| | | if (obj instanceof fabric.Path) { |
| | | const segs = this.getPathSegments(obj); |
| | | for (const [x1, y1, x2, y2] of segs) { |
| | | const dist = this.pointToSegmentDistance(pointer.x, pointer.y, x1, y1, x2, y2); |
| | | if (dist <= tolerance) return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | }, |
| | | |
| | | pointerSelectObject(e) { |
| | | const pointer = this.canvas.getPointer(e); |
| | | const objects = this.canvas.getObjects(); |
| | | |
| | | objects.splice(0, 1); |
| | | this.canvas.discardActiveObject() |
| | | |
| | | let pointerList = [] |
| | | let pointerList2 = [] |
| | | for (let i = objects.length - 1; i >= 0; i--) { |
| | | const obj = objects[i]; |
| | | |
| | | if (obj.selectable && obj.opacity > 0) { |
| | | if (obj instanceof fabric.Path || obj instanceof fabric.Line) { |
| | | if (this.isPointOnStroke(obj, pointer)) { |
| | | console.log(i, obj.eleType) |
| | | pointerList.unshift(obj) |
| | | |
| | | } |
| | | } else { |
| | | const isHit = obj.containsPoint(pointer); |
| | | if (isHit) { |
| | | console.log(i, obj.eleType) |
| | | pointerList.unshift(obj) |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | } else { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "selected_change", |
| | | type: "" |
| | | }); |
| | | } |
| | | for (let i = pointerList.length - 1; i >= 0; i--) { |
| | | const obj = pointerList[i]; |
| | | if (obj instanceof fabric.Path || obj instanceof fabric.Line) { |
| | | if (this.isPointOnStroke(obj, pointer, 1)) { |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList2.unshift(obj) |
| | | } else { |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | } |
| | | |
| | | if (pointerList2.length > 0) { |
| | | if (pointerList2.length == 1) { |
| | | const obj = pointerList2[i]; |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList = pointerList2 |
| | | pointerList2 = [] |
| | | for (let i = pointerList.length - 1; i >= 0; i--) { |
| | | const obj = pointerList[i]; |
| | | if (this.isPointOnStroke(obj, pointer, 2)) { |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList2.unshift(obj) |
| | | } |
| | | } |
| | | if (pointerList2.length > 0) { |
| | | if (pointerList2.length == 1) { |
| | | const obj = pointerList2[i]; |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList = pointerList2 |
| | | pointerList2 = [] |
| | | for (let i = pointerList.length - 1; i >= 0; i--) { |
| | | const obj = pointerList[i]; |
| | | if (this.isPointOnStroke(obj, pointer, 3)) { |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList2.unshift(obj) |
| | | } |
| | | } |
| | | if (pointerList2.length > 0) { |
| | | if (pointerList2.length == 1) { |
| | | const obj = pointerList2[i]; |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList = pointerList2 |
| | | pointerList2 = [] |
| | | for (let i = pointerList.length - 1; i >= 0; i--) { |
| | | const obj = pointerList[i]; |
| | | if (this.isPointOnStroke(obj, pointer, 4)) { |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | pointerList2.unshift(obj) |
| | | } |
| | | } |
| | | if (pointerList2.length > 0) { |
| | | |
| | | const obj = pointerList2[pointerList2.length - 1]; |
| | | this.canvas.discardActiveObject() |
| | | this.canvas.setActiveObject(obj); |
| | | this.canvas.requestRenderAll(); |
| | | return |
| | | } |
| | | // objects.forEach(obj => { |
| | | // if (obj instanceof fabric.Path || obj instanceof fabric.Line) { |
| | | // // 设置一个“点击容忍度”,比如 5 像素 |
| | | // const tolerance = 5; |
| | | // // 临时扩大路径的点击区域 |
| | | // const originalStrokeWidth = obj.strokeWidth; |
| | | // obj.strokeWidth = originalStrokeWidth + tolerance * 2; |
| | | |
| | | // const isHit = obj.intersectsWithPointer(pointer); |
| | | // // 恢复原始宽度 |
| | | // obj.strokeWidth = originalStrokeWidth; |
| | | // if (isHit) { |
| | | // pointerList.push(obj) |
| | | // } |
| | | // } else if (obj instanceof fabric.Rect || obj instanceof fabric.Ellipse) { |
| | | // const isHit = obj.containsPoint(pointer); |
| | | // if (isHit) { |
| | | // pointerList.push(obj) |
| | | // } |
| | | // } |
| | | // // else if (obj instanceof fabric.Group ) |
| | | // // { |
| | | // // const objects2 = obj.getObjects(); |
| | | // // const isHit = obj.containsPoint(pointer); |
| | | // // if (isHit) { |
| | | // // pointerList.push(obj) |
| | | // // } |
| | | // // } |
| | | // }); |
| | | |
| | | // if (pointerList.length === 0) { |
| | | // return |
| | | // } |
| | | // const obj = pointerList.pop() |
| | | // this.canvas.discardActiveObject() |
| | | // this.canvas.setActiveObject(obj) |
| | | |
| | | |
| | | }, |
| | | objectMoving(target) { |
| | | const _this = this |
| | | if (!target) |
| | | return |
| | | if (target?.eleType == "station") { |
| | | const obj = target |
| | | obj.data.x = _this.getActualXFromImg(obj.left) |
| | | obj.data.y = _this.getActualYFromImg(obj.top) |
| | | const vpt = _this.canvas.viewportTransform; |
| | | const zoom = this.canvas.getZoom(); |
| | | let deltaX = obj.left * zoom |
| | | let deltaY = obj.top * zoom |
| | | |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "update_station", |
| | | station: obj.data, |
| | | view: { |
| | | x: vpt[4] + deltaX, |
| | | y: vpt[5] + deltaY, |
| | | } |
| | | |
| | | }); |
| | | _this.createOkCancelControl(obj) |
| | | _this.canvas.renderAll() |
| | | } else if (target?.eleType == "edit_teaching") { |
| | | |
| | | _this.updateEditTeachingPath(target) |
| | | |
| | | } else if (target.eleType == "virtual_wall" || target.eleType == "region") { |
| | | const data = target.data |
| | | |
| | | const offX = target.left - target.oldLeft |
| | | const offY = target.top - target.oldTop |
| | | console.log("path", offX, offY, data.path) |
| | | |
| | | data.path.forEach((pt) => { |
| | | pt.x += _this.getActualSizeFromImg(offX) |
| | | pt.y -= _this.getActualSizeFromImg(offY) |
| | | }) |
| | | console.log("path2", data.path) |
| | | if (target.eleType == "virtual_wall") |
| | | _this.updateVirtualWall(target, data) |
| | | else |
| | | _this.updateRegion(target, data) |
| | | |
| | | _this.canvas.renderAll() |
| | | |
| | | } else if (target?.eleType == "wall_pt") { |
| | | const data = target.mainObj?.data |
| | | if (!data) |
| | | return |
| | | let pt = data.path[0] |
| | | let id = `${data.id}_${ pt.x}_${pt.y}` |
| | | console.log("wall_pt", target.id, id, pt, data.path) |
| | | if (target.id == id) { |
| | | data.path[0] = { |
| | | x: _this.getActualXFromImg(target.left), |
| | | y: _this.getActualYFromImg(target.top) |
| | | } |
| | | } else { |
| | | pt = data.path[1] |
| | | |
| | | id = `${data.id}_${ pt.x}_${pt.y}` |
| | | console.log("wall_pt", id, pt) |
| | | if (target.id == id) { |
| | | data.path[1] = { |
| | | |
| | | x: _this.getActualXFromImg(target.left), |
| | | y: _this.getActualYFromImg(target.top) |
| | | } |
| | | } |
| | | } |
| | | |
| | | _this.updateVirtualWall(target.mainObj, data) |
| | | |
| | | _this.canvas.renderAll() |
| | | } else if (target?.eleType == "region_pt") { |
| | | const data = target.mainObj?.data |
| | | if (!data) |
| | | return |
| | | const curIndex = data.path.findIndex((pt) => `${data.id}_${ pt.x}_${pt.y}` == target.id) |
| | | if (curIndex > -1) { |
| | | let polygon = [] |
| | | data.path.forEach((pt, index) => { |
| | | if (curIndex == index) { |
| | | polygon.push([_this.getActualXFromImg(target.left), _this.getActualYFromImg(target |
| | | .top)]) |
| | | } else { |
| | | polygon.push([pt.x, pt.y]) |
| | | } |
| | | }) |
| | | polygon.push(polygon[0]) |
| | | if (hasSelfIntersection(polygon)) { |
| | | |
| | | _this.showToast("进行区和可行区必须是闭合图形") |
| | | target.set({ |
| | | left: _this.getXOnImg(data.path[curIndex].x), |
| | | top: _this.getYOnImg(data.path[curIndex].y) |
| | | }) |
| | | target.setCoords() |
| | | } else { |
| | | data.path[curIndex] = { |
| | | x: _this.getActualXFromImg(target.left), |
| | | y: _this.getActualYFromImg(target.top) |
| | | } |
| | | _this.updateRegion(target.mainObj, data) |
| | | |
| | | |
| | | |
| | | } |
| | | _this.canvas.renderAll() |
| | | } |
| | | } else if (target?.eleType == "edit_teaching_pt") { |
| | | |
| | | let left = target.mainObj.left |
| | | let top = target.mainObj.top |
| | | let width = target.mainObj.width |
| | | let height = target.mainObj.height |
| | | |
| | | if (target.id == `edit_teaching_pt_0`) { |
| | | if (target.left > target.mainObj.left + target.mainObj.width - 10) { |
| | | target.set({ |
| | | left: target.mainObj.left + target.mainObj.width - 10 |
| | | }) |
| | | } |
| | | width += left - target.left |
| | | left = target.left |
| | | if (target.top > target.mainObj.top + target.mainObj.height - 10) { |
| | | target.set({ |
| | | top: target.mainObj.top + target.mainObj.height - 10 |
| | | }) |
| | | } |
| | | height += top - target.top |
| | | top = target.top |
| | | |
| | | |
| | | } else if (target.id == `edit_teaching_pt_1`) { |
| | | if (target.left > target.mainObj.left + target.mainObj.width - 10) { |
| | | target.set({ |
| | | left: target.mainObj.left + target.mainObj.width - 10 |
| | | }) |
| | | } |
| | | width += left - target.left |
| | | left = target.left |
| | | if (target.top < target.mainObj.top + 10) { |
| | | target.set({ |
| | | top: target.mainObj.top + 10 |
| | | }) |
| | | } |
| | | height = target.top - top |
| | | } else if (target.id == `edit_teaching_pt_2`) { |
| | | if (target.left < target.mainObj.left + 10) { |
| | | target.set({ |
| | | left: target.mainObj.left + 10 |
| | | }) |
| | | } |
| | | width = target.left - left |
| | | if (target.top < target.mainObj.top + 10) { |
| | | target.set({ |
| | | top: target.mainObj.top + 10 |
| | | }) |
| | | } |
| | | height = target.top - top |
| | | } else if (target.id == `edit_teaching_pt_3`) { |
| | | if (target.left < target.mainObj.left + 10) { |
| | | target.set({ |
| | | left: target.mainObj.left + 10 |
| | | }) |
| | | } |
| | | width = target.left - left |
| | | if (target.top > target.mainObj.top + target.mainObj.height - 10) { |
| | | target.set({ |
| | | top: target.mainObj.top + target.mainObj.height - 10 |
| | | }) |
| | | } |
| | | height += top - target.top |
| | | top = target.top |
| | | } |
| | | |
| | | target.mainObj.set({ |
| | | left, |
| | | top, |
| | | height, |
| | | width |
| | | }) |
| | | target.mainObj.setCoords() |
| | | this.updateEditTeachingPath(target.mainObj) |
| | | |
| | | } |
| | | |
| | | }, |
| | | |
| | | onSelectionChanage() { |
| | | const _this = this |
| | | // const list = _this.canvas.getActiveObjects() |
| | | // if (list.length === 1) { |
| | | // if (list[0].eleType == "station") { |
| | | // _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | // method: "selected_change", |
| | | // type: list[0].eleType, |
| | | // param: list[0].data |
| | | // }); |
| | | // } else if (list[0].eleType == "agv") { |
| | | // _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | // method: "selected_change", |
| | | // type: list[0].eleType, |
| | | // param: list[0].data |
| | | // }); |
| | | // } else if (list[0].eleType == "agv_line") { |
| | | // _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | // method: "selected_change", |
| | | // type: list[0].eleType, |
| | | // param: list[0].data |
| | | // }); |
| | | // } else { |
| | | // _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | // method: "selected_change", |
| | | // type: "" |
| | | // }); |
| | | // } |
| | | |
| | | // } else { |
| | | // _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | // method: "selected_change", |
| | | // type: "" |
| | | // }); |
| | | // } |
| | | }, |
| | | safeLoadImage(url, maxSize = 2048) { |
| | | console.log(url) |
| | |
| | | |
| | | }); |
| | | }, |
| | | // 将 Base64 转为 Blob,再生成 URL |
| | | base64ToBlob(base64, mime) { |
| | | const byteString = atob(base64.split(',')[1]); |
| | | const ab = new ArrayBuffer(byteString.length); |
| | | const ia = new Uint8Array(ab); |
| | | for (let i = 0; i < byteString.length; i++) { |
| | | ia[i] = byteString.charCodeAt(i); |
| | | } |
| | | return new Blob([ab], { |
| | | type: mime |
| | | }); |
| | | }, |
| | | async loadBase64ImageWithProgress(data, maxSize = 2048) { |
| | | const _this = this |
| | | return new Promise((resolve, reject) => { |
| | |
| | | if (base64Image.indexOf("data:image/png;base64,") < 0) { |
| | | base64Image = "data:image/png;base64," + data |
| | | } |
| | | const blob = this.base64ToBlob(base64Image, 'image/png'); |
| | | const url = URL.createObjectURL(blob); |
| | | |
| | | |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "set_backgroud_progress", |
| | | type: "start", |
| | |
| | | } |
| | | }; |
| | | img.onload = () => { |
| | | // 用完释放内存 |
| | | URL.revokeObjectURL(url); |
| | | const percent = Math.min(this.progressPercent + 10, 95); |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "set_backgroud_progress", |
| | |
| | | reject(new Error('图片加载失败')); |
| | | }; |
| | | // 开始加载 |
| | | img.src = base64Image; |
| | | //img.src = base64Image; |
| | | img.src = url; |
| | | }); |
| | | }, |
| | | |
| | |
| | | } |
| | | return null; |
| | | }, |
| | | |
| | | clearObjects() { |
| | | const list = this.canvas.getObjects() |
| | | list.splice(0, 1) |
| | | for (let i in list) { |
| | | const obj = list[i] |
| | | this.canvas.remove(obj) |
| | | } |
| | | }, |
| | | setBackground(info) { |
| | | const _this = this |
| | | |
| | | if (!this.canvas) |
| | | if (!this.canvas) { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "set_backgroud_progress", |
| | | type: "error", |
| | | }); |
| | | return |
| | | this.canvas.clear() |
| | | this.canvas.selectionColor = 'rgba(100, 200, 255, 0.3)'; // 选中背景色 |
| | | this.canvas.selectionBorderColor = '#1890ff'; // 边框颜色 |
| | | this.canvas.selectionLineWidth = 3; // 边框宽度 |
| | | } |
| | | |
| | | |
| | | // this.canvas.clear() |
| | | // this.canvas.selectionColor = 'rgba(100, 200, 255, 0.3)'; // 选中背景色 |
| | | // this.canvas.selectionBorderColor = '#1890ff'; // 边框颜色 |
| | | // this.canvas.selectionLineWidth = 3; // 边框宽度 |
| | | this.agvObj = null |
| | | const cantainerEl = document.getElementById("canvasMap") |
| | | this.eleWidth = cantainerEl.clientWidth |
| | |
| | | console.log("client", this.eleWidth, this.eleHeight) |
| | | this.canvas.setWidth(this.eleWidth); |
| | | this.canvas.setHeight(this.eleHeight); |
| | | |
| | | //console.log("setBackground", JSON.stringify(info)) |
| | | |
| | | this.mapInfo = { |
| | | proportion: info.proportion || 1, |
| | | img_proportion: info.img_proportion || 1, |
| | | max_x: info.max_x || 1, |
| | | max_y: info.max_y || 1, |
| | | min_x: info.min_x || 0, |
| | | min_y: info.min_y || 0, |
| | | img_x: info.img_x || 1, |
| | | img_y: info.img_y || 1, |
| | | } |
| | | return new Promise((resolve, reject) => { |
| | | // if (svgUrl) { |
| | | // fabric.loadSVGFromURL(svgUrl).then(({ |
| | | // objects, |
| | | // options |
| | | // }) => { |
| | | // const workSpace = fabric.util.groupSVGElements(objects, options); |
| | | // workSpace.set({ |
| | | // id: "workspace", |
| | | // eleType: "workspace", |
| | | // left: 0, |
| | | // top: 0, |
| | | // selectable: false, |
| | | // hasControls: false, |
| | | |
| | | |
| | | // }); |
| | | // _this.canvas.add(workSpace) |
| | | // if (_this.workSpace) { |
| | | // _this.canvas.remove(_this.workSpace) |
| | | // } |
| | | // _this.workSpace = workSpace |
| | | // // _this.auto() |
| | | // resolve() |
| | | // }); |
| | | // } else if (imgUrl) { |
| | | if (info.filedata) { |
| | | _this.loadBase64ImageWithProgress(info.filedata).then((img) => { |
| | | //console.warn('setBackground', JSON.stringify(img)); |
| | | if (img) { |
| | | if (_this.mapInfo.img_x == 1) { |
| | | _this.mapInfo.img_x = img.width |
| | | _this.mapInfo.max_x = _this.mapInfo.img_proportion * _this.mapInfo |
| | | .img_x + _this.mapInfo.min_x |
| | | } |
| | | if (_this.mapInfo.img_y == 1) { |
| | | _this.mapInfo.img_y = img.height |
| | | _this.mapInfo.max_y = _this.mapInfo.img_proportion * _this.mapInfo |
| | | .img_y + _this.mapInfo.min_y |
| | | } |
| | | img.set({ |
| | | id: "workspace", |
| | | eleType: "workspace", |
| | | left: 0, |
| | | top: 0, |
| | | }); |
| | | // if (_this.workSpace instanceof fabric.Group) { |
| | | |
| | | // const objs = _this.workSpace.getObjects() |
| | | // const rect = objs[1] |
| | | // _this.workSpace.remove(objs[0]) |
| | | // _this.workSpace.insertAt(0,img) |
| | | |
| | | // rect.set({ |
| | | // width: _this.mapInfo.img_x, |
| | | // height: _this.mapInfo.img_y, |
| | | // }) |
| | | // _this.workSpace.set({ |
| | | // width: _this.mapInfo.img_x, |
| | | // height: _this.mapInfo.img_y, |
| | | // }) |
| | | // resolve() |
| | | // return |
| | | // } |
| | | _this.clearObjects() |
| | | const rect = new fabric.Rect({ |
| | | left: 0, |
| | | top: 0, |
| | | width: _this.mapInfo.img_x, |
| | | height: _this.mapInfo.img_y, |
| | | stroke: "#333", |
| | | strokeWidth: 1, |
| | | strokeDashArray: [5, 5], |
| | | strokeLineCap: 'butt', |
| | | fill: "rgba(255,255,255,0)", |
| | | }) |
| | | |
| | | |
| | | console.log(rect.width, _this.mapInfo.img_x, img.width) |
| | | |
| | | let wsGroup = new fabric.Group([img, rect], { |
| | | id: "workspace", |
| | | eleType: "workspace", |
| | | selectable: false, |
| | | hasControls: false, |
| | | left: 0, |
| | | top: 0, |
| | | width: _this.mapInfo.img_x, |
| | | height: _this.mapInfo.img_y, |
| | | |
| | | }); |
| | | _this.canvas.add(img) |
| | | _this.canvas.add(wsGroup) |
| | | if (_this.workSpace) { |
| | | _this.canvas.remove(_this.workSpace) |
| | | } |
| | | _this.workSpace = img |
| | | _this.workSpace = wsGroup |
| | | |
| | | } |
| | | //_this.checkMemoryUsage() |
| | | resolve() |
| | | |
| | | }).catch((err) => { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "set_backgroud_progress", |
| | | type: "error", |
| | | }); |
| | | resolve() |
| | | }) |
| | | |
| | | } else { |
| | | _this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "set_backgroud_progress", |
| | | type: "end", |
| | | }); |
| | | resolve() |
| | | } |
| | | // fabric.Image.fromURL(imgUrl).then((img) => { |
| | | // // 设置背景图像的属性 |
| | | // img.set({ |
| | | // id: "workspace", |
| | | // eleType: "workspace", |
| | | // left: 0, |
| | | // top: 0, |
| | | // selectable: false, |
| | | // hasControls: false, |
| | | // }); |
| | | |
| | | // _this.canvas.add(img) |
| | | // if (_this.workSpace) { |
| | | // _this.canvas.remove(_this.workSpace) |
| | | // } |
| | | // _this.workSpace = img |
| | | // //_this.auto() |
| | | // resolve() |
| | | // }) |
| | | |
| | | //} |
| | | }) |
| | | }, |
| | | |
| | | getAutoScale() { |
| | | // 按照宽度 |
| | | |
| | | const eleWidth = this.eleWidth |
| | | const eleHeight = this.eleHeight |
| | | const eleWidth = this.eleWidth - 20 |
| | | const eleHeight = this.eleHeight - 200 |
| | | if (!this.workSpace) |
| | | return 1 |
| | | const width = this.workSpace.width |
| | |
| | | scale: scale |
| | | }); |
| | | if (!this.workSpace) return; |
| | | this.setCenterFromObject(this.workSpace); |
| | | // this.setCenterFromObject(this.workSpace); |
| | | // 超出画布不展示 |
| | | _this.workSpace.clone().then((cloned) => { |
| | | _this.canvas.clipPath = cloned; |
| | | _this.canvas.requestRenderAll(); |
| | | }); |
| | | // _this.workSpace.clone().then((cloned) => { |
| | | // _this.canvas.clipPath = cloned; |
| | | // _this.canvas.requestRenderAll(); |
| | | // }); |
| | | }, |
| | | setDrawingType(type, svg) { |
| | | if (svg) { |
| | |
| | | x: touch.clientX, |
| | | y: touch.clientY |
| | | }; |
| | | console.log('单点触摸开始'); |
| | | // console.log('单点触摸开始'); |
| | | |
| | | let activeObj = this.canvas.getActiveObject(); |
| | | if (!activeObj) { |
| | |
| | | this.isDragging = true; |
| | | this.lastPosX = touch.clientX; |
| | | this.lastPosY = touch.clientY; |
| | | |
| | | } else { |
| | | this.isDragging = false; |
| | | this.isDrawing = true; |
| | |
| | | // 多点触摸初始逻辑 |
| | | }, |
| | | handleSingleTouchMove(touch) { |
| | | console.log('单点移动', touch.clientX, touch.clientY); |
| | | //console.log('单点移动', touch.clientX, touch.clientY,this.lastPosX,this.lastPosY); |
| | | if (this.isDragging) { |
| | | const deltaX = touch.clientX - this.lastPosX; |
| | | const deltaY = touch.clientY - this.lastPosY; |
| | | // 移动视口 |
| | | console.log('relativePan', deltaX, deltaY); |
| | | |
| | | if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) { |
| | | if (this.pressObjTimer) { |
| | | clearTimeout(this.pressObjTimer); |
| | | this.pressObjTimer = null |
| | | } |
| | | } |
| | | // 移动视口 |
| | | // console.log('relativePan', deltaX, deltaY); |
| | | const vpt = this.canvas.viewportTransform; |
| | | this.canvas.relativePan(new fabric.Point(deltaX, deltaY)); |
| | | if (this.objEditing) { |
| | | if (this.objEditing.eleType == "station") { |
| | | const zoom = this.canvas.getZoom(); |
| | | let deltaX2 = this.objEditing.left * zoom |
| | | let deltaY2 = this.objEditing.top * zoom |
| | | this.$ownerInstance.callMethod('receiveRenderData', { |
| | | method: "update_station", |
| | | station: this.objEditing.data, |
| | | view: { |
| | | x: vpt[4] - deltaX + deltaX2, |
| | | y: vpt[5] - deltaY + deltaY2, |
| | | } |
| | | |
| | | }); |
| | | } |
| | | } |
| | | |
| | | |
| | | this.lastPosX = touch.clientX; |
| | | this.lastPosY = touch.clientY; |
| | | this.canvas.renderAll() |
| | | } else if (this.isDrawing) { |
| | | const vpt = this.canvas.viewportTransform; |
| | | console.log("viewportTransform", vpt[4], vpt[5]) |
| | | // console.log("viewportTransform", vpt[4], vpt[5]) |
| | | let startX = this.touchStartPoint.x - vpt[4] |
| | | let startY = this.touchStartPoint.y - vpt[5] |
| | | let endX = touch.clientX - vpt[4] |
| | |
| | | startY /= scale |
| | | endX /= scale |
| | | endY /= scale |
| | | console.log("viewportTransform", startX, startY, endX, endY) |
| | | // console.log("viewportTransform", startX, startY, endX, endY) |
| | | const left = |
| | | endX > startX ? |
| | | startX : |
| | |
| | | |
| | | this.drawingObj = line |
| | | } |
| | | this.canvas.requestRenderAll(); |
| | | // this.canvas.requestRenderAll(); |
| | | } |
| | | |
| | | |
| | |
| | | const _this = this |
| | | const touch1 = touches[0]; |
| | | const touch2 = touches[1]; |
| | | console.log('多点移动', touch1.identifier, touch2.identifier); |
| | | //console.log('多点移动', touch1.identifier, touch2.identifier); |
| | | |
| | | const distance = Math.sqrt( |
| | | Math.pow(touch2.clientX - touch1.clientX, 2) + |
| | |
| | | } else if (scale == scaleAuto) { |
| | | return |
| | | } |
| | | console.log(scale, scaleAuto) |
| | | //console.log(scale, scaleAuto) |
| | | this.setZoomAuto(scale, center) |
| | | |
| | | console.log('多点移动 - 距离:', distance, '角度:', angle); |
| | | // console.log('多点移动 - 距离:', distance, '角度:', angle); |
| | | // 多点移动逻辑 |
| | | }, |
| | | handleTouchEnd() { |
| | | console.log('所有触摸结束'); |
| | | // console.log('所有触摸结束'); |
| | | this.isDrawing = false |
| | | this.drawingObj = undefined |
| | | this.initialDistance = null; |
| | | // 触摸结束逻辑 |
| | | }, |
| | | |
| | | getXOnImg(x) { |
| | | const mapX = x * this.mapInfo.proportion |
| | | const imgX = (mapX - this.mapInfo.min_x) / this.mapInfo.img_proportion |
| | | return imgX |
| | | }, |
| | | getYOnImg(y) { |
| | | const mapY = y * this.mapInfo.proportion |
| | | const imgY = (this.mapInfo.max_y - mapY) / this.mapInfo.img_proportion |
| | | return imgY |
| | | }, |
| | | getSizeOnImg(size) { |
| | | const imgSize = size * this.mapInfo.proportion / this.mapInfo.img_proportion |
| | | return imgSize |
| | | }, |
| | | getActualXFromImg(x) { |
| | | const mapX = x * this.mapInfo.img_proportion + this.mapInfo.min_x |
| | | const actualX = mapX / this.mapInfo.proportion |
| | | return actualX |
| | | }, |
| | | getActualYFromImg(y) { |
| | | const mapY = this.mapInfo.max_y - y * this.mapInfo.img_proportion |
| | | const actualY = mapY / this.mapInfo.proportion |
| | | return actualY |
| | | }, |
| | | getActualSizeFromImg(size) { |
| | | const actualSize = size * this.mapInfo.img_proportion / this.mapInfo.proportion |
| | | return actualSize |
| | | }, |
| | | onScaleChange() { |
| | | var scale = this.canvas.getZoom() |
| | | if (scale < 1) { |
| | | scale = 1 |
| | | } |
| | | const scale2 = 1 / scale |
| | | |
| | | let list = this.canvas.getObjects() |
| | | const filter = ["agv", "current_teaching", "edit_teaching", "edit_teaching_pt", "cmd", "station", |
| | | "station_mark", "station_tip" |
| | | ] |
| | | list = list.filter((a) => filter.includes(a.eleType)) |
| | | list.forEach((obj) => { |
| | | if (obj.eleType == "edit_teaching") { |
| | | obj.set({ |
| | | strokeWidth: 2 * scale2 |
| | | }) |
| | | } else { |
| | | obj.set({ |
| | | scaleX: scale2, |
| | | scaleY: scale2 |
| | | }) |
| | | } |
| | | if (obj.eleType == "station" || obj.eleType == "edit_teaching") { |
| | | const tipObj = obj.tipObj |
| | | if (tipObj) { |
| | | tipObj.set({ |
| | | left: obj.left, |
| | | top: obj.top - (obj.height / 2 + tipObj |
| | | .height / 2) * scale2 |
| | | }) |
| | | tipObj.setCoords() |
| | | } |
| | | } |
| | | if (obj.eleType == "cmd") { |
| | | const obj2 = obj.mainObj |
| | | if (obj2?.eleType == "station") { |
| | | if (obj.id == `cancel`) { |
| | | obj.set({ |
| | | left: obj2.left - (obj2.width / 2 + 50) * scale2, |
| | | }) |
| | | obj.setCoords() |
| | | } else if (obj.id == `ok`) { |
| | | obj.set({ |
| | | left: obj2.left + (obj2.width / 2 + 50) * scale2, |
| | | }) |
| | | obj.setCoords() |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | }) |
| | | if (this.objEditing) { |
| | | this.createOkCancelControl(this.objEditing) |
| | | } |
| | | this.canvas.renderAll() |
| | | |
| | | }, |
| | | |
| | | addStation(info) { |
| | | const _this = this |
| | | |
| | | return new Promise((resolve) => { |
| | | const zoom = _this.canvas.getZoom(); |
| | | let svg = "static/images/station.svg" |
| | | // if (info.angle > 0) { |
| | | // if (info.angle / 3.14 <= 0.25) { |
| | | // svg = "static/images/station2.svg" |
| | | // } else if (info.angle / 3.14 <= 0.50) { |
| | | // svg = "static/images/station3.svg" |
| | | // } else if (info.angle / 3.14 <= 0.75) { |
| | | // svg = "static/images/station4.svg" |
| | | // } else if (info.angle / 3.14 <= 1) { |
| | | // svg = "static/images/station5.svg" |
| | | // } |
| | | // } else if (info.angle < 0) { |
| | | // if (info.angle / 3.14 < -0.75) { |
| | | // svg = "static/images/station5.svg" |
| | | // } else if (info.angle / 3.14 < -0.5) { |
| | | // svg = "static/images/station6.svg" |
| | | // } else if (info.angle / 3.14 < -0.25) { |
| | | // svg = "static/images/station7.svg" |
| | | // } else if (info.angle / 3.14 < 0) { |
| | | // svg = "static/images/station8.svg" |
| | | // } |
| | | // } |
| | | |
| | | // const scale = this.getAutoScale() |
| | | const left = info.x // * scale |
| | | const top = info.y //* scale |
| | | const angle = info.angle * 180 / 3.14 |
| | | console.log("addStation", svg, info) |
| | | const left = _this.getXOnImg(info.x) // * scale |
| | | const top = _this.getYOnImg(info.y) //* scale |
| | | const angle = info.angle * 180 / Math.PI |
| | | fabric.loadSVGFromURL(svg).then( |
| | | ({ |
| | | objects, |
| | | options |
| | | }) => { |
| | | |
| | | const obj = fabric.util.groupSVGElements(objects, options); |
| | | obj.set({ |
| | | var scale = this.canvas.getZoom() |
| | | if (scale < 1) { |
| | | scale = 1 |
| | | } |
| | | const scale2 = 1 / scale |
| | | const objGroup = fabric.util.groupSVGElements(objects, options); |
| | | objGroup.set({ |
| | | id: `station_${new Date().getTime()}`, |
| | | eleType: "station", |
| | | left, |
| | |
| | | data: info, |
| | | originX: "center", |
| | | originY: "center", |
| | | // width: options.width, |
| | | // height: options.height, |
| | | // viewBoxWidth: options.viewBoxWidth || options.width, |
| | | // viewBoxHeight: options.viewBoxHeight || options.height, |
| | | hasControls: this.editMode, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | canSelect: true, |
| | | lockEdit: true |
| | | lockEdit: true, |
| | | scaleX: scale2, |
| | | scaleY: scale2, |
| | | |
| | | }) |
| | | _this.canvas.add(objGroup) |
| | | |
| | | const objectText = new fabric.Text(`${info.name}`, { |
| | | id: `station_tip${new Date().getTime()}`, |
| | | eleType: "station_tip", |
| | | left: objGroup.left, |
| | | top: objGroup.top - 20, |
| | | fontSize: 14, |
| | | fontFamily: "Microsoft YaHei", // |
| | | fill: "#000", // |
| | | stroke: "#000", // |
| | | textBaseline: "alphabetic", // Correct value |
| | | originX: "center", |
| | | originY: "center", |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | canSelect: false, |
| | | selectable: false, |
| | | |
| | | scaleX: scale2, |
| | | scaleY: scale2, |
| | | }); |
| | | _this.addObject(obj) |
| | | objGroup.set({ |
| | | tipObj: objectText |
| | | }) |
| | | objectText.set({ |
| | | left: objGroup.left, |
| | | top: objGroup.top - (objGroup.height / 2 + objectText |
| | | .height / 2) * scale2, |
| | | }) |
| | | _this.canvas.add(objectText) |
| | | _this.canvas.bringObjectToFront(objGroup); |
| | | resolve() |
| | | } |
| | | ) |
| | | }) |
| | | }, |
| | | setMarkStation(obj, mark) { |
| | | console.log("setMarkStation", obj.id, obj.mark, mark) |
| | | if (mark) { |
| | | if (obj.mark) { |
| | | return |
| | | } |
| | | var scale = this.canvas.getZoom() |
| | | if (scale < 1) { |
| | | scale = 1 |
| | | } |
| | | const scale2 = 1 / scale |
| | | let ellipse = new fabric.Ellipse({ |
| | | id: `station_mark${new Date().getTime()}`, |
| | | eleType: "station_mark", |
| | | left: obj.left, |
| | | top: obj.top, |
| | | rx: 20, |
| | | ry: 20, |
| | | stroke: "#ff7f23", |
| | | strokeWidth: 2, |
| | | fill: "#ffffff00", |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | scaleX: scale2, |
| | | scaleY: scale2, |
| | | }); |
| | | obj.set({ |
| | | mark: true, |
| | | markObj: ellipse, |
| | | }) |
| | | obj.add(ellipse) |
| | | |
| | | } else { |
| | | if (obj.mark) { |
| | | obj.remove(obj.markObj) |
| | | delete obj.markObj |
| | | obj.set({ |
| | | mark: false, |
| | | }) |
| | | } |
| | | return |
| | | } |
| | | |
| | | }, |
| | | updateCurrentTeaching(teachingData) { |
| | | var posArr = teachingData.pos_list || [] |
| | | const pos_list = [] |
| | | if (this.curTeachingObj) { |
| | | this.canvas.remove(this.curTeachingObj) |
| | | this.curTeachingObj = null |
| | | } |
| | | |
| | | posArr.forEach((item) => { |
| | | const curIndex = pos_list.findIndex((item2) => item2.x === item.x && item2.y === item.y) |
| | | if (curIndex < 0) { |
| | | pos_list.push(item) |
| | | } |
| | | }) |
| | | let path2 = "" |
| | | const theta = 20; |
| | | let headlen = 10; |
| | | var main_road = teachingData.main_road || 0 |
| | | |
| | | const len = pos_list.length |
| | | let fromX = 0, |
| | | fromY = 0, |
| | | toX = 0, |
| | | toY = 0; |
| | | for (let index = 0; index < len; index++) { |
| | | const pt = pos_list[index] |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | 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}` |
| | | } |
| | | } else { |
| | | path2 = `M${pt2.x} ${pt2.y}` |
| | | } |
| | | fromX = pt2.x |
| | | fromY = pt2.y |
| | | } |
| | | let strokeWidth = 1 |
| | | let stroke = "#95DE64" |
| | | |
| | | if (main_road == 1) { |
| | | stroke = "#69C0FF" |
| | | } |
| | | const objPath = new fabric.Path( |
| | | path2, { |
| | | id: "current_teaching", |
| | | eleType: "current_teaching", |
| | | stroke: stroke, |
| | | strokeWidth, |
| | | // strokeDashArray: [5, 3], |
| | | // strokeLineCap: 'butt', |
| | | fill: "#ffffff00", |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: false, |
| | | opacity: 1, |
| | | }) |
| | | this.canvas.add(objPath) |
| | | this.curTeachingObj = objPath |
| | | }, |
| | | addTeachingPath(teachingData, id, type) { |
| | | |
| | | var posArr = teachingData.pos_list || [] |
| | | const pos_list = [] |
| | | posArr.forEach((item) => { |
| | | const curIndex = pos_list.findIndex((item2) => item2.x === item.x && item2.y === item.y) |
| | | if (curIndex < 0) { |
| | | pos_list.push(item) |
| | | } |
| | | }) |
| | | |
| | | console.log(posArr.length, pos_list.length) |
| | | let path2 = "" |
| | | |
| | | const theta = 20; |
| | | let headlen = 10; |
| | | var main_road = 1 |
| | | |
| | | const len = pos_list.length |
| | | let fromX = 0, |
| | | fromY = 0, |
| | | toX = 0, |
| | | toY = 0; |
| | | |
| | | |
| | | for (let index = 0; index < len; index++) { |
| | | const pt = pos_list[index] |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | 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}` |
| | | } |
| | | } else { |
| | | main_road = pt.main_road |
| | | if (main_road == 1) { |
| | | headlen = 15 |
| | | } |
| | | path2 = `M${pt2.x} ${pt2.y}` |
| | | } |
| | | fromX = pt2.x |
| | | fromY = pt2.y |
| | | |
| | | |
| | | } |
| | | //console.log(path2) |
| | | // path2 += " Z" |
| | | let strokeWidth = 1 |
| | | let stroke = "#95DE64" |
| | | if (type == "station_teaching") { |
| | | stroke = "#69C0FF" |
| | | } else { |
| | | if (main_road == 1) { |
| | | stroke = "#69C0FF" |
| | | } |
| | | } |
| | | let list = this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "station_teaching" || a.eleType == "public_teaching") |
| | | let lenTeaching = list.length |
| | | if (main_road == 1) { |
| | | list = list.filter((a) => a.eleType == "public_teaching" && a.mainRoad == 1) |
| | | lenTeaching = list.length |
| | | } |
| | | |
| | | let ptList = [] |
| | | const objPath = new fabric.Path( |
| | | path2, { |
| | | id: id, |
| | | eleType: type, |
| | | stroke: stroke, |
| | | strokeWidth, |
| | | // strokeDashArray: [5, 3], |
| | | // strokeLineCap: 'butt', |
| | | fill: "#ffffff00", |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: false, |
| | | opacity: 0, |
| | | mainRoad: main_road, |
| | | data: teachingData |
| | | }) |
| | | this.canvas.add(objPath) |
| | | |
| | | // this.canvas.sendObjectToBack(objPath); |
| | | |
| | | // lenTeaching = 0 |
| | | // for (let i = list.length - 1; i >= 0; i--) { |
| | | // const obj = list[i] |
| | | // if (this.compareOverlap(obj, objPath)) { |
| | | // lenTeaching = i + 1 |
| | | // break |
| | | // } |
| | | // } |
| | | this.canvas.moveObjectTo(objPath, lenTeaching + 1); |
| | | |
| | | return objPath |
| | | }, |
| | | isObjectFullyContained(outerObj, innerObj) { |
| | | const outer = outerObj.getBoundingRect(true, true); |
| | | const inner = innerObj.getBoundingRect(true, true); |
| | | |
| | | return ( |
| | | outer.left <= inner.left && |
| | | outer.top <= inner.top && |
| | | outer.left + outer.width >= inner.left + inner.width && |
| | | outer.top + outer.height >= inner.top + inner.height |
| | | ); |
| | | }, |
| | | |
| | | compareOverlap(bottomObj, topObj) { |
| | | const bottomRect = bottomObj.getBoundingRect(true, true); |
| | | const topRect = topObj.getBoundingRect(true, true); |
| | | const maxLeft = Math.min(bottomRect.left + bottomRect.width, topObj.width + topObj.left) |
| | | const maxTop = Math.min(bottomRect.top + bottomRect.height, topObj.height + topObj.top) |
| | | const minRight = Math.min(bottomRect.left + bottomRect.width, topObj.width + topObj.left) |
| | | const minBottom = Math.min(bottomRect.top + bottomRect.height, topObj.height + topObj.top) |
| | | if (minRight <= maxLeft || minBottom <= maxTop) return true; // 无重叠 |
| | | const bottomArea = bottomRect.width * bottomRect.height; |
| | | const topArea = topRect.width * topRect.height; |
| | | const interArea = (minRight - maxLeft) * (minBottom - maxTop) |
| | | if (bottomArea - interArea > topArea - -interArea) { |
| | | return true; //底部未重叠面积大 |
| | | } |
| | | return false; |
| | | |
| | | }, |
| | | showTeachingPath(show) { |
| | | |
| | | let list = this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "station_teaching" || a.eleType == "public_teaching") |
| | | for (let i2 in list) { |
| | | const obj = list[i2] |
| | | obj.set({ |
| | | opacity: show ? 1 : 0, |
| | | strokeDashArray: [], |
| | | strokeLineCap: '', |
| | | hasControls: show, |
| | | selectable: show, |
| | | }) |
| | | } |
| | | |
| | | |
| | | }, |
| | | showEditTeachingPath(teachingMode) { |
| | | |
| | | let list = this.canvas.getObjects() || [] |
| | | let eleType = "" |
| | | let id = "" |
| | | if (teachingMode.mode == "Public") { |
| | | eleType = "public_teaching" |
| | | id = `public_teaching_${teachingMode.name}` |
| | | } else if (teachingMode.mode == "Stations") { |
| | | eleType = "station_teaching" |
| | | id = `station_teaching_${teachingMode.src_dst}` |
| | | } else { |
| | | return |
| | | } |
| | | |
| | | let objTeaching; |
| | | for (let i2 in list) { |
| | | const obj = list[i2] |
| | | if (obj.eleType == eleType && obj.id == id) { |
| | | obj.set({ |
| | | opacity: 1, |
| | | selectable: false |
| | | }) |
| | | objTeaching = obj |
| | | } else { |
| | | obj.set({ |
| | | opacity: 0.5 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | if (objTeaching) { |
| | | var scale = this.canvas.getZoom() |
| | | if (scale < 1) { |
| | | scale = 1 |
| | | } |
| | | const scale2 = 1 / scale |
| | | |
| | | this.canvas.discardActiveObject(); |
| | | |
| | | const width = (objTeaching.width > 200 ? 200 : objTeaching.width < 100 ? 100 : objTeaching |
| | | .width) * scale2 |
| | | const height = (objTeaching.height > 200 ? 200 : objTeaching.height < 100 ? 100 : objTeaching |
| | | .height) * scale2 |
| | | |
| | | const pt = teachingMode.point |
| | | let left = objTeaching.left - 10 |
| | | let top = objTeaching.top - 10 |
| | | if (pt) { |
| | | left = pt.x - width / 2 |
| | | top = pt.y - height / 2 |
| | | } |
| | | console.log(left, |
| | | top, |
| | | width, |
| | | height, scale2) |
| | | const rect = new fabric.Rect({ |
| | | id: `edit_teaching`, |
| | | eleType: "edit_teaching", |
| | | left, |
| | | top, |
| | | width, |
| | | height, |
| | | stroke: "#ff4d4f", |
| | | strokeWidth: 2 * scale2, |
| | | strokeDashArray: [5, 3], |
| | | strokeLineCap: 'butt', |
| | | fill: "#ff4d4f20", |
| | | hasControls: true, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | mainObj: objTeaching |
| | | }) |
| | | |
| | | this.canvas.add(rect) |
| | | this.createOkCancelControl(rect) |
| | | const ptList = [] |
| | | const path = [{ |
| | | x: rect.left, |
| | | y: rect.top |
| | | }, { |
| | | x: rect.left, |
| | | y: rect.top + rect.height |
| | | }, { |
| | | x: rect.left + rect.width, |
| | | y: rect.top + rect.height |
| | | }, { |
| | | x: rect.left + rect.width, |
| | | y: rect.top |
| | | }] |
| | | path.forEach((pt, index) => { |
| | | let ellipse = new fabric.Ellipse({ |
| | | id: `edit_teaching_pt_${index}`, |
| | | eleType: "edit_teaching_pt", |
| | | left: pt.x, |
| | | top: pt.y, |
| | | rx: 10, |
| | | ry: 10, |
| | | stroke: "#ff4d4f", |
| | | strokeWidth: 1, |
| | | fill: "#ff4d4f", |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | scaleX: scale2, |
| | | scaleY: scale2, |
| | | mainObj: rect |
| | | }); |
| | | this.canvas.add(ellipse) |
| | | ptList.push(ellipse) |
| | | }) |
| | | |
| | | rect.set({ |
| | | ptObjs: ptList, |
| | | oldLeft: rect.left, |
| | | oldTop: rect.top, |
| | | }) |
| | | /*const zoom = this.canvas.getZoom(); |
| | | const eleHeight = this.eleHeight - 150 |
| | | const info = { |
| | | x: rect.left + rect.width / 2, |
| | | y: rect.top + rect.height / 2 |
| | | } |
| | | let deltaX = info.x * zoom - this.eleWidth / 2 // * scale; |
| | | let deltaY = info.y * zoom - eleHeight / 2 //* scale; |
| | | const vpt = this.canvas.viewportTransform; |
| | | const oldX = vpt[4] |
| | | const oldY = vpt[5] |
| | | if (deltaX + this.eleWidth > this.workSpace.width) |
| | | deltaX = this.workSpace.width - this.eleWidth |
| | | if (deltaY + eleHeight > this.workSpace.height) |
| | | deltaY = this.workSpace.height - eleHeight |
| | | if (oldX + this.eleWidth >= info.x * zoom && info.x * zoom >= oldX) { |
| | | deltaX = -oldX |
| | | //console.log("move_canvas X", oldX) |
| | | } |
| | | if (oldY + eleHeight >= info.y * zoom && info.y * zoom >= oldY) { |
| | | // console.log("move_canvas Y", oldY) |
| | | deltaY = -oldY |
| | | } |
| | | this.canvas.absolutePan(new fabric.Point(deltaX, deltaY));*/ |
| | | |
| | | } else { |
| | | for (let i2 in list) { |
| | | const obj = list[i2] |
| | | obj.set({ |
| | | opacity: 1 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | }, |
| | | updateEditTeachingPath(obj) { |
| | | const ptObjs = obj.ptObjs || [] |
| | | ptObjs[0].set({ |
| | | left: obj.left, |
| | | top: obj.top |
| | | }) |
| | | ptObjs[0].setCoords() |
| | | ptObjs[1].set({ |
| | | left: obj.left, |
| | | top: obj.top + obj.height |
| | | }) |
| | | ptObjs[1].setCoords() |
| | | ptObjs[2].set({ |
| | | left: obj.left + obj.width, |
| | | top: obj.top + obj.height |
| | | }) |
| | | ptObjs[2].setCoords() |
| | | ptObjs[3].set({ |
| | | left: obj.left + obj.width, |
| | | top: obj.top |
| | | }) |
| | | ptObjs[3].setCoords() |
| | | this.createOkCancelControl(obj) |
| | | this.canvas.requestRenderAll(); |
| | | }, |
| | | updateAgv(info) { |
| | | const _this = this |
| | | return new Promise((resolve) => { |
| | | // const scale = this.getAutoScale() |
| | | const left = info.x // * scale |
| | | const top = info.y // * scale |
| | | const angle = info.angle * 180 / 3.14 |
| | | const left = _this.getXOnImg(info.x) // * scale |
| | | const top = _this.getYOnImg(info.y) //* scale |
| | | const angle = info.angle * 180 / Math.PI |
| | | if (this.agvObj) { |
| | | this.agvObj.set({ |
| | | left, |
| | |
| | | options |
| | | }) => { |
| | | |
| | | var scale = this.canvas.getZoom() |
| | | if (scale < 1) { |
| | | scale = 1 |
| | | } |
| | | const scale2 = 1 / scale |
| | | const obj = fabric.util.groupSVGElements(objects, options); |
| | | |
| | | obj.set({ |
| | |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: false, |
| | | scaleX: scale2, |
| | | scaleY: scale2, |
| | | lockEdit: true |
| | | |
| | | }); |
| | | console.log("agv", JSON.stringify(info)) |
| | | _this.canvas.add(obj) |
| | | // _this.canvas.bringObjectToFront(obj); |
| | | _this.agvObj = obj |
| | | resolve() |
| | | } |
| | |
| | | |
| | | }) |
| | | }, |
| | | |
| | | |
| | | addVirtualWallShow(info) { |
| | | const path = info.path || [] |
| | | if (path.length != 2) |
| | | return |
| | | |
| | | const line = new fabric.Line([this.getXOnImg(path[0].x), this.getYOnImg(path[0].y), this |
| | | .getXOnImg( |
| | | path[1] |
| | | .x), this.getYOnImg(path[1].y) |
| | | ], { |
| | | id: `${info.id}`, |
| | | eleType: "virtual_wall", |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 3, |
| | | strokeDashArray: [5, 3], |
| | | strokeLineCap: 'butt', |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: true, |
| | | data: info |
| | | }); |
| | | return line |
| | | }, |
| | | |
| | | addVirtualWall(info) { |
| | | const path = info.path || [] |
| | | if (path.length != 2) |
| | | return |
| | | const line = new fabric.Line([this.getXOnImg(path[0].x), this.getYOnImg(path[0].y), this |
| | | .getXOnImg( |
| | | path[1] |
| | | .x), this.getYOnImg(path[1].y) |
| | | ], { |
| | | id: `${info.id}`, |
| | | eleType: "virtual_wall", |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 3, |
| | | strokeDashArray: [5, 3], |
| | | strokeLineCap: 'butt', |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | selectable: true, |
| | | |
| | | data: info |
| | | }); |
| | | this.canvas.add(line) |
| | | let ptImg = { |
| | | x: this.getXOnImg(path[0].x), |
| | | y: this.getYOnImg(path[0].y) |
| | | } |
| | | let pt = { |
| | | x: path[0].x, |
| | | y: path[0].y |
| | | } |
| | | let ellipse = new fabric.Ellipse({ |
| | | id: `${info.id}_${ pt.x}_${pt.y}`, |
| | | eleType: "wall_pt", |
| | | left: ptImg.x, |
| | | top: ptImg.y, |
| | | rx: 10, |
| | | ry: 10, |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 1, |
| | | fill: info.color || "#ff4d4f", |
| | | originX: "center", |
| | | originY: "center", |
| | | lockEdit: true, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | mainObj: line |
| | | }); |
| | | this.canvas.add(ellipse) |
| | | ptImg = { |
| | | x: this.getXOnImg(path[1].x), |
| | | y: this.getYOnImg(path[1].y) |
| | | } |
| | | pt = { |
| | | x: path[1].x, |
| | | y: path[1].y |
| | | } |
| | | let ellipse2 = new fabric.Ellipse({ |
| | | id: `${info.id}_${ pt.x}_${pt.y}`, |
| | | eleType: "wall_pt", |
| | | left: ptImg.x, |
| | | top: ptImg.y, |
| | | rx: 10, |
| | | ry: 10, |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 1, |
| | | fill: info.color || "#ff4d4f", |
| | | originX: "center", |
| | | originY: "center", |
| | | lockEdit: true, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | mainObj: line |
| | | }); |
| | | this.canvas.add(ellipse2) |
| | | line.set({ |
| | | ptObj1: ellipse, |
| | | ptObj2: ellipse2 |
| | | }) |
| | | |
| | | this.createOkCancelControl(line) |
| | | this.editObject = line |
| | | line.set({ |
| | | oldLeft: line.left, |
| | | oldTop: line.top, |
| | | }) |
| | | return line |
| | | }, |
| | | updateVirtualWall(obj, info) { |
| | | const path = info.path || [] |
| | | if (path.length != 2) |
| | | return |
| | | let ptImg1 = { |
| | | x: this.getXOnImg(path[0].x), |
| | | y: this.getYOnImg(path[0].y) |
| | | } |
| | | let ptImg2 = { |
| | | x: this.getXOnImg(path[1].x), |
| | | y: this.getYOnImg(path[1].y) |
| | | } |
| | | let pt1 = { |
| | | x: path[0].x, |
| | | y: path[0].y |
| | | } |
| | | let pt2 = { |
| | | x: path[1].x, |
| | | y: path[1].y |
| | | } |
| | | const left = ptImg2.x > ptImg1.x ? ptImg1.x : ptImg2.x; |
| | | const top = ptImg2.y > ptImg1.y ? ptImg1.y : ptImg2.y; |
| | | obj.set({ |
| | | left: left, |
| | | top: top, |
| | | x1: ptImg1.x, |
| | | y1: ptImg1.y, |
| | | x2: ptImg2.x, |
| | | y2: ptImg2.y, |
| | | data: info, |
| | | }); |
| | | obj.setCoords() |
| | | obj.ptObj1.set({ |
| | | id: `${info.id}_${ pt1.x}_${pt1.y}`, |
| | | left: ptImg1.x, |
| | | top: ptImg1.y, |
| | | |
| | | }) |
| | | obj.ptObj2.set({ |
| | | id: `${info.id}_${ pt2.x}_${pt2.y}`, |
| | | left: ptImg2.x, |
| | | top: ptImg2.y, |
| | | |
| | | }) |
| | | obj.ptObj1.setCoords() |
| | | obj.ptObj2.setCoords() |
| | | |
| | | this.createOkCancelControl(obj) |
| | | this.editObject = obj |
| | | obj.set({ |
| | | oldLeft: obj.left, |
| | | oldTop: obj.top, |
| | | }) |
| | | }, |
| | | addVirtualWallFinish(obj) { |
| | | this.canvas.remove(obj.ptObj1) |
| | | this.canvas.remove(obj.ptObj2) |
| | | delete obj.ptObj1 |
| | | delete obj.ptObj2 |
| | | this.canvas.sendObjectToBack(obj); |
| | | this.canvas.moveObjectTo(obj, 1); |
| | | obj.set({ |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: false |
| | | }) |
| | | |
| | | }, |
| | | removeVirtualWall(obj) { |
| | | this.closeOkCancelControl() |
| | | if (obj.ptObj1) |
| | | this.canvas.remove(obj.ptObj1) |
| | | if (obj.ptObj1) |
| | | this.canvas.remove(obj.ptObj2) |
| | | this.canvas.remove(obj) |
| | | }, |
| | | addRegionShow(info) { |
| | | const _this = this |
| | | const path = info.path || [] |
| | | let path2 = "" |
| | | path.forEach((pt, index) => { |
| | | |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | y: this.getYOnImg(pt.y) |
| | | } |
| | | |
| | | // if (pt.x < 10) { |
| | | // pt.x = 10 |
| | | // } |
| | | // if (pt.y < 10) { |
| | | // pt.y = 10 |
| | | // } |
| | | // if (pt.x > this.workSpace.width - 10) { |
| | | // pt.x = 10 |
| | | // } |
| | | // if (pt.y > this.workSpace.height - 10) { |
| | | // pt.y = 10 |
| | | // } |
| | | if (index > 0) { |
| | | path2 += ` L${pt2} ${pt2.y}` |
| | | } else { |
| | | path2 = `M${pt2.x} ${pt2.y}` |
| | | } |
| | | }) |
| | | path2 += " Z" |
| | | let ptList = [] |
| | | let fillColor = info.color || "#ff4538" |
| | | |
| | | const objPath = new fabric.Path( |
| | | path2, { |
| | | id: `${info.id}`, |
| | | eleType: "region", |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 3, |
| | | strokeDashArray: [5, 3], |
| | | strokeLineCap: 'butt', |
| | | fill: hexToRGBA(fillColor, 0.2), |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: false, |
| | | data: info |
| | | }) |
| | | this.canvas.add(objPath) |
| | | return objPath |
| | | }, |
| | | |
| | | addRegion(info) { |
| | | const _this = this |
| | | const path = info.path || [] |
| | | let path2 = "" |
| | | path.forEach((pt, index) => { |
| | | // if (pt.x < 10) { |
| | | // pt.x = 10 |
| | | // } |
| | | // if (pt.y < 10) { |
| | | // pt.y = 10 |
| | | // } |
| | | // if (pt.x > this.workSpace.width - 10) { |
| | | // pt.x = this.workSpace.width - 10 |
| | | // } |
| | | // if (pt.y > this.workSpace.height - 10) { |
| | | // pt.y = this.workSpace.height - 10 |
| | | // } |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | y: this.getYOnImg(pt.y) |
| | | } |
| | | if (index > 0) { |
| | | path2 += ` L${pt2.x} ${pt2.y}` |
| | | } else { |
| | | path2 = `M${pt2.x} ${pt2.y}` |
| | | } |
| | | }) |
| | | path2 += " Z" |
| | | let ptList = [] |
| | | const objPath = new fabric.Path( |
| | | path2, { |
| | | id: `${info.id}`, |
| | | eleType: "region", |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 3, |
| | | strokeDashArray: [5, 3], |
| | | strokeLineCap: 'butt', |
| | | fill: "rgba(255,255,255,0)", |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | data: info |
| | | }) |
| | | this.canvas.add(objPath) |
| | | path.forEach((pt, index) => { |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | y: this.getYOnImg(pt.y) |
| | | } |
| | | let ellipse = new fabric.Ellipse({ |
| | | id: `${info.id}_${ pt.x}_${pt.y}`, |
| | | eleType: "region_pt", |
| | | left: pt.x, |
| | | top: pt.y, |
| | | rx: 10, |
| | | ry: 10, |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 1, |
| | | fill: info.color || "#ff4d4f", |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | mainObj: objPath |
| | | }); |
| | | this.canvas.add(ellipse) |
| | | ptList.push(ellipse) |
| | | |
| | | }) |
| | | const ptLast = path[0] |
| | | const ptLast2 = path[path.length - 1] |
| | | |
| | | const objAddList = [] |
| | | let ellipse = new fabric.Ellipse({ |
| | | left: -10, |
| | | top: -10, |
| | | rx: 10, |
| | | ry: 10, |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 1, |
| | | fill: info.color || "#ff4d4f", |
| | | }); |
| | | objAddList.push(ellipse) |
| | | let line = new fabric.Line([-6, 0, 6, 0], { |
| | | stroke: "#FEFEFE", |
| | | strokeWidth: 2, |
| | | }); |
| | | objAddList.push(line) |
| | | line = new fabric.Line([0, -6, 0, 6], { |
| | | stroke: "#FEFEFE", |
| | | strokeWidth: 2, |
| | | }); |
| | | objAddList.push(line) |
| | | let objGroup = new fabric.Group(objAddList, { |
| | | id: `${info.id}_add`, |
| | | eleType: "region_pt_add", |
| | | left: ptLast2.x + (ptLast.x - ptLast2.x) / 2, |
| | | top: ptLast2.y + (ptLast.y - ptLast2.y) / 2, |
| | | width: 20, |
| | | height: 20, |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | mainObj: objPath |
| | | }); |
| | | this.canvas.add(objGroup) |
| | | |
| | | objPath.set({ |
| | | ptObjs: ptList, |
| | | ptAddObj: objGroup, |
| | | oldLeft: objPath.left, |
| | | oldTop: objPath.top, |
| | | }) |
| | | this.createOkCancelControl(objPath) |
| | | this.editObject = objPath |
| | | return objPath |
| | | |
| | | }, |
| | | |
| | | updateRegion(obj, info) { |
| | | const path = info.path || [] |
| | | let path2 = "" |
| | | path.forEach((pt, index) => { |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | y: this.getYOnImg(pt.y) |
| | | } |
| | | if (index > 0) { |
| | | path2 += ` L${pt2.x} ${pt2.y}` |
| | | } else { |
| | | path2 = `M${pt2.x} ${pt2.y}` |
| | | } |
| | | }) |
| | | path2 += " Z" |
| | | |
| | | const objList = obj.ptObjs || [] |
| | | const objAdd = obj.ptAddObj |
| | | |
| | | let listObj = this.canvas.getObjects() || [] |
| | | const curIndex = listObj.findIndex((a) => a.eleType == "region" && a.id == obj.id) |
| | | let oldObj |
| | | if (curIndex > -1) { |
| | | oldObj = listObj[curIndex] |
| | | } |
| | | let objNew = new fabric.Path( |
| | | path2, { |
| | | id: `${info.id}`, |
| | | eleType: "region", |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 3, |
| | | strokeDashArray: [5, 3], |
| | | strokeLineCap: 'butt', |
| | | fill: "rgba(255,255,255,0)", |
| | | hasControls: false, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | |
| | | data: info, |
| | | ptObjs: objList, |
| | | ptAddObj: objAdd |
| | | }) |
| | | this.canvas.add(objNew) |
| | | // console.log("remove", curIndex, obj.id, obj) |
| | | if (oldObj) { |
| | | this.canvas.remove(oldObj) |
| | | } |
| | | if (objList.length > path.length) { |
| | | for (let i = path.length; i < objList.length; i++) { |
| | | this.canvas.remove(objList[i]) |
| | | } |
| | | } else if (objList.length == path.length) { |
| | | for (let i = 0; i < objList.length; i++) { |
| | | const pt = path[i] |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | y: this.getYOnImg(pt.y) |
| | | } |
| | | objList[i].set({ |
| | | id: `${info.id}_${ pt.x}_${pt.y}`, |
| | | left: pt2.x, |
| | | top: pt2.y, |
| | | mainObj: objNew |
| | | }) |
| | | |
| | | this.canvas.bringObjectToFront(objList[i]); |
| | | objList[i].setCoords() |
| | | } |
| | | } else { |
| | | for (let i = objList.length; i < path.length; i++) { |
| | | const pt = path[i] |
| | | let pt2 = { |
| | | x: this.getXOnImg(pt.x), |
| | | y: this.getYOnImg(pt.y) |
| | | } |
| | | let ellipse = new fabric.Ellipse({ |
| | | id: `${info.id}_${ pt.x}_${pt.y}`, |
| | | eleType: "region_pt", |
| | | left: pt2.x, |
| | | top: pt2.y, |
| | | rx: 10, |
| | | ry: 10, |
| | | stroke: info.color || "#ff4d4f", |
| | | strokeWidth: 1, |
| | | fill: info.color || "#ff4d4f", |
| | | originX: "center", |
| | | originY: "center", |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | mainObj: objNew |
| | | }); |
| | | this.canvas.add(ellipse) |
| | | objList.push(ellipse) |
| | | } |
| | | } |
| | | const ptLast = { |
| | | x: this.getXOnImg(path[0].x), |
| | | y: this.getYOnImg(path[0].y) |
| | | } |
| | | const ptLast2 = { |
| | | x: this.getXOnImg(path[path.length - 1].x), |
| | | y: this.getYOnImg(path[path.length - 1].y) |
| | | } |
| | | objNew.ptAddObj.set({ |
| | | left: ptLast2.x + (ptLast.x - ptLast2.x) / 2, |
| | | top: ptLast2.y + (ptLast.y - ptLast2.y) / 2, |
| | | mainObj: objNew |
| | | }) |
| | | objNew.set({ |
| | | oldLeft: objNew.left, |
| | | oldTop: objNew.top, |
| | | }) |
| | | this.canvas.bringObjectToFront(objNew.ptAddObj); |
| | | objNew.ptAddObj.setCoords() |
| | | let list = this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "cmd") |
| | | list.forEach((obj) => { |
| | | obj.mainObj = objNew |
| | | }) |
| | | this.editObject = objNew |
| | | this.createOkCancelControl(objNew) |
| | | }, |
| | | addRegionFinish(obj) { |
| | | const objList = obj.ptObjs || [] |
| | | |
| | | |
| | | for (let i = 0; i < objList.length; i++) { |
| | | this.canvas.remove(objList[i]) |
| | | } |
| | | let color = obj.data.color || "#ff4d4f" |
| | | obj.set({ |
| | | fill: hexToRGBA(color, 0.2) |
| | | }) |
| | | this.canvas.remove(obj.ptAddObj) |
| | | |
| | | delete obj.ptObjs |
| | | delete obj.ptAddObj |
| | | this.canvas.sendObjectToBack(obj); |
| | | this.canvas.moveObjectTo(obj, 1); |
| | | obj.set({ |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | selectable: false |
| | | }) |
| | | }, |
| | | removeRegion(obj) { |
| | | this.closeOkCancelControl() |
| | | const objList = obj.ptObjs || [] |
| | | for (let i = 0; i < objList.length; i++) { |
| | | this.canvas.remove(objList[i]) |
| | | } |
| | | if (obj.ptAddObj) |
| | | this.canvas.remove(obj.ptAddObj) |
| | | this.canvas.remove(obj) |
| | | }, |
| | | updateAgvLaser(param) { |
| | | const angle = param.angle - Math.PI / 2 // * 180 / Math.PI |
| | | const pt = { |
| | | x: this.getXOnImg(param.x), |
| | | y: this.getYOnImg(param.y) |
| | | } |
| | | let ellipse = new fabric.Ellipse({ |
| | | id: "agv_laser", |
| | | eleType: "agv_laser", |
| | | left: pt.x, |
| | | top: pt.y, |
| | | rx: 2, |
| | | ry: 2, |
| | | stroke: "#00aa00", |
| | | strokeWidth: 1, |
| | | fill: "#00aa00", |
| | | originX: "center", |
| | | originY: "center", |
| | | selectable: false, |
| | | hasControls: true, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | }); |
| | | this.canvas.add(ellipse) |
| | | const offX = 20 * Math.cos(angle) |
| | | const offY = 20 * Math.sin(angle) |
| | | console.log("angle", param.angle, offX, offY) |
| | | if (this.objAgvLaser) { |
| | | this.canvas.remove(this.objAgvLaser) |
| | | } |
| | | 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, |
| | | }); |
| | | this.objAgvLaser = line |
| | | this.canvas.add(line) |
| | | }, |
| | | updateLaserPoint(param) { |
| | | |
| | | let list2 = this.canvas.getObjects() || [] |
| | | list2 = list2.filter((a) => a.eleType == "laser_point") |
| | | for (let i in list2) { |
| | | const obj = list2[i] |
| | | obj.set({ |
| | | fill: "#000", |
| | | }) |
| | | } |
| | | const list = param.xy || [] |
| | | for (let i in list) { |
| | | const pt = list[i] |
| | | const pt2 = { |
| | | x: this.getXOnImg(pt[0]), |
| | | y: this.getYOnImg(pt[1]) |
| | | } |
| | | const point = new fabric.Rect({ |
| | | id: "laser_point", |
| | | eleType: "laser_point", |
| | | left: pt2.x, |
| | | top: pt2.y, |
| | | width: 1, |
| | | height: 1, |
| | | fill: "#F5222D", |
| | | originX: "center", |
| | | originY: "center", |
| | | selectable: false, |
| | | hasControls: true, |
| | | lockRotation: true, |
| | | lockScalingX: true, |
| | | lockScalingY: true, |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | }); |
| | | // let point = new fabric.Ellipse({ |
| | | // id: "laser_point", |
| | | // eleType: "laser_point", |
| | | // left: pt[0], |
| | | // top: pt[1], |
| | | // rx: 2, |
| | | // ry: 1, |
| | | // strokeWidth: 1, |
| | | // stroke: "#F5222D", |
| | | // fill: "#F5222D", |
| | | // originX: "center", |
| | | // originY: "center", |
| | | // selectable: false, |
| | | // hasControls: true, |
| | | // lockRotation: true, |
| | | // lockScalingX: true, |
| | | // lockScalingY: true, |
| | | // lockMovementX: true, |
| | | // lockMovementY: true, |
| | | // }); |
| | | this.canvas.add(point) |
| | | } |
| | | |
| | | }, |
| | | |
| | | ensurePointVisible(pt) { |
| | | var zoom = this.canvas.getZoom(); |
| | | var vpt = this.canvas.viewportTransform; // 当前变换矩阵 |
| | | |
| | | var newPanX = vpt[4]; |
| | | var newPanY = vpt[5]; |
| | | if (pt.x * zoom < vpt[4] + 80 || pt.x * zoom > vpt[4] + this.eleWidth - 80) { |
| | | if (pt.x * zoom - this.eleWidth / 2 < 80) { |
| | | newPanX = -80 |
| | | } else if (pt.x * zoom > this.mapInfo.img_x * zoom - 80) { |
| | | newPanX = this.mapInfo.img_x * zoom - this.eleWidth + 80 |
| | | } else { |
| | | newPanX = pt.x * zoom - this.eleWidth / 2 |
| | | } |
| | | } |
| | | if (pt.y * zoom < vpt[5] + 80 || pt.y * zoom > vpt[5] + this.eleHeight - 200) { |
| | | |
| | | if (pt.y * zoom - this.eleHeight / 2 < 80) { |
| | | newPanY = -80 |
| | | } else if (pt.y * zoom > this.mapInfo.img_y * zoom - 200) { |
| | | newPanY = this.mapInfo.img_y * zoom - this.eleHeight + 200 |
| | | } else { |
| | | newPanY = pt.y * zoom - this.eleHeight / 2 |
| | | } |
| | | } |
| | | |
| | | // 只有在需要时才平移 |
| | | if (newPanX !== vpt[4] || newPanY !== vpt[5]) { |
| | | this.canvas.absolutePan({ |
| | | x: newPanX, |
| | | y: newPanY |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | setAllObjectSelectable(selectable) { |
| | | let flag = false |
| | | this.canvas.forEachObject(function(obj) { |
| | |
| | | } else { |
| | | _this.receiveMsg(newValue, oldValue) |
| | | } |
| | | }, 500) |
| | | }, 100) |
| | | |
| | | }, |
| | | async handleMsg(newValue, oldValue) { |
| | | |
| | | const _this = this |
| | | try { |
| | | //console.log("handleMsg", newValue) |
| | | var data = JSON.parse(newValue); |
| | | for (var i = 0; i < data.length; i++) { |
| | | const item = data[i] |
| | |
| | | _this.editMode = false |
| | | } |
| | | } |
| | | |
| | | if (item.method == "background") { |
| | | await _this.setBackground(item.param) |
| | | } else if (item.method == "update_agv_state") { |
| | | const info = item.param || {} |
| | | await _this.updateAgv(info) |
| | | // const workSpaceWidth = this.workSpace.width |
| | | // const workSpaceHeight = this.workSpace.height |
| | | |
| | | |
| | | } else if (item.method == "update_current_teaching") { |
| | | const info = item.param || [] |
| | | await _this.updateCurrentTeaching(info) |
| | | } else if (item.method == "move_canvas") { |
| | | const info = item.param || {} |
| | | // const scale = this.getAutoScale() |
| | | const zoom = this.canvas.getZoom(); |
| | | const eleHeight = this.eleHeight - 150 |
| | | const info2 = item.param || {} |
| | | |
| | | let deltaX = info.x * zoom - this.eleWidth / 2 // * scale; |
| | | let deltaY = info.y * zoom - eleHeight / 2 //* scale; |
| | | const vpt = this.canvas.viewportTransform; |
| | | const oldX = vpt[4] |
| | | const oldY = vpt[5] |
| | | if (deltaX + this.eleWidth > this.workSpace.width) |
| | | deltaX = this.workSpace.width - this.eleWidth |
| | | if (deltaY + eleHeight > this.workSpace.height) |
| | | deltaY = this.workSpace.height - eleHeight |
| | | if (oldX + this.eleWidth >= info.x * zoom && info.x * zoom >= oldX) { |
| | | deltaX = -oldX |
| | | //console.log("move_canvas X", oldX) |
| | | const pt = { |
| | | x: this.getXOnImg(info2.x), |
| | | y: this.getYOnImg(info2.y) |
| | | } |
| | | if (oldY + eleHeight >= info.y * zoom && info.y * zoom >= oldY) { |
| | | // console.log("move_canvas Y", oldY) |
| | | deltaY = -oldY |
| | | } |
| | | _this.canvas.absolutePan(new fabric.Point(deltaX, deltaY)); |
| | | this.ensurePointVisible(pt) |
| | | |
| | | |
| | | |
| | | } else if (item.method == "add_station") { |
| | | const stationList = item.param || [] |
| | | let list = _this.canvas.getObjects() || [] |
| | | for (let i2 in stationList) { |
| | | const station = stationList[i2] |
| | | const curIndex = list.findIndex((a) => a.data?.stationID == station.stationID) |
| | | const curIndex = list.findIndex((a) => a.data?.stationID == station |
| | | .stationID) |
| | | if (curIndex < 0) { |
| | | await _this.addStation(station) |
| | | } |
| | |
| | | list = list.filter((a) => a.eleType == "station") |
| | | for (let i2 in stationList) { |
| | | const station = stationList[i2] |
| | | const curIndex = list.findIndex((a) => a.data.stationID == station.stationID) |
| | | const curIndex = list.findIndex((a) => a.data.stationID == station |
| | | .stationID) |
| | | if (curIndex < 0) { |
| | | await _this.addStation(station) |
| | | } else { |
| | | // _this.canvas.remove(list[curIndex]) |
| | | const curStationObj = list[curIndex] |
| | | const angle = station.angle * 180 / 3.14 |
| | | const angle = station.angle * 180 / Math.PI |
| | | //const scale = this.getAutoScale() |
| | | const left = station.x //* scale |
| | | const top = station.y //* scale |
| | | console.log("update_station", curIndex, left, |
| | | top, |
| | | angle) |
| | | if (curStationObj.left != left || top != station.y || curStationObj.angle != |
| | | angle) { |
| | | const left = this.getXOnImg(station.x) //* scale |
| | | const top = this.getYOnImg(station.y) //* scale |
| | | if (curStationObj.left != left || top != station.y || |
| | | curStationObj.angle != angle) { |
| | | curStationObj.set({ |
| | | left, |
| | | top, |
| | | angle, |
| | | data: station |
| | | }) |
| | | |
| | | curStationObj.tipObj.set({ |
| | | text: `${station.name}`, |
| | | left: curStationObj.left, |
| | | top: curStationObj.top - curStationObj.height / 2 - |
| | | curStationObj |
| | | .tipObj.height / 2, |
| | | }) |
| | | curStationObj.tipObj.setCoords() |
| | | curStationObj.setCoords() |
| | | if (_this.editObject == curStationObj) { |
| | | _this.editObject.tipObj.set({ |
| | | visible: false |
| | | }) |
| | | this.createOkCancelControl(curStationObj) |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | } else if (item.method == "remove_station") { |
| | | const stationList = item.param || [] |
| | | let list = _this.canvas.getObjects() || [] |
| | | |
| | | list = list.filter((a) => a.eleType == "station") |
| | | for (let i2 in stationList) { |
| | | const station = stationList[i2] |
| | | const curIndex = list.findIndex((a) => a.data.stationID == station.stationID) |
| | | const curIndex = list.findIndex((a) => a.data.stationID == station |
| | | .stationID) |
| | | if (curIndex > -1) { |
| | | const tipObj = list[curIndex].tipObj |
| | | _this.closeOkCancelControl() |
| | | console.log("remove_station", list[curIndex]) |
| | | _this.canvas.remove(list[curIndex]) |
| | | if (tipObj) { |
| | | _this.canvas.remove(tipObj) |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | } else if (item.method == "select_station") { |
| | | const station = item.param || {} |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "station") |
| | | _this.setAllObjectSelectable(false) |
| | | |
| | | let listSel = [] |
| | | const curIndex = list.findIndex((a) => a.data.stationID == station.stationID) |
| | | if (curIndex > -1) { |
| | | console.log("select_station", curIndex, list[curIndex]) |
| | | listSel.push(list[curIndex]) |
| | | |
| | | list[curIndex].set({ |
| | | selectable: true |
| | | }) |
| | | _this.canvas.discardActiveObject(); |
| | | // let sel = new fabric.ActiveSelection(listSel, { |
| | | // canvas: _this.canvas, |
| | | // }); |
| | | _this.canvas.setActiveObject(list[curIndex]); |
| | | } |
| | | } else if (item.method == "edit_station_pos") { |
| | | const station = item.param || undefined |
| | | |
| | | if (!station) { |
| | | if (_this.editObject) { |
| | | _this.editObject.set({ |
| | | lockMovementX: true, |
| | | lockMovementY: true, |
| | | }) |
| | | |
| | | _this.editObject = null |
| | | } |
| | | |
| | | _this.closeOkCancelControl() |
| | | continue |
| | | } |
| | | let list = _this.canvas.getObjects() || [] |
| | |
| | | } |
| | | list[curIndex].set({ |
| | | selectable: true, |
| | | lockEdit: false |
| | | lockEdit: false, |
| | | lockMovementX: false, |
| | | lockMovementY: false, |
| | | }) |
| | | _this.editObject.tipObj.set({ |
| | | left: _this.editObject.left, |
| | | top: _this.editObject.top - _this.editObject.height / 2 - _this |
| | | .editObject |
| | | .tipObj.height / 2, |
| | | visible: false |
| | | }) |
| | | _this.createOkCancelControl(_this.editObject) |
| | | } |
| | | |
| | | } else if (item.method == "mark_station") { |
| | | const stationIdList = item.param || [] |
| | | let list2 = _this.canvas.getObjects() || [] |
| | | let list = list2.filter((a) => a.eleType == "station") |
| | | const flag = stationIdList.length == 2 |
| | | |
| | | _this.showTeachingPath(_this.showTeachPathFlag ? true : false) |
| | | let objStation1 |
| | | let objStation2 |
| | | for (let i2 in list) { |
| | | const obj = list[i2] |
| | | const curIndex = stationIdList.findIndex((a) => a == obj.data.stationID) |
| | | if (curIndex > -1) { |
| | | await _this.setMarkStation(obj, true) |
| | | obj.set({ |
| | | selectable: true, |
| | | opacity: 1 |
| | | }) |
| | | if (!objStation1) |
| | | objStation1 = obj |
| | | else |
| | | objStation2 = obj |
| | | |
| | | } else { |
| | | await _this.setMarkStation(obj, false) |
| | | if (flag) { |
| | | obj.set({ |
| | | selectable: false, |
| | | opacity: 0.5 |
| | | }) |
| | | } else { |
| | | obj.set({ |
| | | selectable: true, |
| | | opacity: 1 |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | list = list2.filter((a) => a.eleType == "station_teaching") |
| | | if (objStation1 && objStation2) { |
| | | const id = |
| | | `station_teaching_${objStation1.data.stationID}_${objStation2.data.stationID}` |
| | | const curIndex = list.findIndex((a) => a.id == id) |
| | | if (curIndex > -1) { |
| | | list[curIndex].set({ |
| | | opacity: 1, |
| | | strokeDashArray: [3, 2], |
| | | strokeLineCap: 'butt', |
| | | }) |
| | | } |
| | | } |
| | | |
| | | } else if (item.method == "station_teaching") { |
| | | let list = _this.canvas.getObjects() || [] |
| | | list.forEach((obj) => { |
| | | if (obj.eleType == "public_teaching" || obj.eleType == |
| | | "station_teaching") { |
| | | obj.set({ |
| | | hasControls: false, |
| | | selectable: false, |
| | | }) |
| | | } else if (obj.eleType == "station" || obj.eleType == |
| | | "station_tip") { |
| | | obj.set({ |
| | | selectable: true, |
| | | opacity: 1 |
| | | }) |
| | | } else { |
| | | obj.set({ |
| | | opacity: 0.5 |
| | | }) |
| | | } |
| | | }) |
| | | } else if (item.method == "public_teaching") { |
| | | let list = _this.canvas.getObjects() || [] |
| | | list.forEach((obj) => { |
| | | if (obj.eleType == "public_teaching" || obj.eleType == |
| | | "station_teaching") { |
| | | obj.set({ |
| | | hasControls: false, |
| | | selectable: false, |
| | | }) |
| | | } else if (obj.eleType == "agv") |
| | | obj.set({ |
| | | opacity: 1 |
| | | }) |
| | | else |
| | | obj.set({ |
| | | opacity: 0.5 |
| | | }) |
| | | }) |
| | | } else if (item.method == "teaching_finish") { |
| | | if (this.curTeachingObj) { |
| | | this.canvas.remove(this.curTeachingObj) |
| | | this.curTeachingObj = null |
| | | } |
| | | let list = _this.canvas.getObjects() || [] |
| | | for (let i2 in list) { |
| | | const obj = list[i2] |
| | | obj.set({ |
| | | selectable: false, |
| | | opacity: 1 |
| | | }) |
| | | // if (obj.eleType == "station") { |
| | | // await _this.setMarkStation(obj, false) |
| | | // } |
| | | |
| | | } |
| | | _this.showTeachingPath(_this.showTeachPathFlag ? true : false) |
| | | |
| | | } else if (item.method == "public_teaching_path") { |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "public_teaching") |
| | | for (let i2 in list) { |
| | | this.canvas.remove(list[i2]) |
| | | } |
| | | const teachingPathList = item.param || [] |
| | | for (let i2 in teachingPathList) { |
| | | const teachingPath = teachingPathList[i2] |
| | | const id = `public_teaching_${teachingPath.name}` |
| | | await this.addTeachingPath(teachingPath, id, "public_teaching") |
| | | } |
| | | } else if (item.method == "station_teaching_path") { |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "station_teaching") |
| | | for (let i2 in list) { |
| | | this.canvas.remove(list[i2]) |
| | | } |
| | | const teachingPathList = item.param || [] |
| | | for (let i2 in teachingPathList) { |
| | | const teachingPath = teachingPathList[i2] |
| | | |
| | | const id = `station_teaching_${teachingPath.src_dst}` |
| | | |
| | | await this.addTeachingPath(teachingPath, id, "station_teaching") |
| | | } |
| | | } else if (item.method == "show_teaching_path") { |
| | | _this.showTeachPathFlag = item.param.show |
| | | _this.showTeachingPath(item.param.show) |
| | | |
| | | } else if (item.method == "remove_teaching_path") { |
| | | 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 curIndex = list.findIndex((a) => a.id == id) |
| | | |
| | | if (curIndex > -1) { |
| | | const obj = list[curIndex] |
| | | console.log(item.method, curIndex, id, obj) |
| | | _this.canvas.remove(obj) |
| | | } |
| | | } else if (item.param.mode == "Stations") { |
| | | list = list.filter((a) => a.eleType == "station_teaching") |
| | | const id = `station_teaching_${item.param.src_dst}` |
| | | const curIndex = list.findIndex((a) => a.id == id) |
| | | if (curIndex > -1) { |
| | | |
| | | const obj = list[curIndex] |
| | | this.canvas.remove(obj) |
| | | } |
| | | |
| | | } |
| | | |
| | | } else if (item.method == "edit_teaching") { |
| | | const teachingMode = item.param |
| | | _this.showEditTeachingPath(teachingMode) |
| | | |
| | | } else if (item.method == "set_selectable") { |
| | | if (item.param) |
| | |
| | | }) |
| | | _this.editObject = null |
| | | } |
| | | } |
| | | } else if (item.method == "add_wall") { |
| | | const wallList = item.param || [] |
| | | for (let i2 in wallList) { |
| | | const wall = wallList[i2] |
| | | const obj = await _this.addVirtualWall(wall) |
| | | |
| | | } |
| | | } else if (item.method == "wall_list") { |
| | | const wallList = item.param || [] |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "virtual_wall") |
| | | for (let i2 in wallList) { |
| | | const wall = wallList[i2] |
| | | const curIndex = list.findIndex((a) => a.id == wall.id) |
| | | if (curIndex < 0) { |
| | | await _this.addVirtualWallShow(wall) |
| | | } |
| | | } |
| | | } else if (item.method == "add_region") { |
| | | const regionList = item.param || [] |
| | | for (let i2 in regionList) { |
| | | const region = regionList[i2] |
| | | const obj = await _this.addRegion(region) |
| | | |
| | | |
| | | } |
| | | } else if (item.method == "region_list") { |
| | | const regionList = item.param || [] |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "region") |
| | | for (let i2 in regionList) { |
| | | const region = regionList[i2] |
| | | const curIndex = list.findIndex((a) => a.id == region.id) |
| | | if (curIndex < 0) { |
| | | await _this.addRegionShow(region) |
| | | } |
| | | } |
| | | |
| | | } else if (item.method == "remove_wall") { |
| | | const wallList = item.param || [] |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "virtual_wall") |
| | | for (let i2 in wallList) { |
| | | const wall = wallList[i2] |
| | | const curIndex = list.findIndex((a) => a.id == wall.id) |
| | | if (curIndex > -1) { |
| | | _this.removeVirtualWall(list[curIndex]) |
| | | } |
| | | } |
| | | } else if (item.method == "remove_region") { |
| | | const regionList = item.param || [] |
| | | let list = _this.canvas.getObjects() || [] |
| | | list = list.filter((a) => a.eleType == "region") |
| | | for (let i2 in regionList) { |
| | | const region = regionList[i2] |
| | | const curIndex = list.findIndex((a) => a.id == region.id) |
| | | if (curIndex > -1) { |
| | | _this.removeRegion(list[curIndex]) |
| | | } |
| | | } |
| | | } else if (item.method == "agv_laser") { |
| | | this.updateAgvLaser(item.param || {}) |
| | | } else if (item.method == "point_cloud") { |
| | | this.updateLaserPoint(item.param || {}) |
| | | } |
| | | } |
| | | _this.canvas.renderAll() |
| | | } catch (ex) { |
| | | console.log(ex) |
| | | this.showError(ex) |
| | | } |
| | | }, |
| | | showError(ex) { |
| | | const type = typeof ex |
| | | if (type == "string") { |
| | | let tip = ex |
| | | console.log(ex) |
| | | plus.nativeUI.alert(tip, undefined, "错误"); |
| | | return |
| | | } |
| | |
| | | exStr = ex |
| | | |
| | | let tip = typeof ex.msg == "string" ? ex.msg : exStr |
| | | console.log(tip) |
| | | plus.nativeUI.alert(tip, undefined, "错误"); |
| | | }, |
| | | showToast(ex) { |
| | | const type = typeof ex |
| | | if (type == "string") { |
| | | let tip = ex |
| | | console.log(ex) |
| | | plus.nativeUI.toast(tip); // undefined, "错误" |
| | | return |
| | | } |
| | | let exStr = JSON.stringify(ex) |
| | | if (exStr == "{}") |
| | | exStr = ex |
| | | |
| | | let tip = typeof ex.msg == "string" ? ex.msg : exStr |
| | | console.log(tip) |
| | | plus.nativeUI.toast(tip, { |
| | | duration: 'long', |
| | | verticalAlign: "center" |
| | | }); // undefined, "错误" |
| | | }, |
| | | |
| | | }, |
| | | } |