now that things are drawn onto arbitrary canvas elements wrapped with the Canvas class, it's now possible to create temp canvases on the fly, which enables correct-size image filtering, and no limits on node caching

This commit is contained in:
Eric Rowell 2012-07-19 23:30:59 -07:00
parent c09742c77c
commit 4b0b3a2a20
6 changed files with 152 additions and 151 deletions

146
dist/kinetic-core.js vendored
View File

@ -3,7 +3,7 @@
* http://www.kineticjs.com/ * http://www.kineticjs.com/
* Copyright 2012, Eric Rowell * Copyright 2012, Eric Rowell
* Licensed under the MIT or GPL Version 2 licenses. * Licensed under the MIT or GPL Version 2 licenses.
* Date: Jul 18 2012 * Date: Jul 19 2012
* *
* Copyright (C) 2011 - 2012 by Eric Rowell * Copyright (C) 2011 - 2012 by Eric Rowell
* *
@ -384,6 +384,22 @@ Kinetic.Canvas.prototype = {
setHeight: function(height) { setHeight: function(height) {
this.element.height = height; this.element.height = height;
}, },
/**
* get width
* @name getWidth
* @methodOf Kinetic.Canvas.prototype
*/
getWidth: function() {
return this.element.width;
},
/**
* get height
* @name getHeight
* @methodOf Kinetic.Canvas.prototype
*/
getHeight: function() {
return this.element.height;
},
/** /**
* set size * set size
* @name setSize * @name setSize
@ -978,31 +994,12 @@ Kinetic.Node = Kinetic.Class.extend({
*/ */
setAbsolutePosition: function() { setAbsolutePosition: function() {
var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments)); var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments));
/* var trans = this._clearTransform();
* save rotation and scale and // don't clear translation
* then remove them from the transform this.attrs.x = trans.x;
*/ this.attrs.y = trans.y;
var rot = this.attrs.rotation; delete trans.x;
var scale = { delete trans.y;
x: this.attrs.scale.x,
y: this.attrs.scale.y
};
var offset = {
x: this.attrs.offset.x,
y: this.attrs.offset.y
};
this.attrs.rotation = 0;
this.attrs.scale = {
x: 1,
y: 1
};
this.attrs.offset = {
x: 0,
y: 0
};
var o = this.getOffset();
// unravel transform // unravel transform
var it = this.getAbsoluteTransform(); var it = this.getAbsoluteTransform();
@ -1015,17 +1012,7 @@ Kinetic.Node = Kinetic.Class.extend({
}; };
this.setPosition(pos.x, pos.y); this.setPosition(pos.x, pos.y);
this._setTransform(trans);
// restore rotation and scale
this.rotate(rot);
this.attrs.scale = {
x: scale.x,
y: scale.y
};
this.attrs.offset = {
x: offset.x,
y: offset.y
};
}, },
/** /**
* move node by an amount * move node by an amount
@ -1391,17 +1378,21 @@ Kinetic.Node = Kinetic.Class.extend({
* @name saveImageData * @name saveImageData
* @methodOf Kinetic.Node.prototype * @methodOf Kinetic.Node.prototype
*/ */
saveImageData: function() { saveImageData: function(width, height) {
try { try {
var canvas;
if(width && height) {
canvas = new Kinetic.Canvas(width, height);
}
else {
var stage = this.getStage(); var stage = this.getStage();
var bufferCanvas = stage.bufferCanvas; canvas = stage.bufferCanvas;
var bufferContext = bufferCanvas.getContext(); }
var width = stage.getWidth();
var height = stage.getHeight();
bufferCanvas.clear(); var context = canvas.getContext();
this._draw(bufferCanvas); canvas.clear();
var imageData = bufferContext.getImageData(0, 0, width, height); this._draw(canvas);
var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
this.imageData = imageData; this.imageData = imageData;
} }
catch(e) { catch(e) {
@ -1459,6 +1450,40 @@ Kinetic.Node = Kinetic.Class.extend({
callback(img); callback(img);
}); });
}, },
_clearTransform: function() {
var trans = {
x: this.attrs.x,
y: this.attrs.y,
rotation: this.attrs.rotation,
scale: {
x: this.attrs.scale.x,
y: this.attrs.scale.y
},
offset: {
x: this.attrs.offset.x,
y: this.attrs.offset.y
}
};
this.attrs.x = 0;
this.attrs.y = 0;
this.attrs.rotation = 0;
this.attrs.scale = {
x: 1,
y: 1
};
this.attrs.offset = {
x: 0,
y: 0
};
return trans;
},
_setTransform: function(trans) {
for(var key in trans) {
this.attrs[key] = trans[key];
}
},
_setImageData: function(imageData) { _setImageData: function(imageData) {
if(imageData && imageData.data) { if(imageData && imageData.data) {
this.imageData = imageData; this.imageData = imageData;
@ -3988,34 +4013,9 @@ Kinetic.Image = Kinetic.Shape.extend({
*/ */
applyFilter: function(config) { applyFilter: function(config) {
try { try {
// save transformation state var trans = this._clearTransform();
var x = this.getX(); this.saveImageData(this.getWidth(), this.getHeight());
var y = this.getY(); this._setTransform(trans);
var rotation = this.getRotation();
var scaleX = this.getScale().x;
var scaleY = this.getScale().y;
var offsetX = this.getOffset().x;
var offsetY = this.getOffset().y;
// reset transformation state
this.attrs.x = 0;
this.attrs.y = 0;
this.attrs.rotation = 0;
this.attrs.scale.x = 1;
this.attrs.scale.y = 1;
this.attrs.offset.x = 0;
this.attrs.offset.y = 0;
this.saveImageData();
// restore transformation state
this.attrs.x = x;
this.attrs.y = y;
this.attrs.rotation = rotation;
this.attrs.scale.x = scaleX;
this.attrs.scale.y = scaleY;
this.attrs.offset.x = offsetX;
this.attrs.offset.y = offsetY;
config.filter.call(this, config); config.filter.call(this, config);
var that = this; var that = this;

File diff suppressed because one or more lines are too long

View File

@ -400,31 +400,12 @@ Kinetic.Node = Kinetic.Class.extend({
*/ */
setAbsolutePosition: function() { setAbsolutePosition: function() {
var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments)); var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments));
/* var trans = this._clearTransform();
* save rotation and scale and // don't clear translation
* then remove them from the transform this.attrs.x = trans.x;
*/ this.attrs.y = trans.y;
var rot = this.attrs.rotation; delete trans.x;
var scale = { delete trans.y;
x: this.attrs.scale.x,
y: this.attrs.scale.y
};
var offset = {
x: this.attrs.offset.x,
y: this.attrs.offset.y
};
this.attrs.rotation = 0;
this.attrs.scale = {
x: 1,
y: 1
};
this.attrs.offset = {
x: 0,
y: 0
};
var o = this.getOffset();
// unravel transform // unravel transform
var it = this.getAbsoluteTransform(); var it = this.getAbsoluteTransform();
@ -437,17 +418,7 @@ Kinetic.Node = Kinetic.Class.extend({
}; };
this.setPosition(pos.x, pos.y); this.setPosition(pos.x, pos.y);
this._setTransform(trans);
// restore rotation and scale
this.rotate(rot);
this.attrs.scale = {
x: scale.x,
y: scale.y
};
this.attrs.offset = {
x: offset.x,
y: offset.y
};
}, },
/** /**
* move node by an amount * move node by an amount
@ -813,17 +784,21 @@ Kinetic.Node = Kinetic.Class.extend({
* @name saveImageData * @name saveImageData
* @methodOf Kinetic.Node.prototype * @methodOf Kinetic.Node.prototype
*/ */
saveImageData: function() { saveImageData: function(width, height) {
try { try {
var canvas;
if(width && height) {
canvas = new Kinetic.Canvas(width, height);
}
else {
var stage = this.getStage(); var stage = this.getStage();
var bufferCanvas = stage.bufferCanvas; canvas = stage.bufferCanvas;
var bufferContext = bufferCanvas.getContext(); }
var width = stage.getWidth();
var height = stage.getHeight();
bufferCanvas.clear(); var context = canvas.getContext();
this._draw(bufferCanvas); canvas.clear();
var imageData = bufferContext.getImageData(0, 0, width, height); this._draw(canvas);
var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
this.imageData = imageData; this.imageData = imageData;
} }
catch(e) { catch(e) {
@ -881,6 +856,40 @@ Kinetic.Node = Kinetic.Class.extend({
callback(img); callback(img);
}); });
}, },
_clearTransform: function() {
var trans = {
x: this.attrs.x,
y: this.attrs.y,
rotation: this.attrs.rotation,
scale: {
x: this.attrs.scale.x,
y: this.attrs.scale.y
},
offset: {
x: this.attrs.offset.x,
y: this.attrs.offset.y
}
};
this.attrs.x = 0;
this.attrs.y = 0;
this.attrs.rotation = 0;
this.attrs.scale = {
x: 1,
y: 1
};
this.attrs.offset = {
x: 0,
y: 0
};
return trans;
},
_setTransform: function(trans) {
for(var key in trans) {
this.attrs[key] = trans[key];
}
},
_setImageData: function(imageData) { _setImageData: function(imageData) {
if(imageData && imageData.data) { if(imageData && imageData.data) {
this.imageData = imageData; this.imageData = imageData;

View File

@ -106,34 +106,9 @@ Kinetic.Image = Kinetic.Shape.extend({
*/ */
applyFilter: function(config) { applyFilter: function(config) {
try { try {
// save transformation state var trans = this._clearTransform();
var x = this.getX(); this.saveImageData(this.getWidth(), this.getHeight());
var y = this.getY(); this._setTransform(trans);
var rotation = this.getRotation();
var scaleX = this.getScale().x;
var scaleY = this.getScale().y;
var offsetX = this.getOffset().x;
var offsetY = this.getOffset().y;
// reset transformation state
this.attrs.x = 0;
this.attrs.y = 0;
this.attrs.rotation = 0;
this.attrs.scale.x = 1;
this.attrs.scale.y = 1;
this.attrs.offset.x = 0;
this.attrs.offset.y = 0;
this.saveImageData();
// restore transformation state
this.attrs.x = x;
this.attrs.y = y;
this.attrs.rotation = rotation;
this.attrs.scale.x = scaleX;
this.attrs.scale.y = scaleY;
this.attrs.offset.x = offsetX;
this.attrs.offset.y = offsetY;
config.filter.call(this, config); config.filter.call(this, config);
var that = this; var that = this;

View File

@ -59,6 +59,22 @@ Kinetic.Canvas.prototype = {
setHeight: function(height) { setHeight: function(height) {
this.element.height = height; this.element.height = height;
}, },
/**
* get width
* @name getWidth
* @methodOf Kinetic.Canvas.prototype
*/
getWidth: function() {
return this.element.width;
},
/**
* get height
* @name getHeight
* @methodOf Kinetic.Canvas.prototype
*/
getHeight: function() {
return this.element.height;
},
/** /**
* set size * set size
* @name setSize * @name setSize

View File

@ -2004,7 +2004,8 @@ Test.prototype.tests = {
x: 10, x: 10,
y: 10, y: 10,
image: imageObj, image: imageObj,
draggable: true draggable: true,
stroke: 'blue'
}); });
layer.add(darth); layer.add(darth);