aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreleanor-park <eleanor_park@brown.edu>2024-05-15 14:33:50 -0400
committereleanor-park <eleanor_park@brown.edu>2024-05-15 14:33:50 -0400
commit84098c41aaa4970d43b88645489e64c1cac22934 (patch)
tree3cb8e0ac540334b2d8a5d0fbaf882f8d5f3fa339 /src
parentf8053c9d1f7d849cc0c3e8c0b8bf4a466ffd85b9 (diff)
three eraser modes implemented
Diffstat (limited to 'src')
-rw-r--r--src/client/views/InkingStroke.tsx49
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx141
-rw-r--r--src/client/views/global/globalScripts.ts3
3 files changed, 73 insertions, 120 deletions
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 03acd5393..9e09c0aa9 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -331,55 +331,6 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
};
- splitByEraser = (startInkCoordsIn: { X: number; Y: number }, endInkCoordsIn: { X: number; Y: number }) => {
- const radius = ActiveEraserWidth() / 2 + 3; // reduce values to avoid extreme radii
- const c = 0.551915024494; // circle tangent length to side ratio
- const movement = { x: endInkCoordsIn.X - startInkCoordsIn.X, y: endInkCoordsIn.Y - startInkCoordsIn.Y };
- const moveLen = Math.sqrt(movement.x ** 2 + movement.y ** 2);
- const direction = { x: (movement.x / moveLen) * radius, y: (movement.y / moveLen) * radius };
- const normal = { x: -direction.y, y: direction.x }; // prettier-ignore
-
- const startCoords = { X: startInkCoordsIn.X - direction.x, Y: startInkCoordsIn.Y - direction.y };
- const endCoords = { X: endInkCoordsIn.X + direction.x, Y: endInkCoordsIn.Y + direction.y };
- return new InkField([
- // left bot arc
- { X: startCoords.X, Y: startCoords.Y }, // prettier-ignore
- { X: startCoords.X + normal.x * c, Y: startCoords.Y + normal.y * c }, // prettier-ignore
- { X: startCoords.X + direction.x + normal.x - direction.x * c, Y: startCoords.Y + direction.y + normal.y - direction.y * c },
- { X: startCoords.X + direction.x + normal.x, Y: startCoords.Y + direction.y + normal.y }, // prettier-ignore
-
- // bot
- { X: startCoords.X + direction.x + normal.x, Y: startCoords.Y + direction.y + normal.y }, // prettier-ignore
- { X: startCoords.X + direction.x + normal.x + direction.x * c, Y: startCoords.Y + direction.y + normal.y + direction.y * c },
- { X: endCoords.X - direction.x + normal.x - direction.x * c, Y: endCoords.Y - direction.y + normal.y - direction.y * c }, // prettier-ignore
- { X: endCoords.X - direction.x + normal.x, Y: endCoords.Y - direction.y + normal.y }, // prettier-ignore
-
- // right bot arc
- { X: endCoords.X - direction.x + normal.x, Y: endCoords.Y - direction.y + normal.y }, // prettier-ignore
- { X: endCoords.X - direction.x + normal.x + direction.x * c, Y: endCoords.Y - direction.y + normal.y + direction.y * c}, // prettier-ignore
- { X: endCoords.X + normal.x * c, Y: endCoords.Y + normal.y * c }, // prettier-ignore
- { X: endCoords.X, Y: endCoords.Y }, // prettier-ignore
-
- // right top arc
- { X: endCoords.X, Y: endCoords.Y }, // prettier-ignore
- { X: endCoords.X - normal.x * c, Y: endCoords.Y - normal.y * c }, // prettier-ignore
- { X: endCoords.X - direction.x - normal.x + direction.x * c, Y: endCoords.Y - direction.y - normal.y + direction.y * c}, // prettier-ignore
- { X: endCoords.X - direction.x - normal.x, Y: endCoords.Y - direction.y - normal.y }, // prettier-ignore
-
- // top
- { X: endCoords.X - direction.x - normal.x, Y: endCoords.Y - direction.y - normal.y }, // prettier-ignore
- { X: endCoords.X - direction.x - normal.x - direction.x * c, Y: endCoords.Y - direction.y - normal.y - direction.y * c}, // prettier-ignore
- { X: startCoords.X + direction.x - normal.x + direction.x * c, Y: startCoords.Y + direction.y - normal.y + direction.y * c },
- { X: startCoords.X + direction.x - normal.x, Y: startCoords.Y + direction.y - normal.y }, // prettier-ignore
-
- // left top arc
- { X: startCoords.X + direction.x - normal.x, Y: startCoords.Y + direction.y - normal.y }, // prettier-ignore
- { X: startCoords.X + direction.x - normal.x - direction.x * c, Y: startCoords.Y + direction.y - normal.y - direction.y * c }, // prettier-ignore
- { X: startCoords.X - normal.x * c, Y: startCoords.Y - normal.y * c }, // prettier-ignore
- { X: startCoords.X, Y: startCoords.Y }, // prettier-ignore
- ]);
- };
-
_subContentView: ViewBoxInterface | undefined;
setSubContentView = (doc: ViewBoxInterface) => (this._subContentView = doc);
@computed get fillColor() {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 14d20eb4a..e2965c1ba 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -738,12 +738,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
_eraserLock = 0;
_eraserPts: number[][] = []; // keep track of the last few eraserPts to make the eraser circle 'stretch'
+
/**
* Erases strokes by intersecting them with an invisible "eraser stroke".
* By default this iterates through all intersected ink strokes, determines their segmentation, draws back the non-intersected segments,
* and deletes the original stroke.
*/
-
@action
onEraserMove = (e: PointerEvent, down: number[], delta: number[]) => {
const currPoint = { X: e.clientX, Y: e.clientY };
@@ -776,7 +776,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
);
});
newStrokes && this.addDocument?.(newStrokes);
- setTimeout(() => this._eraserLock--);
+ // setTimeout(() => this._eraserLock--);
}
// Lower ink opacity to give the user a visual indicator of deletion.
intersect.inkView.layoutDoc.opacity = 0;
@@ -797,23 +797,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
*/
@action
onRadiusEraserMove = (e: PointerEvent, down: number[], delta: number[]) => {
- // const currZoom = this.zoomScaling();
- // console.log("curr zoom", currZoom);
- // console.log("prev zoom", this.prevZoom);
const currPoint = { X: e.clientX, Y: e.clientY };
this._eraserPts.push([currPoint.X, currPoint.Y]);
this._eraserPts = this._eraserPts.slice(Math.max(0, this._eraserPts.length - 5));
- const intersections: any[] = this.getRadiusEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint);
- // if (intersections[0].size > 0 && currZoom === this.prevZoom) {
- const strokeMap: Map<DocumentView, number[]> = intersections[0];
- const eraserStroke = intersections[1];
+ const strokeMap: Map<DocumentView, number[]> = this.getRadiusEraserIntersections({ X: currPoint.X - delta[0], Y: currPoint.Y - delta[1] }, currPoint);
strokeMap.forEach((intersects, stroke) => {
if (!this._deleteList.includes(stroke)) {
this._deleteList.push(stroke);
SetActiveInkWidth(StrCast(stroke.Document.stroke_width?.toString()) || '1');
SetActiveInkColor(StrCast(stroke.Document.color?.toString()) || 'black');
- const segments = this.radiusErase(stroke, intersects.sort(), eraserStroke);
+ const segments = this.radiusErase(stroke, intersects.sort());
segments?.forEach(segment =>
this.forceStrokeGesture(
e,
@@ -825,12 +819,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
stroke.layoutDoc.opacity = 0;
stroke.layoutDoc.dontIntersect = true;
});
- // } else if (intersections[0].length > 0) {
- // this.prevZoom = currZoom;
- // console.log("skipping occurred");
- // } else if (this.prevZoom = currZoom) {
- // this.prevZoom = currZoom;
- // }
return false;
};
@@ -852,7 +840,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
/**
- * Creates the eraser outline for a radius eraser. The outline be
+ * Creates the eraser outline for a radius eraser. The outline is used to intersect with ink strokes and determine
+ * what falls inside the eraser outline.
* @param startInkCoordsIn
* @param endInkCoordsIn
* @param inkStrokeWidth
@@ -860,7 +849,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
*/
createEraserOutline = (startInkCoordsIn: { X: number; Y: number }, endInkCoordsIn: { X: number; Y: number }, inkStrokeWidth: number) => {
// increase radius slightly based on the erased stroke's width, added to make eraser look more realistic
- var radius = ActiveEraserWidth() + inkStrokeWidth * 0.2;
+ var radius = ActiveEraserWidth() + 5 + inkStrokeWidth * 0.1; // add 5 to prevent eraser from being too small
const c = 0.551915024494; // circle tangent length to side ratio
const movement = { x: endInkCoordsIn.X - startInkCoordsIn.X, y: endInkCoordsIn.Y - startInkCoordsIn.Y };
const moveLen = Math.sqrt(movement.x ** 2 + movement.y ** 2);
@@ -909,7 +898,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
/**
- * Ray-tracing algorithm to determine whether a point is inside the eraser outline
+ * Ray-tracing algorithm to determine whether a point is inside the eraser outline.
* @param eraserOutline
* @param point
* @returns
@@ -917,8 +906,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
insideEraserOutline = (eraserOutline: InkData, point: { X: number; Y: number }) => {
var isInside = false;
if (!isNaN(eraserOutline[0].X) && !isNaN(eraserOutline[0].Y)) {
- let minX = eraserOutline[0].X, maxX = eraserOutline[0].X; // prettier-ignore
- let minY = eraserOutline[0].Y, maxY = eraserOutline[0].Y; // prettier-ignore
+ let minX = eraserOutline[0].X, maxX = eraserOutline[0].X;
+ let minY = eraserOutline[0].Y, maxY = eraserOutline[0].Y;
for (let i = 1; i < eraserOutline.length; i++) {
const currPoint: { X: number; Y: number } = eraserOutline[i];
minX = Math.min(currPoint.X, minX);
@@ -985,14 +974,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
/**
- * Same as getEraserIntersections but specific to the radius eraser. Populates a Map of each intersected DocumentView
- * to the t-values where the eraser intersected it, then returns this map.
- * @returns
+ * Same as getEraserIntersections but specific to the radius eraser. The key difference is that the radius eraser
+ * will often intersect multiple strokes, depending on what strokes are inside the eraser. Populates a Map of each
+ * intersected DocumentView to the t-values where the eraser intersected it, then returns this map.
+ * @returns
*/
getRadiusEraserIntersections = (lastPoint: { X: number; Y: number }, currPoint: { X: number; Y: number }) => {
- const eraserRadius = ActiveEraserWidth() / this.zoomScaling();
- 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 };
+ // set distance of the eraser's bounding box based on the zoom
+ var boundingBoxDist = ActiveEraserWidth() + 5;
+ this.zoomScaling() < 1 ? boundingBoxDist = boundingBoxDist / (this.zoomScaling() * 1.5) : boundingBoxDist *= this.zoomScaling();
+
+ const eraserMin = { X: Math.min(lastPoint.X, currPoint.X) - boundingBoxDist, Y: Math.min(lastPoint.Y, currPoint.Y) - boundingBoxDist };
+ const eraserMax = { X: Math.max(lastPoint.X, currPoint.X) + boundingBoxDist, Y: Math.max(lastPoint.Y, currPoint.Y) + boundingBoxDist };
const strokeToTVals = new Map<DocumentView, number[]>();
const intersectingStrokes = this.childDocs
.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))
@@ -1006,13 +999,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
eraserMax.X >= inkViewBounds.left &&
eraserMax.Y >= inkViewBounds.top
);
- const erasers: InkData[] = [];
+
intersectingStrokes.forEach(({ inkStroke, inkView }) => {
const { inkData, inkStrokeWidth } = inkStroke.inkScaledData();
const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint);
const currPointInkSpace = inkStroke.ptFromScreen(currPoint);
const eraserInkData = this.createEraserOutline(prevPointInkSpace, currPointInkSpace, inkStrokeWidth).inkData;
- // erasers.push(eraserInkData);
// add the ends of the stroke in as "intersections"
if (this.insideEraserOutline(eraserInkData, inkData[0])) {
@@ -1039,7 +1031,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// here, add to the map
const inkList = strokeToTVals.get(inkView);
if (inkList !== undefined) {
- const tValOffset = ActiveEraserWidth() / 1000; // to prevent tVals from being added when too close, but scaled by eraser width
+ const tValOffset = ActiveEraserWidth() / 1050; // to prevent tVals from being added when too close, but scaled by eraser width
const inList = inkList.some(val => Math.abs(val - (t + Math.floor(i / 4))) <= tValOffset);
if (!inList) {
inkList.push(t + Math.floor(i / 4));
@@ -1052,42 +1044,34 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
}
});
- return [strokeToTVals, erasers];
+ return strokeToTVals;
};
/**
- * Splits the passed in ink stroke at the intersection t values, taking out the erased parts.
+ * Splits the passed in ink stroke at the intersection t values, taking out the erased parts.
* Operates in pairs of t values, where the first t value is the start of the erased portion and the following t value is the end.
* @param ink the ink stroke DocumentView to split
* @param tVals all the t values to split the ink stroke at
* @returns a list of the new segments with the erased part removed
*/
@action
- radiusErase = (ink: DocumentView, tVals: number[], erasers: InkData[]): Segment[] => {
+ radiusErase = (ink: DocumentView, tVals: number[]): Segment[] => {
const segments: Segment[] = [];
- var eraser: Segment = [];
- // for (var i = 0; i < erasers.length; i ++) {
- // for (var j = 0; j < erasers[i].length - 3; j +=4) {
- // eraser.push(InkField.Segment(erasers[i], j));
- // }
- // segments.push(eraser);
- // eraser = [];
- // }
-
const inkStroke = ink?.ComponentView as InkingStroke;
const { inkData } = inkStroke.inkScaledData();
var currSegment: Segment = [];
+
+ // any radius erase stroke will always result in even tVals, since the ends are included
if (tVals.length % 2 !== 0) {
- // any radius erase stroke will always result in even tVals, since the ends are included
for (var i = 0; i < inkData.length - 3; i += 4) {
currSegment.push(InkField.Segment(inkData, i));
}
segments.push(currSegment);
- return segments; // want to return the full original stroke
+ return segments; // return the full original stroke
}
var continueErasing = false; // used to erase segments if they are completely enclosed in the eraser
- var firstSegment: Segment = []; // used to keep track of the first segment for closed curves
+ var firstSegment: Segment = []; // used to keep track of the first segment for closed curves
// early return if nothing to split on
if (tVals.length === 0 || (tVals.length === 1 && tVals[0] === 0)) {
@@ -1108,15 +1092,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (segmentTs.length > 0) {
for (var j = 0; j < segmentTs.length; j++) {
- if (segmentTs[j] === 0) { // if the first end of the segment is within the eraser
+ if (segmentTs[j] === 0) {
+ // if the first end of the segment is within the eraser
continueErasing = true;
- } else if (segmentTs[j] === Math.floor(inkData.length / 4) + 1) { // the last end
+ } else if (segmentTs[j] === Math.floor(inkData.length / 4) + 1) {
+ // the last end
break;
} else {
if (!continueErasing) {
currSegment.push(inkBezier.split(0, segmentTs[j] - currCurveT));
continueErasing = true;
- } else { // we've reached the end of the part to take out...
+ } else {
+ // we've reached the end of the part to take out...
continueErasing = false;
if (currSegment.length > 0) {
segments.push(currSegment); // ...so we add it to the list and reset currSegment
@@ -1168,7 +1155,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
for (var i = 0; i < inkData.length - 3; i += 4) {
const inkSegment: Bezier = InkField.Segment(inkData, i);
var currIntersects = this.getInkIntersections(i, ink, inkSegment).sort();
- // get current segments intersections (if any) and add the curve index
+ // get current segment's intersections (if any) and add the curve index
currIntersects = currIntersects.filter(tVal => tVal > 0 && tVal < 1).map(tVal => tVal + Math.floor(i / 4));
if (currIntersects.length) {
intersections = [...intersections, ...currIntersects];
@@ -1181,6 +1168,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
var isClosedCurve = false;
if (InkingStroke.IsClosed(inkData)) {
isClosedCurve = true;
+ if (intersections.length === 1) { // delete whole stroke if a closed curve has 1 intersection
+ return segments;
+ }
}
if (intersections.length) {
@@ -1190,19 +1180,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// find the segments that need to be split
var splitSegment1 = -1; // stays -1 if left end is deleted
var splitSegment2 = -1; // stays -1 if right end is deleted
- if (closestTs[0] !== -1 && closestTs[1] !== -1) {
- // if not on the ends
+ if (closestTs[0] !== -1 && closestTs[1] !== -1) { // if not on the ends
splitSegment1 = segmentIndexes[closestTs[0]];
splitSegment2 = segmentIndexes[closestTs[1]];
- } else if (closestTs[0] === -1) {
- // for a curve before an intersection
+ } else if (closestTs[0] === -1) { // for a curve before an intersection
splitSegment2 = segmentIndexes[closestTs[1]];
- } else {
- // for a curve after an intersection
+ } else { // for a curve after an intersection
splitSegment1 = segmentIndexes[closestTs[0]];
}
-
- // so here splitSegment1 and splitSegment2 will be the index(es) of the segment(s) to split
+ // so by this point splitSegment1 and splitSegment2 will be the index(es) of the segment(s) to split
var hasSplit = false;
var continueErasing = false;
@@ -1236,7 +1222,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
} else if (splitSegment1 === -1) {
// case where first end is erased
if (currCurveT === splitSegment2) {
- segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1));
+ if (isClosedCurve && currCurveT === segmentIndexes.lastElement()) {
+ segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, intersections.lastElement() - currCurveT));
+ continueErasing = true;
+ } else {
+ segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1));
+ }
hasSplit = true;
} else {
if (isClosedCurve && currCurveT === segmentIndexes.lastElement()) {
@@ -1249,13 +1240,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
} else {
// case where last end is erased
if (currCurveT === segmentIndexes[0] && isClosedCurve) {
- segment1.push(inkSegment.split(intersections[0] - currCurveT, 1));
+ if (isClosedCurve && currCurveT === segmentIndexes.lastElement()) {
+ segment1.push(inkSegment.split(intersections[0] - currCurveT, intersections.lastElement() - currCurveT));
+ continueErasing = true;
+ } else {
+ segment1.push(inkSegment.split(intersections[0] - currCurveT, 1));
+ }
hasSplit = true;
} else if (currCurveT === splitSegment1) {
segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT));
hasSplit = true;
+ continueErasing = true;
} else {
- if ((isClosedCurve && hasSplit) || (!isClosedCurve && !hasSplit)) {
+ if ((isClosedCurve && hasSplit && !continueErasing) || (!isClosedCurve && !hasSplit)) {
segment1.push(inkSegment);
}
}
@@ -1311,6 +1308,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
};
+
// 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) => {
@@ -2045,14 +2043,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onCursorMove = (e: React.PointerEvent) => {
this._eraserX = e.clientX;
this._eraserY = e.clientY;
- if (this._eraserX < 0 || this._eraserY < 0) {
- this._showEraserCircle = false;
- } else {
- this._showEraserCircle = true;
- }
// super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
};
+ @action
+ onMouseLeave = () => {
+ this._showEraserCircle = false;
+ };
+
+ @action
+ onMouseEnter = () => {
+ this._showEraserCircle = true;
+ };
+
@undoBatch
promoteCollection = () => {
const childDocs = this.childDocs.slice();
@@ -2321,6 +2324,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._oldWheel = r;
// prevent wheel events from passivly propagating up through containers
r?.addEventListener('wheel', this.onPassiveWheel, { passive: false });
+ r?.addEventListener('mouseleave', this.onMouseLeave);
+ r?.addEventListener('mouseenter', this.onMouseEnter);
}}
onWheel={this.onPointerWheel}
onClick={this.onClick}
@@ -2336,15 +2341,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
width: `${100 / (this.nativeDimScaling || 1)}%`,
height: this._props.getScrollHeight?.() ?? `${100 / (this.nativeDimScaling || 1)}%`,
}}>
- {Doc.ActiveTool === InkTool.RadiusEraser && (
+ {(Doc.ActiveTool === InkTool.RadiusEraser && this._showEraserCircle) && (
<div
onPointerMove={this.onCursorMove}
style={{
position: 'fixed',
left: this._eraserX - 60,
top: this._eraserY - 100,
- width: ActiveEraserWidth() * 2,
- height: ActiveEraserWidth() * 2,
+ width: (ActiveEraserWidth() + 5) * 2,
+ height: (ActiveEraserWidth() + 5) * 2,
borderRadius: '50%',
border: '1px solid gray',
transform: 'translate(-50%, -50%)',
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 19741e2e0..0a8434148 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -362,9 +362,6 @@ ScriptingGlobals.add(function activeEraserTool() {
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'labels' | 'fillColor' | 'strokeWidth' | 'strokeColor' | 'eraserWidth', value: any, checkResult?: boolean) {
const selected = SelectionManager.Docs.lastElement() ?? Doc.UserDoc();
- if (option === 'eraserWidth') {
- console.log('eraserWidth', value);
- }
// prettier-ignore
const map: Map<'inkMask' | 'labels' | 'fillColor' | 'strokeWidth' | 'strokeColor' | 'eraserWidth', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([
['inkMask', {