Is there a way to layer objects on a Fabric.js canvas via the official API? Right now the only way I have found to do it is to manually iterate through the canvas._objects and reorder them so that they get drawn in a specific order. Is there a better way to do this that doesn't (potentially) break the object?
4 Answers
[Edit] I've corrected my info below (my bad, I was originally thinking of the KineticJs api).
FabricJS has these API methods that change the z-index of objects:
canvas.sendBackwards(myObject)
canvas.sendToBack(myObject)
canvas.bringForward(myObject)
canvas.bringToFront(myObject)
Under the covers, FabricJs changes the z-index by removing the object from the getObjects() array and splicing it back in the desired position. It has a nice optimization that checks for intersecting objects.
bringForward: function (object) {
var objects = this.getObjects(),
idx = objects.indexOf(object),
nextIntersectingIdx = idx;
// if object is not on top of stack (last item in an array)
if (idx !== objects.length-1) {
// traverse up the stack looking for the nearest intersecting object
for (var i = idx + 1, l = this._objects.length; i < l; ++i) {
var isIntersecting = object.intersectsWithObject(objects[i]) ||
object.isContainedWithinObject(this._objects[i]) ||
this._objects[i].isContainedWithinObject(object);
if (isIntersecting) {
nextIntersectingIdx = i;
break;
}
}
removeFromArray(objects, object);
objects.splice(nextIntersectingIdx, 0, object);
}
this.renderAll();
},

- 102,905
- 11
- 164
- 176
-
Thank you! This saves me a lot of trouble. – Zwade Feb 25 '13 at 22:16
-
does fabricjs have a built-in object stack index system ... then I could do something like `var idx = some_object.get_zIndex()` – dsdsdsdsd Apr 27 '13 at 13:04
-
11You can get the z-index: canvas.getObjects().indexOf(some_object). Four commands are available to change the stacking order: some_object.sendBackwards(), some_object.sendToBack(), some_object.bringForward(), and some_object.bringToFront(). – markE Apr 27 '13 at 14:00
-
ahh geez, of course ... if it was a snake it would have bit me ... thanks. – dsdsdsdsd Apr 27 '13 at 21:06
-
@markE ???=canvas.getObjects().indexOf(Obj])+1; , how to change z-ndex position using these method? – anam Sep 13 '13 at 05:51
-
2@simmisimmi. You use these canvas methods to affect the z-index of objects in relation to other objects: bringToFront(object) bringFoward(object) sendToBack(object) sendBackwards(object). Both sendBackwards and bringForward accept a second object that you want to index relative to. – markE Sep 13 '13 at 18:23
-
Using markE suggestion worked for me. I had a line that needed to be behind everything except one object. This worked: canvas.sendToBack(aLine); canvas.bringForward(aLine, bg_group); – adg Sep 14 '16 at 00:14
step 1 : You can Use preserveObjectStacking: true
step 2 : then use sendtoback,sendtofront....fabricjs options like below
This is how I did it. I added a zIndex property to every fabric object and then called a sort function after they were added to the canvas:
const CIRCLE_INDEX = 1
let object = new fabric.Circle({
left: 10,
top: 10,
radius: 5
...other properties
zIndex: CIRCLE_INDEX
});
And then call a function like this after you added your objects
const sortObjects = () => {
canvas._objects.sort((a, b) => (a.zIndex > b.zIndex) ? 1 : -1);
canvas.renderAll();
}

- 307
- 2
- 8
If you want to set a specific ordering for all objects, instead of moving one object forward/backward, iterative calls to bring/send to front/back are slow.
You can use the code of bringToFront
as inspiration to speed this use case up: https://github.com/kangax/fabric.js/blob/586e61dd282b22c1d50e15c0361875707e526fd8/src/static_canvas.class.js#L1468
And do this:
fabric.Canvas.prototype.orderObjects = function(compare) {
this._objects.sort(compare);
this.renderAll();
}
Where compare defines the sorting, like:
function compare(x,y) {
return x.getWidth() * x.getHeight() < y.getWidth() * y.getHeight();
}
some_canvas.orderObjects(compare)
If you wish to bring smaller objects to the front.

- 5,279
- 5
- 44
- 69