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