pixel detection performance was horrible for large amounts of shapes. Added some optimizations which require knowledge of a shape's perceivable position and size based on transforms. This will be added in later. For the time being, only Kinetic.Images will have access to the detectionType property. Image cannot be transformed or offset with the center offset. Support for these will come soon as well.

This commit is contained in:
Eric Rowell 2012-04-01 17:18:01 -07:00
parent 313c6a1541
commit 72c0555d0b
4 changed files with 67 additions and 23 deletions

31
dist/kinetic-core.js vendored
View File

@ -2108,21 +2108,40 @@ Kinetic.Shape.prototype = {
return pathLayerContext.isPointInPath(pos.x, pos.y);
}
else {
var ax = this.getAbsolutePosition().x;
var ay = this.getAbsolutePosition().y;
var aw = this.getWidth();
var ah = this.getHeight();
/*
* TODO: need to also take into account absolute
* rotation, absolute scale, and center offsets
* to calculate the correct aw, ah, ax, and ay values. Also need
* to implement getHeight and getWidth methods for each Shape
* object
*/
// only check pixels if it's possibly in range
if(pos.x >= ax && pos.x <= (ax + aw) && pos.y >= ay && pos.y <= ay + ah) {
var bufferLayer = stage.bufferLayer;
var bufferLayerContext = bufferLayer.getContext();
this._draw(bufferLayer);
var w = stage.width;
var h = stage.height;
var x = pos.x;
var y = pos.y;
var imageData = bufferLayerContext.getImageData(0, 0, w, h);
var px = pos.x - ax;
var py = pos.y - ay;
// only get the image data for possible area
var imageData = bufferLayerContext.getImageData(ax, ay, aw, ah);
var data = imageData.data;
var alpha = data[((w * y) + x) * 4 + 3];
var alpha = data[((aw * py) + px) * 4 + 3];
return (alpha !== undefined && alpha !== 0);
}
else {
return false;
}
}
}
};
// extend Node

File diff suppressed because one or more lines are too long

View File

@ -192,21 +192,40 @@ Kinetic.Shape.prototype = {
return pathLayerContext.isPointInPath(pos.x, pos.y);
}
else {
var ax = this.getAbsolutePosition().x;
var ay = this.getAbsolutePosition().y;
var aw = this.getWidth();
var ah = this.getHeight();
/*
* TODO: need to also take into account absolute
* rotation, absolute scale, and center offsets
* to calculate the correct aw, ah, ax, and ay values. Also need
* to implement getHeight and getWidth methods for each Shape
* object
*/
// only check pixels if it's possibly in range
if(pos.x >= ax && pos.x <= (ax + aw) && pos.y >= ay && pos.y <= ay + ah) {
var bufferLayer = stage.bufferLayer;
var bufferLayerContext = bufferLayer.getContext();
this._draw(bufferLayer);
var w = stage.width;
var h = stage.height;
var x = pos.x;
var y = pos.y;
var imageData = bufferLayerContext.getImageData(0, 0, w, h);
var px = pos.x - ax;
var py = pos.y - ay;
// only get the image data for possible area
var imageData = bufferLayerContext.getImageData(ax, ay, aw, ah);
var data = imageData.data;
var alpha = data[((w * y) + x) * 4 + 3];
var alpha = data[((aw * py) + px) * 4 + 3];
return (alpha !== undefined && alpha !== 0);
}
else {
return false;
}
}
}
};
// extend Node

View File

@ -553,6 +553,11 @@ Test.prototype.tests = {
};
imageObj.src = '../lion.png';
},
/*
* TODO: need to implement area x, y, width and height
* in order to support other shape pixel detection
*/
/*
'EVENTS - star pixel detection': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
@ -591,6 +596,7 @@ Test.prototype.tests = {
};
imageObj.src = '../lion.png';
},
*/
'EVENTS - drag events click': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,