From b8e3f10d3aec0109fabdfdb6f2331a4c8f8e4a47 Mon Sep 17 00:00:00 2001 From: Eric Rowell Date: Sat, 10 Aug 2013 16:19:33 -0700 Subject: [PATCH] getVisible returns the visible attr. isVisible takes ancestors into account. getListening returns listening attr. isListening takes ancestors into account. added unit tests. --- src/Node.js | 80 ++++++++++++++++++++++++-------------- tests/js/unit/nodeTests.js | 15 +++++-- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/Node.js b/src/Node.js index 1986c67f..f57e097b 100644 --- a/src/Node.js +++ b/src/Node.js @@ -16,6 +16,7 @@ HASH = '#', ID = 'id', KINETIC = 'kinetic', + LISTENING = 'listening', MOUSEENTER = 'mouseenter', MOUSELEAVE = 'mouseleave', NAME = 'name', @@ -79,6 +80,18 @@ } } + // clear listening cache pair + function _clearListeningCacheEachChild(node) { + _clearListeningCache.call(node); + } + function _clearListeningCache() { + this._clearCache(LISTENING); + + if (this.children) { + this.getChildren().each(_clearListeningCacheEachChild); + } + } + // clear absolute opacity cache pair function _clearAbsoluteOpacityCacheEachChild(node) { _clearAbsoluteOpacityCache.call(node); @@ -102,11 +115,13 @@ // event bindings for cache handling this.on(transformChangeStr, _clearTransformCache); this.on('visibleChange.kinetic', _clearVisibleCache); + this.on('listeningChange.kinetic', _clearListeningCache); this.on('opacityChange.kinetic', _clearAbsoluteOpacityCache); this._clearTransformCache = _clearTransformCache; this._clearAbsoluteTransformCache = _clearAbsoluteTransformCache; this._clearVisibleCache = _clearVisibleCache; + this._clearListeningCache = _clearListeningCache; this._clearAbsoluteOpacityCache = _clearAbsoluteOpacityCache; }, _clearCache: function(attr){ @@ -370,6 +385,25 @@ } return this; }, + /** + * determine if node is listening for events. The node is listening only + * if it's listening and all of its ancestors are listening. If an ancestor + * is listening, this means that the node is also listening + * @method + * @memberof Kinetic.Node.prototype + */ + isListening: function() { + return this._getCache(LISTENING, this._isListening); + }, + _isListening: function() { + var listening = this.getListening(), + parent = this.getParent(); + + if(listening && parent && !parent.isListening()) { + return false; + } + return listening; + }, /** * determine if node is visible or not. Node is visible only * if it's visible and all of its ancestors are visible. If an ancestor @@ -377,19 +411,14 @@ * @method * @memberof Kinetic.Node.prototype */ - getVisible: function() { - return this._getCache(VISIBLE, this._getVisible); + isVisible: function() { + return this._getCache(VISIBLE, this._isVisible); }, - _getVisible: function() { - var visible = this.attrs.visible, + _isVisible: function() { + var visible = this.getVisible(), parent = this.getParent(); - // default - if (visible === undefined) { - visible = true; - } - - if(visible && parent && !parent.getVisible()) { + if(visible && parent && !parent.isVisible()) { return false; } return visible; @@ -1471,7 +1500,7 @@ }; // add getters setters - Kinetic.Node.addGetterSetter(Kinetic.Node, 'x', 0, TRANSFORM); + Kinetic.Node.addGetterSetter(Kinetic.Node, 'x', 0); /** * set x position @@ -1488,7 +1517,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addGetterSetter(Kinetic.Node, 'y', 0, TRANSFORM); + Kinetic.Node.addGetterSetter(Kinetic.Node, 'y', 0); /** * set y position @@ -1505,7 +1534,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addGetterSetter(Kinetic.Node, 'opacity', 1, ABSOLUTE_OPACITY); + Kinetic.Node.addGetterSetter(Kinetic.Node, 'opacity', 1); /** * set opacity. Opacity values range from 0 to 1. @@ -1542,7 +1571,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addRotationGetterSetter(Kinetic.Node, 'rotation', 0, TRANSFORM); + Kinetic.Node.addRotationGetterSetter(Kinetic.Node, 'rotation', 0); /** * set rotation in radians @@ -1574,7 +1603,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'scale', 1, TRANSFORM); + Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'scale', 1); /** * set scale @@ -1635,7 +1664,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'skew', 0, TRANSFORM); + Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'skew', 0); /** * set skew @@ -1697,7 +1726,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'offset', 0, TRANSFORM); + Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'offset', 0); /** * set offset. A node's offset defines the position and rotation point @@ -1796,7 +1825,7 @@ * @memberof Kinetic.Node.prototype */ - Kinetic.Node.addSetter(Kinetic.Node, 'visible', VISIBLE); + Kinetic.Node.addGetterSetter(Kinetic.Node, 'visible', true); /** * set visible @@ -1806,22 +1835,13 @@ * @param {Boolean} visible */ - // aliases - /** - * Alias of getListening() - * @name isListening + * get visible property for the node. If you need to determine if the node is actually visible, + * use the isVisible() method because it takes ancestors into account + * @name getVisible * @method * @memberof Kinetic.Node.prototype */ - Kinetic.Node.prototype.isListening = Kinetic.Node.prototype.getListening; - /** - * Alias of getVisible() - * @name isVisible - * @method - * @memberof Kinetic.Node.prototype - */ - Kinetic.Node.prototype.isVisible = Kinetic.Node.prototype.getVisible; Kinetic.Collection.mapMethods([ 'on', diff --git a/tests/js/unit/nodeTests.js b/tests/js/unit/nodeTests.js index b77e27f5..722c2b90 100644 --- a/tests/js/unit/nodeTests.js +++ b/tests/js/unit/nodeTests.js @@ -125,7 +125,7 @@ Test.Modules.NODE = { test(circle.cache.visible === false, '7) circle visible cache should be primed'); circle.show(); test(circle.cache.visible === undefined, '8) circle visible cache should be empty'); - stage.draw(); + layer.draw(); test(circle.cache.visible === true, '9) circle visible cache should be primed'); // shadow cache @@ -142,9 +142,16 @@ Test.Modules.NODE = { test(circle.cache.absoluteOpacity === 1, '14) circle absolute opacity cache should be primed'); circle.setOpacity(0.5); test(circle.cache.absoluteOpacity === undefined, '15) circle absolute opacity cache should be empty'); - circle.draw(); + layer.draw(); test(circle.cache.absoluteOpacity === 0.5, '15) circle absolute opacity cache should be primed'); + // listening cache + test(circle.cache.listening === true, '16) circle listening cache should be primed'); + circle.setListening(false); + test(circle.cache.listening === undefined, '17) circle listening cache should be empty'); + layer.draw(); + test(circle.cache.listening === false, '18) circle listening cache should be primed'); + }, 'test pixel ratio toDataURL': function(containerId) { var stage = new Kinetic.Stage({ @@ -1566,13 +1573,13 @@ Test.Modules.NODE = { test(rect.isListening(), 'rect should be listening'); layer.setListening(false); - test(rect.isListening(), 'rect should be listening even though layer is not listening'); + test(!rect.isListening(), 'rect should not be listening because layer is not listening'); layer.setListening(true); test(rect.isListening(), 'rect should be listening'); stage.setListening(false); - test(rect.isListening(), 'rect should be listening even though stage is not listening'); + test(!rect.isListening(), 'rect should not be listening because stage is not listening'); }, 'test fire event': function(containerId) { var stage = new Kinetic.Stage({