0

I am trying to help my users in the creation of a polygon, using circles in the vertices of said polygon. I know how to add the circles, but I do not see how to eliminate them at the end of the creation of the polygon with the double click, it always throws an error telling me that the object to be deleted is not defined

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);
  };

How can I solve this error?

Pedro Jose
  • 442
  • 3
  • 19

2 Answers2

1

Please replace your code

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

with

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

See fabric.js issue on GitHub

Since FabricJs v1.6.6 function forEachObject loops through all elements in the array form 0 to n. remove function is splicing that array and then it gives you undefined when item successfully removed from the array. You need to get all object on the canvas then loop from the last element to the first one.

Observer
  • 3,506
  • 1
  • 16
  • 32
1
var circleObjects = [];
canvas.forEachObject(function(o){
  if(o.id == "guiaPol"){
    circleObjects.push(o);
  }
});
canvas.remove(...circleObjects);

You can get all your circle objects and remove using canvas.remove(). Here is updated fiddle.

And remove the previous polygon using canvas.remove(currentShape); so old polygon will be removed and then add new polygon inside dblclick handler.

Durga
  • 15,263
  • 2
  • 28
  • 52