mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 07:25:56 +08:00
fixed mouseover / mouseout incorrectly firing when moving from one node to another node inside the same container
This commit is contained in:
parent
d28d2c910d
commit
014d4f198f
62
dist/kinetic-core.js
vendored
62
dist/kinetic-core.js
vendored
@ -3,7 +3,7 @@
|
||||
* http://www.kineticjs.com/
|
||||
* Copyright 2012, Eric Rowell
|
||||
* Licensed under the MIT or GPL Version 2 licenses.
|
||||
* Date: Jul 04 2012
|
||||
* Date: Jul 06 2012
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 by Eric Rowell
|
||||
*
|
||||
@ -1152,8 +1152,8 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
}
|
||||
|
||||
var stage = this.getStage();
|
||||
var mouseoverNode = stage ? stage.mouseoverShape : null;
|
||||
var mouseoutNode = stage ? stage.mouseoutShape : null;
|
||||
var mover = stage ? stage.mouseoverShape : null;
|
||||
var mout = stage ? stage.mouseoutShape : null;
|
||||
var el = this.eventListeners;
|
||||
var okayToRun = true;
|
||||
|
||||
@ -1161,26 +1161,30 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
* determine if event handler should be skipped by comparing
|
||||
* parent nodes
|
||||
*/
|
||||
if(eventType === 'mouseover' && mouseoutNode && mouseoutNode._id === this._id) {
|
||||
if(eventType === 'mouseover' && mout && mout._id === this._id) {
|
||||
okayToRun = false;
|
||||
}
|
||||
else if(eventType === 'mouseout' && mouseoverNode && mouseoverNode._id === this._id) {
|
||||
else if(eventType === 'mouseout' && mover && mover._id === this._id) {
|
||||
okayToRun = false;
|
||||
}
|
||||
|
||||
if(el[eventType] && okayToRun) {
|
||||
var events = el[eventType];
|
||||
for(var i = 0; i < events.length; i++) {
|
||||
events[i].handler.apply(this, [evt]);
|
||||
if(okayToRun) {
|
||||
if(el[eventType]) {
|
||||
var events = el[eventType];
|
||||
for(var i = 0; i < events.length; i++) {
|
||||
events[i].handler.apply(this, [evt]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mouseoverParent = mouseoverNode ? mouseoverNode.parent : undefined;
|
||||
var mouseoutParent = mouseoutNode ? mouseoutNode.parent : undefined;
|
||||
if(stage && mover && mout) {
|
||||
stage.mouseoverShape = mover.parent;
|
||||
stage.mouseoutShape = mout.parent;
|
||||
}
|
||||
|
||||
// simulate event bubbling
|
||||
if(!evt.cancelBubble && this.parent && this.parent.nodeType !== 'Stage') {
|
||||
this._handleEvent.call(this.parent, eventType, evt);
|
||||
// simulate event bubbling
|
||||
if(!evt.cancelBubble && this.parent) {
|
||||
this._handleEvent.call(this.parent, eventType, evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -2705,19 +2709,6 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
}, 17);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* set throttle
|
||||
* @param {Number} throttle in ms
|
||||
*/
|
||||
setThrottle: function(throttle) {
|
||||
this.attrs.throttle = throttle;
|
||||
},
|
||||
/**
|
||||
* get throttle
|
||||
*/
|
||||
getThrottle: function() {
|
||||
return this.attrs.throttle;
|
||||
},
|
||||
/**
|
||||
* set before draw function handler
|
||||
*/
|
||||
@ -2788,7 +2779,7 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
});
|
||||
|
||||
// add getters and setters
|
||||
Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw']);
|
||||
Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw', 'throttle']);
|
||||
|
||||
/**
|
||||
* set flag which determines if the layer is cleared or not
|
||||
@ -2798,12 +2789,25 @@ Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw']);
|
||||
* @param {Boolean} clearBeforeDraw
|
||||
*/
|
||||
|
||||
/**
|
||||
* set throttle
|
||||
* @name setThrottle
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
* @param {Number} throttle
|
||||
*/
|
||||
|
||||
/**
|
||||
* get flag which determines if the layer is cleared or not
|
||||
* before drawing
|
||||
* @name getClearBeforeDraw
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
*/
|
||||
|
||||
/**
|
||||
* get throttle
|
||||
* @name getThrottle
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Group
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
6
dist/kinetic-core.min.js
vendored
6
dist/kinetic-core.min.js
vendored
File diff suppressed because one or more lines are too long
28
src/Layer.js
28
src/Layer.js
@ -61,19 +61,6 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
}, 17);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* set throttle
|
||||
* @param {Number} throttle in ms
|
||||
*/
|
||||
setThrottle: function(throttle) {
|
||||
this.attrs.throttle = throttle;
|
||||
},
|
||||
/**
|
||||
* get throttle
|
||||
*/
|
||||
getThrottle: function() {
|
||||
return this.attrs.throttle;
|
||||
},
|
||||
/**
|
||||
* set before draw function handler
|
||||
*/
|
||||
@ -144,7 +131,7 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
});
|
||||
|
||||
// add getters and setters
|
||||
Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw']);
|
||||
Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw', 'throttle']);
|
||||
|
||||
/**
|
||||
* set flag which determines if the layer is cleared or not
|
||||
@ -154,9 +141,22 @@ Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw']);
|
||||
* @param {Boolean} clearBeforeDraw
|
||||
*/
|
||||
|
||||
/**
|
||||
* set throttle
|
||||
* @name setThrottle
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
* @param {Number} throttle
|
||||
*/
|
||||
|
||||
/**
|
||||
* get flag which determines if the layer is cleared or not
|
||||
* before drawing
|
||||
* @name getClearBeforeDraw
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
*/
|
||||
|
||||
/**
|
||||
* get throttle
|
||||
* @name getThrottle
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
*/
|
32
src/Node.js
32
src/Node.js
@ -732,8 +732,8 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
}
|
||||
|
||||
var stage = this.getStage();
|
||||
var mouseoverNode = stage ? stage.mouseoverShape : null;
|
||||
var mouseoutNode = stage ? stage.mouseoutShape : null;
|
||||
var mover = stage ? stage.mouseoverShape : null;
|
||||
var mout = stage ? stage.mouseoutShape : null;
|
||||
var el = this.eventListeners;
|
||||
var okayToRun = true;
|
||||
|
||||
@ -741,26 +741,30 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
* determine if event handler should be skipped by comparing
|
||||
* parent nodes
|
||||
*/
|
||||
if(eventType === 'mouseover' && mouseoutNode && mouseoutNode._id === this._id) {
|
||||
if(eventType === 'mouseover' && mout && mout._id === this._id) {
|
||||
okayToRun = false;
|
||||
}
|
||||
else if(eventType === 'mouseout' && mouseoverNode && mouseoverNode._id === this._id) {
|
||||
else if(eventType === 'mouseout' && mover && mover._id === this._id) {
|
||||
okayToRun = false;
|
||||
}
|
||||
|
||||
if(el[eventType] && okayToRun) {
|
||||
var events = el[eventType];
|
||||
for(var i = 0; i < events.length; i++) {
|
||||
events[i].handler.apply(this, [evt]);
|
||||
if(okayToRun) {
|
||||
if(el[eventType]) {
|
||||
var events = el[eventType];
|
||||
for(var i = 0; i < events.length; i++) {
|
||||
events[i].handler.apply(this, [evt]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mouseoverParent = mouseoverNode ? mouseoverNode.parent : undefined;
|
||||
var mouseoutParent = mouseoutNode ? mouseoutNode.parent : undefined;
|
||||
if(stage && mover && mout) {
|
||||
stage.mouseoverShape = mover.parent;
|
||||
stage.mouseoutShape = mout.parent;
|
||||
}
|
||||
|
||||
// simulate event bubbling
|
||||
if(!evt.cancelBubble && this.parent && this.parent.nodeType !== 'Stage') {
|
||||
this._handleEvent.call(this.parent, eventType, evt);
|
||||
// simulate event bubbling
|
||||
if(!evt.cancelBubble && this.parent) {
|
||||
this._handleEvent.call(this.parent, eventType, evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -23,7 +23,7 @@
|
||||
test.run();
|
||||
|
||||
document.getElementsByTagName('body')[0].addEventListener('mousemove', function(evt) {
|
||||
console.log(evt.clientX + ',' + evt.clientY);
|
||||
//console.log(evt.clientX + ',' + evt.clientY);
|
||||
}, false);
|
||||
};
|
||||
|
||||
|
@ -257,7 +257,7 @@ Test.prototype.tests = {
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200,
|
||||
throttle: 9999
|
||||
throttle: 999
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var circle = new Kinetic.Ellipse({
|
||||
@ -302,7 +302,7 @@ Test.prototype.tests = {
|
||||
|
||||
circle.on('mouseout', function() {
|
||||
mouseout = true;
|
||||
//log('mousedown');
|
||||
//log('mouseout');
|
||||
});
|
||||
|
||||
circle.on('mousemove', function() {
|
||||
@ -435,7 +435,11 @@ Test.prototype.tests = {
|
||||
test(!mouseout, '6) mouseout should be false');
|
||||
|
||||
// move mouse outside of circle to trigger mouseout
|
||||
stage._mouseout({
|
||||
stage._mousemove({
|
||||
clientX: 0,
|
||||
clientY: 100
|
||||
});
|
||||
stage._mousemove({
|
||||
clientX: 0,
|
||||
clientY: 100
|
||||
});
|
||||
@ -447,10 +451,10 @@ Test.prototype.tests = {
|
||||
test(click, '7) click should be true');
|
||||
test(dblclick, '7) dblclick should be true');
|
||||
test(mouseout, '7) mouseout should be true');
|
||||
|
||||
/*
|
||||
* mobile tests
|
||||
*/
|
||||
|
||||
// reset inDoubleClickWindow
|
||||
stage.inDoubleClickWindow = false;
|
||||
|
||||
@ -601,5 +605,151 @@ Test.prototype.tests = {
|
||||
|
||||
test(groupMousedowns === 4, 'groupMousedowns should be 4');
|
||||
test(greenCircleMousedowns === 2, 'greenCircleMousedowns should be 2');
|
||||
},
|
||||
'EVENTS - group mouseover events': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200,
|
||||
throttle: 9999
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var group = new Kinetic.Group({
|
||||
name: 'group'
|
||||
});
|
||||
|
||||
var redMouseovers = 0;
|
||||
var redMouseouts = 0;
|
||||
var greenMouseovers = 0;
|
||||
var greenMouseouts = 0;
|
||||
var groupMouseovers = 0;
|
||||
var groupMouseouts = 0;
|
||||
|
||||
var redEllipse = new Kinetic.Ellipse({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 80,
|
||||
strokeWidth: 4,
|
||||
fill: 'red',
|
||||
stroke: 'black',
|
||||
name: 'red'
|
||||
});
|
||||
|
||||
var greenEllipse = new Kinetic.Ellipse({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 40,
|
||||
strokeWidth: 4,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
name: 'green'
|
||||
});
|
||||
|
||||
group.on('mouseover', function() {
|
||||
groupMouseovers++;
|
||||
//onsole.log('over')
|
||||
});
|
||||
|
||||
group.on('mouseout', function() {
|
||||
groupMouseouts++;
|
||||
//console.log('out')
|
||||
});
|
||||
|
||||
redEllipse.on('mouseover', function() {
|
||||
redMouseovers++;
|
||||
//console.log('over')
|
||||
});
|
||||
|
||||
redEllipse.on('mouseout', function() {
|
||||
redMouseouts++;
|
||||
//console.log('out')
|
||||
});
|
||||
|
||||
greenEllipse.on('mouseover', function() {
|
||||
greenMouseovers++;
|
||||
});
|
||||
|
||||
greenEllipse.on('mouseout', function() {
|
||||
greenMouseouts++;
|
||||
});
|
||||
|
||||
group.add(redEllipse);
|
||||
group.add(greenEllipse);
|
||||
|
||||
layer.add(group);
|
||||
stage.add(layer);
|
||||
|
||||
// move mouse outside of circles
|
||||
stage._mousemove({
|
||||
clientX: 177,
|
||||
clientY: 146
|
||||
});
|
||||
|
||||
test(redMouseovers === 0, 'redMouseovers should be 0');
|
||||
test(redMouseouts === 0, 'redMouseouts should be 0');
|
||||
test(greenMouseovers === 0, 'greenMouseovers should be 0');
|
||||
test(greenMouseouts === 0, 'greenMouseouts should be 0');
|
||||
test(groupMouseovers === 0, 'groupMouseovers should be 0');
|
||||
test(groupMouseouts === 0, 'groupMouseouts should be 0');
|
||||
|
||||
// move mouse inside of red circle
|
||||
stage._mousemove({
|
||||
clientX: 236,
|
||||
clientY: 145
|
||||
});
|
||||
|
||||
test(redMouseovers === 1, 'redMouseovers should be 1');
|
||||
test(redMouseouts === 0, 'redMouseouts should be 0');
|
||||
test(greenMouseovers === 0, 'greenMouseovers should be 0');
|
||||
test(greenMouseouts === 0, 'greenMouseouts should be 0');
|
||||
test(groupMouseovers === 1, 'groupMouseovers should be 1');
|
||||
test(groupMouseouts === 0, 'groupMouseouts should be 0');
|
||||
|
||||
// move mouse inside of green circle
|
||||
stage._mousemove({
|
||||
clientX: 284,
|
||||
clientY: 118
|
||||
});
|
||||
|
||||
test(redMouseovers === 1, 'redMouseovers should be 1');
|
||||
test(redMouseouts === 1, 'redMouseouts should be 1');
|
||||
test(greenMouseovers === 1, 'greenMouseovers should be 1');
|
||||
test(greenMouseouts === 0, 'greenMouseouts should be 0');
|
||||
test(groupMouseovers === 1, 'groupMouseovers should be 1');
|
||||
test(groupMouseouts === 0, 'groupMouseouts should be 0');
|
||||
|
||||
// move mouse back to red circle
|
||||
|
||||
stage._mousemove({
|
||||
clientX: 345,
|
||||
clientY: 105
|
||||
});
|
||||
stage._mousemove({
|
||||
clientX: 345,
|
||||
clientY: 105
|
||||
});
|
||||
|
||||
test(redMouseovers === 2, 'redMouseovers should be 2');
|
||||
test(redMouseouts === 1, 'redMouseouts should be 1');
|
||||
test(greenMouseovers === 1, 'greenMouseovers should be 1');
|
||||
test(greenMouseouts === 1, 'greenMouseouts should be 1');
|
||||
test(groupMouseovers === 1, 'groupMouseovers should be 1');
|
||||
test(groupMouseouts === 0, 'groupMouseouts should be 0');
|
||||
|
||||
// move mouse outside of circles
|
||||
stage._mousemove({
|
||||
clientX: 177,
|
||||
clientY: 146
|
||||
});
|
||||
stage._mousemove({
|
||||
clientX: 177,
|
||||
clientY: 146
|
||||
});
|
||||
test(redMouseovers === 2, 'redMouseovers should be 2');
|
||||
test(redMouseouts === 2, 'redMouseouts should be 2');
|
||||
test(greenMouseovers === 1, 'greenMouseovers should be 1');
|
||||
test(greenMouseouts === 1, 'greenMouseouts should be 1');
|
||||
test(groupMouseovers === 1, 'groupMouseovers should be 1');
|
||||
test(groupMouseouts === 1, 'groupMouseouts should be 1');
|
||||
}
|
||||
};
|
||||
|
@ -622,50 +622,6 @@ Test.prototype.tests = {
|
||||
layer.add(group);
|
||||
stage.add(layer);
|
||||
},
|
||||
'EVENTS - group mouseover events': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var group = new Kinetic.Group({
|
||||
name: 'group'
|
||||
});
|
||||
|
||||
group.on('mouseover', function() {
|
||||
log('mouseover group');
|
||||
});
|
||||
|
||||
group.on('mouseout', function() {
|
||||
log('mouseout group');
|
||||
});
|
||||
var redEllipse = new Kinetic.Ellipse({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 80,
|
||||
strokeWidth: 4,
|
||||
fill: 'red',
|
||||
stroke: 'black',
|
||||
name: 'red'
|
||||
});
|
||||
|
||||
var greenEllipse = new Kinetic.Ellipse({
|
||||
x: stage.getWidth() / 2,
|
||||
y: stage.getHeight() / 2,
|
||||
radius: 40,
|
||||
strokeWidth: 4,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
name: 'green'
|
||||
});
|
||||
|
||||
group.add(redEllipse);
|
||||
group.add(greenEllipse);
|
||||
|
||||
layer.add(group);
|
||||
stage.add(layer);
|
||||
},
|
||||
'EVENTS - cancel event bubbling (only the red Ellipse should fire click event)': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
|
Loading…
Reference in New Issue
Block a user