javascript 在 Fabric.js 中分层画布对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15032497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Layering canvas objects in Fabric.js
提问by Zwade
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?
有没有办法通过官方 API 在 Fabric.js 画布上分层对象?现在我发现的唯一方法是手动遍历 canvas._objects 并重新排序它们,以便它们以特定顺序绘制。有没有更好的方法来做到这一点而不(可能)破坏对象?
回答by markE
[Edit] I've corrected my info below (my bad, I was originally thinking of the KineticJs api).
[编辑] 我在下面更正了我的信息(我的不好,我最初想到的是 KineticJs api)。
FabricJS has these API methods that change the z-index of objects:
FabricJS 有这些改变对象 z-index 的 API 方法:
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.
在幕后,FabricJs 通过从 getObjects() 数组中移除对象并将其拼接回所需位置来更改 z-index。它有一个很好的优化,可以检查相交的对象。
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();
},
回答by vijay
step 1 : You can Use preserveObjectStacking: true
第 1 步:您可以使用 preserveObjectStacking: true
step 2 : then use sendtoback,sendtofront....fabricjs options like below
第 2 步:然后使用 sendtoback,sendtofront....fabricjs 选项,如下所示
回答by Herbert
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
您可以使用bringToFront
作为灵感的代码来加速这个用例: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:
compare 定义排序的位置,例如:
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.
如果您希望将较小的物体带到前面。