aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/DragManager.ts
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-05-12 02:59:48 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-05-12 02:59:48 -0400
commit5c4865247b4aca883d39950a15c172ae0431a74e (patch)
tree2df3975ca721403c828d172a7650948f6ee12600 /src/client/util/DragManager.ts
parentf1473fc5bf7f2b3109be358ae14d28725240284c (diff)
added snapping for fixedAspect br/tl drag handles.
Diffstat (limited to 'src/client/util/DragManager.ts')
-rw-r--r--src/client/util/DragManager.ts45
1 files changed, 38 insertions, 7 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 1ee4c57a2..d1d7f2a8a 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -255,9 +255,42 @@ export namespace DragManager {
export function SetSnapLines(horizLines: number[], vertLines: number[]) {
SnappingManager.setSnapLines(horizLines, vertLines);
}
+ export function snapDragAspect(dragPt: number[], snapAspect: number) {
+ let closest = NumCast(Doc.UserDoc()["constants-snapThreshold"], 10);
+ let near = dragPt;
+ const intersect = (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, dragx: number, dragy: number) => {
+ if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) return undefined; // Check if none of the lines are of length 0
+ const denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
+ if (denominator === 0) return undefined; // Lines are parallel
+ let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
+ // let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator;
+ //if (ua < 0 || ua > 1 || ub < 0 || ub > 1) return undefined; // is the intersection along the segments
+
+ // Return a object with the x and y coordinates of the intersection
+ let x = x1 + ua * (x2 - x1)
+ let y = y1 + ua * (y2 - y1)
+ const dist = Math.sqrt((dragx - x) * (dragx - x) + (dragy - y) * (dragy - y));
+ return { pt: [x, y], dist }
+ }
+ SnappingManager.vertSnapLines().forEach((xCoord, i) => {
+ const pt = intersect(dragPt[0], dragPt[1], dragPt[0] + snapAspect, dragPt[1] + 1, xCoord, -1, xCoord, 1, dragPt[0], dragPt[1]);
+ if (pt && pt.dist < closest) {
+ closest = pt.dist;
+ near = pt.pt;
+ }
+ });
+ SnappingManager.horizSnapLines().forEach((yCoord, i) => {
+ const pt = intersect(dragPt[0], dragPt[1], dragPt[0] + snapAspect, dragPt[1] + 1, -1, yCoord, 1, yCoord, dragPt[0], dragPt[1]);
+ if (pt && pt.dist < closest) {
+ closest = pt.dist;
+ near = pt.pt;
+ }
+ });
+ return { thisX: near[0], thisY: near[1] };
+ }
// snap to the active snap lines - if oneAxis is set (eg, for maintaining aspect ratios), then it only snaps to the nearest horizontal/vertical line
- export function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number, oneAxis: boolean = false) {
+ export function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number) {
const snapThreshold = NumCast(Doc.UserDoc()["constants-snapThreshold"], 10);
const snapVal = (pts: number[], drag: number, snapLines: number[]) => {
if (snapLines.length) {
@@ -266,15 +299,13 @@ export namespace DragManager {
const closestPts = rangePts.map(pt => snapLines.reduce((nearest, curr) => Math.abs(nearest - pt) > Math.abs(curr - pt) ? curr : nearest));
const closestDists = rangePts.map((pt, i) => Math.abs(pt - closestPts[i]));
const minIndex = closestDists[0] < closestDists[1] && closestDists[0] < closestDists[2] ? 0 : closestDists[1] < closestDists[2] ? 1 : 2;
- return closestDists[minIndex] < snapThreshold ? [closestDists[minIndex], closestPts[minIndex] + offs[minIndex]] : [Number.MAX_VALUE, drag];
+ return closestDists[minIndex] < snapThreshold ? closestPts[minIndex] + offs[minIndex] : drag;
}
- return [Number.MAX_VALUE, drag];
+ return drag;
};
- const xsnap = snapVal([xFromLeft, xFromRight], e.pageX, SnappingManager.vertSnapLines());
- const ysnap = snapVal([yFromTop, yFromBottom], e.pageY, SnappingManager.horizSnapLines());
return {
- thisX: !oneAxis || xsnap[0] < ysnap[0] ? xsnap[1] : e.pageX,
- thisY: !oneAxis || xsnap[0] > ysnap[0] ? ysnap[1] : e.pageY
+ thisX: snapVal([xFromLeft, xFromRight], e.pageX, SnappingManager.vertSnapLines()),
+ thisY: snapVal([yFromTop, yFromBottom], e.pageY, SnappingManager.horizSnapLines())
};
}
export let docsBeingDragged: Doc[] = [];