Improve handling of SymbolItem in#hitTestAll()

Closes #1199
This commit is contained in:
Jürg Lehni 2017-01-01 18:32:45 +01:00
parent fa4502dfe3
commit e24402542a

View file

@ -1739,20 +1739,14 @@ new function() { // Injection scope for hit-test functions shared with project
function hitTestAll(/* point, options */) { function hitTestAll(/* point, options */) {
var point = Point.read(arguments), var point = Point.read(arguments),
options = HitResult.getOptions(arguments), options = HitResult.getOptions(arguments),
callback = options.match, all = [];
results = []; this._hitTest(point, Base.set({ all: all }, options));
options = Base.set({}, options, { return all;
match: function(hit) {
if (!callback || callback(hit))
results.push(hit);
}
});
this._hitTest(point, options);
return results;
} }
function hitTestChildren(point, options, viewMatrix, _exclude) { function hitTestChildren(point, options, viewMatrix, _exclude) {
// NOTE: _exclude is only used in Group#_hitTestChildren() // NOTE: _exclude is only used in Group#_hitTestChildren()
// to exclude #clipItem
var children = this._children; var children = this._children;
if (children) { if (children) {
// Loop backwards, so items that get drawn last are tested first. // Loop backwards, so items that get drawn last are tested first.
@ -1760,7 +1754,9 @@ new function() { // Injection scope for hit-test functions shared with project
var child = children[i]; var child = children[i];
var res = child !== _exclude && child._hitTest(point, options, var res = child !== _exclude && child._hitTest(point, options,
viewMatrix); viewMatrix);
if (res) // Only return the found result if we're not asked to collect
// all matches through hitTestAll()
if (res && !options.all)
return res; return res;
} }
} }
@ -1888,13 +1884,18 @@ new function() { // Injection scope for hit-test functions shared with project
// class-names. // class-names.
|| options.type && options.type !== Base.hyphenate(this._class) || options.type && options.type !== Base.hyphenate(this._class)
|| options.class && !(this instanceof options.class)), || options.class && !(this instanceof options.class)),
callback = options.match, match = options.match,
that = this, that = this,
bounds, bounds,
res; res;
function match(hit) { function filter(hit) {
return !callback || hit && callback(hit) ? hit : null; if (hit && match && !match(hit))
hit = null;
// If we're collecting all matches, add it to options.all
if (hit && options.all)
options.all.push(hit);
return hit;
} }
function checkBounds(type, part) { function checkBounds(type, part) {
@ -1925,15 +1926,15 @@ new function() { // Injection scope for hit-test functions shared with project
res = checkBounds('bounds', points[i]); res = checkBounds('bounds', points[i]);
} }
} }
res = match(res); res = filter(res);
} }
if (!res) { if (!res) {
res = this._hitTestChildren(point, options, viewMatrix) res = this._hitTestChildren(point, options, viewMatrix)
// NOTE: We don't call callback on _hitTestChildren() // NOTE: We don't call match on _hitTestChildren() because
// because that's already called internally. // it is already called internally.
|| checkSelf || checkSelf
&& match(this._hitTestSelf(point, options, viewMatrix, && filter(this._hitTestSelf(point, options, viewMatrix,
strokeMatrix)) strokeMatrix))
|| null; || null;
} }