diff options
author | bobzel <zzzman@gmail.com> | 2021-09-14 15:49:21 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2021-09-14 15:49:21 -0400 |
commit | abc5f96945fc0716fb1ccb4c99005bc7b7473086 (patch) | |
tree | e555b7219ede49b613039427c96fe174eee322ba /src | |
parent | d22dd9550a2ae4de98b6b56c0f57b9de9d6122bd (diff) |
fixed adding a new point on an ink stroke
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/InkControls.tsx | 119 | ||||
-rw-r--r-- | src/client/views/InkHandles.tsx | 15 | ||||
-rw-r--r-- | src/client/views/InkingStroke.tsx | 25 |
3 files changed, 83 insertions, 76 deletions
diff --git a/src/client/views/InkControls.tsx b/src/client/views/InkControls.tsx index e4861c086..4df7ee813 100644 --- a/src/client/views/InkControls.tsx +++ b/src/client/views/InkControls.tsx @@ -1,20 +1,22 @@ import React = require("react"); -import { observable, action } from "mobx"; +import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import { InkStrokeProperties } from "./InkStrokeProperties"; -import { setupMoveUpEvents, emptyFunction } from "../../Utils"; -import { UndoManager } from "../util/UndoManager"; -import { ControlPoint, InkData, PointData } from "../../fields/InkField"; -import { Transform } from "../util/Transform"; -import { Colors } from "./global/globalEnums"; import { Doc } from "../../fields/Doc"; +import { ControlPoint, InkData, PointData } from "../../fields/InkField"; import { listSpec } from "../../fields/Schema"; import { Cast } from "../../fields/Types"; +import { setupMoveUpEvents } from "../../Utils"; +import { Transform } from "../util/Transform"; +import { UndoManager } from "../util/UndoManager"; +import { Colors } from "./global/globalEnums"; +import { InkStrokeProperties } from "./InkStrokeProperties"; export interface InkControlProps { inkDoc: Doc; - data: InkData; - addedPoints: PointData[]; + inkCtrlPoints: InkData; + screenCtrlPoints: InkData; + inkStrokeSamplePts: PointData[]; + screenStrokeSamplePoints: PointData[]; format: number[]; ScreenToLocalTransform: () => Transform; } @@ -87,57 +89,60 @@ export class InkControls extends React.Component<InkControlProps> { if (!formatInstance) return (null); // Accessing the current ink's data and extracting all control points. - const data = this.props.data; - const controlPoints: ControlPoint[] = []; - if (data.length >= 4) { - for (let 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 }); - } + const scrData = this.props.screenCtrlPoints; + const sreenCtrlPoints: ControlPoint[] = []; + for (let i = 0; i <= scrData.length - 4; i += 4) { + sreenCtrlPoints.push({ X: scrData[i].X, Y: scrData[i].Y, I: i }); + sreenCtrlPoints.push({ X: scrData[i + 3].X, Y: scrData[i + 3].Y, I: i + 3 }); } - const addedPoints = this.props.addedPoints; + + const inkData = this.props.inkCtrlPoints; + const inkCtrlPts: ControlPoint[] = []; + for (let i = 0; i <= inkData.length - 4; i += 4) { + inkCtrlPts.push({ X: inkData[i].X, Y: inkData[i].Y, I: i }); + inkCtrlPts.push({ X: inkData[i + 3].X, Y: inkData[i + 3].Y, I: i + 3 }); + } + const [left, top, scaleX, scaleY, strokeWidth, screenSpaceLineWidth] = this.props.format; const rectHdlSize = (i: number) => this._overControl === i ? screenSpaceLineWidth * 6 : screenSpaceLineWidth * 4; - return ( - <> - {addedPoints.map((pts, i) => - <svg height="10" width="10" key={`add${i}`}> - <circle - cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} - cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} - r={strokeWidth / 1.5} - stroke={this._overAddPoint === i ? Colors.MEDIUM_BLUE : "transparent"} - strokeWidth={0} fill={this._overAddPoint === i ? Colors.MEDIUM_BLUE : "transparent"} - onPointerDown={() => { formatInstance?.addPoints(pts.X, pts.Y, addedPoints, i, controlPoints); }} - onMouseEnter={() => this.onEnterAddPoint(i)} - onMouseLeave={this.onLeaveAddPoint} - pointerEvents="all" - cursor="all-scroll" - /> - </svg> - )} - {controlPoints.map((control, i) => - <svg height="10" width="10" key={`ctrl${i}`}> - <rect - x={(control.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2 - rectHdlSize(i) / 2} - y={(control.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2 - rectHdlSize(i) / 2} - height={rectHdlSize(i)} - width={rectHdlSize(i)} - strokeWidth={screenSpaceLineWidth / 2} - stroke={Colors.MEDIUM_BLUE} - fill={formatInstance?._currentPoint === control.I ? Colors.MEDIUM_BLUE : Colors.WHITE} - onPointerDown={(e) => { - this.changeCurrPoint(control.I); - this.onControlDown(e, control.I); - }} - onMouseEnter={() => this.onEnterControl(i)} - onMouseLeave={this.onLeaveControl} - pointerEvents="all" - cursor="default" - /> - </svg> - )} - </> + return (<svg> + {/* should really have just one circle here that represents the neqraest point on the stroke to the users hover point. + This points should be passed as a prop from InkingStroke's UI which should set it in its onPointerOver method */} + {this.props.screenStrokeSamplePoints.map((pts, i) => + <circle key={i} + cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} + cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} + r={screenSpaceLineWidth * 4} + fill={this._overAddPoint === i ? "#00007777" : "transparent"} + stroke={this._overAddPoint === i ? "#00007777" : "transparent"} + strokeWidth={0} + onPointerDown={() => formatInstance?.addPoints(this.props.inkStrokeSamplePts[i].X, this.props.inkStrokeSamplePts[i].Y, this.props.inkStrokeSamplePts, i, inkCtrlPts)} + onMouseEnter={() => this.onEnterAddPoint(i)} + onMouseLeave={this.onLeaveAddPoint} + pointerEvents="all" + cursor="all-scroll" + /> + )} + {sreenCtrlPoints.map((control, i) => + <rect key={i} + x={(control.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2 - rectHdlSize(i) / 2} + y={(control.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2 - rectHdlSize(i) / 2} + height={rectHdlSize(i)} + width={rectHdlSize(i)} + strokeWidth={screenSpaceLineWidth / 2} + stroke={Colors.MEDIUM_BLUE} + fill={formatInstance?._currentPoint === control.I ? Colors.MEDIUM_BLUE : Colors.WHITE} + onPointerDown={(e) => { + this.changeCurrPoint(control.I); + this.onControlDown(e, control.I); + }} + onMouseEnter={() => this.onEnterControl(i)} + onMouseLeave={this.onLeaveControl} + pointerEvents="all" + cursor="default" + /> + )} + </svg> ); } }
\ No newline at end of file diff --git a/src/client/views/InkHandles.tsx b/src/client/views/InkHandles.tsx index 4e3a842d0..afe94cdfb 100644 --- a/src/client/views/InkHandles.tsx +++ b/src/client/views/InkHandles.tsx @@ -1,17 +1,16 @@ import React = require("react"); -import { observable, action } from "mobx"; +import { action } from "mobx"; import { observer } from "mobx-react"; -import { InkStrokeProperties } from "./InkStrokeProperties"; -import { setupMoveUpEvents, emptyFunction } from "../../Utils"; -import { UndoManager } from "../util/UndoManager"; -import { InkData, HandlePoint, HandleLine } from "../../fields/InkField"; -import { Transform } from "../util/Transform"; import { Doc } from "../../fields/Doc"; -import { listSpec } from "../../fields/Schema"; +import { HandleLine, HandlePoint, InkData } from "../../fields/InkField"; import { List } from "../../fields/List"; +import { listSpec } from "../../fields/Schema"; import { Cast } from "../../fields/Types"; +import { emptyFunction, setupMoveUpEvents } from "../../Utils"; +import { Transform } from "../util/Transform"; +import { UndoManager } from "../util/UndoManager"; import { Colors } from "./global/globalEnums"; -import { GestureOverlay } from "./GestureOverlay"; +import { InkStrokeProperties } from "./InkStrokeProperties"; export interface InkHandlesProps { inkDoc: Doc; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 06d15a108..768808569 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -115,28 +115,29 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume } componentUI = (boundsLeft: number, boundsTop: number) => { - const { inkData, inkScaleX, inkScaleY, inkStrokeWidth } = this.inkScaledData(); + const inkDoc = this.props.Document; + const screenSpaceCenterlineStrokeWidth = 3; // the width of the blue line widget that shows the centerline of the ink stroke + const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); const screenInkWidth = this.props.ScreenToLocalTransform().inverse().transformDirection(inkStrokeWidth, inkStrokeWidth); const screenPts = inkData.map(point => this.props.ScreenToLocalTransform().inverse().transformPoint(point.X, point.Y)).map(p => ({ X: p[0], Y: p[1] })); const screenTop = Math.min(...screenPts.map(p => p.Y)) - screenInkWidth[0] / 2; const screenLeft = Math.min(...screenPts.map(p => p.X)) - screenInkWidth[0] / 2; - - const inkDoc = this.props.Document; - - const overlayWidth = 3; const screenOrigin = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - const addedPoints = InteractionUtils.CreatePoints(inkData, screenLeft, screenTop, StrCast(inkDoc.strokeColor, "none"), screenInkWidth[0], overlayWidth, + const screenSpaceSamplePoints = InteractionUtils.CreatePoints(screenPts, screenLeft, screenTop, StrCast(inkDoc.strokeColor, "none"), screenInkWidth[0], screenSpaceCenterlineStrokeWidth, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), inkScaleX, inkScaleY, "", "none", this.props.isSelected() && inkStrokeWidth <= 5, false); + const inkSpaceSamplePoints = InteractionUtils.CreatePoints(inkData, inkLeft, inkTop, StrCast(inkDoc.strokeColor, "none"), inkStrokeWidth, screenSpaceCenterlineStrokeWidth, + StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), + StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), 1, 1, "", "none", this.props.isSelected() && inkStrokeWidth <= 5, false); return <div className="inkstroke-UI" style={{ left: screenOrigin[0], top: screenOrigin[1], clip: `rect(${boundsTop - screenOrigin[1]}px, 10000px, 10000px, ${boundsLeft - screenOrigin[0]}px)` }} > - {InteractionUtils.CreatePolyline(screenPts, screenLeft, screenTop, Colors.MEDIUM_BLUE, screenInkWidth[0], overlayWidth, + {InteractionUtils.CreatePolyline(screenPts, screenLeft, screenTop, Colors.MEDIUM_BLUE, screenInkWidth[0], screenSpaceCenterlineStrokeWidth, StrCast(inkDoc.strokeBezier), StrCast(inkDoc.fillColor, "none"), StrCast(inkDoc.strokeStartMarker), StrCast(inkDoc.strokeEndMarker), StrCast(inkDoc.strokeDash), inkScaleX, inkScaleY, "", "none", 1.0, false)} @@ -144,14 +145,16 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume <> <InkControls inkDoc={inkDoc} - data={screenPts} - addedPoints={addedPoints} - format={[screenLeft, screenTop, inkScaleX, inkScaleY, screenInkWidth[0], overlayWidth]} + inkCtrlPoints={inkData} + screenCtrlPoints={screenPts} + inkStrokeSamplePts={inkSpaceSamplePoints} + screenStrokeSamplePoints={screenSpaceSamplePoints} + format={[screenLeft, screenTop, inkScaleX, inkScaleY, screenInkWidth[0], screenSpaceCenterlineStrokeWidth]} ScreenToLocalTransform={this.props.ScreenToLocalTransform} /> <InkHandles inkDoc={inkDoc} data={screenPts} - format={[screenLeft, screenTop, inkScaleX, inkScaleY, screenInkWidth[0], overlayWidth]} + format={[screenLeft, screenTop, inkScaleX, inkScaleY, screenInkWidth[0], screenSpaceCenterlineStrokeWidth]} ScreenToLocalTransform={this.props.ScreenToLocalTransform} /> </> : ""} </div> |