From 90b07cea057ae153194e1af0d3d0f46dfacef80f Mon Sep 17 00:00:00 2001 From: Eric Rowell Date: Sun, 29 Dec 2013 14:07:58 -0800 Subject: [PATCH] refactored Container drawScene and drawHit methods, and cleaned up clipping logic. Clipping now correctly also clips the hit graph --- src/Container.js | 76 ++++++++++++++++++------------------------ src/Context.js | 16 --------- src/Node.js | 14 +++++--- test/unit/Node-test.js | 60 +++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 65 deletions(-) diff --git a/src/Container.js b/src/Container.js index f5ecc20d..23928b4c 100644 --- a/src/Container.js +++ b/src/Container.js @@ -238,57 +238,45 @@ child.index = n; }); }, - drawScene: function(canvas) { - var layer = this.getLayer(), - clip = this.getClipWidth() && this.getClipHeight(), - children, n, len; - - // if (!canvas && layer) { - // canvas = layer.getCanvas(); - // } - - if(this.isVisible()) { - if (clip) { - canvas.getContext()._clip(this); - } - else { - this._drawChildren(canvas); - } + drawScene: function(can) { + if (this.isVisible()) { + this._draw(can, 'drawScene'); } - return this; }, - _drawChildren: function(canvas) { + drawHit: function(can) { + if (this.shouldDrawHit()) { + this._draw(can, 'drawHit'); + } + return this; + }, + _draw: function(can, method) { + var clipWidth = this.getClipWidth(), + clipHeight = this.getClipHeight(), + hasClip = clipWidth && clipHeight, + canvas, context, clipX, clipY; + + if (hasClip) { + canvas = can || this.getLayer().hitCanvas; + context = canvas.getContext(); + clipX = this.getClipX(); + clipY = this.getClipY(); + + context.save(); + context._applyTransform(this); + context.beginPath(); + context.rect(clipX, clipY, clipWidth, clipHeight); + context.clip(); + context.reset(); + } + this.children.each(function(child) { - child.drawScene(canvas); + child[method](canvas); }); - }, - drawHit: function() { - var hasClip = this.getClipWidth() && this.getClipHeight() && this.nodeType !== 'Stage', - n = 0, - len = 0, - children = [], - hitCanvas; - if(this.shouldDrawHit()) { - - if (hasClip) { - hitCanvas = this.getLayer().hitCanvas; - hitCanvas.getContext()._clip(this); - } - - children = this.children; - len = children.length; - - for(n = 0; n < len; n++) { - children[n].drawHit(); - } - if (hasClip) { - hitCanvas.getContext()._context.restore(); - } + if (hasClip) { + context.restore(); } - - return this; } }); diff --git a/src/Context.js b/src/Context.js index f7f68557..1b236c2a 100644 --- a/src/Context.js +++ b/src/Context.js @@ -236,22 +236,6 @@ this.translate(shape.getX(), shape.getY()); } }, - _clip: function(container) { - var clipX = container.getClipX(), - clipY = container.getClipY(), - clipWidth = container.getClipWidth(), - clipHeight = container.getClipHeight(); - - this.save(); - this._applyTransform(container); - this.beginPath(); - this.rect(clipX, clipY, clipWidth, clipHeight); - this.clip(); - this.reset(); - container._drawChildren(this.getCanvas()); - this.restore(); - }, - setAttr: function(attr, val) { this._context[attr] = val; }, diff --git a/src/Node.js b/src/Node.js index ea344c6e..fad74c00 100644 --- a/src/Node.js +++ b/src/Node.js @@ -61,7 +61,12 @@ }); }, _clearCache: function(attr){ - delete this._cache[attr]; + if (attr) { + delete this._cache[attr]; + } + else { + this._cache = {}; + } }, _getCache: function(attr, privateGetter){ var cache = this._cache[attr]; @@ -94,9 +99,8 @@ * @example * node.clearCache(); */ - clearCache: function() { - this._cache = {}; - return this; + clearCache: function(attr) { + delete this._cache.canvas; }, /** * cache node to improve drawing performance. @@ -482,7 +486,7 @@ }, /** * determine if listening is enabled by taking into account descendants. If self or any children - * have _isListeningEnabled set to true, than self also has listening enabled. + * have _isListeningEnabled set to true, then self also has listening enabled. * @method * @memberof Kinetic.Node.prototype * @returns {Boolean} diff --git a/test/unit/Node-test.js b/test/unit/Node-test.js index 379d9728..838c4953 100644 --- a/test/unit/Node-test.js +++ b/test/unit/Node-test.js @@ -2944,4 +2944,64 @@ suite('Node', function() { assert.equal(circle._cache.canvas.scene.getContext().getTrace(), 'save();translate(74,74);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();'); }); + + test('cache group', function(){ + var stage = addStage(); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group({ + x: 100, + y: 100, + draggable: true + }); + var top = new Kinetic.Circle({ + x: 0, + y: -70, + radius: 30, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + var right = new Kinetic.Circle({ + x: 70, + y: 0, + radius: 30, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + var bottom = new Kinetic.Circle({ + x: 0, + y: 70, + radius: 30, + fill: 'blue', + stroke: 'black', + strokeWidth: 4 + }); + var left = new Kinetic.Circle({ + x: -70, + y: 0, + radius: 30, + fill: 'yellow', + stroke: 'black', + strokeWidth: 4 + }); + + group.add(top).add(right).add(bottom).add(left); + layer.add(group); + stage.add(layer); + + assert.equal(group._cache.canvas, undefined); + + group.cache({ + width: 100, + height: 100 + }); + + assert.notEqual(group._cache.canvas.scene, undefined); + assert.notEqual(group._cache.canvas.hit, undefined); + + layer.draw(); + + + }); }); \ No newline at end of file