38

I have a simple fabric js based application where I will let users add shapes connect them and animate them.

Following is my JS

var canvas; 
window.newAnimation = function(){
   canvas = new fabric.Canvas('canvas');
}

window.addRect = function(){
    var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 20,
  height: 20,
});
    canvas.add(rect);

}

window.addCircle = function(){
    var circle = new fabric.Circle({
  radius: 20, fill: 'green', left: 100, top: 100
});
    canvas.add(circle);
}

This is my Fiddle. You can click on new animation and then add objects as of now.

I want the user to select some object and then also be able to delete it I am not sure how. I found this Delete multiple Objects at once on a fabric.js canvas in html5 But i was not able to implement it successfully. I basically want users to be able to select an object and delete it.

Community
  • 1
  • 1

8 Answers8

94

Since new version of fabric.js was released - you should use:

canvas.remove(canvas.getActiveObject());
Alex Andre
  • 1,006
  • 1
  • 7
  • 7
  • 3
    This works only for one single object . What about multiple selected objects? – rostamiani Apr 15 '20 at 10:37
  • 1
    @rostamiani , just use `canvas.getActiveObjects();` and loop through them, calling canvas.remove() in the loop. Something like: `while (canvas.getActiveObjects.length > 0) { canvas.remove(canvas.getActiveObject[0]); }` – Shmack Jun 15 '20 at 22:00
  • So when I call the canvas.remove(object) function, after the objects are deleted, it won't let me add new itext to the canvas. – Shmack Jun 15 '20 at 22:04
  • It seems to work with `canvas.remove(...canvas.getActiveObjects());` or `canvas.getActiveObjects().forEach((obj) => {canvas.remove(obj);});`. [JSDoc: Class: Canvas](http://fabricjs.com/docs/fabric.Canvas.html#remove) – eternal novice Aug 21 '23 at 03:13
40

Edit: This is for older versions now.

You can use the remove() method, eg.

window.deleteObject = function() {
        canvas.getActiveObject().remove();
}

jsfiddle

Ian
  • 13,724
  • 4
  • 52
  • 75
  • 12
    This answer is outdated and doesn't work for newer versions of Fabric.js check the answer of @AlexAndre here: https://stackoverflow.com/a/46179274/1697459 – Wilt Apr 10 '19 at 13:55
23

Delete all selected objects:

canvas.getActiveObjects().forEach((obj) => {
  canvas.remove(obj)
});
canvas.discardActiveObject().renderAll()
cby016
  • 1,121
  • 1
  • 10
  • 13
7

I am using Fabric JS 2.3.6.

I wanted to allow the user to select one or more objects on the canvas and delete them by clicking the delete button.

Removed methods from old versions

The following methods are no longer available since the introduction of ActiveSelection:

setActiveGroup(group);
getActiveGroup();
deactivateAll();
discardActiveGroup();
deactivateAllWithDispatch();

Here is my code that works great for me and hopefully you as well.

$('html').keyup(function(e){
        if(e.keyCode == 46) {
            deleteSelectedObjectsFromCanvas();
        }
});    

function deleteSelectedObjectsFromCanvas(){
    var selection = canvas.getActiveObject();
    if (selection.type === 'activeSelection') {
        selection.forEachObject(function(element) {
            console.log(element);
            canvas.remove(element);
        });
    }
    else{
        canvas.remove(selection);
    }
    canvas.discardActiveObject();
    canvas.requestRenderAll();
}
Jim Dandy BOA
  • 533
  • 7
  • 13
2

It's pretty simple actually.

Just use Fabric's event handling to manage the object selection, and then fire the delete function for whatever object is selected.

I'm using the canvas selection events to cover all the objects of the canvas. The idea is to add a delete button, keeping it hidden unless needed, and then handling its display on canvas selection events.

Deletion is made easy with the help of remove property of the Fabric library, which obviously triggers when the delete button is clicked.

Here is some sample code to demo what I said above.

// Grab the required elements
var canvas = new fabric.Canvas('c'),
    delBtn = document.getElementById('delete')

// Hide the delete button until needed
delBtn.style.display = 'none'

// Initialize a rectangle object
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 100,
  height: 50
})

