Implement support for clip-masks in hit-testing.

Closes #671
This commit is contained in:
Jürg Lehni 2016-02-09 17:02:03 +01:00
parent 740c94e367
commit 0ae232e4ab
3 changed files with 41 additions and 3 deletions

View file

@ -167,6 +167,12 @@ var Group = Item.extend(/** @lends Group# */{
child.setClipMask(clipped);
},
_hitTestChildren: function _hitTestChildren(point, options) {
var clipItem = this._getClipItem();
return (!clipItem || clipItem.contains(point))
&& _hitTestChildren.base.call(this, point, options, clipItem);
},
_draw: function(ctx, param) {
var clip = param.clip,
clipItem = !clip && this._getClipItem();

View file

@ -1836,12 +1836,14 @@ new function() { // // Scope to inject various item event handlers
return res;
},
_hitTestChildren: function(point, options) {
_hitTestChildren: function(point, options, _exclude) {
// NOTE: _exclude is only used in Group#_hitTestChildren()
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);
var child = children[i];
var res = child !== _exclude && child._hitTest(point, options);
if (res)
return res;
}

View file

@ -684,7 +684,7 @@ test('hit-testing compound-paths', function() {
var result = paper.project.hitTest(center, {
fill: true
});
return result === null ;
return result === null;
}, true);
// When asking specifically for paths, she should get the top-most path in
// the center (the one that cuts out the hole)
@ -697,5 +697,35 @@ test('hit-testing compound-paths', function() {
}, true);
});
test('hit-testing clipped items', function() {
var rect = new Path.Rectangle({
point: [50, 150],
size: [100, 50],
fillColor: 'red'
});
var circle = new Path.Circle({
center: [100, 200],
radius: 20,
fillColor: 'green'
});
var group = new Group({
children: [rect, circle]
});
group.clipped = true;
var point1 = new Point(100, 190);
var point2 = new Point(100, 210);
equals(function() {
var result = paper.project.hitTest(point1);
return result && result.item === circle;
}, true);
equals(function() {
var result = paper.project.hitTest(point2);
return result === null;
}, true);
});
// TODO: project.hitTest(point, {type: AnItemType});