<script>export default {  data () {    return {      setColor: ['#FF0000', '#F2C94C', '#EBFF00', '#9B51E0', '#6FCF97',        '#F2F2F2', '#00FFF0', '#33FF00', '#00A3FF', '#FF00C7', '#FF7A00', '#0075FF']    }  },  mounted () {  },  methods: {    oCoords (w, h, x2, y2, reg) {      return {        tl: this.rotatoNi(x2 - w / 2, y2 - h / 2, x2, y2, reg),        tr: this.rotatoNi(x2 + w / 2, y2 - h / 2, x2, y2, reg),        bl: this.rotatoNi(x2 - w / 2, y2 + h / 2, x2, y2, reg),        br: this.rotatoNi(x2 + w / 2, y2 + h / 2, x2, y2, reg)      }    },    rotatoNi (x1, y1, x2, y2, reg) {      // 在平面坐标上,任意点P(x1,y1),绕一个坐标点Q(x2,y2)逆时针旋转角度后,新的坐标设为(x, y)的计算公式:      // x= (x1 - x2)*cos() - (y1 - y2)*sin() + x2 ;      // y= (x1 - x2)*sin() + (y1 - y2)*cos() + y2 ;      let x = parseInt((x1 - x2) * Math.cos(Math.PI * reg / 180) - (y1 - y2) * Math.sin(Math.PI * reg / 180) + x2);      let y = parseInt((x1 - x2) * Math.sin(Math.PI * reg / 180) + (y1 - y2) * Math.cos(Math.PI * reg / 180) + y2);      return { x: x, y: y } //旋转后的坐标(x,y)    },    rotatoNi2 (x1, y1, x2, y2, reg) {      let x = ((x1 - x2) * Math.cos(Math.PI * reg / 180) - (y1 - y2) * Math.sin(Math.PI * reg / 180) + x2);      let y = ((x1 - x2) * Math.sin(Math.PI * reg / 180) + (y1 - y2) * Math.cos(Math.PI * reg / 180) + y2);      return { x: x, y: y } //旋转后的坐标(x,y)    },    //左上角直角三角形    creatPath (list, i, type) {      //console.log('以后箱体左上角直角三角形数据', list, i, type)      let wc = 0      let x1 = list.x - list.width / 2 + wc      let y1 = list.y - list.height / 2 + wc      let prot = this.rotatoNi(x1, y1, list.x, list.y, list.rotationAngle)      let x = prot.x      let y = prot.y      let u = 'M ' + x + ' ' + y + ' L ' + (x + 10) + ' ' + y + ' L ' + x + ' ' + (y + 10) + ' z'      var path = new fabric.Path(u);      //console.log(i + '三角形的坐标点', x, y)      return path.set({        angle: list.rotationAngle,        left: x, //间隔画布上边的间隔        top: y, //间隔画布左侧的间隔,单位是像素        fill: '#FFFFFF', //填充的色彩        selectable: false,        stroke: '#FFFFFF', // 边框色彩        opacity: 0.3,        strokeWidth: 1,        id: list.id,        networkPort: list.networkPort,        operateType: type,      });    },    //创立中心点    makeCircle2 (list) {      var circle = new fabric.Circle({        originX: "center",        originY: "center",        left: list.x, //间隔画布上边的间隔        top: list.y, //间隔画布左侧的间隔,单位是像素        radius: 4, //圆形半径        fill: '#000', //填充的色彩        stroke: this.setColor[list.portId % 12] ? this.setColor[list.portId % 12] : '#fff', // 边框色彩        selectable: false,        evented: false,        id: list.id,        networkPort: list.networkPort,        index: list.index,        hoverCursor: "pointer",//鼠标指针形式        strokeWidth: 2 // 边框大小      });      return circle    },    //创立文本    makeText (t, list, i, type) {      let x1 = list.x - list.width / 2      let y1 = list.y - list.height / 2      let prot = this.rotatoNi(x1, y1, list.x, list.y, list.rotationAngle)      let x = (prot.x - list.x) / 1.5 + list.x      let y = (prot.y - list.y) / 1.5 + list.y      //console.log(i + '文本的坐标点', x, y)            var textBox = new fabric.Textbox(t, {        /* originX: "left",        originY: "top", */        originX: "center",        originY: "center",        left: x,        top: y,        centeredRotation: true, //核心旋转        fontSize: 12,        selectable: false,        evented: false,        networkPort: list.networkPort,        fill: '#fff',        id: list.id,        operateType: type,      });      return textBox    },    //创立矩形    makeRect (left, top, ids, width, height, angle, groupId, boxId, boxFileId) {      let rect = new fabric.Rect({        //rx: 4, //圆角半径        // ry: 4, //圆角半径        angle: angle,        left: left,        top: top,        originX: "center", //绝对于坐标点地位        originY: "center", //绝对于坐标点地位        width: width,        height: height,        //hoverCursor: "pointer",        fill: "rgba(0,153,255,0.20)",//"#1C445E",        stroke: '#136094', // 边框色彩        strokeWidth: 2, // 边框大小        borderColor: "#0099FF", //选中边框色        cornerStyle: "circle", // 手柄形态 正方形 rect||圆 circle        cornerColor: "#0099FF", //手柄背景色        cornerStrokeColor: "#0099FF", //手柄框边框        hasControls: true, //手柄        hasBorders: true, //手柄线        visible: true, //是否可见        selectable: true, //是否可抉择的对象        evented: true, //是否拖动        centeredRotation: true, //核心旋转        centeredScaling: true, //居中缩放        transparentCorners: false, //选中框通明角        preserveObjectStacking: true,        // opacity: 0.5,        networkPort: ids.networkPort,//网口        index: ids.index,//序号        groupId: groupId,        id: boxId ? boxId : null,        boxFileId: boxFileId,        //lockRotation: true,//锁定对象旋转      });      rect.setControlsVisibility({        mt: false,        mb: false,        bl: false,        br: false,        tl: false,        tr: false,        mr: false,        ml: false,        mtr: true,      });      return rect;    },    //创立线段    /*       coords 坐标      list 以后对象      arr虚线      jt, 虚线箭头    */    makeLine (coords, list, arr, jt, startId, endId) {      //console.log('list.networkPort', list.networkPort)      return new fabric.Line(coords, {        fill: this.setColor[list && list.portId % 12] ? this.setColor[list && list.portId % 12] : '#fff',        stroke: this.setColor[list && list.portId % 12] ? this.setColor[list && list.portId % 12] : '#fff',        strokeWidth: 2,        originX: "center",        originY: "center",        selectable: false,        evented: false,        hasControls: false,        hasBorders: false,        hasRotatingPoint: false,        hoverCursor: "default",        index: list.index,        networkPort: list && list.networkPort,        jt: jt || '',        id: list && list.id,        startId,        endId,        //myJoker: arr,        strokeDashArray: arr || [],        huadongbs: list.huadongbs || false      });    },    //创立连线上的实体三角形箭头    createArrowHead (x1, y1, x2, y2, width, height, list, type, startId, endId) {      return new fabric.Triangle({        angle: this.getAngle(x1, y1, x2, y2),        fill: "white",        top: y2,        left: x2,        width: width,        height: height,        originX: "center",        originY: "center",        selectable: false,        evented: false,        id: list.id,        index: list.index,        networkPort: list.networkPort,        startId,        endId,        huadongbs: list.huadongbs || false      });    },    /* 绘制箭头函数 ------->--------      fromX, fromY:终点坐标(也能够换成p1,只不过它是一个数组)      toX, toY:起点坐标 (也能够换成p2,只不过它是一个数组)      theta:三角斜边一直线夹角      headlen:三角斜边长度      width:箭头线宽度      color:箭头色彩 */    drawArrow (canvas, fromX, fromY, toX, toY, theta, headlen, width, color) {      width = 1;//箭头宽度设置为1      var theta = theta || 30,        headlen = headlen || 10,        width = width || 1,        color = color || '#000',        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);      var arrowX, arrowY;      arrowX = toX + topX; //箭头结尾右边坐标      arrowY = toY + topY;      canvas.add(this.makeLine([arrowX, arrowY, toX, toY], '', [], 'jt'));      //ctx.moveTo(arrowX, arrowY);      //ctx.lineTo(toX, toY); //箭头开始坐标      arrowX = toX + botX; //箭头结尾左边坐标      arrowY = toY + botY;      canvas.add(this.makeLine([arrowX, arrowY, toX, toY], '', [], 'jt'));      // ctx.lineTo(arrowX, arrowY);    },    //三角形角度计算    getAngle (x1, y1, x2, y2) {      var dx = x2 - x1,        dy = y2 - y1,        angle = Math.atan2(dy, dx);      angle *= 180 / Math.PI;      angle += 90;      return angle;    },    // //扭转画布大小    // zoomIt (factor) { // factor: 比例    //   let cWidth = canvas.width;    //   canvas.setWidth(cWidth * factor);    //   canvas.setHeight(cWidth * factor);    //   if (canvas.backgroundImage) {    //     var bi = canvas.backgroundImage;    //     bi.width = bi.width * factor;    //     bi.height = bi.height * factor;    //   }    //   var objects = canvas.getObjects();    //   for (var i in objects) {    //     var scaleX = objects[i].scaleX;    //     var scaleY = objects[i].scaleY;    //     var left = objects[i].left;    //     var top = objects[i].top;    //     var tempScaleX = scaleX * factor;    //     var tempScaleY = scaleY * factor;    //     var tempLeft = left * factor;    //     var tempTop = top * factor;    //     objects[i].scaleX = tempScaleX;    //     objects[i].scaleY = tempScaleY;    //     objects[i].left = tempLeft;    //     objects[i].top = tempTop;    //     objects[i].setCoords();    //   }    //   canvas.renderAll();    //   canvas.calcOffset();    // },    //阻止右键默认行为    preventYj () {      $(document).contextmenu(function (ev) {        if (ev.preventDefault) {          ev.preventDefault();        } else {          window.event.returnValue = false;        }      })    },    getTanDeg (tan) {      var result = Math.atan(tan) / (Math.PI / 180);      result = parseInt(result);      return result;    },    //自定义批改序号从新排序    setArrIndex (str, end, list) {      for (var i = 0; i < list.length; i++) {        if (end.index > list[i].index && list[i].index > str.index) {          list[i].index = list[i].index + 1        }        if (end.id == list[i].id) {          list[i].index = str.index + 1        }      }      list = list.sort((a, b) => {        return a.index - b.index      });      return list;    },    //自定义批改序号从新排序    setArrIndex2 (str, end, list) {      //序号2和4 理论就是3和4调换地位      if (str.index < end.index) {        list[str.index] = list.splice(end.index - 1, 1, list[str.index])[0];        for (var i = 0; i < list.length; i++) {          list[i].index = i + 1        }      } else {        list[end.index - 1].index = str.index        for (var i = 0; i < list.length; i++) {          if (str.index > list[i].index && list[i].index > end.index) {            list[i].index = list[i].index - 1          }        }        list[str.index - 1].index = str.index - 1        list = list.sort((a, b) => {          return a.index - b.index        });      }      return list;    },    compare (pro) {      return function (obj1, obj2) {        var val1 = obj1[pro];        var val2 = obj2[pro];        if (val1 < val2) { //正序          return 1;        } else if (val1 > val2) {          return -1;        } else {          return 0;        }      }    },    isMouseoeut (x, y) {      let that = this      var a = -15      let cdiv = document.getElementById("canvasZone")      var X1 = that.getOffsetLeft(cdiv) - a      var Y1 = that.getOffsetTop(cdiv) - a      var X2 = that.getOffsetLeft(cdiv) + cdiv.offsetWidth + a      var Y2 = that.getOffsetTop(cdiv) + cdiv.offsetHeight + a      if (x < X2 && x > X1 && y < Y2 && y > Y1) {        return true      } else {        return false      }    },    groupAdd (list, canvas) {      //console.log('旧式分组')      /* x.y示意左上角点 */      var x1 = -50, y1 = -50, width = 100, height = 100;      let x = list.x - list.width / 2      let y = list.y - list.height / 2      let u = 'M ' + x + ' ' + y + ' L ' + (x + 10) + ' ' + y + ' L ' + x + ' ' + (y + 10) + ' z'      var path2 = new fabric.Path(u);      //左上角三角形      path2.set({        left: this.face == true ? (-(list.width / 2)) : (list.width / 2),        left: this.showFace == true ? (-(list.width / 2)) : (list.width / 2), top: -(list.height / 2),        fill: '#dadcdb', //填充的色彩        opacity: list.boxStatus == 1 ? 0.3 : 1,        strokeWidth: 1,        angle: this.face == true ? 0 : 90,        angle: this.showFace == true ? 0 : 90,      })      var t = list.index == 0 ? '' : (list.slotId ? list.slotId : 0) + "_" + (list.portId ? list.portId : 0) + "_" + list.index      //文字      // console.log(this.face);      var text2 = new fabric.Text(t, {        angle: -list.rotationAngle,        fontSize: 12,        originX: 'center',        originY: 'center',        fill: '#fff',        left: this.face == true ? (-(list.width / 2) + 20) : (list.width / 2 - 20),        left: this.showFace == true ? (-(list.width / 2) + 20) : (list.width / 2 - 20),        top: -(list.height / 2) + 20,      });      //中心点      var circle2 = new fabric.Circle({        originX: "center",        originY: "center",        radius: 4, //圆形半径        fill: '#000', //填充的色彩        stroke: this.setColor[list.portId] ? this.setColor[list.portId] : '#fff', // 边框色彩        selectable: false,        evented: false,        hoverCursor: "pointer",//鼠标指针形式        strokeWidth: 2 // 边框大小      });      //矩形      var rect2 = new fabric.Rect({        width: list.width,        height: list.height,        originX: 'center',        originY: 'center',        fill: "rgba(0,153,255,0.20)",//"#1C445E",        stroke: '#136094', // 边框色彩        strokeWidth: 2, // 边框大小        borderColor: "#0099FF", //选中边框色        cornerStyle: "circle", // 手柄形态 正方形 rect||圆 circle        cornerColor: "#0099FF", //手柄背景色        cornerStrokeColor: "#0099FF", //手柄框边框        centeredRotation: true,        portId: list.portId,        slotId: list.slotId,        isSwitch: list.isSwitch,      });      var group2 = new fabric.Group([rect2, circle2, text2, path2], {        left: list.x,        top: list.y,        width: list.width,        height: list.height,        originX: 'center',        originY: 'center',        isCheckTo: true, //有这个字段示意单选,没有多选        networkPort: list.networkPort,//网口        index: list.index,//序号        groupId: 'box',        groupIdd: list.groupId,        id: list.id,        angle: list.rotationAngle,        centeredRotation: true,        fill: "#0099FF",//"#1C445E",        stroke: '#0099FF', // 边框色彩        strokeWidth: 2, // 边框大小        borderColor: "#0099FF", //选中边框色        cornerStyle: "circle", // 手柄形态 正方形 rect||圆 circle        cornerColor: "#0099FF", //手柄背景色        cornerStrokeColor: "#0099FF", //手柄框边框        huadongbs: list.huadongbs || false,        boxFileId: list.boxFileId,        portId: list.portId,        slotId: list.slotId,        isSwitch: list.isSwitch,        //scaleX: this.canvasZoom,        //scaleY: this.canvasZoom      });      return group2    }  },};</script>