refactored Container drawScene and drawHit methods, and cleaned up clipping logic. Clipping now correctly also clips the hit graph

This commit is contained in:
Eric Rowell 2013-12-29 14:07:58 -08:00
parent 264f24e241
commit 90b07cea05
4 changed files with 101 additions and 65 deletions

View File

@ -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;
}
});

View File

@ -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;
},

View File

@ -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}

View File

@ -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();
});
});