2017-10-18 14:08:03 -04:00
|
|
|
import paper from '@scratch/paper';
|
2017-10-24 13:21:57 -04:00
|
|
|
import {getItems} from './selection';
|
2017-10-18 14:08:03 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {paper.Point} point1 point 1
|
|
|
|
* @param {paper.Point} point2 point 2
|
|
|
|
* @param {number} tolerance Distance allowed between points that are "touching"
|
|
|
|
* @return {boolean} true if points are within the tolerance distance.
|
|
|
|
*/
|
|
|
|
const touching = function (point1, point2, tolerance) {
|
|
|
|
return point1.getDistance(point2, true) < Math.pow(tolerance / paper.view.zoom, 2);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {!paper.Point} point Point to check line endpoint hits against
|
|
|
|
* @param {!number} tolerance Distance within which it counts as a hit
|
|
|
|
* @param {?paper.Path} excludePath Path to exclude from hit test, if any. For instance, you
|
|
|
|
* are drawing a line and don't want it to snap to its own start point.
|
|
|
|
* @return {object} data about the end point of an unclosed path, if any such point is within the
|
|
|
|
* tolerance distance of the given point, or null if none exists.
|
|
|
|
*/
|
|
|
|
const endPointHit = function (point, tolerance, excludePath) {
|
2017-10-24 13:21:57 -04:00
|
|
|
const lines = getItems({
|
2017-10-18 14:08:03 -04:00
|
|
|
class: paper.Path
|
|
|
|
});
|
|
|
|
// Prefer more recent lines
|
|
|
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
|
|
if (lines[i].closed) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!(lines[i].parent instanceof paper.Layer)) {
|
|
|
|
// Don't connect to lines inside of groups
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (excludePath && lines[i] === excludePath) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (lines[i].firstSegment && touching(lines[i].firstSegment.point, point, tolerance)) {
|
|
|
|
return {
|
|
|
|
path: lines[i],
|
|
|
|
segment: lines[i].firstSegment,
|
|
|
|
isFirst: true
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (lines[i].lastSegment && touching(lines[i].lastSegment.point, point, tolerance)) {
|
|
|
|
return {
|
|
|
|
path: lines[i],
|
|
|
|
segment: lines[i].lastSegment,
|
|
|
|
isFirst: false
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
export {
|
|
|
|
endPointHit,
|
|
|
|
touching
|
|
|
|
};
|