diff options
author | bobzel <zzzman@gmail.com> | 2021-10-26 23:26:49 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2021-10-26 23:26:49 -0400 |
commit | 67ad73e9acc56d5b0951711b05426289c60a06c1 (patch) | |
tree | 773e439dd8ea4fe7383d851399217509ed2b9db8 /src | |
parent | 3e23fb9b9c8e82485c0744193629f82550e09e7e (diff) |
simplified snapping
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/InkStrokeProperties.ts | 52 | ||||
-rw-r--r-- | src/client/views/InkingStroke.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 |
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 { |