Only update the z-indices that do change after reordering nodes

Right now, when updating the z-index of a node in a container,
the indices of all its siblings are refreshed. However, if the
node changes its z-index from z1 to z2, we only need to refresh
the z-indexes of the node's parent's children in the closed
range [ min(z1,z2), max(z1,z2) ]. For groups and layers with
many children that will be more optimal in many cases.

In addition to the above change, this patch:
* forces the parameter of Node#setZIndex() to be in the valid
  range.
* adds the (now absent) unit tests for the methods of Node that
  change z-indices of the parent's children.
This commit is contained in:
VladimirTechMan
2018-07-28 18:43:06 -04:00
parent 5dcea1863f
commit 940fdfe787
3 changed files with 231 additions and 14 deletions

View File

@@ -3479,3 +3479,208 @@ suite('Node', function() {
assert.equal(rect.findAncestor(), null, 'return null if no selector');
});
});
test('moveToTop() properly changes z-indices of the node and its siblings', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect();
var rect2 = new Konva.Rect();
var rect3 = new Konva.Rect();
var rect4 = new Konva.Rect();
layer.add(rect1, rect2, rect3, rect4);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect2.moveToTop();
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect3.getZIndex(), 1);
assert.equal(rect4.getZIndex(), 2);
assert.equal(rect2.getZIndex(), 3);
rect1.moveToTop();
assert.equal(rect3.getZIndex(), 0);
assert.equal(rect4.getZIndex(), 1);
assert.equal(rect2.getZIndex(), 2);
assert.equal(rect1.getZIndex(), 3);
});
test('moveToBottom() properly changes z-indices of the node and its siblings', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect();
var rect2 = new Konva.Rect();
var rect3 = new Konva.Rect();
var rect4 = new Konva.Rect();
layer.add(rect1, rect2, rect3, rect4);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect3.moveToBottom();
assert.equal(rect3.getZIndex(), 0);
assert.equal(rect1.getZIndex(), 1);
assert.equal(rect2.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect4.moveToBottom();
assert.equal(rect4.getZIndex(), 0);
assert.equal(rect3.getZIndex(), 1);
assert.equal(rect1.getZIndex(), 2);
assert.equal(rect2.getZIndex(), 3);
});
test('moveUp() properly changes z-indices of the node and its siblings', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect();
var rect2 = new Konva.Rect();
var rect3 = new Konva.Rect();
var rect4 = new Konva.Rect();
layer.add(rect1, rect2, rect3, rect4);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect1.moveUp();
assert.equal(rect2.getZIndex(), 0);
assert.equal(rect1.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect3.moveUp();
assert.equal(rect2.getZIndex(), 0);
assert.equal(rect1.getZIndex(), 1);
assert.equal(rect4.getZIndex(), 2);
assert.equal(rect3.getZIndex(), 3);
});
test('moveDown() properly changes z-indices of the node and its siblings', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect();
var rect2 = new Konva.Rect();
var rect3 = new Konva.Rect();
var rect4 = new Konva.Rect();
layer.add(rect1, rect2, rect3, rect4);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect4.moveDown();
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect4.getZIndex(), 2);
assert.equal(rect3.getZIndex(), 3);
rect2.moveDown();
assert.equal(rect2.getZIndex(), 0);
assert.equal(rect1.getZIndex(), 1);
assert.equal(rect4.getZIndex(), 2);
assert.equal(rect3.getZIndex(), 3);
});
test('setZIndex() properly changes z-indices of the node and its siblings', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect();
var rect2 = new Konva.Rect();
var rect3 = new Konva.Rect();
var rect4 = new Konva.Rect();
layer.add(rect1, rect2, rect3, rect4);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect1.setZIndex(2);
assert.equal(rect2.getZIndex(), 0);
assert.equal(rect3.getZIndex(), 1);
assert.equal(rect1.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect2.setZIndex(3);
assert.equal(rect3.getZIndex(), 0);
assert.equal(rect1.getZIndex(), 1);
assert.equal(rect4.getZIndex(), 2);
assert.equal(rect2.getZIndex(), 3);
rect2.setZIndex(1);
assert.equal(rect3.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect1.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect4.setZIndex(0);
assert.equal(rect4.getZIndex(), 0);
assert.equal(rect3.getZIndex(), 1);
assert.equal(rect2.getZIndex(), 2);
assert.equal(rect1.getZIndex(), 3);
});
test('remove() removes the node and properly changes z-indices of its siblings', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect();
var rect2 = new Konva.Rect();
var rect3 = new Konva.Rect();
var rect4 = new Konva.Rect();
layer.add(rect1, rect2, rect3, rect4);
assert.equal(layer.getChildren().length, 4);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
assert.equal(rect4.getZIndex(), 3);
rect4.remove();
assert.equal(layer.getChildren().length, 3);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect2.getZIndex(), 1);
assert.equal(rect3.getZIndex(), 2);
rect2.remove();
assert.equal(layer.getChildren().length, 2);
assert.equal(rect1.getZIndex(), 0);
assert.equal(rect3.getZIndex(), 1);
rect1.remove();
assert.equal(layer.getChildren().length, 1);
assert.equal(rect3.getZIndex(), 0);
});