Skip to content

Commit

Permalink
Implement Item#_hitTestChildren()
Browse files Browse the repository at this point in the history
As suggested by @iconexperience in paperjs#671
  • Loading branch information
lehni committed Feb 9, 2016
1 parent bd7f355 commit 740c94e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
36 changes: 20 additions & 16 deletions src/item/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,7 @@ new function() { // // Scope to inject various item event handlers
children = this._children,
// Both `insert` and `deep` are true by default:
insert = Base.pick(options ? options.insert : undefined,
// Also support boolean parameter for insert, default: true.
options === undefined || options === true),
deep = Base.pick(options ? options.deep : undefined, true);
// On items with children, for performance reasons due to the way that
Expand Down Expand Up @@ -1819,29 +1820,32 @@ new function() { // // Scope to inject various item event handlers
}
}

options._viewMatrix = viewMatrix;
options._strokeMatrix = strokeMatrix;
var children = !res && this._children;
if (children) {
var opts = this._getChildHitTestOptions(options);
// Loop backwards, so items that get drawn last are tested first
for (var i = children.length - 1; i >= 0 && !res; i--)
res = children[i]._hitTest(point, opts);
if (!res) {
options._viewMatrix = viewMatrix;
options._strokeMatrix = strokeMatrix;
res = this._hitTestChildren(point, options)
|| checkSelf && this._hitTestSelf(point, options)
|| null;
// Restore viewMatrix for next child, so appended matrix chains are
// calculated correctly.
options._viewMatrix = parentViewMatrix;
}
if (!res && checkSelf)
res = this._hitTestSelf(point, options);
// Transform the point back to the outer coordinate system.
if (res && res.point)
res.point = matrix.transform(res.point);
// Restore viewMatrix for next child, so appended matrix chains are
// calculated correctly.
options._viewMatrix = parentViewMatrix;
return res;
},

_getChildHitTestOptions: function(options) {
// This is overridden in CompoundPath, for treatment of type === 'path'.
return options;
_hitTestChildren: function(point, options) {
var children = this._children;
if (children) {
// Loop backwards, so items that get drawn last are tested first
for (var i = children.length - 1; i >= 0; i--) {
var res = children[i]._hitTest(point, options);
if (res)
return res;
}
}
},

_hitTestSelf: function(point, options) {
Expand Down
16 changes: 8 additions & 8 deletions src/path/CompoundPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,14 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
return paths.join(' ');
}
}, /** @lends CompoundPath# */{
_getChildHitTestOptions: function(options) {
// If we're not specifically asked to returns paths through
// options.class == Path, do not test children for fill, since a
// compound path forms one shape.
// Also support legacy format `type: 'path'`.
return options.class === Path || options.type === 'path'
? options
: new Base(options, { fill: false });
_hitTestChildren: function _hitTestChildren(point, options) {
return _hitTestChildren.base.call(this, point,
// If we're not specifically asked to returns paths through
// options.class == Path, do not test children for fill, since a
// compound path forms one shape.
// Also support legacy format `type: 'path'`.
options.class === Path || options.type === 'path' ? options
: new Base(options, { fill: false }));
},

_draw: function(ctx, param, strokeMatrix) {
Expand Down

0 comments on commit 740c94e

Please sign in to comment.