diff options
author | vkalev <50213748+vkalev@users.noreply.github.com> | 2021-06-30 12:52:52 -0500 |
---|---|---|
committer | vkalev <50213748+vkalev@users.noreply.github.com> | 2021-06-30 12:52:52 -0500 |
commit | b0efa4a390415072eaeb06c8719ea57d73e10466 (patch) | |
tree | 867e9bd5c1c05908e2e6ab39f0b7abf18b2e5272 /src | |
parent | 441a3dab4ada425d28a55435be51339e3d28c892 (diff) |
ink Bézier handle movement fixed + small visual changes
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/InteractionUtils.tsx | 2 | ||||
-rw-r--r-- | src/client/views/InkStrokeProperties.ts | 119 | ||||
-rw-r--r-- | src/client/views/InkingStroke.scss | 18 | ||||
-rw-r--r-- | src/client/views/InkingStroke.tsx | 93 | ||||
-rw-r--r-- | src/fields/InkField.ts | 24 |
5 files changed, 177 insertions, 79 deletions
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index 01d00db30..ba935e3bf 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -208,7 +208,7 @@ export namespace InteractionUtils { <polyline points={strpts} style={{ - filter: drawHalo ? "url(#inkSelectionHalo)" : undefined, + // filter: drawHalo ? "url(#inkSelectionHalo)" : undefined, fill: fill ? fill : "none", opacity: strokeWidth !== width ? 0.5 : undefined, pointerEvents: pevents as any, diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 533fdf006..5c5395984 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -2,12 +2,11 @@ import { action, computed, observable } from "mobx"; import { ColorState } from 'react-color'; import { Doc, Field, Opt } from "../../fields/Doc"; import { Document } from "../../fields/documentSchemas"; -import { InkField, InkData } from "../../fields/InkField"; +import { InkField, InkData, PointData } from "../../fields/InkField"; import { Cast, NumCast } from "../../fields/Types"; import { DocumentType } from "../documents/DocumentTypes"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; -import { bool } from "sharp"; export class InkStrokeProperties { static Instance: InkStrokeProperties | undefined; @@ -15,15 +14,15 @@ export class InkStrokeProperties { private _lastFill = "#D0021B"; private _lastLine = "#D0021B"; private _lastDash = "2"; - private _inkDocs: { x: number, y: number, width: number, height: number }[] = []; - // Indicates whether the ink is locked. @observable _lock = false; - // Indicates whether the ink's format is being currently edited (displaying of control points). @observable _controlBtn = false; - // Stores the index of the current selected control point of the ink instance. @observable _currPoint = -1; + constructor() { + InkStrokeProperties.Instance = this; + } + 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>); @@ -79,10 +78,6 @@ export class InkStrokeProperties { }); } - constructor() { - InkStrokeProperties.Instance = this; - } - /** * Adds a new control point to the ink instance when editing its format. * @param x The x-coordinate of the current new point. @@ -213,36 +208,100 @@ export class InkStrokeProperties { } /** - * Handles the movement / scaling of control points of an ink instance. - * @param xDiff The movement of the control point's x-coordinate. - * @param yDiff The movement of the control point's y-coordinate. - * @param controlNum The index of the current control point selected. - * @returns The changed x- and y-coordinates of the control points. + * Handles the movement/scaling of a control point. */ @undoBatch @action - control = (xDiff: number, yDiff: number, controlNum: number) => - this.applyFunction((doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { + 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 = controlNum % 4; + const order = controlIndex % 4; for (var i = 0; i < ink.length; i++) { - newPoints.push( - (controlNum === i || - (order === 0 && i === controlNum + 1) || - (order === 0 && controlNum !== 0 && i === controlNum - 2) || - (order === 0 && controlNum !== 0 && i === controlNum - 1) || - (order === 3 && i === controlNum - 1) || - (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 1) || - (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 2) || - ((ink[0].X === ink[ink.length - 1].X) && (ink[0].Y === ink[ink.length - 1].Y) && (i === 0 || i === ink.length - 1) && (controlNum === 0 || controlNum === ink.length - 1)) - ) ? - { X: ink[i].X - xDiff / ptsXscale, Y: ink[i].Y - yDiff / ptsYscale } : - { X: ink[i].X, Y: ink[i].Y }); + const leftHandlePoint = order === 0 && i === controlIndex + 1; + const rightHandlePoint = order === 0 && controlIndex !== 0 && i === controlIndex - 2; + if (controlIndex === i || + leftHandlePoint || + rightHandlePoint || + (order === 0 && controlIndex !== 0 && i === controlIndex - 1) || + (order === 3 && i === controlIndex - 1) || + (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 newPoints; }); /** + * Rotates the target point about the origin point for a given angle (radians). + */ + @action + rotatePoint = (target: PointData, origin: PointData, angle: number) => { + target.X -= origin.X; + target.Y -= origin.Y; + const newX = Math.cos(angle) * target.X - Math.sin(angle) * target.Y; + const newY = Math.sin(angle) * target.X + Math.cos(angle) * target.Y; + target.X = newX + origin.X; + target.Y = newY + origin.Y; + return target + } + + /** + * Finds the angle difference (in radians) between two vectors relative to an arbitrary origin. + */ + angleChange = (a: PointData, b: PointData, origin: PointData) => { + // Finding vector representation of inputted points relative to new origin. + let vectorA = { X: a.X - origin.X, Y: a.Y - origin.Y }; + let vectorB = { X: b.X - origin.X, Y: b.Y - origin.Y }; + const crossProduct = vectorB.X * vectorA.Y - vectorB.Y * vectorA.X; + // Determining whether rotation is clockwise or counterclockwise. + const sign = crossProduct < 0 ? 1 : -1; + const magnitudeA = Math.sqrt(vectorA.X * vectorA.X + vectorA.Y * vectorA.Y); + const magnitudeB = Math.sqrt(vectorB.X * vectorB.X + vectorB.Y * vectorB.Y); + // 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; + const theta = Math.acos(dotProduct); + return sign * theta; + } + + /** + * Handles the movement/scaling of a handle point. + */ + @undoBatch + @action + moveHandle = (deltaX: number, deltaY: number, handleIndex: number) => + this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => { + const newPoints: { X: number, Y: number }[] = []; + const order = handleIndex % 4; + let newHandlePoint = { X: 0, Y: 0 }; + + for (var i = 0; i < ink.length; i++) { + if (handleIndex === i) { + newHandlePoint = { X: ink[i].X - deltaX / xScale, Y: ink[i].Y - deltaY / yScale }; + newPoints.push({ X: newHandlePoint.X, Y: newHandlePoint.Y }); + } else { + newPoints.push({ X: ink[i].X, Y: ink[i].Y }); + } + } + + if (handleIndex !== 1 && handleIndex !== ink.length - 2) { + const oldHandlePoint = ink[handleIndex]; + let oppositeHandlePoint = order === 1 ? ink[handleIndex - 3] : ink[handleIndex + 3]; + const controlPoint = order === 1 ? ink[handleIndex - 1] : ink[handleIndex + 1]; + const angle = this.angleChange(oldHandlePoint, newHandlePoint, controlPoint); + oppositeHandlePoint = this.rotatePoint(oppositeHandlePoint, controlPoint, angle); + order === 1 ? newPoints[handleIndex - 3] = oppositeHandlePoint : newPoints[handleIndex + 3] = oppositeHandlePoint; + } + + return newPoints; + }); + + /** * Changes the color of the border of the ink instance. * @param color The new hex value to change the border to. * @returns true. diff --git a/src/client/views/InkingStroke.scss b/src/client/views/InkingStroke.scss index 30ab1967e..f67b1779d 100644 --- a/src/client/views/InkingStroke.scss +++ b/src/client/views/InkingStroke.scss @@ -1,11 +1,11 @@ .inkingStroke { - mix-blend-mode: multiply; - stroke-linejoin: round; - stroke-linecap: round; - overflow: visible !important; - transform-origin: top left; + mix-blend-mode: multiply; + stroke-linejoin: round; + stroke-linecap: round; + overflow: visible !important; + transform-origin: top left; - svg:not(:root) { - overflow: visible !important; - } -}
\ No newline at end of file + svg:not(:root) { + overflow: visible !important; + } +} diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 859e53b97..163eb05b0 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -2,7 +2,7 @@ import { action } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../fields/Doc"; import { documentSchema } from "../../fields/documentSchemas"; -import { InkData, InkField, InkTool } from "../../fields/InkField"; +import { InkData, InkField, InkTool, ControlPoint, HandlePoint, HandleLine } from "../../fields/InkField"; import { makeInterface } from "../../fields/Schema"; import { Cast, StrCast } from "../../fields/Types"; import { TraceMobx } from "../../fields/util"; @@ -28,33 +28,51 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume public static LayoutString(fieldStr: string) { return FieldView.LayoutString(InkingStroke, fieldStr); } - private analyzeStrokes = () => { + analyzeStrokes = () => { const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], [data]); } - public static toggleMask = action((inkDoc: Doc) => { + @action + public static toggleMask = (inkDoc: Doc) => { inkDoc.isInkMask = !inkDoc.isInkMask; inkDoc._backgroundColor = inkDoc.isInkMask ? "rgba(0,0,0,0.7)" : undefined; inkDoc.mixBlendMode = inkDoc.isInkMask ? "hard-light" : undefined; inkDoc.color = "#9b9b9bff"; inkDoc._stayInCollection = inkDoc.isInkMask ? true : undefined; - }); + }; /** * Handles the movement of a selected control point when the user clicks and drags. - * @param e React Pointer Event. - * @param controlNum The number of the currently selected control point. + * @param controlNum The index of the currently selected control point. */ @action onControlDown = (e: React.PointerEvent, controlNum: number): void => { if (InkStrokeProperties.Instance) { - InkStrokeProperties.Instance.control(0, 0, 1); + InkStrokeProperties.Instance.moveControl(0, 0, 1); + const controlUndo = UndoManager.StartBatch("DocDecs set radius"); + const screenScale = this.props.ScreenToLocalTransform().Scale; + setupMoveUpEvents(this, e, + (e: PointerEvent, down: number[], delta: number[]) => { + InkStrokeProperties.Instance?.moveControl(-delta[0] * screenScale, -delta[1] * screenScale, controlNum); + return false; + }, + () => controlUndo?.end(), emptyFunction); + } + } + + /** + * Handles the movement of a selected handle point when the user clicks and drags. + * @param controlNum The index of the currently selected handle point. + */ + onHandleDown = (e: React.PointerEvent, handleNum: number): void => { + if (InkStrokeProperties.Instance) { + InkStrokeProperties.Instance.moveControl(0, 0, 1); const controlUndo = UndoManager.StartBatch("DocDecs set radius"); const screenScale = this.props.ScreenToLocalTransform().Scale; setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { - InkStrokeProperties.Instance?.control(-delta[0] * screenScale, -delta[1] * screenScale, controlNum); + InkStrokeProperties.Instance?.moveHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleNum); return false; }, () => controlUndo?.end(), emptyFunction); @@ -69,7 +87,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume changeCurrPoint = (i: number) => { if (InkStrokeProperties.Instance) { InkStrokeProperties.Instance._currPoint = i; - document.addEventListener("keydown", this.delPts, true); + document.addEventListener("keydown", this.onDelete, true); } } @@ -78,7 +96,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume * @param e Keyboard Event. */ @action - delPts = (e: KeyboardEvent) => { + onDelete = (e: KeyboardEvent) => { if (["-", "Backspace", "Delete"].includes(e.key)) { if (InkStrokeProperties.Instance?.deletePoints()) e.stopPropagation(); } @@ -101,7 +119,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume const formatInstance = InkStrokeProperties.Instance; if (!formatInstance) return (null); const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; - // const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth())); const strokeWidth = Number(this.layoutDoc.strokeWidth); const xs = data.map(p => p.X); const ys = data.map(p => p.Y); @@ -118,12 +135,18 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume const scaleX = width === strokeWidth ? 1 : (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth); const scaleY = height === strokeWidth ? 1 : (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth); const strokeColor = StrCast(this.layoutDoc.color, ""); + const dotsize = Math.max(width * scaleX, height * scaleY) / 40; // Visually renders the polygonal line made by the user. const points = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5 && lineBot - lineTop > 1 && lineRgt - lineLft > 1, false); + + const selectedLine = InteractionUtils.CreatePolyline(data, lineLft - strokeWidth * 3, lineTop - strokeWidth * 3, "#1F85DE", strokeWidth / 6, strokeWidth / 6, + StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), + StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker), + StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5 && lineBot - lineTop > 1 && lineRgt - lineLft > 1, false); // Invisible polygonal line that enables the ink to be selected by the user. const hpoints = InteractionUtils.CreatePolyline(data, left, top, @@ -136,10 +159,13 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false); - const controlPoints: { X: number, Y: number, I: number }[] = []; - const handlePoints: { X: number, Y: number, I: number, dot1: number, dot2: number }[] = []; - const handleLine: { X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, dot1: number, dot2: number }[] = []; + const controlPoints: ControlPoint[] = []; + const handlePoints: HandlePoint[] = []; + const handleLine: HandleLine[] = []; + // check the purpose of this conditional if (data.length >= 4) { + + // create separate functions for these for (var i = 0; i <= data.length - 4; i += 4) { controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i }); controlPoints.push({ X: data[i + 3].X, Y: data[i + 3].Y, I: i + 3 }); @@ -147,29 +173,21 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 }); } - handleLine.push({ X1: data[0].X, Y1: data[0].Y, X2: data[0].X, Y2: data[0].Y, X3: data[1].X, Y3: data[1].Y, dot1: 0, dot2: 0 }); + // first (single) handle line + handleLine.push({ X1: data[0].X, Y1: data[0].Y, X2: data[1].X, Y2: data[1].Y, dot1: 0, dot2: 0 }); for (var i = 2; i < data.length - 4; i += 4) { - handleLine.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 1].X, Y2: data[i + 1].Y, X3: data[i + 3].X, Y3: data[i + 3].Y, dot1: i + 1, dot2: i + 2 }); + handleLine.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 3].X, Y2: data[i + 3].Y, dot1: i + 1, dot2: i + 2 }); } - handleLine.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, X3: data[data.length - 1].X, Y3: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 }); + // last (single) handle line + handleLine.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 }); for (var i = 0; i <= data.length - 4; i += 4) { handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 }); handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 }); } } - // if (data.length <= 4) { - // handlePoints = []; - // handleLine = []; - // controlPoints = []; - // for (var i = 0; i < data.length; i++) { - // controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i }); - // } - - // } - const dotsize = Math.max(width * scaleX, height * scaleY) / 40; // Additional points (controls) added by the user via click when editing the ink's format. const addpoints = apoints.map((pts, i) => @@ -178,27 +196,24 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume onPointerDown={(e) => { formatInstance.addPoints(pts.X, pts.Y, apoints, i, controlPoints); }} pointerEvents="all" cursor="all-scroll" /> </svg>); - // Green circles that allow the user to edit the curvature of the line using the selected point as the anchor. + // Blue circles that allow the user to edit the curvature of the line using the selected control point as the anchor. const handles = handlePoints.map((pts, i) => <svg height="10" width="10" key={`hdl${i}`}> - <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth} strokeWidth={0} fill="green" - onPointerDown={(e) => this.onControlDown(e, pts.I)} pointerEvents="all" cursor="default" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> + <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} strokeWidth={0} fill="#1F85DE" + onPointerDown={(e) => this.onHandleDown(e, pts.I)} pointerEvents="all" cursor="default" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> </svg>); - // Points (red circles) of the ink that are made visible to user when editing its format. + // Control points of the ink (blue outlined squares) that are made visible to user when editing its format. const controls = controlPoints.map((pts, i) => <svg height="10" width="10" key={`ctrl${i}`}> - <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} strokeWidth={0} fill="red" + <rect x={(pts.X - left) * scaleX} y={(pts.Y - top) * scaleY} height={strokeWidth} width={strokeWidth} strokeWidth={strokeWidth / 6} stroke="#1F85DE" fill={formatInstance && formatInstance._currPoint === pts.I ? "#1F85DE" : "white"} onPointerDown={(e) => { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="default" /> </svg>); - // Set of two green lines (each with a handle at the end) that are rendered perpendicular to the current selected point while editing. + // Set of two blue lines (each with a handle at the end) that are rendered perpendicular to the current selected point while editing. const handleLines = handleLine.map((pts, i) => - <svg height="100" width="100" key={`line${i}`} > + <svg height="100" width="100" key={`line${i}`}> <line x1={(pts.X1 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y1 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} - x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="green" strokeWidth={dotsize / 6} - display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> - <line x1={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} - x2={(pts.X3 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y3 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="green" strokeWidth={dotsize / 6} + x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="#1F85DE" strokeWidth={dotsize / 10} display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> </svg>); @@ -227,8 +242,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume {formatInstance._controlBtn && this.props.isSelected() ? addpoints : ""} {formatInstance._controlBtn && this.props.isSelected() ? handleLines : ""} {formatInstance._controlBtn && this.props.isSelected() ? handles : ""} + {this.props.isSelected() ? selectedLine : ""} {formatInstance._controlBtn && this.props.isSelected() ? controls : ""} - </svg> ); } diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts index b79a03146..c158dac42 100644 --- a/src/fields/InkField.ts +++ b/src/fields/InkField.ts @@ -13,6 +13,7 @@ export enum InkTool { Stamp = "stamp" } + // Defines a point in an ink as a pair of x- and y-coordinates. export interface PointData { X: number; @@ -22,6 +23,29 @@ export interface PointData { // Defines an ink as an array of points. export type InkData = Array<PointData>; +export interface ControlPoint { + X: number; + Y: number; + I: number; +} + +export interface HandlePoint { + X: number; + Y: number; + I: number; + dot1: number; + dot2: number; +} + +export interface HandleLine { + X1: number; + Y1: number; + X2: number; + Y2: number; + dot1: number; + dot2: number; +} + const pointSchema = createSimpleSchema({ X: true, Y: true }); |