From 304ecbc3bef46f84598f1fbbdc49e01653a292f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Fri, 18 Oct 2013 15:40:41 +0200 Subject: [PATCH] Define compoundChildren hitTest option to get matching children instead of parent. --- src/path/CompoundPath.js | 31 +++++++++++++++---------------- src/path/Path.js | 3 ++- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/path/CompoundPath.js b/src/path/CompoundPath.js index c1a2f291..89e6383d 100644 --- a/src/path/CompoundPath.js +++ b/src/path/CompoundPath.js @@ -205,34 +205,33 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{ children[i]._draw(ctx, param); var res = ctx.isPointInPath(point.x, point.y, this.getWindingRule()); CanvasProvider.release(ctx); - return res && children; -/*#*/ } // options.nativeContains - + return res; +/*#*/ } else { // !options.nativeContains // Compound paths are a little complex: In order to determine whether a // point is inside a path or not due to the winding rule, we need to // check all the children and count how many intersect. If it's an odd // number, the point is inside the path. Once we know it's inside the // path, _hitTest also needs access to the first intersecting element, // for the HitResult, so we return it here. - var total = 0, - first = null, - evenOdd = this.getWindingRule() === 'evenodd'; - for (var i = 0, l = this._children.length; i < l; i++) { - var child = this._children[i], - winding = child._getWinding(point); - total += winding; - if (!first && (evenOdd ? winding & 1 : winding)) - first = child; - } - return (evenOdd ? total & 1 : total) && first; + var children = this._children, + winding = 0; + for (var i = 0, l = children.length; i < l; i++) + winding += children[i]._getWinding(point); + return !!(this.getWindingRule() === 'evenodd' ? winding & 1 : winding); +/*#*/ } // !options.nativeContains }, _hitTest: function _hitTest(point, options) { var res = _hitTest.base.call(this, point, Base.merge(options, { fill: false })); if (!res && options.fill && this.hasFill()) { - res = this._contains(point); - res = res ? new HitResult('fill', res) : null; + if (options.compoundChildren) { + var children = this._children; + for (var i = children.length - 1; i >= 0 && !res; i--) + res = children[i]._hitTest(point, options); + } else if (this._contains(point)) { + res = new HitResult('fill', this); + } } return res; }, diff --git a/src/path/Path.js b/src/path/Path.js index dd72b725..8dd7eb61 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -1735,9 +1735,10 @@ var Path = PathItem.extend(/** @lends Path# */{ var res = ctx.isPointInPath(point.x, point.y, this.getWindingRule()); CanvasProvider.release(ctx); return res; -/*#*/ } // options.nativeContains +/*#*/ } else { // !options.nativeContains var winding = this._getWinding(point); return !!(this.getWindingRule() == 'evenodd' ? winding & 1 : winding); +/*#*/ } // !options.nativeContains }, _hitTest: function(point, options) {