Implement CompoundPath#contains() and #hitTest() correctly.

And change the way that styles are stored on CompoundPaths: Not in the first child but in the item itself.
This commit is contained in:
Jürg Lehni 2012-10-22 18:48:51 -04:00
parent f73717a7e7
commit f6f80e4061
2 changed files with 27 additions and 7 deletions

View file

@ -89,23 +89,39 @@ var CompoundPath = this.CompoundPath = PathItem.extend(/** @lends CompoundPath#
return this._children.length == 0; return this._children.length == 0;
}, },
contains: function(point) {
point = Point.read(arguments);
var count = 0;
for (var i = 0, l = this._children.length; i < l; i++) {
if (this._children[i].contains(point))
count++;
}
return (count & 1) == 1;
},
_hitTest: function(point, options) {
return this.base(point, Base.merge(options, { fill: false }))
|| options.fill && this._style._fillColor && this.contains(point)
? new HitResult('fill', this)
: null;
},
draw: function(ctx, param) { draw: function(ctx, param) {
var children = this._children; var children = this._children,
style = this._style;
// Return early if the compound path doesn't have any children: // Return early if the compound path doesn't have any children:
if (children.length == 0) if (children.length == 0)
return; return;
var firstChild = children[0],
style = firstChild._style;
ctx.beginPath(); ctx.beginPath();
param.compound = true; param.compound = true;
for (var i = 0, l = children.length; i < l; i++) for (var i = 0, l = children.length; i < l; i++)
Item.draw(children[i], ctx, param); Item.draw(children[i], ctx, param);
firstChild._setStyles(ctx); param.compound = false;
this._setStyles(ctx);
if (style._fillColor) if (style._fillColor)
ctx.fill(); ctx.fill();
if (style._strokeColor) if (style._strokeColor)
ctx.stroke(); ctx.stroke();
param.compound = false;
} }
}, new function() { // Injection scope for PostScript-like drawing functions }, new function() { // Injection scope for PostScript-like drawing functions
/** /**

View file

@ -36,6 +36,10 @@ var Style = Item.extend({
}, this); }, this);
}, },
_getChildren: function() {
return this._item instanceof Group && this._item._children;
},
statics: { statics: {
create: function(item) { create: function(item) {
var style = new this(this.dont); var style = new this(this.dont);
@ -69,7 +73,7 @@ var Style = Item.extend({
// Simply extend src with these getters and setters, to be // Simply extend src with these getters and setters, to be
// injected into this class using this.base() further down. // injected into this class using this.base() further down.
src[set] = function(value) { src[set] = function(value) {
var children = this._item && this._item._children; var children = this._getChildren();
// Clone color objects since they reference their owner // Clone color objects since they reference their owner
value = isColor ? Color.read(arguments, 0, 0, true) : value; value = isColor ? Color.read(arguments, 0, 0, true) : value;
if (children) { if (children) {
@ -97,7 +101,7 @@ var Style = Item.extend({
return this; return this;
}; };
src[get] = function() { src[get] = function() {
var children = this._item && this._item._children, var children = this._getChildren(),
style; style;
// If this item has children, walk through all of them and // If this item has children, walk through all of them and
// see if they all have the same style. // see if they all have the same style.