javascript - Capas de objetos de lienzo en Fabric.js
sorting fabricjs (3)
¿Hay alguna forma de colocar objetos en un lienzo Fabric.js a través de la API oficial? En este momento, la única forma que encontré para hacerlo es recorrer manualmente el lienzo.objetos y reordenarlos para que se dibujen en un orden específico. ¿Hay una mejor manera de hacerlo que no rompa (potencialmente) el objeto?
Paso 1: puedes usar preserveObjectStacking: true
paso 2: luego use sendtoback, sendtofront .... fabricjs opciones como abajo
Respondido por aqui
Si desea establecer un orden específico para todos los objetos, en lugar de mover un objeto hacia adelante / hacia atrás, las llamadas iterativas para traer / enviar al frente / atrás son lentas.
Puede usar el código de bringToFront
como inspiración para acelerar este uso: https://github.com/kangax/fabric.js/blob/586e61dd282b22c1d50e15c0361875707e526fd8/src/static_canvas.class.js#L1468
Y haz esto:
fabric.Canvas.prototype.orderObjects = function(compare) {
this._objects.sort(compare);
this.renderAll();
}
Donde comparar define la clasificación, como:
function compare(x,y) {
return x.getWidth() * x.getHeight() < y.getWidth() * y.getHeight();
}
some_canvas.orderObjects(compare)
Si deseas traer objetos más pequeños al frente.
[Editar] He corregido mi información a continuación (mal, originalmente estaba pensando en la API de Kinetic).
FabricJS tiene estos métodos API que cambian el índice z de objetos:
canvas.sendBackwards(myObject)
canvas.sendToBack(myObject)
canvas.bringForward(myObject)
canvas.bringToFront(myObject)
Debajo de las cubiertas, FabricJs cambia el índice z eliminando el objeto de la matriz getObjects () y empalmándolo de nuevo en la posición deseada. Tiene una buena optimización que comprueba la intersección de objetos.
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();
},