mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Implement option.type filtering in #hitTest() functions.
This commit is contained in:
parent
2896f14e43
commit
afe00add32
5 changed files with 44 additions and 50 deletions
|
@ -108,7 +108,8 @@ var HitResult = Base.extend(/** @lends HitResult# */{
|
|||
// Use _merged property to not repeatetly merge using new Base in
|
||||
// recursion.
|
||||
return options && options._merged ? options : new Base({
|
||||
// Type of item, for instanceof check: PathItem, TexItem, etc
|
||||
// Type of item, for instanceof check: 'group', 'layer', 'path',
|
||||
// 'compound-path', 'shape','raster', 'placed-symbol', ...
|
||||
type: null,
|
||||
// Tolerance
|
||||
tolerance: paper.project.options.hitTolerance || 2,
|
||||
|
|
|
@ -292,8 +292,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
/**
|
||||
* The type of the item as a string.
|
||||
*
|
||||
* @type String('group', 'layer', 'path', 'compound-path', 'raster',
|
||||
* 'placed-symbol', 'point-text')
|
||||
* @type String('group', 'layer', 'path', 'compound-path', 'shape',
|
||||
* 'raster', 'placed-symbol', 'point-text')
|
||||
* @bean
|
||||
*/
|
||||
getType: function() {
|
||||
|
@ -1532,7 +1532,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
* in points. Can also be controlled through
|
||||
* {@link Project#options}{@code .hitTolerance}.
|
||||
* <b>options.type:</b> Only hit test again a certain item
|
||||
* type: {@link PathItem}, {@link Raster}, {@link TextItem}, etc.
|
||||
* type: {String('group', 'layer', 'path', 'compound-path', 'shape',
|
||||
* 'raster', 'placed-symbol', 'point-text')}, etc.
|
||||
* <b>options.fill:</b> {@code Boolean} – hit test the fill of items.
|
||||
* <b>options.stroke:</b> {@code Boolean} – hit test the curves of path
|
||||
* items, taking into account stroke width.
|
||||
|
@ -1574,9 +1575,13 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
// Transform point to local coordinates but use untransformed point
|
||||
// for bounds check above.
|
||||
point = this._matrix._inverseTransform(point);
|
||||
|
||||
var that = this,
|
||||
// Filter for type, guides and selected items if that's required.
|
||||
var checkSelf = !(options.guides && !this._guide
|
||||
|| options.selected && !this._selected
|
||||
|| options.type && this._type !== options.type),
|
||||
that = this,
|
||||
res;
|
||||
|
||||
function checkBounds(type, part) {
|
||||
var pt = bounds['get' + part]();
|
||||
// TODO: We need to transform the point back to the coordinate
|
||||
|
@ -1586,9 +1591,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
{ name: Base.hyphenate(part), point: pt });
|
||||
}
|
||||
|
||||
if ((options.center || options.bounds) &&
|
||||
// Ignore top level layers:
|
||||
!(this instanceof Layer && !this._parent)) {
|
||||
// Ignore top level layers by checking for _parent:
|
||||
if (checkSelf && (options.center || options.bounds) && this._parent) {
|
||||
// Don't get the transformed bounds, check against transformed
|
||||
// points instead
|
||||
var bounds = this._getBounds('getBounds');
|
||||
|
@ -1605,30 +1609,29 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Support option.type even for things like CompoundPath where
|
||||
// children are matched but the parent is returned.
|
||||
|
||||
// Filter for guides or selected items if that's required
|
||||
if ((res || (res = this._children || !(options.guides && !this._guide
|
||||
|| options.selected && !this._selected)
|
||||
? this._hitTest(point, options) : null))
|
||||
&& res.point) {
|
||||
// Transform the point back to the outer coordinate system.
|
||||
res.point = that._matrix.transform(res.point);
|
||||
var children = !res && this._children;
|
||||
if (children) {
|
||||
var opts = this._getChildHitTestOptions(options);
|
||||
// Loop backwards, so items that get drawn last are tested first
|
||||
for (var i = children.length - 1; i >= 0 && !res; i--)
|
||||
res = children[i].hitTest(point, opts);
|
||||
}
|
||||
if (!res && checkSelf)
|
||||
res = this._hitTest(point, options);
|
||||
// Transform the point back to the outer coordinate system.
|
||||
if (res && res.point)
|
||||
res.point = that._matrix.transform(res.point);
|
||||
return res;
|
||||
},
|
||||
|
||||
_getChildHitTestOptions: function(options) {
|
||||
return options;
|
||||
},
|
||||
|
||||
_hitTest: function(point, options) {
|
||||
var children = this._children;
|
||||
if (children) {
|
||||
// Loop backwards, so items that get drawn last are tested first
|
||||
for (var i = children.length - 1, res; i >= 0; i--)
|
||||
if (res = children[i].hitTest(point, options))
|
||||
return res;
|
||||
} else if (options.fill && this.hasFill() && this._contains(point)) {
|
||||
// The default implementation honly handles 'fill' through #_contains()
|
||||
if (options.fill && this.hasFill() && this._contains(point))
|
||||
return new HitResult('fill', this);
|
||||
}
|
||||
},
|
||||
|
||||
// DOCS: Item#matches
|
||||
|
|
|
@ -121,12 +121,12 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
|
|||
},
|
||||
|
||||
_hitTest: function(point, options, matrix) {
|
||||
var result = this._symbol._definition._hitTest(point, options, matrix);
|
||||
var res = this._symbol._definition._hitTest(point, options, matrix);
|
||||
// TODO: When the symbol's definition is a path, should hitResult
|
||||
// contain information like HitResult#curve?
|
||||
if (result)
|
||||
result.item = this;
|
||||
return result;
|
||||
if (res)
|
||||
res.item = this;
|
||||
return res;
|
||||
},
|
||||
|
||||
_draw: function(ctx, param) {
|
||||
|
|
|
@ -244,24 +244,13 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
|
|||
return winding;
|
||||
},
|
||||
|
||||
_hitTest : function _hitTest(point, options) {
|
||||
// Do not test children for fill, since a compound path forms one shape.
|
||||
// options.compoundChildren allows to specifically do so, see below.
|
||||
var res = _hitTest.base.call(this, point,
|
||||
new Base(options, { fill: false }));
|
||||
if (!res) {
|
||||
// If asked to query all children seperately, perform the same loop
|
||||
// as Item#hitTest() now on the compound children.
|
||||
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 (options.fill && this.hasFill()
|
||||
&& this._contains(point)) {
|
||||
res = new HitResult('fill', this);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
_getChildHitTestOptions: function(options) {
|
||||
// If we're not specifically asked to returns paths through
|
||||
// options.type == 'path' do not test children for fill, since a
|
||||
// compound path forms one shape.
|
||||
return options.type === 'path'
|
||||
? options
|
||||
: new Base(options, { fill: false });
|
||||
},
|
||||
|
||||
_draw: function(ctx, param) {
|
||||
|
|
|
@ -263,7 +263,8 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
|
|||
* in points, can also be controlled through
|
||||
* {@link Project#options}{@code .hitTolerance}.
|
||||
* <b>options.type:</b> Only hit test again a certain item
|
||||
* type: {@link PathItem}, {@link Raster}, {@link TextItem}, etc.
|
||||
* type: {String('group', 'layer', 'path', 'compound-path', 'shape',
|
||||
* 'raster', 'placed-symbol', 'point-text')}, etc.
|
||||
* <b>options.fill:</b> {@code Boolean} – hit test the fill of items.
|
||||
* <b>options.stroke:</b> {@code Boolean} – hit test the curves of path
|
||||
* items, taking into account stroke width.
|
||||
|
|
Loading…
Reference in a new issue