you can now cache regions of a node outside of the stage viewport. added more unit tests

This commit is contained in:
Eric Rowell 2012-07-21 15:38:25 -07:00
parent d74ec8ab06
commit f1cb695e1f
8 changed files with 176 additions and 102 deletions

72
dist/kinetic-core.js vendored
View File

@ -1433,25 +1433,34 @@ Kinetic.Node = Kinetic.Class.extend({
* level as quality (range 0.0 - 1.0)
* @name toDataURL
* @methodOf Kinetic.Node.prototype
* @param {String} [mimeType]
* @param {Number} [quality]
* @param {Object} config
*/
toDataURL: function(mimeType, quality) {
var bufferCanvas = this.getStage().bufferCanvas;
var bufferContext = bufferCanvas.getContext();
bufferCanvas.clear();
this._draw(bufferCanvas);
return bufferCanvas.toDataURL(mimeType, quality);
toDataURL: function(config) {
var mimeType = config && config.mimeType ? config.mimeType : null;
var quality = config && config.quality ? config.quality : null;
var canvas;
if(config && config.width && config.height) {
canvas = new Kinetic.Canvas(config.width, config.height);
}
else {
canvas = this.getStage().bufferCanvas;
}
var context = canvas.getContext();
canvas.clear();
this._draw(canvas);
return canvas.toDataURL(mimeType, quality);
},
/**
* converts node into an image. Since the toImage
* method is asynchronous, a callback is required
* @name toImage
* @methodOf Kinetic.Stage.prototype
* @param {Object} config
*/
toImage: function(callback) {
Kinetic.Type._getImage(this.toDataURL(), function(img) {
callback(img);
toImage: function(config) {
Kinetic.Type._getImage(this.toDataURL(config), function(img) {
config.callback(img);
});
},
_clearTransform: function() {
@ -2344,17 +2353,19 @@ Kinetic.Stage = Kinetic.Container.extend({
* the current state of each node
* @name toDataURL
* @methodOf Kinetic.Stage.prototype
* @param {Function} callback
* @param {String} [mimeType]
* @param {Number} [quality]
* @param {Object} config
*/
toDataURL: function(callback, mimeType, quality) {
toDataURL: function(config) {
var mimeType = config && config.mimeType ? config.mimeType : null;
var quality = config && config.quality ? config.quality : null;
/*
* need to create a canvas element rather than using the buffer canvas
* because this method is asynchonous which means that other parts of the
* code could modify the buffer canvas before it's finished
*/
var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
var width = config && config.width ? config.width : this.attrs.width;
var height = config && config.height ? config.height : this.attrs.height;
var canvas = new Kinetic.Canvas(width, height);
var context = canvas.getContext();
var layers = this.children;
@ -2369,7 +2380,7 @@ Kinetic.Stage = Kinetic.Container.extend({
drawLayer(n + 1);
}
else {
callback(canvas.toDataURL(mimeType, quality));
config.callback(canvas.toDataURL(mimeType, quality));
}
};
imageObj.src = layerUrl;
@ -2381,13 +2392,15 @@ Kinetic.Stage = Kinetic.Container.extend({
* is asynchronous, a callback function is required
* @name toImage
* @methodOf Kinetic.Stage.prototype
* @param {Function} callback
* @param {Object} config
*/
toImage: function(callback) {
this.toDataURL(function(dataUrl) {
toImage: function(config) {
this.toDataURL({
callback: function(dataUrl) {
Kinetic.Type._getImage(dataUrl, function(img) {
callback(img);
config.callback(img);
});
}
});
},
_resizeDOM: function() {
@ -3157,11 +3170,20 @@ Kinetic.Layer = Kinetic.Container.extend({
* the current state of each child node
* @name toDataURL
* @methodOf Kinetic.Layer.prototype
* @param {String} [mimeType]
* @param {Number} [quality]
* @param {Object} config
*/
toDataURL: function(mimeType, quality) {
return this.getCanvas().toDataURL(mimeType, quality);
toDataURL: function(config) {
var canvas;
var mimeType = config && config.mimeType ? config.mimeType : null;
var quality = config && config.quality ? config.quality : null;
if(config && config.width && config.height) {
canvas = new Kinetic.Canvas(config.width, config.height);
}
else {
canvas = this.getCanvas();
}
return canvas.toDataURL(mimeType, quality);
},
/**
* private draw children

File diff suppressed because one or more lines are too long

View File

@ -102,11 +102,20 @@ Kinetic.Layer = Kinetic.Container.extend({
* the current state of each child node
* @name toDataURL
* @methodOf Kinetic.Layer.prototype
* @param {String} [mimeType]
* @param {Number} [quality]
* @param {Object} config
*/
toDataURL: function(mimeType, quality) {
return this.getCanvas().toDataURL(mimeType, quality);
toDataURL: function(config) {
var canvas;
var mimeType = config && config.mimeType ? config.mimeType : null;
var quality = config && config.quality ? config.quality : null;
if(config && config.width && config.height) {
canvas = new Kinetic.Canvas(config.width, config.height);
}
else {
canvas = this.getCanvas();
}
return canvas.toDataURL(mimeType, quality);
},
/**
* private draw children

View File

@ -826,25 +826,34 @@ Kinetic.Node = Kinetic.Class.extend({
* level as quality (range 0.0 - 1.0)
* @name toDataURL
* @methodOf Kinetic.Node.prototype
* @param {String} [mimeType]
* @param {Number} [quality]
* @param {Object} config
*/
toDataURL: function(mimeType, quality) {
var bufferCanvas = this.getStage().bufferCanvas;
var bufferContext = bufferCanvas.getContext();
bufferCanvas.clear();
this._draw(bufferCanvas);
return bufferCanvas.toDataURL(mimeType, quality);
toDataURL: function(config) {
var mimeType = config && config.mimeType ? config.mimeType : null;
var quality = config && config.quality ? config.quality : null;
var canvas;
if(config && config.width && config.height) {
canvas = new Kinetic.Canvas(config.width, config.height);
}
else {
canvas = this.getStage().bufferCanvas;
}
var context = canvas.getContext();
canvas.clear();
this._draw(canvas);
return canvas.toDataURL(mimeType, quality);
},
/**
* converts node into an image. Since the toImage
* method is asynchronous, a callback is required
* @name toImage
* @methodOf Kinetic.Stage.prototype
* @param {Object} config
*/
toImage: function(callback) {
Kinetic.Type._getImage(this.toDataURL(), function(img) {
callback(img);
toImage: function(config) {
Kinetic.Type._getImage(this.toDataURL(config), function(img) {
config.callback(img);
});
},
_clearTransform: function() {

View File

@ -283,17 +283,19 @@ Kinetic.Stage = Kinetic.Container.extend({
* the current state of each node
* @name toDataURL
* @methodOf Kinetic.Stage.prototype
* @param {Function} callback
* @param {String} [mimeType]
* @param {Number} [quality]
* @param {Object} config
*/
toDataURL: function(callback, mimeType, quality) {
toDataURL: function(config) {
var mimeType = config && config.mimeType ? config.mimeType : null;
var quality = config && config.quality ? config.quality : null;
/*
* need to create a canvas element rather than using the buffer canvas
* because this method is asynchonous which means that other parts of the
* code could modify the buffer canvas before it's finished
*/
var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
var width = config && config.width ? config.width : this.attrs.width;
var height = config && config.height ? config.height : this.attrs.height;
var canvas = new Kinetic.Canvas(width, height);
var context = canvas.getContext();
var layers = this.children;
@ -308,7 +310,7 @@ Kinetic.Stage = Kinetic.Container.extend({
drawLayer(n + 1);
}
else {
callback(canvas.toDataURL(mimeType, quality));
config.callback(canvas.toDataURL(mimeType, quality));
}
};
imageObj.src = layerUrl;
@ -320,13 +322,15 @@ Kinetic.Stage = Kinetic.Container.extend({
* is asynchronous, a callback function is required
* @name toImage
* @methodOf Kinetic.Stage.prototype
* @param {Function} callback
* @param {Object} config
*/
toImage: function(callback) {
this.toDataURL(function(dataUrl) {
toImage: function(config) {
this.toDataURL({
callback: function(dataUrl) {
Kinetic.Type._getImage(dataUrl, function(img) {
callback(img);
config.callback(img);
});
}
});
},
_resizeDOM: function() {

File diff suppressed because one or more lines are too long

View File

@ -124,7 +124,8 @@ Test.prototype.tests = {
stage.add(layer);
console.log('call toImage')
star.toImage(function(img) {
star.toImage({
callback: function(img) {
startTimer();
for(var n = 0; n < 1000; n++) {
var image = new Kinetic.Image({
@ -140,6 +141,7 @@ Test.prototype.tests = {
layer.draw();
endTimer('draw 1,000 cached stars');
}
});
}
};

View File

@ -1040,9 +1040,11 @@ Test.prototype.tests = {
layer.draw();
}
stage.toDataURL(function(dataUrl) {
stage.toDataURL({
callback: function(dataUrl) {
warn(urls[0] === dataUrl, 'stage data url is incorrect');
})
}
});
warn(urls[0] === layer.toDataURL(), 'layer data url is incorrect');
warn(urls[1] === group.toDataURL(), 'group data url is incorrect');
warn(urls[1] === circle.toDataURL(), 'shape data url is incorrect');
@ -2227,7 +2229,8 @@ Test.prototype.tests = {
};
imageObj.src = '../assets/scorpion-sprite.png';
},
'Node - shape caching': function(containerId) {
'Node - node caching': function(containerId) {
var urls = dataUrls['Node - node caching'];
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -2238,7 +2241,7 @@ Test.prototype.tests = {
var points = [{
x: 73,
y: 192
y: 250
}, {
x: 73,
y: 160
@ -2260,24 +2263,50 @@ Test.prototype.tests = {
points: points,
fill: 'green',
stroke: 'blue',
strokeWidth: 5
strokeWidth: 5,
draggable: true
});
group.add(poly);
layer.add(group);
stage.add(layer);
poly.toImage(function(imageObj) {
poly.toImage({
width: 500,
height: 300,
callback: function(imageObj) {
test(Kinetic.Type._isElement(imageObj), 'shape toImage() should be an image object');
var cachedShape = new Kinetic.Image({
image: imageObj,
draggable: true,
stroke: 'red',
strokeWidth: 5,
x: 50,
y: -120
});
group.toImage(function(imageObj) {
layer.add(cachedShape);
layer.draw();
warn(urls[0] === layer.toDataURL(), 'layer data url is incorrect');
}
});
group.toImage({
callback: function(imageObj) {
test(Kinetic.Type._isElement(imageObj), 'group toImage() should be an image object');
}
});
layer.toImage(function(imageObj) {
layer.toImage({
callback: function(imageObj) {
test(Kinetic.Type._isElement(imageObj), 'layer toImage() should be an image object');
}
});
stage.toImage(function(imageObj) {
stage.toImage({
callback: function(imageObj) {
test(Kinetic.Type._isElement(imageObj), 'stage toImage() should be an image object');
}
});
},
'SHAPE - add polygon': function(containerId) {