mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
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:
parent
5dcea1863f
commit
940fdfe787
@ -389,10 +389,11 @@
|
||||
|
||||
return arr;
|
||||
},
|
||||
_setChildrenIndices: function() {
|
||||
this.children.each(function(child, n) {
|
||||
child.index = n;
|
||||
});
|
||||
_setChildrenIndicesBetween: function(idx, maxIdx) {
|
||||
var children = this.children;
|
||||
for (; idx <= maxIdx; ++idx) {
|
||||
children[idx].index = idx;
|
||||
}
|
||||
},
|
||||
drawScene: function(can, top, caching) {
|
||||
var layer = this.getLayer(),
|
||||
@ -681,5 +682,6 @@
|
||||
* });
|
||||
*/
|
||||
|
||||
|
||||
Konva.Collection.mapMethods(Konva.Container);
|
||||
})();
|
||||
|
30
src/Node.js
30
src/Node.js
@ -609,7 +609,7 @@
|
||||
|
||||
if (parent && parent.children) {
|
||||
parent.children.splice(this.index, 1);
|
||||
parent._setChildrenIndices();
|
||||
parent._setChildrenIndicesBetween(this.index, parent.children.length - 1);
|
||||
delete this.parent;
|
||||
}
|
||||
|
||||
@ -1089,10 +1089,11 @@
|
||||
Konva.Util.warn('Node has no parent. moveToTop function is ignored.');
|
||||
return false;
|
||||
}
|
||||
var children = this.parent.children;
|
||||
var index = this.index;
|
||||
this.parent.children.splice(index, 1);
|
||||
this.parent.children.push(this);
|
||||
this.parent._setChildrenIndices();
|
||||
children.splice(index, 1);
|
||||
children.push(this);
|
||||
this.parent._setChildrenIndicesBetween(index, children.length - 1);
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
@ -1111,7 +1112,7 @@
|
||||
if (index < len - 1) {
|
||||
this.parent.children.splice(index, 1);
|
||||
this.parent.children.splice(index + 1, 0, this);
|
||||
this.parent._setChildrenIndices();
|
||||
this.parent._setChildrenIndicesBetween(index, index + 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1131,7 +1132,7 @@
|
||||
if (index > 0) {
|
||||
this.parent.children.splice(index, 1);
|
||||
this.parent.children.splice(index - 1, 0, this);
|
||||
this.parent._setChildrenIndices();
|
||||
this.parent._setChildrenIndicesBetween(index - 1, index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1153,7 +1154,7 @@
|
||||
if (index > 0) {
|
||||
this.parent.children.splice(index, 1);
|
||||
this.parent.children.unshift(this);
|
||||
this.parent._setChildrenIndices();
|
||||
this.parent._setChildrenIndicesBetween(0, index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1170,10 +1171,19 @@
|
||||
Konva.Util.warn('Node has no parent. zIndex parameter is ignored.');
|
||||
return false;
|
||||
}
|
||||
var children = this.parent.children;
|
||||
zIndex = Math.max(0, Math.min(zIndex, children.length - 1));
|
||||
|
||||
var index = this.index;
|
||||
this.parent.children.splice(index, 1);
|
||||
this.parent.children.splice(zIndex, 0, this);
|
||||
this.parent._setChildrenIndices();
|
||||
if (zIndex !== index) {
|
||||
children.splice(index, 1);
|
||||
children.splice(zIndex, 0, this);
|
||||
if (index < zIndex) {
|
||||
this.parent._setChildrenIndicesBetween(index, zIndex);
|
||||
} else {
|
||||
this.parent._setChildrenIndicesBetween(zIndex, index);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
|
@ -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);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user