zOrder inheritance

This commit is contained in:
SkyeBlep 2023-01-12 19:45:57 -08:00
parent c02e4413bf
commit f53b589c8c
3 changed files with 98 additions and 5 deletions

View File

@ -122,16 +122,19 @@ export class AbsoluteRenderOrderGroup extends Group {
});
} else {
// Is a leaf / don't descend farther -- this can be added to children map
let zOrder:number = node.zOrder();
// Determine zOrder
let zOrder:number = node.evaluateZOrderRecursively();
// Add zOrder if needed
if (!orderedChildren.has(zOrder))
{
orderedChildren.set(zOrder, new Array<Node>());
}
// Add to the correct bucket of zOrders
orderedChildren.get(zOrder).push(node); // I'd much prefer the [] syntax for clarity, but seems TS/JS doesn't seem to support it, ugh.
}
}
}
//AbsoluteRenderOrderGroup.prototype.nodeType = 'AbsoluteRenderOrderGroup';

View File

@ -2574,6 +2574,21 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
return Util.haveIntersection(screenRect, this.getClientRect());
}
/**
* Utility function to evaluate the zOrder of a node. This differs from just checking the zOrder() as this function
* will check parents to inherit a zOrder value if this node does not have one set. Otherwise, if no zOrders are set
* recursively, this will return 0 (this function will not return undefined).
* @returns {number}
*/
evaluateZOrderRecursively():number {
if (this.zOrder() != undefined)
return this.zOrder();
if (this.parent == null)
return 0;
else
return this.parent.evaluateZOrderRecursively();
}
preventDefault: GetSet<boolean, this>;
// from filters
@ -2619,7 +2634,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
rotation: GetSet<number, this>;
zIndex: GetSet<number, this>;
zOrder: GetSet<number, this>;
zOrder: GetSet<number | undefined, this>;
scale: GetSet<Vector2d | undefined, this>;
scaleX: GetSet<number, this>;
@ -3285,9 +3300,14 @@ addGetterSetter(Node, 'draggable', false, getBooleanValidator());
* AbsoluteRenderOrderContainer to recursively render child objects in an absolute z-order. This field will otherwise
* be ignored. Alternatively, you can use the z-index features to move an object within a particular group, relative to
* the other nodes in the group.
*
* If not set (/set to undefined), the z-order of the parent (recursively) will be inherited. If no z-orders are set
* through parents, the default z-order is 0.
*
* Higher z-orders will be rendered on top of lower z-orders.
* @name Konva.Node#zOrder
* @method
* @param {Number} zOrder
* @param {Number | undefined} zOrder
* @returns {Object}
* @example
* // get z-order
@ -3295,9 +3315,12 @@ addGetterSetter(Node, 'draggable', false, getBooleanValidator());
*
* // set z-order
* node.zOrder(5);
*
* // unset z-order
* node.zOrder(undefined);
*/
addGetterSetter(Node, 'zOrder', 0, getNumberValidator());
addGetterSetter(Node, 'zOrder', undefined, getNumberValidator());
Factory.backCompat(Node, {
rotateDeg: 'rotate',

View File

@ -138,4 +138,71 @@ describe('AbsoluteRenderOrderGroup', function () {
assert.equal(red3, 119, "Did not find correct amount of red in medium dark red pixel for test 1, ordering is possibly incorrect. Red amount found was: " + red3);
assert.equal(black, 0, "Did not find correct amount of red in black pixel for test 1, ordering is possibly incorrect. Red amount found was: " + black);
});
it('check render order inherits null correctly', function () {
var stage = addStage();
const layer = new Konva.Layer();
stage.add(layer);
// This will test that AbsoluteRenderOrderGroup renders based on z-order, not z-index
const absoluteRenderOrderGroupTest = new Konva.AbsoluteRenderOrderGroup({
x: 0,
y: 0
});
layer.add(absoluteRenderOrderGroupTest);
const redRect = new Konva.Rect({
zOrder: 5,
width: 100,
height: 100,
fill: 'red'
});
absoluteRenderOrderGroupTest.add(redRect);
const groupInheritanceTest = new Konva.Group();
absoluteRenderOrderGroupTest.add(groupInheritanceTest);
const groupInheritanceTest2 = new Konva.Group();
groupInheritanceTest.add(groupInheritanceTest2);
const blueRect = new Konva.Rect({
x: 0,
y: 0,
width: 100,
height: 100,
fill: 'blue'
});
groupInheritanceTest2.add(blueRect);
layer.draw();
// Check default z-order.
// When looking at pixel color rendered, should be Red as the red rect has higher z-order priority than the
// blue rect, which at this point should be defaulting to 0
let context = layer.canvas.getContext();
let imageData = context.getImageData(55, 55, 1, 1); // this is an intersecting pixel location between red & blue
let red = imageData.data[0];
assert.equal(red, 255, "Default test: Did not find red pixel, unexpected defaulting. Red amount found was: " + red);
// Test setting immediate parent higher and check that blue rect inherits it
groupInheritanceTest2.zOrder(10);
layer.draw();
imageData = context.getImageData(55, 55, 1, 1); // this is an intersecting pixel location between red & blue
let blue = imageData.data[2];
assert.equal(blue, 255, "Immediate parent test: did not find blue pixel, unexpected defaulting. Red amount found was: " + red);
// Test setting parent of parent and check that blue rect inherits it
groupInheritanceTest.zOrder(10);
groupInheritanceTest2.zOrder(undefined);
layer.draw();
imageData = context.getImageData(55, 55, 1, 1); // this is an intersecting pixel location between red & blue
blue = imageData.data[2];
assert.equal(blue, 255, "Immediate parent test: did not find blue pixel, unexpected defaulting. Red amount found was: " + red);
});
});