Implement Item#_hitTestChildren()

As suggested by @iconexperience in #671
This commit is contained in:
Jürg Lehni 2016-02-09 16:52:55 +01:00
parent bd7f3554d8
commit 740c94e367
2 changed files with 28 additions and 24 deletions

View file

@ -1474,6 +1474,7 @@ new function() { // // Scope to inject various item event handlers
children = this._children, children = this._children,
// Both `insert` and `deep` are true by default: // Both `insert` and `deep` are true by default:
insert = Base.pick(options ? options.insert : undefined, insert = Base.pick(options ? options.insert : undefined,
// Also support boolean parameter for insert, default: true.
options === undefined || options === true), options === undefined || options === true),
deep = Base.pick(options ? options.deep : undefined, true); deep = Base.pick(options ? options.deep : undefined, true);
// On items with children, for performance reasons due to the way that // On items with children, for performance reasons due to the way that
@ -1819,29 +1820,32 @@ new function() { // // Scope to inject various item event handlers
} }
} }
options._viewMatrix = viewMatrix; if (!res) {
options._strokeMatrix = strokeMatrix; options._viewMatrix = viewMatrix;
var children = !res && this._children; options._strokeMatrix = strokeMatrix;
if (children) { res = this._hitTestChildren(point, options)
var opts = this._getChildHitTestOptions(options); || checkSelf && this._hitTestSelf(point, options)
// Loop backwards, so items that get drawn last are tested first || null;
for (var i = children.length - 1; i >= 0 && !res; i--) // Restore viewMatrix for next child, so appended matrix chains are
res = children[i]._hitTest(point, opts); // calculated correctly.
options._viewMatrix = parentViewMatrix;
} }
if (!res && checkSelf)
res = this._hitTestSelf(point, options);
// Transform the point back to the outer coordinate system. // Transform the point back to the outer coordinate system.
if (res && res.point) if (res && res.point)
res.point = matrix.transform(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; return res;
}, },
_getChildHitTestOptions: function(options) { _hitTestChildren: function(point, options) {
// This is overridden in CompoundPath, for treatment of type === 'path'. var children = this._children;
return options; 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) { _hitTestSelf: function(point, options) {

View file

@ -259,14 +259,14 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
return paths.join(' '); return paths.join(' ');
} }
}, /** @lends CompoundPath# */{ }, /** @lends CompoundPath# */{
_getChildHitTestOptions: function(options) { _hitTestChildren: function _hitTestChildren(point, options) {
// If we're not specifically asked to returns paths through return _hitTestChildren.base.call(this, point,
// options.class == Path, do not test children for fill, since a // If we're not specifically asked to returns paths through
// compound path forms one shape. // options.class == Path, do not test children for fill, since a
// Also support legacy format `type: 'path'`. // compound path forms one shape.
return options.class === Path || options.type === 'path' // Also support legacy format `type: 'path'`.
? options options.class === Path || options.type === 'path' ? options
: new Base(options, { fill: false }); : new Base(options, { fill: false }));
}, },
_draw: function(ctx, param, strokeMatrix) { _draw: function(ctx, param, strokeMatrix) {