// Initialize a circle object
var circle = new fabric.Circle({
  left: 250,
  top: 100,
  radius: 20,
  fill: 'purple'
})

// Add objects to the canvas
canvas.add(rect)
canvas.add(circle)

// When a selection is being made
canvas.on({
  'selection:created': () => {
    delBtn.style.display = 'inline-block'
  }
})

// When a selection is cleared
canvas.on({
  'selection:cleared': () => {
    delBtn.style.display = 'none'
  }
})

// Rmove the active object on clicking the delete button
delBtn.addEventListener('click', e => {
  canvas.remove(canvas.getActiveObject())
})
body {
  background-color: #eee;
  color: #333;
}

#c {
  background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>

<h4>Select an object</h4>

<canvas id="c" width="600" height="200"></canvas>

<input type="button" id="delete" value="Delete selection">

Easy, wasn't it? Cheers!

Rahul
  • 822
  • 6
  • 12
2

On further improving @Rahul answer, we can also support deletion of selected object using key events like 'Delete', 'Backscape'.

// Grab the required elements
var canvas = new fabric.Canvas('c'),
    delBtn = document.getElementById('delete'),
wrapper= document.getElementById('canvasWrapper')

// Hide the delete button until needed
delBtn.style.display = 'none'

// Initialize a rectangle object
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 100,
  height: 50
})

// Initialize a circle object
var circle = new fabric.Circle({
  left: 250,
  top: 100,
  radius: 20,
  fill: 'purple'
})

// Add objects to the canvas
canvas.add(rect)
canvas.add(circle)

// When a selection is being made
canvas.on({
  'selection:created': () => {
    delBtn.style.display = 'inline-block'
  }
})

// When a selection is cleared
canvas.on({
  'selection:cleared': () => {
    delBtn.style.display = 'none'
  }
})

// Rmove the active object on clicking the delete button
delBtn.addEventListener('click', e => {
  canvas.remove(canvas.getActiveObject())
})

//Remove using keyboard events
wrapper.addEventListener('keyup', e => {
   if (
      e.keyCode == 46 ||
      e.key == 'Delete' ||
      e.code == 'Delete' ||
      e.key == 'Backspace'
    ) {
      if (canvas.getActiveObject()) {
        if (canvas.getActiveObject().isEditing) {
          return
        }
        canvas.remove(canvas.getActiveObject())
      }
    }
})
body {
  background-color: #eee;
  color: #333;
}

#c {
  background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>

<h4>Select an object</h4>
<div tabIndex="1000"id="canvasWrapper" @keyup="checkDelete($event)" >
<canvas id="c" width="600" height="200"></canvas>
</div>
<input type="button" id="delete" value="Delete selection">
Yogesh Yadav
  • 723
  • 6
  • 21
  • This doesn't seem to handle selection of multiple objects. I think looping is needed as @venkystroke mentioned. – Kalnode May 17 '23 at 14:04
1

Delete object in Fabricjs. This works completely fine.

this.canvas.getActiveObjects().forEach((o) => {
    this.canvas.remove(o);
})
this.canvas.discardActiveObject() // Removes selection box
Kalnode
  • 9,386
  • 3
  • 34
  • 62
0

you can delete active object by using backspace key

$(document).keydown(function(event){
    if (event.which == 8) {
        if (canvas.getActiveObject()) {
            canvas.getActiveObject().remove();
        }
    }
});
Soubhagya Kumar Barik
  • 1,979
  • 20
  • 26
  • outdated? this throws an error... it says there is no function called .remove(). – Shmack Jun 15 '20 at 21:56
  • can't you see when the answer has been posted it's been 1 year.if you are using latest version of fabric js then what's my fault.you should follow the official documentation of latest fabric js please follow below link http://fabricjs.com/v2-breaking-changes-2 – Soubhagya Kumar Barik Jun 16 '20 at 03:48
  • Ah, yes. I can see the post date... just a thought tho... why does Larry Roberston's .remove() work, which is older than your code, or even Alex Andre's, which again is even older than your code. Nonetheless, thanks for the link to the docs, which is pretty useful. – Shmack Jun 16 '20 at 18:09
  • 2019; why jQuery? =) – Kalnode Dec 15 '20 at 15:59