使用fabric.js来实现正方形

通过鼠标点击 然后放开鼠标 移动会生成正方形的轮廓 再次点击会生成正方形 求解

你好,我是有问必答小助手。为了技术专家团更好地为您解答问题,烦请您补充下(1)问题背景详情,(2)您想解决的具体问题,(3)问题相关代码图片或者报错信息。便于技术专家团更好地理解问题,并给出解决方案。

您可以点击问题下方的【编辑】,进行补充修改问题。
img

img

<script>

import { fabric} from 'fabric';
var pointArray=[];

export default {
name: "Fabric",
data() {
return {
width: 800,
height: 550,
rect: [],
canvas: {},
showMenu: false,
x: "",
y: "",
z:"",
t:"",

  mouseFrom: {},
  mouseTo: {},
  drawType: null,  //当前绘制图像的种类
  canvasObjectIndex: 0,
  textbox: null,
  rectangleLabel: "warning",
  drawWidth: 2, //笔触宽度
  color: "#E34F51", //画笔颜色
  drawingObject: null, //当前绘制对象
  moveCount: 1, //绘制移动计数器
  doDrawing: false, // 绘制状态
  

  //polygon 相关参数
  polygonMode: false,
  pointArray: [],
  lineArray: [],
  activeShape: false,
  activeLine: "",
  line: {},

,

  delectKlass: {},
  imgFile: {},
  imgSrc: "",
      
    defaultProps: {
      children: 'children',
      label: 'label'
    }
    
};

},
watch: {
drawType() {
this.canvas.selection = !this.drawType;
},
width() {
this.canvas.setWidth(this.width)
},
height() {
this.canvas.setHeight(this.height)
},
},
methods: {
// 保存当前画布为png图片
save() {
var canvas = document.getElementById('canvas')
this.downFile(canvas)
},
saveFile(data, filename) {
var save_link = document.createElement('a');
save_link.href = data;
save_link.download = filename;

  var event = document.createEvent('MouseEvents');
  event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  save_link.dispatchEvent(event);
},

// 开始绘制时,指定绘画种类
drawTypeChange(e) {
  this.drawType = e;
  this.canvas.skipTargetFind = !!e
  if (e == "pen") {
    // isDrawingMode为true 才可以自由绘画
    this.canvas.isDrawingMode = true;
  } else {
    this.canvas.isDrawingMode = false;
  }
},
ondel(){
    console.log('1111')
    this.deleteObj();
    this.canvas.remove
      this.canvas.getObjects()[this.canvas.getObjects().length - 1]

},
// 鼠标按下时触发
mousedown(e) {
  // 记录鼠标按下时的坐标
  var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
  this.mouseFrom.x = xy.x;
  this.mouseFrom.y = xy.y;
  
  this.doDrawing = true;
  if (this.drawType == "text") {
    this.drawing();
  }

  if (this.textbox) {
    this.textbox.enterEditing();
    this.textbox.hiddenTextarea.focus();
  }
  // 绘制多边形
  if (this.drawType == "polygon") {
    this.canvas.skipTargetFind = false;
    try {
      // 此段为判断是否闭合多边形,点击红点时闭合多边形
      if (this.pointArray.length > 1) {
        // e.target.id == this.pointArray[0].id 表示点击了初始红点
        if (e.target && e.target.id == this.pointArray[0].id) {
          this.generatePolygon();
        }
      }
      //未点击红点则继续作画
      if (this.polygonMode) {
        this.addPoint(e);
        
      }
    } catch (error) {
      console.log(error);
    }
  }
  if(this.drawType == "pentagram"){
    this.pentagram.top=xy.y
    this.pentagram.left=xy.x
    
    this.mouseups()

  }


  
 
},
'selection:created': (e)=>{
        if (e.target._objects) {
          //多选删除
          var etCount = e.target._objects.length;
          for (var etindex = 0; etindex < etCount; etindex++) {
            this.fabricObj.remove(e.target._objects[etindex]);
          }
        } else {
          //单选删除
          this.fabricObj.remove(e.target);
        }
        this.fabricObj.discardActiveObject(); //清楚选中框
        this.updateModifications(true) 
      },
     
// 鼠标松开执行
mouseup(e) {
  var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
  this.mouseTo.x = xy.x;
  this.mouseTo.y = xy.y;

  pointArray.push({
          x:xy.x,
          y:xy.y,

        })
  
  this.drawingObject = null;
  if (this.drawType != "polygon") {
    this.doDrawing = false;
  }
},
mouseups(e) {

   var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
  this.mouseTo.x = xy.x;
  this.mouseTo.y = xy.y;

  pointArrays.push({
          x:xy.x,
          y:xy.y,

        })
    this.drawingObject = null;
  if (this.drawType != "pentagram") {
    this.doDrawing = false;
  }
    this.canvas.renderAll();


},

//鼠标移动过程中已经完成了绘制
mousemove(e) {
  if (this.moveCount % 2 && !this.doDrawing) {
    //减少绘制频率
    return;
  }
  this.moveCount++;
  var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
  this.mouseTo.x = xy.x;
  this.mouseTo.y = xy.y;
  // 多边形与文字框特殊处理
  if (this.drawType != "text" || this.drawType != "polygon" ) {
    this.drawing(e);
  }
  if (this.drawType == "polygon") {
    if (this.activeLine && this.activeLine.class == "line") {
      var pointer = this.canvas.getPointer(e.e);
      this.activeLine.set({ x2: pointer.x, y2: pointer.y });

      var points = this.activeShape.get("points");
      points[this.pointArray.length] = {
        x: pointer.x,
        y: pointer.y,
        zIndex: 1
      };
      this.activeShape.set({
        points: points
      });
      this.canvas.renderAll();
    }
    this.canvas.renderAll();
  }
            

},
deleteObj() {
  this.canvas.getActiveObjects().map(item => {
    this.canvas.remove(item);
  });
},
transformMouse(mouseX, mouseY) {
  return { x: mouseX / 1, y: mouseY / 1 };
},

// 绘制多边形开始,绘制多边形和其他图形不一样,需要单独处理
drawPolygon() {
  this.drawType = "polygon";
  this.polygonMode = true;
  //这里画的多边形,由顶点与线组成
  this.pointArray = new Array();  // 顶点集合
  this.lineArray = new Array();  //线集合
  this.canvas.isDrawingMode = false;
},
pentagram() {
     this.drawType = "pentagram";
  this.polygonMode = true;
  //这里画的多边形,由顶点与线组成
  this.pointer = new Array();  // 顶点集合
  this.lineArray = new Array();  //线集合
  this.canvas.isDrawingMode = false;
 
},
addPoint(e) {
  var random = Math.floor(Math.random() * 10000);
  var id = new Date().getTime() + random;
  var circle = new fabric.Circle({
    radius: 5,
    fill: "#ffffff",
    stroke: "#333333",
    strokeWidth: 0.5,
    left: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
    top: (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
    selectable: false,
    hasBorders: false,
    hasControls: false,
    originX: "center",
    originY: "center",
    id: id,
    objectCaching: false
  });
  if (this.pointArray.length == 0) {
    circle.set({
      fill: "red"
    });
  }
  var points = [
    (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
    (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
    (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
    (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
  ];

  this.line = new fabric.Line(points, {
    strokeWidth: 2,
    fill: "#999999",
    stroke: "#999999",
    class: "line",
    originX: "center",
    originY: "center",
    selectable: false,
    hasBorders: false,
    hasControls: false,
    evented: false,

    objectCaching: false
  });
  if (this.activeShape) {
    var pos = this.canvas.getPointer(e.e);
    var points = this.activeShape.get("points");
    points.push({
      x: pos.x,
      y: pos.y
    });
    var polygon = new fabric.Polygon(points, {
      stroke: "#333333",
      strokeWidth: 1,
      fill: "#cccccc",
      opacity: 0.3,

      selectable: false,
      hasBorders: false,
      hasControls: false,
      evented: false,
      objectCaching: false
    });
    this.canvas.remove(this.activeShape);
    this.canvas.add(polygon);
    this.activeShape = polygon;
    this.canvas.renderAll();
  } else {
    var polyPoint = [
      {
        x: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
        y: (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
      }
    ];
    var polygon = new fabric.Polygon(polyPoint, {
      stroke: "#333333",
      strokeWidth: 1,
      fill: "#cccccc",
      opacity: 0.5,

      selectable: false,
      hasBorders: false,
      hasControls: false,
      evented: false,
      objectCaching: false
    });
    this.activeShape = polygon;
    this.canvas.add(polygon);
  }
  this.activeLine = this.line;

  this.pointArray.push(circle);
  this.lineArray.push(this.line);
  this.canvas.add(this.line);
  this.canvas.add(circle);
},
generatePolygon() {
  var points = new Array();
  this.pointArray.map((point, index) => {
    points.push({
      x: point.left,
      y: point.top
    });
    this.canvas.remove(point);
  });
  this.lineArray.map((line, index) => {
    this.canvas.remove(line);
  });
  this.canvas.remove(this.activeShape).remove(this.activeLine);
  var polygon = new fabric.Polygon(points, {
    stroke: this.color,
    strokeWidth: this.drawWidth,
    fill: "rgba(255, 255, 255, 0)",
    opacity: 1,
    hasBorders: true,
    hasControls: false
  });
  this.canvas.add(polygon);

  this.activeLine = null;
  this.activeShape = null;
  this.polygonMode = false;
  this.doDrawing = false;
  this.drawType = null;
},
drawing(e) {
  if (this.drawingObject) {
    this.canvas.remove(this.drawingObject);
  }
  var canvasObject = null;
  var left = this.mouseFrom.x,
    top = this.mouseFrom.y,
    mouseFrom = this.mouseFrom,
    mouseTo = this.mouseTo;
  switch (this.drawType) {
    
    case "rectangle": //长方形
      // 按shift时画正方型
      if (e.e.shiftKey) {
        mouseTo.x - left > mouseTo.y - top ? mouseTo.y = top + mouseTo.x - left : mouseTo.x = left + mouseTo.y - top
      }
      var path =
        "M " +
        mouseFrom.x +
        " " +
        mouseFrom.y +
        " L " +
        mouseTo.x +
        " " +
        mouseFrom.y +
        " L " +
        mouseTo.x +
        " " +
        mouseTo.y +
        " L " +
        mouseFrom.x +
        " " +
        mouseTo.y +
        " L " +
        mouseFrom.x +
        " " +
        mouseFrom.y +
        " z";
      canvasObject = new fabric.Path(path, {
        left: left,
        top: top,
        stroke: this.color,
        strokeWidth: this.drawWidth,
        fill: "rgba(255, 255, 255, 0)",
        hasControls: false
      });
      //也可以使用fabric.Rect
      break;
    case "text": //文本框
      this.textbox = new fabric.Textbox("", {
        left: mouseFrom.x,
        top: mouseFrom.y - 10,
        // width: 150,
        fontSize: 16,
        borderColor: this.color,
        fill: this.color,
        hasControls: false
      });
      this.canvas.add(this.textbox);
      this.textbox.enterEditing();
      this.textbox.hiddenTextarea.focus();
      break;
    default:
      break;
  case "del":
      this.drawingObject.selection = true
      this.drawingObject.skipTargetFind = false
      this.drawingObject.selectable = true
    break;
  }

  if (canvasObject) {
    // canvasObject.index = getCanvasObjectIndex();\
    this.canvas.add(canvasObject); //.setActiveObject(canvasObject)
    this.drawingObject = canvasObject;
  }
},
 transferred(data) {
       return data.replace(/<br>/g, "\r\n").replace(/&gt;/g, ">");
    },
downFile(){
      let fileName = Date.now() + "point.json";
      var columnDelimiter = ","; //列分割符
      var lineDelimiter = "\r\n"; //行分割符
      let result = "";// 最终结果的字符串
      var ths=[
          "label"
          ,"abc"
          ,"ab1c",
          

      ]
      for (let i = 0, l = ths.length; i < l; i++) {
        result +=
          this.transferred('"' + ths[i] + '"') + columnDelimiter;//每一列用逗号分隔
      }
      result += lineDelimiter;// 每一行使用"\r\n"分隔
      var trs = pointArray;
      
      for (let i = 0, l = trs.length; i < l; i++) {
        result +=
        this.transferred('"' + trs[i].x + '"') + columnDelimiter
          + this.transferred('"' + trs[i].y + '"') + columnDelimiter
        result += lineDelimiter;
      }
      var blob = new Blob(["\uFEFF" + result], { type: "text/json;" });//记得将编码格式设置一下,避免最终下载的文件出现乱码
      var downloadLink = document.createElement("a");
      if ("download" in downloadLink) {
        var url = URL.createObjectURL(blob);
        downloadLink.href = url;
        downloadLink.download = fileName;
        downloadLink.hidden = true;
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
      } else {
        if (navigator.msSaveBlob) {
          //IE10+
          navigator.msSaveBlob(blob, fileName);
        }
      }
    }

},
mounted() {
this.canvas = new fabric.Canvas("canvas", {
// skipTargetFind: false, //当为真时,跳过目标检测。目标检测将返回始终未定义。点击选择将无效
// selectable: false, //为false时,不能选择对象进行修改
// selection: false // 是否可以多个对象为一组
});
this.canvas.selectionColor = "rgba(0,0,0,0.05)";
this.canvas.on("mouse:down", this.mousedown);
this.canvas.on("mouse:move", this.mousemove);
this.canvas.on("mouse:up", this.mouseup);

document.onkeydown = e => {
  // 键盘 delect删除所选元素
  if (e.keyCode == 46) {
    this.deleteObj();
  }
  // ctrl+z 删除最近添加的元素
  if (e.keyCode == 90 && e.ctrlKey) {
    this.canvas.remove(
      this.canvas.getObjects()[this.canvas.getObjects().length - 1]
    );
  }

};

}
};