From 0ae232e4abf40947755907590080afb3e595db96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Tue, 9 Feb 2016 17:02:03 +0100 Subject: [PATCH] Implement support for clip-masks in hit-testing. Closes #671 --- src/item/Group.js | 6 ++++++ src/item/Item.js | 6 ++++-- test/tests/HitResult.js | 32 +++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/item/Group.js b/src/item/Group.js index 650b0ef6..3e05198f 100644 --- a/src/item/Group.js +++ b/src/item/Group.js @@ -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(); diff --git a/src/item/Item.js b/src/item/Item.js index 688fcbde..1c92b8b6 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -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; } diff --git a/test/tests/HitResult.js b/test/tests/HitResult.js index c5b30709..5dd1c86e 100644 --- a/test/tests/HitResult.js +++ b/test/tests/HitResult.js @@ -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});