mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Correctly handle paths with only one segment in hit-testing code.
Closes #430.
This commit is contained in:
parent
dfacc16788
commit
09d0f5f389
4 changed files with 16 additions and 10 deletions
|
@ -1690,7 +1690,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
hitTest: function(point, options) {
|
hitTest: function(point, options) {
|
||||||
point = Point.read(arguments);
|
point = Point.read(arguments);
|
||||||
options = HitResult.getOptions(Base.read(arguments));
|
options = HitResult.getOptions(Base.read(arguments));
|
||||||
if (this._locked || !this._visible || this._guide && !options.guides)
|
if (this._locked || !this._visible || this._guide && !options.guides
|
||||||
|
|| this.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Check if the point is withing roughBounds + tolerance, but only if
|
// Check if the point is withing roughBounds + tolerance, but only if
|
||||||
|
|
|
@ -151,7 +151,7 @@ var Shape = Item.extend(/** @lends Shape# */{
|
||||||
},
|
},
|
||||||
|
|
||||||
isEmpty: function() {
|
isEmpty: function() {
|
||||||
// A shape can never be "empty" in the sense that it does not hold a
|
// A shape can never be "empty" in the sense that it always holds a
|
||||||
// definition. This is required for Group#bounds to work correctly when
|
// definition. This is required for Group#bounds to work correctly when
|
||||||
// containing a Shape.
|
// containing a Shape.
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1747,6 +1747,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
var that = this,
|
var that = this,
|
||||||
style = this.getStyle(),
|
style = this.getStyle(),
|
||||||
segments = this._segments,
|
segments = this._segments,
|
||||||
|
numSegments = segments.length,
|
||||||
closed = this._closed,
|
closed = this._closed,
|
||||||
// transformed tolerance padding, see Item#hitTest. We will add
|
// transformed tolerance padding, see Item#hitTest. We will add
|
||||||
// stroke padding on top if stroke is defined.
|
// stroke padding on top if stroke is defined.
|
||||||
|
@ -1817,7 +1818,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
// to run the hit-test on it.
|
// to run the hit-test on it.
|
||||||
area = new Path({ internal: true, closed: true });
|
area = new Path({ internal: true, closed: true });
|
||||||
if (closed || segment._index > 0
|
if (closed || segment._index > 0
|
||||||
&& segment._index < segments.length - 1) {
|
&& segment._index < numSegments - 1) {
|
||||||
// It's a join. See that it's not a round one (one of
|
// It's a join. See that it's not a round one (one of
|
||||||
// the handles has to be zero too for this!)
|
// the handles has to be zero too for this!)
|
||||||
if (join !== 'round' && (segment._handleIn.isZero()
|
if (join !== 'round' && (segment._handleIn.isZero()
|
||||||
|
@ -1848,22 +1849,25 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
// before stroke or fill.
|
// before stroke or fill.
|
||||||
if (options.ends && !options.segments && !closed) {
|
if (options.ends && !options.segments && !closed) {
|
||||||
if (res = checkSegmentPoints(segments[0], true)
|
if (res = checkSegmentPoints(segments[0], true)
|
||||||
|| checkSegmentPoints(segments[segments.length - 1], true))
|
|| checkSegmentPoints(segments[numSegments - 1], true))
|
||||||
return res;
|
return res;
|
||||||
} else if (options.segments || options.handles) {
|
} else if (options.segments || options.handles) {
|
||||||
for (var i = 0, l = segments.length; i < l; i++)
|
for (var i = 0; i < numSegments; i++)
|
||||||
if (res = checkSegmentPoints(segments[i]))
|
if (res = checkSegmentPoints(segments[i]))
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
// If we're querying for stroke, perform that before fill
|
// If we're querying for stroke, perform that before fill
|
||||||
if (radius != null) {
|
if (radius != null) {
|
||||||
loc = this.getNearestLocation(point);
|
loc = this.getNearestLocation(point);
|
||||||
|
// Note that paths need at least two segments to have an actual
|
||||||
|
// stroke. But we still check for segments with the radius fallback
|
||||||
|
// check if there is only one segment.
|
||||||
if (loc) {
|
if (loc) {
|
||||||
// Now see if we're on a segment, and if so, check for its
|
// Now see if we're on a segment, and if so, check for its
|
||||||
// stroke join / cap first. If not, do a normal radius check
|
// stroke join / cap first. If not, do a normal radius check
|
||||||
// for round strokes.
|
// for round strokes.
|
||||||
var parameter = loc.getParameter();
|
var parameter = loc.getParameter();
|
||||||
if (parameter === 0 || parameter === 1) {
|
if (parameter === 0 || parameter === 1 && numSegments > 1) {
|
||||||
if (!checkSegmentStroke(loc.getSegment()))
|
if (!checkSegmentStroke(loc.getSegment()))
|
||||||
loc = null;
|
loc = null;
|
||||||
} else if (!isCloseEnough(loc.getPoint(), strokePadding)) {
|
} else if (!isCloseEnough(loc.getPoint(), strokePadding)) {
|
||||||
|
@ -1872,8 +1876,8 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
}
|
}
|
||||||
// If we have miter joins, we may not be done yet, since they can be
|
// If we have miter joins, we may not be done yet, since they can be
|
||||||
// longer than the radius. Check for each segment within reach now.
|
// longer than the radius. Check for each segment within reach now.
|
||||||
if (!loc && join === 'miter') {
|
if (!loc && join === 'miter' && numSegments > 1) {
|
||||||
for (var i = 0, l = segments.length; i < l; i++) {
|
for (var i = 0; i < numSegments; i++) {
|
||||||
var segment = segments[i];
|
var segment = segments[i];
|
||||||
if (point.getDistance(segment._point) <= miterLimit
|
if (point.getDistance(segment._point) <= miterLimit
|
||||||
&& checkSegmentStroke(segment)) {
|
&& checkSegmentStroke(segment)) {
|
||||||
|
|
|
@ -387,8 +387,9 @@ var Segment = Base.extend(/** @lends Segment# */{
|
||||||
var path = this._path,
|
var path = this._path,
|
||||||
index = this._index;
|
index = this._index;
|
||||||
if (path) {
|
if (path) {
|
||||||
// The last segment of an open path belongs to the last curve
|
// The last segment of an open path belongs to the last curve.
|
||||||
if (!path._closed && index == path._segments.length - 1)
|
if (index > 0 && !path._closed
|
||||||
|
&& index === path._segments.length - 1)
|
||||||
index--;
|
index--;
|
||||||
return path.getCurves()[index] || null;
|
return path.getCurves()[index] || null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue