aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLauren <victor_kalev@brown.edu>2021-10-26 15:51:02 -0400
committerLauren <victor_kalev@brown.edu>2021-10-26 15:51:02 -0400
commit2155d39fbc4a9bac3945e40ee10f95f41df466d3 (patch)
tree03c8688e46a79ab6f685e0dc136533fa1719e5d6 /src
parentbf896f7f7c287c9a78cca91d7ceab88f66613b61 (diff)
refactoring snapping slightly
Diffstat (limited to 'src')
-rw-r--r--src/client/views/InkStrokeProperties.ts74
1 files changed, 48 insertions, 26 deletions
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index ba85b851c..712459125 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -1,6 +1,7 @@
import { Bezier } from "bezier-js";
import { action, computed, observable, reaction } from "mobx";
import { Doc } from "../../fields/Doc";
+import { DocumentView } from "./nodes/DocumentView";
import { Document } from "../../fields/documentSchemas";
import { InkData, InkField, InkTool, PointData } from "../../fields/InkField";
import { List } from "../../fields/List";
@@ -232,43 +233,64 @@ export class InkStrokeProperties {
return { distance, nearestT, nearestSeg, nearestPt };
}
- /**
- * Handles the movement/scaling of a control point.
- */
snapControl = (inkDoc: Doc, controlIndex: number) => {
const ink = Cast(inkDoc.data, InkField)?.inkData;
- if (ink) {
- const closed = InkingStroke.IsClosed(ink);
-
- // figure out which segments we don't want to snap to - avoid the dragged control point's segment and the next and prev segments (when they exist -- ie not for endpoints of unclosed curve)
- const thisseg = Math.floor(controlIndex / 4) * 4;
- const which = controlIndex % 4;
- const nextseg = which > 1 && (closed || controlIndex < ink.length - 1) ? (thisseg + 4) % ink.length : -1;
- const prevseg = which < 2 && (closed || controlIndex > 0) ? (thisseg - 4 + ink.length) % ink.length : -1;
- const refPt = ink[controlIndex];
- const { nearestPt } = InkStrokeProperties.nearestPtToStroke(ink, refPt, [thisseg, prevseg, nextseg]);
-
- // nearestPt is in inkDoc coordinates -- we need to compute the distance in screen coordinates.
- // so we scale the X & Y distances by the internal ink scale factor and then transform the final distance by the ScreenToLocal.Scale of the inkDoc itself.
- const oldXrange = (xs => ({ coord: NumCast(inkDoc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X));
- const oldYrange = (ys => ({ coord: NumCast(inkDoc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y));
- const ptsXscale = ((NumCast(inkDoc._width) - NumCast(inkDoc.strokeWidth)) / ((oldXrange.max - oldXrange.min) || 1)) || 1;
- const ptsYscale = ((NumCast(inkDoc._height) - NumCast(inkDoc.strokeWidth)) / ((oldYrange.max - oldYrange.min) || 1)) || 1;
- const near = Math.sqrt((nearestPt.X - refPt.X) * (nearestPt.X - refPt.X) * ptsXscale * ptsXscale +
- (nearestPt.Y - refPt.Y) * (nearestPt.Y - refPt.Y) * ptsYscale * ptsYscale);
+ if (ink) {
+ const { near, nearestPt, ptsXscale, ptsYscale } = this.snapWithinCurve(ink, inkDoc, controlIndex);
if (near / (this.selectedInk?.lastElement().props.ScreenToLocalTransform().Scale || 1) < 10) {
- return this.moveControlPtHandle((nearestPt.X - ink[controlIndex].X) * ptsXscale, (nearestPt.Y - ink[controlIndex].Y) * ptsYscale, controlIndex);
+ const deltaX = (nearestPt.X - ink[controlIndex].X) * ptsXscale;
+ const deltaY = (nearestPt.Y - ink[controlIndex].Y) * ptsYscale;
+ return this.moveControlPtHandle(deltaX, deltaY, controlIndex);
} else {
- return
+ return this.snapBetweenCurves(ink, inkDoc, controlIndex);
}
}
return false;
}
- // snapControlBetweenCurves = (ink, controlIndex) => {
+ snapWithinCurve = (ink: InkData, inkDoc: Doc, controlIndex: number) => {
+ const closed = InkingStroke.IsClosed(ink);
+
+ // figure out which segments we don't want to snap to - avoid the dragged control point's segment and the next and prev segments (when they exist -- ie not for endpoints of unclosed curve)
+ const thisseg = Math.floor(controlIndex / 4) * 4;
+ const which = controlIndex % 4;
+ const nextseg = which > 1 && (closed || controlIndex < ink.length - 1) ? (thisseg + 4) % ink.length : -1;
+ const prevseg = which < 2 && (closed || controlIndex > 0) ? (thisseg - 4 + ink.length) % ink.length : -1;
+ const refPt = ink[controlIndex];
+ const { nearestPt } = InkStrokeProperties.nearestPtToStroke(ink, refPt, [thisseg, prevseg, nextseg]);
+
+ // nearestPt is in inkDoc coordinates -- we need to compute the distance in screen coordinates.
+ // so we scale the X & Y distances by the internal ink scale factor and then transform the final distance by the ScreenToLocal.Scale of the inkDoc itself.
+ const { ptsXscale, ptsYscale } = this.inkToScreenScale(ink, inkDoc);
+ const near = Math.sqrt((nearestPt.X - refPt.X) * (nearestPt.X - refPt.X) * ptsXscale * ptsXscale +
+ (nearestPt.Y - refPt.Y) * (nearestPt.Y - refPt.Y) * ptsYscale * ptsYscale);
+
+ return { near, nearestPt, ptsXscale, ptsYscale };
+ }
+
+ snapBetweenCurves = (ink: InkData, inkDoc: Doc, controlIndex: number) => {
+ const inkContext = Cast(inkDoc.context, Doc, null);
+ // Cast(inkContext.data)
- // }
+ // .filter(doc => doc.type === DocumentType.INK)
+ // .map(doc => {
+ // if (InkStrokeProperties.Instance?._lock) {
+ // Doc.SetNativeHeight(doc, NumCast(doc._height));
+ // Doc.SetNativeWidth(doc, NumCast(doc._width));
+ // }
+ // return ({ doc, x: NumCast(doc.x), y: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) });
+ // });
+ return false;
+ }
+
+ inkToScreenScale = (ink: InkData, inkDoc: Doc) => {
+ const oldXrange = (xs => ({ coord: NumCast(inkDoc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X));
+ const oldYrange = (ys => ({ coord: NumCast(inkDoc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y));
+ const ptsXscale = ((NumCast(inkDoc._width) - NumCast(inkDoc.strokeWidth)) / ((oldXrange.max - oldXrange.min) || 1)) || 1;
+ const ptsYscale = ((NumCast(inkDoc._height) - NumCast(inkDoc.strokeWidth)) / ((oldYrange.max - oldYrange.min) || 1)) || 1;
+ return { ptsXscale, ptsYscale };
+ }
/**
* Snaps a control point with broken tangency back to synced rotation.