mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-04 03:45:58 -05:00
Improve stroke hit-testing.
This commit is contained in:
parent
eb32bad57e
commit
1cab9aad90
1 changed files with 24 additions and 25 deletions
|
@ -1642,8 +1642,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
_hitTest: function(point, options) {
|
_hitTest: function(point, options) {
|
||||||
var style = this.getStyle(),
|
var style = this.getStyle(),
|
||||||
tolerance = options.tolerance || 0,
|
tolerance = options.tolerance || 0,
|
||||||
radius = (options.stroke && style.getStrokeColor()
|
strokeRadius = options.stroke && style.getStrokeColor()
|
||||||
? style.getStrokeWidth() / 2 : 0) + tolerance,
|
? style.getStrokeWidth() / 2 : 0,
|
||||||
|
radius = strokeRadius + tolerance,
|
||||||
that = this,
|
that = this,
|
||||||
loc,
|
loc,
|
||||||
res;
|
res;
|
||||||
|
@ -1692,8 +1693,6 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
point.x, point.y, roots);
|
point.x, point.y, roots);
|
||||||
previous = curve;
|
previous = curve;
|
||||||
}
|
}
|
||||||
crossings += Curve._getCrossings(last, previous,
|
|
||||||
point.x, point.y, roots);
|
|
||||||
return (crossings & 1) === 1;
|
return (crossings & 1) === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1716,27 +1715,32 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
var join = style.getStrokeJoin(),
|
var join = style.getStrokeJoin(),
|
||||||
cap = style.getStrokeCap(),
|
cap = style.getStrokeCap(),
|
||||||
param = loc.getParameter();
|
param = loc.getParameter();
|
||||||
if (join !== 'round' || cap !== 'round'
|
// Handle joins / caps that are not round specificelly, by
|
||||||
|
// hit-testing their polygon areas.
|
||||||
|
if ((join !== 'round' || cap !== 'round')
|
||||||
&& (param === 0 || param === 1)) {
|
&& (param === 0 || param === 1)) {
|
||||||
var segments = this._segments,
|
var segment = loc.getSegment();
|
||||||
segment = loc.getSegment(),
|
|
||||||
strokeRadius = style.getStrokeWidth() / 2;
|
|
||||||
if (this._closed || segment._index > 0
|
if (this._closed || segment._index > 0
|
||||||
&& segment._index < segments.length - 1) {
|
&& segment._index < this._segments.length - 1) {
|
||||||
// It's a join
|
// It's a join. See that it's not a round one (one of
|
||||||
Path._addSquareJoin(segment, join, strokeRadius,
|
// the handles has to be zero too for this!)
|
||||||
style.getMiterLimit() * strokeRadius,
|
if (join !== 'round' && (segment._handleIn.isZero()
|
||||||
addAreaPoint, true);
|
|| segment._handleOut.isZero()))
|
||||||
} else {
|
Path._addSquareJoin(segment, join, strokeRadius,
|
||||||
|
style.getMiterLimit(), addAreaPoint, true);
|
||||||
|
} else if (cap !== 'round') {
|
||||||
// It's a cap
|
// It's a cap
|
||||||
Path._addSquareCap(segment, cap, param, strokeRadius,
|
Path._addSquareCap(segment, cap, param, strokeRadius,
|
||||||
addAreaPoint, true);
|
addAreaPoint, true);
|
||||||
}
|
}
|
||||||
if (!isInArea(point))
|
// See if the above produced an area to check for
|
||||||
|
if (area.length > 0 && !isInArea(point))
|
||||||
loc = null;
|
loc = null;
|
||||||
} else if (loc._distance > radius) {
|
|
||||||
loc = null;
|
|
||||||
}
|
}
|
||||||
|
// Fallback scenario is a round join / cap, but make sure we
|
||||||
|
// didn't check for areas already.
|
||||||
|
if (loc && !area.length && loc._distance > radius)
|
||||||
|
loc = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Don't process loc yet, as we also need to query for stroke after fill
|
// Don't process loc yet, as we also need to query for stroke after fill
|
||||||
|
@ -2408,12 +2412,7 @@ statics: {
|
||||||
bounds = Path.getBounds(segments, closed, style, matrix, padding),
|
bounds = Path.getBounds(segments, closed, style, matrix, padding),
|
||||||
join = style.getStrokeJoin(),
|
join = style.getStrokeJoin(),
|
||||||
cap = style.getStrokeCap(),
|
cap = style.getStrokeCap(),
|
||||||
miterLimit;
|
miterLimit = style.getMiterLimit();
|
||||||
if (join == 'miter' && length > 1) {
|
|
||||||
// miter is relative to stroke width. Divide it by 2 since we're
|
|
||||||
// measuring half the distance below
|
|
||||||
miterLimit = style.getMiterLimit() * radius;
|
|
||||||
}
|
|
||||||
// Create a rectangle of padding size, used for union with bounds
|
// Create a rectangle of padding size, used for union with bounds
|
||||||
// further down
|
// further down
|
||||||
var joinBounds = new Rectangle(new Size(padding).multiply(2));
|
var joinBounds = new Rectangle(new Size(padding).multiply(2));
|
||||||
|
@ -2483,7 +2482,7 @@ statics: {
|
||||||
), true);
|
), true);
|
||||||
// See if we actually get a bevel point and if its distance is below
|
// See if we actually get a bevel point and if its distance is below
|
||||||
// the miterLimit. If not, make a normal bevel.
|
// the miterLimit. If not, make a normal bevel.
|
||||||
if (corner && point.getDistance(corner) <= miterLimit) {
|
if (corner && point.getDistance(corner) <= radius * miterLimit) {
|
||||||
addPoint(corner);
|
addPoint(corner);
|
||||||
if (!area)
|
if (!area)
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue