aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreleanor-park <eleanor_park@brown.edu>2024-05-12 01:01:11 -0400
committereleanor-park <eleanor_park@brown.edu>2024-05-12 01:01:11 -0400
commit1ba63ee1afd43376da023d07dc12e5908d68478e (patch)
treeca4d5638198c8be0e8998e245a5f21c0f97ac2f5
parentd2c67049891493551e39f8c2423ee6e40109bb65 (diff)
parent4a332476db24555260820b8c5e268acc2000041c (diff)
Merge branch 'eleanor-starter' of https://github.com/brown-dash/Dash-Web into eleanor-starter
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx65
1 files changed, 38 insertions, 27 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ab47c105e..622189b80 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,7 +1,5 @@
-import { inside } from '@turf/turf';
import { Bezier } from 'bezier-js';
import { Colors } from 'browndash-components';
-import { validationResult } from 'express-validator';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
@@ -695,7 +693,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
@action
onEraserUp = (e: PointerEvent): void => {
- this._deleteList.forEach(ink => ink._props.removeDocument?.(ink.Document));
+ this._deleteList.lastElement()?._props.removeDocument?.(this._deleteList.map(ink => ink.Document));
this._deleteList = [];
this._batch?.end();
};
@@ -759,13 +757,23 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (Doc.ActiveTool !== InkTool.StrokeEraser) {
this._eraserLock++;
const segments = this.segmentErase(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
- segments?.forEach(segment =>
- this.forceStrokeGesture(
- e,
- GestureUtils.Gestures.Stroke,
- segment.reduce((data, curve) => [...data, ...curve.points.map(p => intersect.inkView.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[])
- )
- );
+ const newStrokes = segments?.map(segment => {
+ const points = segment.reduce((data, curve) => [...data, ...curve.points.map(p => intersect.inkView.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[]);
+ const bounds = GestureOverlay.getBounds(points);
+ const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height);
+ const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
+ return Docs.Create.InkDocument(
+ points,
+ { title: 'stroke',
+ x: B.x - inkWidth / 2,
+ y: B.y - inkWidth / 2,
+ _width: B.width + inkWidth,
+ _height: B.height + inkWidth,
+ stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
+ inkWidth
+ );
+ });
+ newStrokes && this.addDocument?.(newStrokes);
setTimeout(() => this._eraserLock--);
}
// Lower ink opacity to give the user a visual indicator of deletion.
@@ -877,17 +885,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
/**
* Ray-tracing algorithm to determine whether a point is inside the eraser outline
- * @param eraserOutline
- * @param point
- * @returns
+ * @param eraserOutline
+ * @param point
+ * @returns
*/
insideEraserOutline = (eraserOutline: InkData, point: { X: number; Y: number }) => {
var isInside = false;
if (!isNaN(eraserOutline[0].X) && !isNaN(eraserOutline[0].Y)) {
- var minX = eraserOutline[0].X, maxX = eraserOutline[0].X;
- var minY = eraserOutline[0].Y, maxY = eraserOutline[0].Y;
- for (var i = 1; i < eraserOutline.length; i++) {
- const currPoint: {X: number, Y: number} = eraserOutline[i];
+ let minX = eraserOutline[0].X, maxX = eraserOutline[0].X; // prettier-ignore
+ let minY = eraserOutline[0].Y, maxY = eraserOutline[0].Y; // prettier-ignore
+ for (let i = 1; i < eraserOutline.length; i++) {
+ const currPoint: { X: number; Y: number } = eraserOutline[i];
minX = Math.min(currPoint.X, minX);
maxX = Math.max(currPoint.X, maxX);
minY = Math.min(currPoint.Y, minY);
@@ -899,8 +907,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
for (var i = 0, j = eraserOutline.length - 1; i < eraserOutline.length; j = i, i++) {
- if ((eraserOutline[i].Y > point.Y) != (eraserOutline[j].Y > point.Y) &&
- point.X < (eraserOutline[j].X - eraserOutline[i].X) * (point.Y - eraserOutline[i].Y) / (eraserOutline[j].Y - eraserOutline[i].Y) + eraserOutline[i].X ) {
+ if (eraserOutline[i].Y > point.Y != eraserOutline[j].Y > point.Y && point.X < ((eraserOutline[j].X - eraserOutline[i].X) * (point.Y - eraserOutline[i].Y)) / (eraserOutline[j].Y - eraserOutline[i].Y) + eraserOutline[i].X) {
isInside = !isInside;
}
}
@@ -955,7 +962,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
getRadiusEraserIntersections = (lastPoint: { X: number; Y: number }, currPoint: { X: number; Y: number }) => {
const eraserRadius = ActiveEraserWidth() + 3;
const eraserMin = { X: Math.min(lastPoint.X, currPoint.X) - eraserRadius, Y: Math.min(lastPoint.Y, currPoint.Y) - eraserRadius };
- const eraserMax = { X: Math.max(lastPoint.X, currPoint.X) + eraserRadius, Y: Math.max(lastPoint.Y, currPoint.Y) + eraserRadius};
+ const eraserMax = { X: Math.max(lastPoint.X, currPoint.X) + eraserRadius, Y: Math.max(lastPoint.Y, currPoint.Y) + eraserRadius };
const strokeToTVals = new Map<DocumentView, number[]>();
const intersectingStrokes = this.childDocs
.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))
@@ -969,6 +976,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
eraserMax.X >= inkViewBounds.left &&
eraserMax.Y >= inkViewBounds.top
);
+
intersectingStrokes.forEach(({ inkStroke, inkView }) => {
const { inkData } = inkStroke.inkScaledData();
const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint);
@@ -1027,8 +1035,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const inkStroke = ink?.ComponentView as InkingStroke;
const { inkData } = inkStroke.inkScaledData();
var currSegment: Segment = [];
- if (tVals.length % 2 !== 0) { // should always have even tVals
- for (var i = 0; i < inkData.length - 3; i +=4) {
+ if (tVals.length % 2 !== 0) {
+ // should always have even tVals
+ for (var i = 0; i < inkData.length - 3; i += 4) {
currSegment.push(InkField.Segment(inkData, i));
}
segments.push(currSegment);
@@ -1047,18 +1056,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
for (var i = 0; i < inkData.length - 3; i += 4) {
- const currCurveT = Math.floor(i/4);
+ const currCurveT = Math.floor(i / 4);
const inkBezier: Bezier = InkField.Segment(inkData, i);
const segmentTs = tVals.filter(t => t >= currCurveT && t < currCurveT + 1);
if (segmentTs.length > 0) {
for (var j = 0; j < segmentTs.length; j++) {
// if the first end of the segment is within the eraser
- if (segmentTs[j] === 0 ) {
+ if (segmentTs[j] === 0) {
continueErasing = true;
} else if (segmentTs[j] === Math.floor(inkData.length / 4) + 1) {
break;
- }else {
+ } else {
if (!continueErasing) {
currSegment.push(inkBezier.split(0, segmentTs[j] - currCurveT));
continueErasing = true;
@@ -1076,7 +1085,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
}
} else {
- if (!continueErasing) { // push the bezier piece if not in the eraser circle
+ if (!continueErasing) {
+ // push the bezier piece if not in the eraser circle
currSegment.push(inkBezier);
}
}
@@ -1199,7 +1209,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
hasSplit = true;
} else if (currCurveT === splitSegment1) {
segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT));
- hasSplit = true;
+ hasSplit = true;
} else {
if ((isClosedCurve && hasSplit) || (!isClosedCurve && !hasSplit)) {
segment1.push(inkSegment);
@@ -2138,6 +2148,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
for (var i = 0; i < Math.min(layout_unrendered.length, loadIncrement); i++) {
this._renderCutoffData.set(layout_unrendered[i][Id] + '', true);
}
+ layout_unrendered.forEach(lu => lu.stroke && this._renderCutoffData.set(lu[Id] + '', true));
}
this.childDocs.some(doc => !this._renderCutoffData.get(doc[Id])) && setTimeout(this.incrementalRender, 1);
});