Improve handling of nested matrices in hit-testing.

Closes #134.
This commit is contained in:
Jürg Lehni 2012-11-23 12:41:00 -08:00
parent 450c8fc1df
commit 906faf7956
4 changed files with 10 additions and 9 deletions

View file

@ -106,10 +106,9 @@ HitResult = Base.extend(/** @lends HitResult# */{
* *
* @private * @private
*/ */
getOptions: function(point, options) { getOptions: function(options) {
// Use _merged property to not repeatetly call merge in recursion. // Use _merged property to not repeatetly call merge in recursion.
return options && options._merged ? options : Base.merge({ return options && options._merged ? options : Base.merge({
point: Point.read([point]),
// Type of item, for instanceof check: PathItem, TexItem, etc // Type of item, for instanceof check: PathItem, TexItem, etc
type: null, type: null,
// Tolerance // Tolerance

View file

@ -1062,16 +1062,17 @@ function(name) {
* hit. * hit.
*/ */
hitTest: function(point, options) { hitTest: function(point, options) {
options = HitResult.getOptions(point, options); point = Point.read(arguments);
options = HitResult.getOptions(Base.readValue(arguments));
// Check if the point is withing roughBounds + tolerance, but only if // Check if the point is withing roughBounds + tolerance, but only if
// this item does not have children, since we'd have to travel up the // this item does not have children, since we'd have to travel up the
// chain already to determine the rough bounds. // chain already to determine the rough bounds.
if (!this._children && !this.getRoughBounds() if (!this._children && !this.getRoughBounds()
.expand(options.tolerance)._containsPoint(options.point)) .expand(options.tolerance)._containsPoint(point))
return null; return null;
// Transform point to local coordinates but use untransformed point // Transform point to local coordinates but use untransformed point
// for bounds check above. // for bounds check above.
point = options.point = this._matrix._inverseTransform(options.point); point = this._matrix._inverseTransform(point);
if ((options.center || options.bounds) && if ((options.center || options.bounds) &&
// Ignore top level layers: // Ignore top level layers:
!(this instanceof Layer && !this._parent)) { !(this instanceof Layer && !this._parent)) {

View file

@ -28,8 +28,7 @@ var PlacedItem = this.PlacedItem = Item.extend(/** @lends PlacedItem# */{
_boundsType: { bounds: 'strokeBounds' }, _boundsType: { bounds: 'strokeBounds' },
_hitTest: function(point, options, matrix) { _hitTest: function(point, options, matrix) {
var hitResult = this._symbol._definition.hitTest( var hitResult = this._symbol._definition._hitTest(point, options, matrix);
this.matrix._transformPoint(point), options, matrix);
// TODO: When the symbol's definition is a path, should hitResult contain // TODO: When the symbol's definition is a path, should hitResult contain
// information like HitResult#curve? // information like HitResult#curve?
if (hitResult) if (hitResult)

View file

@ -223,8 +223,10 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
* hit. * hit.
*/ */
hitTest: function(point, options) { hitTest: function(point, options) {
options = HitResult.getOptions(point, options); // We don't need to do this here, but it speeds up things since we won't
point = options.point; // repeatetly convert in Item#hitTest() then.
point = Point.read(arguments);
options = HitResult.getOptions(Base.readValue(arguments));
// Loop backwards, so layers that get drawn last are tested first // Loop backwards, so layers that get drawn last are tested first
for (var i = this.layers.length - 1; i >= 0; i--) { for (var i = this.layers.length - 1; i >= 0; i--) {
var res = this.layers[i].hitTest(point, options); var res = this.layers[i].hitTest(point, options);