Implement Item#_contains() with local coordinates, and have Item#contains() take Item#matrix into account.

This commit is contained in:
Jürg Lehni 2013-04-21 08:43:05 -07:00
parent 13276b7134
commit 2fc4ff10ee
5 changed files with 17 additions and 14 deletions

View file

@ -1277,8 +1277,7 @@ var Item = this.Item = Base.extend(Callback, {
},
/**
* Checks wether the item's geometry contains the given point in local
* coordinates.
* Checks wether the item's geometry contains the given point.
*
* @example {@paperscript} // Click within and outside the star below
* // Create a star shaped path:
@ -1302,10 +1301,15 @@ var Item = this.Item = Base.extend(Callback, {
* }
* }
*
* @param {Point} point The point to check in local coordinates
* @param {Point} point The point to check for.
*/
contains: function(point) {
point = Point.read(arguments);
// See CompoundPath#_contains() for the reason for !!
return !!this._contains(
this._matrix._inverseTransform(Point.read(arguments)));
},
_contains: function(point) {
if (this._children) {
for (var i = this._children.length - 1; i >= 0; i--) {
if (this._children[i].contains(point))

View file

@ -523,7 +523,7 @@ var Raster = this.Raster = Item.extend(/** @lends Raster# */{
},
_hitTest: function(point, options) {
if (this.contains(point)) {
if (this._contains(point)) {
var that = this;
return new HitResult('pixel', that, {
offset: point.add(that._size.divide(2)).round(),

View file

@ -66,8 +66,7 @@ var Shape = this.Shape = Item.extend(/** @lends Shape# */{
}
},
contains: function(point) {
point = Point.read(arguments);
_contains: function(point) {
switch (this._type) {
case 'rect':
return this.base(point);

View file

@ -163,6 +163,9 @@ var CompoundPath = this.CompoundPath = PathItem.extend(/** @lends CompoundPath#
/**
* A private method to help with both #contains() and #_hitTest().
* Instead of simply returning a boolean, it returns a children of all the
* children that contain the point. This is required by _hitTest(), and
* Item#contains() is prepared for such a result.
*/
_contains: function(point) {
// Compound paths are a little complex: In order to determine wether a
@ -180,10 +183,6 @@ var CompoundPath = this.CompoundPath = PathItem.extend(/** @lends CompoundPath#
return (children.length & 1) == 1 && children;
},
contains: function(point) {
return !!this._contains(Point.read(arguments));
},
_hitTest: function(point, options) {
var res = this.base(point, Base.merge(options, { fill: false }));
if (!res && options.fill && this._style.getFillColor()) {

View file

@ -1604,13 +1604,14 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
&& this._parent._style.getFillColor());
},
contains: function(point) {
point = Point.read(arguments);
_contains: function(point) {
// If the path is not closed, we should not bail out in case it has a
// fill color!
var hasFill = this.hasFill();
if (!this._closed && !hasFill
|| !this.getRoughBounds()._containsPoint(point))
// We need to call the internal _getBounds, to get non-
// transformed bounds.
|| !this._getBounds('getRoughBounds')._containsPoint(point))
return false;
// Note: This only works correctly with even-odd fill rule, or paths
// that do not overlap with themselves.