aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-10-26 23:26:49 -0400
committerbobzel <zzzman@gmail.com>2021-10-26 23:26:49 -0400
commit67ad73e9acc56d5b0951711b05426289c60a06c1 (patch)
tree773e439dd8ea4fe7383d851399217509ed2b9db8 /src
parent3e23fb9b9c8e82485c0744193629f82550e09e7e (diff)
simplified snapping
Diffstat (limited to 'src')
-rw-r--r--src/client/views/InkStrokeProperties.ts52
-rw-r--r--src/client/views/InkingStroke.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
3 files changed, 23 insertions, 35 deletions
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 4ecedbfd6..2048b9a19 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -242,19 +242,20 @@ export class InkStrokeProperties {
const ink = Cast(inkDoc[Doc.LayoutFieldKey(inkDoc)], InkField)?.inkData;
if (ink) {
- const snapData = this.snapWithinCurve(ink, inkView, controlIndex);
- if (snapData && snapData.distance < 10) {
- const deltaX = (snapData.nearestPt.X - ink[controlIndex].X);
- const deltaY = (snapData.nearestPt.Y - ink[controlIndex].Y);
- return this.moveControlPtHandle(inkView, deltaX, deltaY, controlIndex);
- } else {
- return this.snapBetweenCurves(ink, inkView, controlIndex);
+ const screenDragPt = inkView.ComponentView?.ptToScreen?.(ink[controlIndex]);
+ if (screenDragPt) {
+ var snapData = this.snapToAllCurves(screenDragPt, inkView, { nearestPt: { X: 0, Y: 0 }, distance: 10 }, ink, controlIndex);
+ if (snapData.distance < 10) {
+ const deltaX = (snapData.nearestPt.X - ink[controlIndex].X);
+ const deltaY = (snapData.nearestPt.Y - ink[controlIndex].Y);
+ return this.moveControlPtHandle(inkView, deltaX, deltaY, controlIndex);
+ }
}
}
return false;
}
- snapWithinCurve = (ink: InkData, inkView: DocumentView, controlIndex: number) => {
+ excludeSelfSnapSegs = (ink: InkData, 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)
@@ -262,38 +263,25 @@ export class InkStrokeProperties {
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 screenDragPt = inkView.ComponentView?.ptToScreen?.(ink[controlIndex]);
- if (screenDragPt) {
- const { nearestPt, distance } = InkStrokeProperties.nearestPtToStroke(ink, ink[controlIndex], [thisseg, prevseg, nextseg]);
- return {
- nearestPt,
- distance: distance * inkView.props.ScreenToLocalTransform().inverse().Scale
- };
- }
+ return [thisseg, prevseg, nextseg];
}
- snapBetweenCurves = (ink: InkData, inkView: DocumentView, controlIndex: number) => {
- const screenDragPt = inkView.ComponentView?.ptToScreen?.(ink[controlIndex]);
+ snapToAllCurves = (screenDragPt: { X: number, Y: number }, inkView: DocumentView, snapData: { nearestPt: { X: number, Y: number }, distance: number }, ink: InkData, controlIndex: number) => {
const containingCollection = inkView.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
- screenDragPt && containingCollection?.childDocs
- .filter(doc => doc.type === DocumentType.INK && doc !== inkView.rootDoc)
+ containingCollection?.childDocs
+ .filter(doc => doc.type === DocumentType.INK)
.forEach(doc => {
const testInkView = DocumentManager.Instance.getDocumentView(doc, containingCollection?.props.CollectionView);
- const snapped = testInkView?.ComponentView?.snapPt?.(screenDragPt);
- if (snapped) {
- const { nearestPt, distance } = snapped;
- if (distance < 10 /* refactor out snapping threshold and test that this is closer than any other curve */) {
- const snappedScrPt = testInkView?.ComponentView?.ptToScreen?.(nearestPt); // convert from snapped ink coordinate system to dragged ink coordinate system by converting to/from screen space
- const snappedInkPt = snappedScrPt && inkView.ComponentView?.ptFromScreen?.(snappedScrPt);
- if (snappedInkPt) {
- const deltaX = (snappedInkPt.X - ink[controlIndex].X);
- const deltaY = (snappedInkPt.Y - ink[controlIndex].Y);
- return this.moveControlPtHandle(inkView, deltaX, deltaY, controlIndex);
- }
+ const snapped = testInkView?.ComponentView?.snapPt?.(screenDragPt, doc === inkView.rootDoc ? this.excludeSelfSnapSegs(ink, controlIndex) : []);
+ if (snapped && snapped.distance < snapData.distance) {
+ const snappedScrPt = testInkView?.ComponentView?.ptToScreen?.(snapped.nearestPt); // convert from snapped ink coordinate system to dragged ink coordinate system by converting to/from screen space
+ const snappedInkPt = snappedScrPt && inkView.ComponentView?.ptFromScreen?.(snappedScrPt);
+ if (snappedInkPt) {
+ snapData = { nearestPt: snappedInkPt, distance: snapped.distance };
}
}
});
- return false;
+ return snapData;
}
/**
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index b258ea741..81a888256 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -143,10 +143,10 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
return { X: scrPt[0], Y: scrPt[1] };
}
- snapPt = (scrPt: { X: number, Y: number }) => {
+ snapPt = (scrPt: { X: number, Y: number }, excludeSegs?: number[]) => {
const { inkData } = this.inkScaledData();
const inkPt = this.ptFromScreen(scrPt);
- const { nearestPt, distance } = InkStrokeProperties.nearestPtToStroke(inkData, inkPt, []);
+ const { nearestPt, distance } = InkStrokeProperties.nearestPtToStroke(inkData, inkPt, excludeSegs ?? []);
return { nearestPt, distance: distance * this.props.ScreenToLocalTransform().inverse().Scale };
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d7d886667..c9b246c10 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -100,7 +100,7 @@ export interface DocComponentView {
getCenter?: (xf: Transform) => { X: number, Y: number };
ptToScreen?: (pt: { X: number, Y: number }) => { X: number, Y: number };
ptFromScreen?: (pt: { X: number, Y: number }) => { X: number, Y: number };
- snapPt?: (pt: { X: number, Y: number }) => { nearestPt: { X: number, Y: number }, distance: number };
+ snapPt?: (pt: { X: number, Y: number }, excludeSegs?: number[]) => { nearestPt: { X: number, Y: number }, distance: number };
search?: (str: string, bwd?: boolean, clear?: boolean) => boolean;
}
export interface DocumentViewSharedProps {