mirror of
https://github.com/konvajs/konva.git
synced 2025-09-18 09:50:05 +08:00
added new destroy Node method which removes and destroys a node. remove() now simply removes a node from the stage. You can re add the node at a later time with add(). getDOM() changed to getContent(). stage.remove() now correctly removes content node
This commit is contained in:
@@ -40,8 +40,6 @@
|
||||
*/
|
||||
add: function(child) {
|
||||
var go = Kinetic.Global, children = this.children;
|
||||
|
||||
child._id = Kinetic.Global.idCounter++;
|
||||
child.index = children.length;
|
||||
child.parent = this;
|
||||
children.push(child);
|
||||
|
18
src/Layer.js
18
src/Layer.js
@@ -7,7 +7,7 @@
|
||||
* @param {Object} config
|
||||
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
|
||||
* to clear the canvas before each layer draw. The default value is true.
|
||||
*
|
||||
*
|
||||
* @param {Number} [config.x]
|
||||
* @param {Number} [config.y]
|
||||
* @param {Number} [config.width]
|
||||
@@ -101,7 +101,7 @@
|
||||
}
|
||||
// otherwise get data url of the currently drawn layer
|
||||
else {
|
||||
return this.getCanvas().toDataURL(mimeType, quality);
|
||||
return this.getCanvas().toDataURL(mimeType, quality);
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -222,17 +222,11 @@
|
||||
* remove layer from stage
|
||||
*/
|
||||
remove: function() {
|
||||
var stage = this.getStage();
|
||||
var stage = this.getStage(), canvas = this.canvas, element = canvas.element;
|
||||
Kinetic.Node.prototype.remove.call(this);
|
||||
/*
|
||||
* remove canvas DOM from the document if
|
||||
* it exists
|
||||
*/
|
||||
try {
|
||||
stage.content.removeChild(this.canvas.element);
|
||||
}
|
||||
catch(e) {
|
||||
Kinetic.Global.warn('unable to remove layer scene canvas element from the document');
|
||||
|
||||
if(stage && canvas && Kinetic.Type._isInDocument(element)) {
|
||||
stage.content.removeChild(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
54
src/Node.js
54
src/Node.js
@@ -30,6 +30,8 @@
|
||||
|
||||
Kinetic.Node.prototype = {
|
||||
_nodeInit: function(config) {
|
||||
this._id = Kinetic.Global.idCounter++;
|
||||
|
||||
this.defaultNodeAttrs = {
|
||||
visible: true,
|
||||
listening: true,
|
||||
@@ -147,38 +149,44 @@
|
||||
}
|
||||
},
|
||||
/**
|
||||
* remove child from container
|
||||
* remove child from container, but don't destroy it
|
||||
* @name remove
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
*/
|
||||
remove: function() {
|
||||
var parent = this.getParent();
|
||||
if(parent && this.index !== undefined && parent.children[this.index]._id == this._id) {
|
||||
var stage = parent.getStage();
|
||||
/*
|
||||
* remove event listeners and references to the node
|
||||
* from the ids and names hashes
|
||||
*/
|
||||
if(stage) {
|
||||
stage._removeId(this.getId());
|
||||
stage._removeName(this.getName(), this._id);
|
||||
}
|
||||
|
||||
Kinetic.Global._removeTempNode(this);
|
||||
if(parent && parent.children) {
|
||||
parent.children.splice(this.index, 1);
|
||||
parent._setChildrenIndices();
|
||||
}
|
||||
delete this.parent;
|
||||
},
|
||||
/**
|
||||
* remove and destroy node
|
||||
* @name destroy
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
*/
|
||||
destroy: function() {
|
||||
// destroy children
|
||||
while(this.children && this.children.length > 0) {
|
||||
this.children[0].destroy();
|
||||
}
|
||||
|
||||
// remove from DD
|
||||
var dd = Kinetic.DD;
|
||||
if(dd && dd.node && dd.node._id === this._id) {
|
||||
delete Kinetic.DD.node;
|
||||
}
|
||||
var parent = this.getParent(), stage = this.getStage(), dd = Kinetic.DD;
|
||||
this.remove();
|
||||
|
||||
// remove children
|
||||
while(this.children && this.children.length > 0) {
|
||||
this.children[0].remove();
|
||||
}
|
||||
delete this.parent;
|
||||
// remove ids and names hashes
|
||||
if(stage) {
|
||||
stage._removeId(this.getId());
|
||||
stage._removeName(this.getName(), this._id);
|
||||
}
|
||||
|
||||
// remove from temp nodes
|
||||
Kinetic.Global._removeTempNode(this);
|
||||
|
||||
// remove from DD
|
||||
if(dd && dd.node && dd.node._id === this._id) {
|
||||
delete Kinetic.DD.node;
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
19
src/Stage.js
19
src/Stage.js
@@ -108,6 +108,17 @@
|
||||
layers[n].clear();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* remove stage
|
||||
*/
|
||||
remove: function() {
|
||||
var content = this.content;
|
||||
Kinetic.Node.prototype.remove.call(this);
|
||||
|
||||
if(content && Kinetic.Type._isInDocument(content)) {
|
||||
this.attrs.container.removeChild(content);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* reset stage to default state
|
||||
* @name reset
|
||||
@@ -154,12 +165,12 @@
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* get stage DOM node which is a div element
|
||||
* with the class name "kineticjs-content"
|
||||
* @name getDOM
|
||||
* get stage content div element which has the
|
||||
* the class name "kineticjs-content"
|
||||
* @name getContent
|
||||
* @methodOf Kinetic.Stage.prototype
|
||||
*/
|
||||
getDOM: function() {
|
||||
getContent: function() {
|
||||
return this.content;
|
||||
},
|
||||
/**
|
||||
|
@@ -35,6 +35,14 @@
|
||||
}
|
||||
return names.length > 0;
|
||||
},
|
||||
_isInDocument: function(el) {
|
||||
while( el = el.parentNode) {
|
||||
if(el == document) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/*
|
||||
* The argument can be:
|
||||
* - an integer (will be applied to both x and y)
|
||||
|
@@ -90,60 +90,6 @@ Test.Modules.CONTAINER = {
|
||||
test(node.nodeType === 'Layer', 'node type should be Layer');
|
||||
|
||||
},
|
||||
'remove shape by id or name': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var circle = new Kinetic.Circle({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 70,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
id: 'myCircle'
|
||||
});
|
||||
|
||||
var rect = new Kinetic.Rect({
|
||||
x: 300,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'purple',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myRect'
|
||||
});
|
||||
|
||||
var circleColorKey = circle.colorKey;
|
||||
var rectColorKey = rect.colorKey;
|
||||
|
||||
layer.add(circle);
|
||||
layer.add(rect);
|
||||
stage.add(layer);
|
||||
|
||||
test(stage.ids.myCircle._id === circle._id, 'circle not in ids hash');
|
||||
test(stage.names.myRect[0]._id === rect._id, 'rect not in names hash');
|
||||
test(Kinetic.Global.shapes[circleColorKey]._id === circle._id, 'circle color key should be in shapes hash');
|
||||
test(Kinetic.Global.shapes[rectColorKey]._id === rect._id, 'rect color key should be in shapes hash');
|
||||
|
||||
circle.remove();
|
||||
|
||||
test(stage.ids.myCircle === undefined, 'circle still in hash');
|
||||
test(stage.names.myRect[0]._id === rect._id, 'rect not in names hash');
|
||||
test(Kinetic.Global.shapes[circleColorKey] === undefined, 'circle color key should not be in shapes hash');
|
||||
test(Kinetic.Global.shapes[rectColorKey]._id === rect._id, 'rect color key should be in shapes hash');
|
||||
|
||||
rect.remove();
|
||||
|
||||
test(stage.ids.myCircle === undefined, 'circle still in hash');
|
||||
test(stage.names.myRect === undefined, 'rect still in hash');
|
||||
test(Kinetic.Global.shapes[circleColorKey] === undefined, 'circle color key should not be in shapes hash');
|
||||
test(Kinetic.Global.shapes[rectColorKey] === undefined, 'rect color key should not be in shapes hash');
|
||||
},
|
||||
'set x on an array of nodes': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
|
@@ -421,8 +421,8 @@ Test.Modules.NODE = {
|
||||
|
||||
rect.setSize(210);
|
||||
rect.setShadowOffset({
|
||||
x: 20
|
||||
});
|
||||
x: 20
|
||||
});
|
||||
|
||||
test(widthChanged === 1, 'width change event was not fired correctly');
|
||||
test(shadowChanged === 1, 'shadow change event not fired correctly');
|
||||
@@ -1098,23 +1098,23 @@ Test.Modules.NODE = {
|
||||
test(rect.getShadowBlur() === 12, 'shadow blur should still be 12');
|
||||
|
||||
rect.setShadowOffset({
|
||||
x: 3,
|
||||
y: 4
|
||||
x: 3,
|
||||
y: 4
|
||||
});
|
||||
test(rect.getShadowOffset().x === 3, 'shadow offset x should be 3');
|
||||
test(rect.getShadowOffset().y === 4, 'shadow offset y should be 4');
|
||||
|
||||
// test partial setting
|
||||
rect.setShadowOffset({
|
||||
x: 5
|
||||
x: 5
|
||||
});
|
||||
test(rect.getShadowOffset().x === 5, 'shadow offset x should be 5');
|
||||
test(rect.getShadowOffset().y === 4, 'shadow offset y should be 4');
|
||||
|
||||
// test partial setting
|
||||
rect.setShadowOffset({
|
||||
y: 6
|
||||
});
|
||||
y: 6
|
||||
});
|
||||
test(rect.getShadowOffset().x === 5, 'shadow offset x should be 5');
|
||||
test(rect.getShadowOffset().y === 6, 'shadow offset y should be 6');
|
||||
|
||||
@@ -2197,13 +2197,42 @@ Test.Modules.NODE = {
|
||||
circle.remove();
|
||||
|
||||
test(layer.children.length === 0, 'layer should have 0 children');
|
||||
//test(layer.getChild('myCircle') === undefined, 'shape should be null');
|
||||
|
||||
layer.draw();
|
||||
|
||||
test(circle.getParent() === undefined, 'circle parent should be undefined');
|
||||
},
|
||||
'remove shape without adding its parent to stage': function(containerId) {
|
||||
'destroy shape': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var circle = new Kinetic.Circle({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 70,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myCircle'
|
||||
});
|
||||
|
||||
layer.add(circle);
|
||||
stage.add(layer);
|
||||
|
||||
test(layer.children.length === 1, 'layer should have 1 children');
|
||||
|
||||
circle.destroy();
|
||||
|
||||
test(layer.children.length === 0, 'layer should have 0 children');
|
||||
|
||||
layer.draw();
|
||||
|
||||
test(circle.getParent() === undefined, 'circle parent should be undefined');
|
||||
},
|
||||
'destroy shape without adding its parent to stage': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
@@ -2232,12 +2261,12 @@ Test.Modules.NODE = {
|
||||
|
||||
test(go.tempNodes[circle._id].attrs.id === 'myCircle', 'circle should be in temp nodes');
|
||||
|
||||
circle.remove();
|
||||
circle.destroy();
|
||||
|
||||
test(go.tempNodes[circle._id] === undefined, 'circle shouldn\'t be in the temp nodes hash');
|
||||
|
||||
},
|
||||
'remove layer with shape': function(containerId) {
|
||||
'destroy layer with shape': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
@@ -2263,7 +2292,7 @@ Test.Modules.NODE = {
|
||||
test(stage.get('.myLayer')[0] !== undefined, 'layer should exist');
|
||||
test(stage.get('.myCircle')[0] !== undefined, 'circle should exist');
|
||||
|
||||
layer.remove();
|
||||
layer.destroy();
|
||||
|
||||
test(stage.children.length === 0, 'stage should have 0 children');
|
||||
test(stage.get('.myLayer')[0] === undefined, 'layer should not exist');
|
||||
@@ -2271,7 +2300,75 @@ Test.Modules.NODE = {
|
||||
|
||||
stage.draw();
|
||||
},
|
||||
'remove layer with no shapes': function(containerId) {
|
||||
'destroy stage with layer and shape': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer({
|
||||
name: 'myLayer'
|
||||
});
|
||||
var circle = new Kinetic.Circle({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 70,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myCircle'
|
||||
});
|
||||
|
||||
layer.add(circle);
|
||||
stage.add(layer);
|
||||
|
||||
stage.destroy();
|
||||
|
||||
test(layer.getParent() === undefined, 'layer parent should be undefined');
|
||||
test(circle.getParent() === undefined, 'circle parent should be undefined');
|
||||
test(stage.children.length === 0, 'stage children length should be 0');
|
||||
test(layer.children.length === 0, 'layer children length should be 0');
|
||||
},
|
||||
'destroy group with shape': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer({
|
||||
name: 'myLayer'
|
||||
});
|
||||
var group = new Kinetic.Group({
|
||||
name: 'myGroup'
|
||||
});
|
||||
|
||||
var circle = new Kinetic.Circle({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 70,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myCircle'
|
||||
});
|
||||
|
||||
group.add(circle);
|
||||
layer.add(group);
|
||||
stage.add(layer);
|
||||
|
||||
test(layer.getChildren().length === 1, 'layer should have 1 children');
|
||||
test(stage.get('.myGroup')[0] !== undefined, 'group should exist');
|
||||
test(stage.get('.myCircle')[0] !== undefined, 'circle should exist');
|
||||
|
||||
group.destroy();
|
||||
|
||||
test(layer.children.length === 0, 'layer should have 0 children');
|
||||
test(stage.get('.myGroup')[0] === undefined, 'group should not exist');
|
||||
test(stage.get('.myCircle')[0] === undefined, 'circle should not exist');
|
||||
|
||||
stage.draw();
|
||||
},
|
||||
'destroy layer with no shapes': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
@@ -2279,11 +2376,11 @@ Test.Modules.NODE = {
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
stage.add(layer);
|
||||
layer.remove();
|
||||
layer.destroy();
|
||||
|
||||
test(stage.children.length === 0, 'stage should have 0 children');
|
||||
},
|
||||
'remove shape multiple times': function(containerId) {
|
||||
'destroy shape multiple times': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
@@ -2312,8 +2409,8 @@ Test.Modules.NODE = {
|
||||
|
||||
test(layer.getChildren().length === 2, 'layer should have two children');
|
||||
|
||||
shape1.remove();
|
||||
shape1.remove();
|
||||
shape1.destroy();
|
||||
shape1.destroy();
|
||||
|
||||
test(layer.getChildren().length === 1, 'layer should have two children');
|
||||
|
||||
@@ -2359,5 +2456,59 @@ Test.Modules.NODE = {
|
||||
|
||||
stage.draw();
|
||||
|
||||
},
|
||||
'destroy shape by id or name': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var circle = new Kinetic.Circle({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 70,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
id: 'myCircle'
|
||||
});
|
||||
|
||||
var rect = new Kinetic.Rect({
|
||||
x: 300,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'purple',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myRect'
|
||||
});
|
||||
|
||||
var circleColorKey = circle.colorKey;
|
||||
var rectColorKey = rect.colorKey;
|
||||
|
||||
layer.add(circle);
|
||||
layer.add(rect);
|
||||
stage.add(layer);
|
||||
|
||||
test(stage.ids.myCircle._id === circle._id, 'circle not in ids hash');
|
||||
test(stage.names.myRect[0]._id === rect._id, 'rect not in names hash');
|
||||
test(Kinetic.Global.shapes[circleColorKey]._id === circle._id, 'circle color key should be in shapes hash');
|
||||
test(Kinetic.Global.shapes[rectColorKey]._id === rect._id, 'rect color key should be in shapes hash');
|
||||
|
||||
circle.destroy();
|
||||
|
||||
test(stage.ids.myCircle === undefined, 'circle still in hash');
|
||||
test(stage.names.myRect[0]._id === rect._id, 'rect not in names hash');
|
||||
test(Kinetic.Global.shapes[circleColorKey] === undefined, 'circle color key should not be in shapes hash');
|
||||
test(Kinetic.Global.shapes[rectColorKey]._id === rect._id, 'rect color key should be in shapes hash');
|
||||
|
||||
rect.destroy();
|
||||
|
||||
test(stage.ids.myCircle === undefined, 'circle still in hash');
|
||||
test(stage.names.myRect === undefined, 'rect still in hash');
|
||||
test(Kinetic.Global.shapes[circleColorKey] === undefined, 'circle color key should not be in shapes hash');
|
||||
test(Kinetic.Global.shapes[rectColorKey] === undefined, 'rect color key should not be in shapes hash');
|
||||
}
|
||||
};
|
||||
|
@@ -62,8 +62,8 @@ Test.Modules.STAGE = {
|
||||
|
||||
test(stage.getSize().width === 333, 'stage width should be 333');
|
||||
test(stage.getSize().height === 155, 'stage height should be 155');
|
||||
test(stage.getDOM().style.width === '333px', 'content width should be 333');
|
||||
test(stage.getDOM().style.height === '155px', 'content height should be 155px');
|
||||
test(stage.getContent().style.width === '333px', 'content width should be 333');
|
||||
test(stage.getContent().style.height === '155px', 'content height should be 155px');
|
||||
test(layer.getCanvas().element.width === 333, 'layer canvas element width should be 333');
|
||||
test(layer.getCanvas().element.height === 155, 'layer canvas element width should be 155');
|
||||
},
|
||||
@@ -105,7 +105,7 @@ Test.Modules.STAGE = {
|
||||
height: 200
|
||||
});
|
||||
|
||||
test(stage.getDOM().className === 'kineticjs-content', 'stage DOM class name is wrong');
|
||||
test(stage.getContent().className === 'kineticjs-content', 'stage DOM class name is wrong');
|
||||
},
|
||||
'test getIntersections': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
|
Reference in New Issue
Block a user