diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/InkStrokeProperties.ts | 65 |
1 files changed, 23 insertions, 42 deletions
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 510c5f2dd..6a503cc91 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -1,6 +1,6 @@ import { Bezier } from "bezier-js"; import { action, computed, observable, reaction } from "mobx"; -import { Doc, Field, Opt } from "../../fields/Doc"; +import { Doc } from "../../fields/Doc"; import { Document } from "../../fields/documentSchemas"; import { InkData, InkField, InkTool, PointData } from "../../fields/InkField"; import { List } from "../../fields/List"; @@ -29,11 +29,6 @@ export class InkStrokeProperties { return inks.length ? inks : undefined; } - getField(key: string) { - return this.selectedInk?.reduce((p, i) => - (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt<string>); - } - /** * Helper function that enables other functions to be applied to a particular ink instance. * @param func The inputted function. @@ -79,9 +74,10 @@ export class InkStrokeProperties { @action addPoints = (t: number, i: number, controls: { X: number, Y: number }[]) => { this.applyFunction((doc: Doc, ink: InkData) => { - const array = [{ x: controls[i].X, y: controls[i].Y }, { x: controls[i + 1].X, y: controls[i + 1].Y }, { x: controls[i + 2].X, y: controls[i + 2].Y }, { x: controls[i + 3].X, y: controls[i + 3].Y }]; - const newsegs = new Bezier(array).split(t); - controls.splice(i, 4, ...[...newsegs.left.points.map(p => ({ X: p.x, Y: p.y })), ...newsegs.right.points.map(p => ({ X: p.x, Y: p.y }))]); + const array = [controls[i], controls[i + 1], controls[i + 2], controls[i + 3]]; + const newsegs = new Bezier(array.map(p => ({ x: p.X, y: p.Y }))).split(t); + const splicepts = [...newsegs.left.points, ...newsegs.right.points]; + controls.splice(i, 4, ...splicepts.map(p => ({ X: p.x, Y: p.y }))); // Updating the indices of the control points whose handle tangency has been broken. doc.brokenInkIndices = new List(Cast(doc.brokenInkIndices, listSpec("number"), []).map(control => control > i ? control + 4 : control)); @@ -101,8 +97,7 @@ export class InkStrokeProperties { const prevSize = end - start; const newSize = isLeft ? index - start : end - index; const handleVector = { X: control.X - handle.X, Y: control.Y - handle.Y }; - const scaledVector = { X: handleVector.X * (newSize / prevSize), Y: handleVector.Y * (newSize / prevSize) }; - return scaledVector; + return { X: handleVector.X * (newSize / prevSize), Y: handleVector.Y * (newSize / prevSize) }; } /** @@ -159,8 +154,7 @@ export class InkStrokeProperties { doc.brokenInkIndices = new List(Cast(doc.brokenInkIndices, listSpec("number"), []).map(control => control >= toRemove * 4 ? control - 4 : control)); if (last) newPoints.splice(newPoints.length - 3, 2); this._currentPoint = -1; - if (newPoints.length < 4) return undefined; - return newPoints; + return newPoints.length < 4 ? undefined : newPoints; }, true) /** @@ -174,11 +168,11 @@ export class InkStrokeProperties { const oldXrange = (xs => ({ coord: NumCast(doc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X)); const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y)); const centerPoint = { X: (oldXrange.min + oldXrange.max) / 2, Y: (oldYrange.min + oldYrange.max) / 2 }; - const newPoints: { X: number, Y: number }[] = []; - ink.map(i => ({ X: i.X - centerPoint.X, Y: i.Y - centerPoint.Y })).forEach(i => { - const newX = Math.cos(angle) * i.X - Math.sin(angle) * i.Y; - const newY = Math.sin(angle) * i.X + Math.cos(angle) * i.Y; - newPoints.push({ X: newX + centerPoint.X, Y: newY + centerPoint.Y }); + const newPoints = ink.map(i => { + const pt = { X: i.X - centerPoint.X, Y: i.Y - centerPoint.Y }; + const newX = Math.cos(angle) * pt.X - Math.sin(angle) * pt.Y; + const newY = Math.sin(angle) * pt.X + Math.cos(angle) * pt.Y; + return { X: newX + centerPoint.X, Y: newY + centerPoint.Y }; }); doc.rotation = NumCast(doc.rotation) + angle; return newPoints; @@ -192,10 +186,10 @@ export class InkStrokeProperties { @action moveControl = (deltaX: number, deltaY: number, controlIndex: number) => this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => { - const newPoints: { X: number, Y: number }[] = []; const order = controlIndex % 4; const closed = ink.lastElement().X === ink[0].X && ink.lastElement().Y === ink[0].Y; - for (var i = 0; i < ink.length; i++) { + + return ink.map((pt, i) => { const leftHandlePoint = order === 0 && i === controlIndex + 1; const rightHandlePoint = order === 0 && controlIndex !== 0 && i === controlIndex - 2; if (controlIndex === i || @@ -207,12 +201,10 @@ export class InkStrokeProperties { (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 1) || (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 2) || ((ink[0].X === ink[ink.length - 1].X) && (ink[0].Y === ink[ink.length - 1].Y) && (i === 0 || i === ink.length - 1) && (controlIndex === 0 || controlIndex === ink.length - 1))) { - newPoints.push({ X: ink[i].X - deltaX / xScale, Y: ink[i].Y - deltaY / yScale }); - } else { - newPoints.push({ X: ink[i].X, Y: ink[i].Y }); + return ({ X: pt.X - deltaX / xScale, Y: pt.Y - deltaY / yScale }); } - } - return newPoints; + return pt; + }); }) /** @@ -224,18 +216,11 @@ export class InkStrokeProperties { this.applyFunction((doc: Doc, ink: InkData) => { const brokenIndices = Cast(doc.brokenInkIndices, listSpec("number")); if (brokenIndices) { - const newBrokenIndices = new List; - brokenIndices.forEach(brokenIndex => { - if (brokenIndex !== controlIndex) { - newBrokenIndices.push(brokenIndex); - } - }); - doc.brokenInkIndices = newBrokenIndices; + doc.brokenInkIndices = new List<number>(brokenIndices.filter(brokenIndex => brokenIndex !== controlIndex)); const [controlPoint, handleA, handleB] = [ink[controlIndex], ink[handleIndexA], ink[handleIndexB]]; const oppositeHandleA = this.rotatePoint(handleA, controlPoint, Math.PI); const angleDifference = this.angleChange(handleB, oppositeHandleA, controlPoint); - const newHandleB = this.rotatePoint(handleB, controlPoint, angleDifference); - ink[handleIndexB] = newHandleB; + ink[handleIndexB] = this.rotatePoint(handleB, controlPoint, angleDifference); return ink; } }); @@ -249,9 +234,7 @@ export class InkStrokeProperties { const rotatedTarget = { X: target.X - origin.X, Y: target.Y - origin.Y }; const newX = Math.cos(angle) * rotatedTarget.X - Math.sin(angle) * rotatedTarget.Y; const newY = Math.sin(angle) * rotatedTarget.X + Math.cos(angle) * rotatedTarget.Y; - rotatedTarget.X = newX + origin.X; - rotatedTarget.Y = newY + origin.Y; - return rotatedTarget; + return { X: newX + origin.X, Y: newY + origin.Y }; } /** @@ -265,8 +248,7 @@ export class InkStrokeProperties { // Normalizing the vectors. vectorA = { X: vectorA.X / magnitudeA, Y: vectorA.Y / magnitudeA }; vectorB = { X: vectorB.X / magnitudeB, Y: vectorB.Y / magnitudeB }; - const dotProduct = vectorB.X * vectorA.X + vectorB.Y * vectorA.Y; - return Math.acos(dotProduct); + return Math.acos(vectorB.X * vectorA.X + vectorB.Y * vectorA.Y); } /** @@ -292,7 +274,7 @@ export class InkStrokeProperties { this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => { const closed = ink.lastElement().X === ink[0].X && ink.lastElement().Y === ink[0].Y; const oldHandlePoint = ink[handleIndex]; - let oppositeHandlePoint = ink[oppositeHandleIndex]; + const oppositeHandlePoint = ink[oppositeHandleIndex]; const controlPoint = ink[controlIndex]; const newHandlePoint = { X: ink[handleIndex].X - deltaX / xScale, Y: ink[handleIndex].Y - deltaY / yScale }; ink[handleIndex] = newHandlePoint; @@ -300,8 +282,7 @@ export class InkStrokeProperties { // Rotate opposite handle if user hasn't held 'Alt' key or not first/final control (which have only 1 handle). if ((!brokenIndices || !brokenIndices?.includes(controlIndex)) && (closed || (handleIndex !== 1 && handleIndex !== ink.length - 2))) { const angle = this.angleChange(oldHandlePoint, newHandlePoint, controlPoint); - oppositeHandlePoint = this.rotatePoint(oppositeHandlePoint, controlPoint, angle); - ink[oppositeHandleIndex] = oppositeHandlePoint; + ink[oppositeHandleIndex] = this.rotatePoint(oppositeHandlePoint, controlPoint, angle); } return ink; }) |