isVisible() method now takes into account ancestor visibility. This fixes several bugs related to odd event detection behavior with clusters of visible and invisible nodes

This commit is contained in:
Eric Rowell 2012-06-02 19:12:06 -07:00
parent 9f243d4a2e
commit 91eb4ea371
6 changed files with 125 additions and 17 deletions

13
dist/kinetic-core.js vendored
View File

@ -596,9 +596,14 @@ Kinetic.Node.prototype = {
}
},
/**
* determine if shape is visible or not
* determine if shape is visible or not. Shape is visible only
* if it's visible and all of its ancestors are visible. If one ancestor
* is invisible, this means that the shape is also invisible
*/
isVisible: function() {
if(this.getParent() && !this.getParent().isVisible()) {
return false;
}
return this.attrs.visible;
},
/**
@ -1875,7 +1880,7 @@ Kinetic.Stage.prototype = {
this.targetFound = true;
}
if(shape.attrs.visible && pos !== undefined && shape.intersects(pos)) {
if(shape.isVisible() && pos !== undefined && shape.intersects(pos)) {
// handle onmousedown
if(!isDragging && this.mouseDown) {
this.mouseDown = false;
@ -2067,7 +2072,7 @@ else if(!isDragging && this.touchMove) {
var shapeDetected = false;
for(var n = this.children.length - 1; n >= 0; n--) {
var layer = this.children[n];
if(layer.attrs.visible && n >= 0 && layer.attrs.listening) {
if(layer.isVisible() && n >= 0 && layer.attrs.listening) {
if(this._traverseChildren(layer, evt)) {
n = -1;
shapeDetected = true;
@ -2595,7 +2600,7 @@ Kinetic.Layer.prototype = {
}
this.clear();
if(this.attrs.visible) {
if(this.isVisible()) {
// draw custom func
if(this.attrs.drawFunc !== undefined) {
this.attrs.drawFunc.call(this);

File diff suppressed because one or more lines are too long

View File

@ -126,7 +126,7 @@ Kinetic.Layer.prototype = {
}
this.clear();
if(this.attrs.visible) {
if(this.isVisible()) {
// draw custom func
if(this.attrs.drawFunc !== undefined) {
this.attrs.drawFunc.call(this);

View File

@ -233,9 +233,14 @@ Kinetic.Node.prototype = {
}
},
/**
* determine if shape is visible or not
* determine if shape is visible or not. Shape is visible only
* if it's visible and all of its ancestors are visible. If one ancestor
* is invisible, this means that the shape is also invisible
*/
isVisible: function() {
if(this.getParent() && !this.getParent().isVisible()) {
return false;
}
return this.attrs.visible;
},
/**

View File

@ -397,7 +397,7 @@ Kinetic.Stage.prototype = {
this.targetFound = true;
}
if(shape.attrs.visible && pos !== undefined && shape.intersects(pos)) {
if(shape.isVisible() && pos !== undefined && shape.intersects(pos)) {
// handle onmousedown
if(!isDragging && this.mouseDown) {
this.mouseDown = false;
@ -589,7 +589,7 @@ else if(!isDragging && this.touchMove) {
var shapeDetected = false;
for(var n = this.children.length - 1; n >= 0; n--) {
var layer = this.children[n];
if(layer.attrs.visible && n >= 0 && layer.attrs.listening) {
if(layer.isVisible() && n >= 0 && layer.attrs.listening) {
if(this._traverseChildren(layer, evt)) {
n = -1;
shapeDetected = true;

View File

@ -813,7 +813,7 @@ Test.prototype.tests = {
// LAYERS tests
////////////////////////////////////////////////////////////////////////
'LAYERS - add layer': function(containerId) {
'LAYER - add layer': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -822,7 +822,53 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer();
stage.add(layer);
},
'LAYERS - beforeDraw and afterDraw': function(containerId) {
'LAYER - hide layer': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer1 = new Kinetic.Layer();
var layer2 = new Kinetic.Layer();
var circle1 = new Kinetic.Circle({
x: 100,
y: stage.getHeight() / 2,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
var circle2 = new Kinetic.Circle({
x: 150,
y: stage.getHeight() / 2,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
circle1.on('mousemove', function() {
console.log('mousemove circle1');
});
circle2.on('mousemove', function() {
console.log('mousemove circle2');
});
layer1.add(circle1);
layer2.add(circle2);
stage.add(layer1).add(layer2);
test(layer2.isVisible(), 'layer2 should be visible');
layer2.hide();
layer2.draw();
test(!layer2.isVisible(), 'layer2 should be invisible');
},
'LAYER - beforeDraw and afterDraw': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -857,7 +903,7 @@ Test.prototype.tests = {
layer.draw();
},
'LAYERS - throttling': function(containerId) {
'LAYER - throttling': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -872,7 +918,7 @@ Test.prototype.tests = {
layer.setThrottle(13);
test(layer.getThrottle() === 13, 'throttle should be 13');
},
'LAYERS - add layer': function(containerId) {
'LAYER - add layer': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -881,7 +927,7 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer();
stage.add(layer);
},
'LAYERS - remove all children from layer': function(containerId) {
'LAYER - remove all children from layer': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -921,7 +967,7 @@ Test.prototype.tests = {
// GROUPS tests
////////////////////////////////////////////////////////////////////////
'GROUPS - add group': function(containerId) {
'GROUP - add group': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -943,7 +989,55 @@ Test.prototype.tests = {
layer.add(group);
stage.add(layer);
},
'GROUPS - create two groups, move first group': function(containerId) {
'GROUP - hide group': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var group = new Kinetic.Group();
var circle1 = new Kinetic.Circle({
x: 100,
y: stage.getHeight() / 2,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
var circle2 = new Kinetic.Circle({
x: 150,
y: stage.getHeight() / 2,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
circle1.on('mousemove', function() {
console.log('mousemove circle1');
});
circle2.on('mousemove', function() {
console.log('mousemove circle2');
});
group.add(circle2);
layer.add(circle1).add(group);
stage.add(layer);
test(group.isVisible(), 'group should be visible');
test(circle2.isVisible(), 'circle2 should be visible');
group.hide();
layer.draw();
test(!group.isVisible(), 'group should be invisible');
test(!circle2.isVisible(), 'circle2 should be invisible');
},
'GROUP - create two groups, move first group': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -3375,6 +3469,10 @@ Test.prototype.tests = {
circle.on('click', function() {
foo = 'bar';
var evt = window.event;
var rightClick = evt.which ? evt.which == 3 : evt.button == 2;
console.log(rightClick);
});
circle.simulate('click');