引导点多边形创建

guide points polygon creation

我试图帮助我的用户创建一个多边形,在所述多边形的顶点使用圆圈。 我知道如何添加圆圈,但我不知道如何在创建多边形的最后通过双击消除它们,它总是抛出一个错误告诉我要删除的对象未定义

Fiddle

var canvas = window._canvas = new fabric.Canvas('c');


drawPoligon(6);

 function drawPoligon (id){
  //I define the variables that I need
      var mode = "add", currentShape;
  var puntos;
  var obj;
      newColor = "#FF0000";

  //I prepare the reading of the event mouse: down, 
  //for when I click, if I am adding the polygon for 
  //the first time, that is created and added to the canvas
  canvas.on("mouse:down", function (event) {
    var pos = canvas.getPointer(event.e);
        if (mode === "add") {
      // console.log(this.getRandomColor);
            currentShape = new fabric.Polygon([{
                            x: pos.x,
                            y: pos.y
                }, {
                  x: pos.x + 1, 
                  y: pos.y + 1
                        }], {
                  fill: "#FF0000",
                            selectable: false,
                      id: id,
                  objectCaching:false,
                  olvidar: "olvidar"
                });
      canvas.add(currentShape);
      var circ = new fabric.Circle({
        id: "guiaPol",
        evented: false,
        top: pos.y-5,
        left: pos.x-5,
        radius: 10,
        fill: "red",
        perPixelTargetFind: true
      });
      canvas.add(circ);
      canvas.renderAll();
            newColor= currentShape.get('fill');
      mode = "edit";
          } else if (mode === "edit" && currentShape && currentShape.type === "polygon") {
      //In the case that I have added the polygon, what I have to do is add the points, as I click
      var points = currentShape.get("points");
      points.push({
        x: pos.x ,
        y: pos.y
      });
      puntos = points;
      currentShape.set({
        points: points
      });
      var circ = new fabric.Circle({
        id: "guiaPol",
        evented: false,
        top: pos.y-5,
        left: pos.x-5,
        radius: 10,
        fill: "red",
        perPixelTargetFind: true
      });
      canvas.add(circ)
              canvas.renderAll();
          }
  });
  //I set up a mouse: move listener that modifies the poligo in real time, 
  //to see where the next point will go, following the position of the mouse
  canvas.on("mouse:move", function (event) {
    //console.log("Hola");
    var pos = canvas.getPointer(event.e);
    //console.log("CurrShape", currentShape);
    if (mode == "edit" && currentShape) {
      var points = currentShape.get("points");

      points[points.length - 1].x = pos.x;
      points[points.length - 1].y = pos.y;
      currentShape.set({
        points: points,
        dirty: true
      });
      currentShape.setCoords();
      canvas.renderAll();
    }
  });

  // <%'
  // 'Descripción: función que nos ayuda a parar la creación del poligono cuando hacemos doble click 
  // 'Inputs: 
  // 'Outputs:
  // 'DFDNSCADA0676
  // %>

  //This function is executed at the end of the creation of the polygon, which is double clicking on the screen
  function pararCreacion(){
    if (mode === 'edit' || mode === 'add') {
      mode = 'normal';
      var obj = currentShape.toObject();
      currentShape = new fabric.Polygon(puntos,{obj});
      currentShape.set({
        id:id,
        originY: "top",
        originX: "left",
        fill: newColor,
        type: 'polygon',
        nombre: 'Objeto_' + id
      });
      canvas._objects.pop();
      canvas.add(currentShape);
      currentShape.set({
        selectable: true,
      });
      //$("#Elemento_186").removeAttr("style");
      canvas.renderAll();
      canvas.forEachObject(function(o){
        if(o.id == "guiaPol"){
        canvas.remove(o);
        }
      });
      // <%' Cuando ya termino con el poligono y refresco el canvas entonces es cuando añado el cambio a mi matriz deshacer %>
      canvas.off("mouse:move");
    }   
    currentShape = null;
        fabric.util.removeListener(fabric.document,'dblclick', pararCreacion);    //de esta forma cuando termina la creación me sale de la función y me anula el evento
 }
     fabric.util.addListener(fabric.document, 'dblclick', pararCreacion);
  };

如何解决这个错误?

请替换您的代码

canvas.forEachObject(function(o){
    if(o.id == "guiaPol"){
        canvas.remove(o);
    }
});

var objects = canvas.getObjects(),
    i = objects.length;
while (i--) {
    if(objects[i].id == "guiaPol"){
       canvas.remove(objects[i]);
    }
}

请参阅 GitHub

上的 fabric.js 问题

因为 FabricJs v1.6.6 函数 forEachObject 循环遍历数组中从 0 到 n 的所有元素。 remove 函数正在拼接该数组,然后当项目成功从数组中删除时,它会为您提供 undefined 。您需要获取 canvas 上的所有对象,然后从最后一个元素循环到第一个元素。

var circleObjects = [];
canvas.forEachObject(function(o){
  if(o.id == "guiaPol"){
    circleObjects.push(o);
  }
});
canvas.remove(...circleObjects);

您可以获取所有圈子对象并使用 canvas.remove() 删除。 这里更新了 fiddle.

并使用 canvas.remove(currentShape); 删除之前的多边形,这样旧的多边形将被删除,然后在 dblclick 处理程序中添加新的多边形。