aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreleanor-park <eleanor_park@brown.edu>2024-03-12 16:26:00 -0400
committereleanor-park <eleanor_park@brown.edu>2024-03-12 16:26:00 -0400
commit33cb02498a330ede6a90e67bdaf0ff56aed21819 (patch)
treeaa324048de5907bc6712917cd4b72a0b07cdd1a0 /src
parent2279f029ce19c9f7f886a6966ea5f23be9468890 (diff)
i have an error
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx181
1 files changed, 171 insertions, 10 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e4c71a086..70b21309e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,3 +1,4 @@
+import { findSegment } from '@turf/turf';
import { Bezier } from 'bezier-js';
import { Colors } from 'browndash-components';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
@@ -739,7 +740,25 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// create a new curve by appending all curves of the current segment together in order to render a single new stroke.
if (!e.shiftKey) {
this._eraserLock++;
- const segments = this.segmentInkStroke(intersect.inkView, intersect.t);
+ const segments = this.segmentInkStroke(intersect.inkView, intersect.t); // intersect.t is where the eraser intersected the ink stroke - want to remove the segment that starts at the intersection just before this t value and goes to the one just after it
+ // we delete the original ink stroke, then create new strokes for each of the remaining segments
+ // we do this through the hack of calling the stroke Gesture code as if the strokes had just be drawn by hand
+ // [[(0,0), (3,7), (9,4), (4,5)],[(4,5), (13,17), (19,14), (14,15)], [(23,19),(...}]]
+ // [[(0,0), (3,7), (9,4), (4,5), (13,17), (19,14), (14,15)], [(23,19),(...}]]
+ // segments.map(segment => segment.map(pt => pt))
+ // segments[0][3].x === segments[1][0].x
+
+ // 3 == "3" true
+ // 3 === "3" falsen !==
+
+ // for (var i = 0; i < segments.length; i ++) {
+ // if (segments[i][0].points.lastElement().x === segments[i+1][0].points.lastElement().x && segments[i][0].points.lastElement().y === segments[i+1][0].points.lastElement().y) {
+ // segments[i][0].points.pop();
+ // segments[i][0].points = segments[i][0].points.concat(segments[i+1][0].points);
+ // segments.splice(i+1, 1);
+ // }
+ // i++;
+ // }
segments.forEach(segment =>
this.forceStrokeGesture(
e,
@@ -750,7 +769,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
setTimeout(() => this._eraserLock--);
}
// Lower ink opacity to give the user a visual indicator of deletion.
- intersect.inkView.layoutDoc.opacity = 0.5;
+ intersect.inkView.layoutDoc.opacity = 0.0;
intersect.inkView.layoutDoc.dontIntersect = true;
}
});
@@ -796,12 +815,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
)
.reduce(
(intersections, { inkStroke, inkView }) => {
- const { inkData } = inkStroke.inkScaledData();
+ const { inkData } = inkStroke.inkScaledData(); // get bezier curve as set of control points
// Convert from screen space to ink space for the intersection.
const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint);
const currPointInkSpace = inkStroke.ptFromScreen(currPoint);
for (var i = 0; i < inkData.length - 3; i += 4) {
+ // iterate over each segment of bezier curve
const rawIntersects = InkField.Segment(inkData, i).intersects({
+ // segment's are indexed by 0, 4, 8,
// compute all unique intersections
p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y },
p2: { x: currPointInkSpace.X, y: currPointInkSpace.Y },
@@ -825,9 +846,106 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
*/
@action
segmentInkStroke = (ink: DocumentView, excludeT: number): Segment[] => {
+ // const segments: Segment[] = [];
+ // var segment: Segment = [];
+ // var segment2: Segment = [];
+ // var startSegmentT = 0;
+ // const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData();
+ // This iterates through all segments of the curve and splits them where they intersect another curve.
+ // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted)
+
+ // var hasSplit = false;
+ // var continueErasing = false;
+ // for (var i = 0; i < inkData.length - 3; i += 4) {
+ // const inkSegment: Bezier = InkField.Segment(inkData, i);
+ // const tVals: number[] = this.getInkIntersections(i, ink, inkSegment).sort();
+ // console.log("TVALS", tVals);
+ // if (tVals.length) {
+ // if ((!hasSplit) && ((excludeT <= tVals[0]) ||
+ // (excludeT > tVals[0] && excludeT < tVals.lastElement()) || continueErasing)) {
+
+ // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
+ // if (closestTs[0] != -1 && closestTs[1] != -1) {
+ // segment1.push(inkSegment.split(0, closestTs[0]));
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // } else if (closestTs[0] == -1) {
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // continueErasing = !continueErasing;
+ // } else {
+ // segment1.push(inkSegment.split(0, closestTs[0]));
+ // continueErasing = !continueErasing;
+ // }
+ // if (!continueErasing) {
+ // hasSplit = true;
+ // }
+ // // segment1 = [];
+ // // segment2 = [];
+ // }
+ // else {
+ // if (hasSplit) {
+ // segment2.push(inkSegment);
+ // } else {
+ // segment1.push(inkSegment);
+ // }
+ // }
+ // } else if (hasSplit) {
+ // segment2.push(inkSegment);
+ // } else {
+ // continueErasing = true;
+ // }
+ // }
+
+ // if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) {
+ // segments.push(segment1);
+ // }
+ // if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) {
+ // segments.push(segment2);
+ // }
+ // if (excludeT < startSegmentT || excludeT > inkData.length / 4) {
+ // segment1.length && segments.push(segment1);
+ // }
+ // const tVals = []
+ // for (var i = 0; i < inkData.length - 3; i += 4) {
+ // const inkSegment = InkField.Segment(inkData, i);
+ // // Getting all t-value intersections of the current curve with all other curves.
+ // tVals.push(this.getInkIntersections(i, ink, inkSegment));
+ // tVals.sort();
+
+ // if (tVals.length) {
+ // const docCurveTVal = tVals.lastElement() + Math.floor(i / 4);
+ // if (excludeT > docCurveTVal) {
+ // continue;
+ // } else {
+ // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
+ // segment.push(inkSegment.split(0, closestTs[0]));
+ // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) {
+ // segments.push(segment);
+ // }
+ // }
+
+ // const closestT = this.getClosestT(tVals, excludeT, 0, tVals.length - 1);
+ // if (closestT != undefined) {
+ // var startSegmentT = closestT[0]
+ // const localStartTVal = startSegmentT - Math.floor(i / 4);
+ // segment.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, startSegmentT))
+ // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) {
+ // segments.push(segment);
+ // }
+ // const split = inkSegment.split(closestT[1]).right;
+ // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) {
+ // segments.push([split]);
+ // }
+ // }
+ // } else {
+ // segment.push(inkSegment);
+ // segments.push(segment);
+ // }
+ // }
const segments: Segment[] = [];
- var segment: Segment = [];
+ var segment1: Segment = [];
+ var segment2: Segment = [];
var startSegmentT = 0;
+ var hasSplit = false;
const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData();
// This iterates through all segments of the curve and splits them where they intersect another curve.
// if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted)
@@ -840,23 +958,66 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const docCurveTVal = t + Math.floor(i / 4);
if (excludeT < startSegmentT || excludeT > docCurveTVal) {
const localStartTVal = startSegmentT - Math.floor(i / 4);
- t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
- segment.length && segments.push(segment);
+ if (!hasSplit) {
+ t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment1.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
+ } else {
+ t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment2.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
+ }
+ // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) segments.push(segment);
}
// start a new segment from the intersection t value
- segment = tVals.length - 1 === index ? [inkSegment.split(t).right] : [];
+ if (tVals.length - 1 === index) {
+ const split = inkSegment.split(t).right;
+ if (!hasSplit) {
+ if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment1.push(split);
+ } else {
+ if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment2.push(split);
+ }
+ }
startSegmentT = docCurveTVal;
});
} else {
- segment.push(inkSegment);
+ if (!hasSplit) {
+ segment1.push(inkSegment);
+ } else {
+ segment2.push(inkSegment);
+ }
}
}
- if (excludeT < startSegmentT || excludeT > inkData.length / 4) {
- segment.length && segments.push(segment);
+ if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) {
+ segments.push(segment1);
+ }
+ if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) {
+ segments.push(segment2);
}
return segments;
};
+ getClosestTs = (tVals: number[], excludeT: number, startIndex: number, endIndex: number): number[] => {
+ if (tVals[startIndex] >= excludeT) {
+ return [-1, tVals[startIndex]];
+ }
+ else if (tVals[endIndex] < excludeT) {
+ return [tVals[endIndex], -1];
+ }
+ else {
+ const mid = Math.floor(startIndex + endIndex / 2);
+ if (excludeT >= tVals[mid]) {
+ if (mid + 1 <= endIndex && tVals[mid + 1] > excludeT) {
+ return [tVals[mid], tVals[mid + 1]];
+ } else {
+ return this.getClosestTs(tVals, excludeT, mid + 1, endIndex);
+ }
+ } else {
+ if (mid - 1 <= startIndex && tVals[mid - 1] < excludeT) {
+ return [tVals[mid - 1], tVals[mid]];
+ } else {
+ return this.getClosestTs(tVals, excludeT, startIndex, mid - 1);
+ }
+ }
+ }
+ };
+
// for some reason bezier.js doesn't handle the case of intersecting a linear curve, so we wrap the intersection
// call in a test for linearity
bintersects = (curve: Bezier, otherCurve: Bezier) => {