mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
parent
1ac8e46d55
commit
4351ca310f
1 changed files with 31 additions and 26 deletions
|
@ -309,14 +309,20 @@ new function() { // Scope for _contains() and _hitTestSelf() code.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the length of the ellipse radius that passes through the point
|
function isOnEllipseStroke(point, radius, padding, quadrant) {
|
||||||
function getEllipseRadius(point, radius) {
|
// Translate the ellipse / circle to the unit circle with radius 1, and
|
||||||
var angle = point.getAngleInRadians(),
|
// translate the point along by dividing with radius (a number for
|
||||||
width = radius.width * 2,
|
// circle, a size for ellipse). Then subtract the radius with the same
|
||||||
height = radius.height * 2,
|
// direction as point (vector.normalize()), to get a vector that
|
||||||
x = width * Math.sin(angle),
|
// describe proximity and direction to the stroke. Translate this back
|
||||||
y = height * Math.cos(angle);
|
// by multiplying with radius, then divide by strokePadding to get a new
|
||||||
return width * height / (2 * Math.sqrt(x * x + y * y));
|
// vector in stroke space, and finally check its length.
|
||||||
|
var vector = point.divide(radius);
|
||||||
|
// We also have to check the vector's quadrant in case we're matching
|
||||||
|
// quarter ellipses in the corners.
|
||||||
|
return (!quadrant || vector.quadrant === quadrant) &&
|
||||||
|
vector.subtract(vector.normalize()).multiply(radius)
|
||||||
|
.divide(padding).length <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return /** @lends Shape# */{
|
return /** @lends Shape# */{
|
||||||
|
@ -335,36 +341,35 @@ new function() { // Scope for _contains() and _hitTestSelf() code.
|
||||||
},
|
},
|
||||||
|
|
||||||
_hitTestSelf: function _hitTestSelf(point, options) {
|
_hitTestSelf: function _hitTestSelf(point, options) {
|
||||||
var hit = false;
|
var hit = false,
|
||||||
// TODO: Correctly support strokeScaling here too!
|
style = this._style;
|
||||||
if (this.hasStroke()) {
|
if (style.hasStroke()) {
|
||||||
var type = this._type,
|
var type = this._type,
|
||||||
radius = this._radius,
|
radius = this._radius,
|
||||||
strokeWidth = this.getStrokeWidth() + 2 * options.tolerance;
|
strokeWidth = style.getStrokeWidth(),
|
||||||
|
strokePadding = options._tolerancePadding.add(
|
||||||
|
Path._getStrokePadding(strokeWidth / 2,
|
||||||
|
!style.getStrokeScaling() &&
|
||||||
|
options._strokeMatrix));
|
||||||
if (type === 'rectangle') {
|
if (type === 'rectangle') {
|
||||||
var center = getCornerCenter(this, point, strokeWidth);
|
var padding = strokePadding.multiply(2),
|
||||||
|
center = getCornerCenter(this, point, padding);
|
||||||
if (center) {
|
if (center) {
|
||||||
// Check the stroke of the quarter corner ellipse,
|
// Check the stroke of the quarter corner ellipse:
|
||||||
// similar to the ellipse check further down:
|
hit = isOnEllipseStroke(point.subtract(center), radius,
|
||||||
var pt = point.subtract(center);
|
strokePadding, center.getQuadrant());
|
||||||
hit = 2 * Math.abs(pt.getLength()
|
|
||||||
- getEllipseRadius(pt, radius)) <= strokeWidth;
|
|
||||||
} else {
|
} else {
|
||||||
var rect = new Rectangle(this._size).setCenter(0, 0),
|
var rect = new Rectangle(this._size).setCenter(0, 0),
|
||||||
outer = rect.expand(strokeWidth),
|
outer = rect.expand(padding),
|
||||||
inner = rect.expand(-strokeWidth);
|
inner = rect.expand(padding.negate());
|
||||||
hit = outer._containsPoint(point)
|
hit = outer._containsPoint(point)
|
||||||
&& !inner._containsPoint(point);
|
&& !inner._containsPoint(point);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (type === 'ellipse')
|
hit = isOnEllipseStroke(point, radius, strokePadding);
|
||||||
radius = getEllipseRadius(point, radius);
|
|
||||||
hit = 2 * Math.abs(point.getLength() - radius)
|
|
||||||
<= strokeWidth;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hit
|
return hit ? new HitResult('stroke', this)
|
||||||
? new HitResult('stroke', this)
|
|
||||||
: _hitTestSelf.base.apply(this, arguments);
|
: _hitTestSelf.base.apply(this, arguments);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue