From 061dab5285d3a334a258d8097a6e95b065b30de3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 29 Nov 2021 14:09:17 -0500 Subject: added moving ink stroke segments. added stretching and rotating ink strokes about opposite end point. --- src/client/views/InkControlPtHandles.tsx | 77 +++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 10 deletions(-) (limited to 'src/client/views/InkControlPtHandles.tsx') diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx index f24dab949..df803ba31 100644 --- a/src/client/views/InkControlPtHandles.tsx +++ b/src/client/views/InkControlPtHandles.tsx @@ -6,7 +6,7 @@ import { ControlPoint, InkData, PointData, InkField } from "../../fields/InkFiel import { List } from "../../fields/List"; import { listSpec } from "../../fields/Schema"; import { Cast, NumCast } from "../../fields/Types"; -import { setupMoveUpEvents } from "../../Utils"; +import { setupMoveUpEvents, returnFalse } from "../../Utils"; import { Transform } from "../util/Transform"; import { UndoManager } from "../util/UndoManager"; import { Colors } from "./global/globalEnums"; @@ -133,7 +133,6 @@ export class InkControlPtHandles extends React.Component { inkCtrlPts.push({ ...inkData[i + 3], I: i + 3 }); } - const screenSpaceLineWidth = this.props.screenSpaceLineWidth; const closed = InkingStroke.IsClosed(inkData); const nearestScreenPt = this.props.nearestScreenPt(); const TagType = (broken?: boolean) => broken ? "rect" : "circle"; @@ -141,18 +140,18 @@ export class InkControlPtHandles extends React.Component { const broken = Cast(this.props.inkDoc.brokenInkIndices, listSpec("number"))?.includes(control.I); const Tag = TagType((control.I === 0 || control.I === inkData.length - 1) && !closed) as keyof JSX.IntrinsicElements; return this.onControlDown(e, control.I)} + onPointerDown={(e: React.PointerEvent) => this.onControlDown(e, control.I)} onMouseEnter={() => this.onEnterControl(control.I)} onMouseLeave={this.onLeaveControl} pointerEvents="all" @@ -164,7 +163,7 @@ export class InkControlPtHandles extends React.Component { { ); } +} + + +export interface InkEndProps { + inkDoc: Doc; + inkView: DocumentView; + screenSpaceLineWidth: number; + startPt: PointData; + endPt: PointData; +} +@observer +export class InkEndPtHandles extends React.Component { + @observable controlUndo: UndoManager.Batch | undefined; + @observable _overStart: boolean = false; + @observable _overEnd: boolean = false; + + @action + dragRotate = (e: React.PointerEvent, p1: () => { X: number, Y: number }, p2: () => { X: number, Y: number }) => { + setupMoveUpEvents(this, e, (e) => { + if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("stretch ink"); + // compute stretch factor by finding scaling along axis between start and end points + const v1 = { x: p1().X - p2().X, y: p1().Y - p2().Y }; + const v2 = { x: e.clientX - p2().X, y: e.clientY - p2().Y }; + const v1len = Math.sqrt(v1.x * v1.x + v1.y * v1.y); + const v2len = Math.sqrt(v2.x * v2.x + v2.y * v2.y); + const scaling = v2len / v1len; + const v1n = { x: v1.x / v1len, y: v1.y / v1len }; + const v2n = { x: v2.x / v2len, y: v2.y / v2len }; + const angle = Math.acos(v1n.x * v2n.x + v1n.y * v2n.y) * Math.sign(v1.x * v2.y - v2.x * v1.y) + InkStrokeProperties.Instance?.stretchInk([this.props.inkView], scaling, { x: p2().X, y: p2().Y }, v1n); + InkStrokeProperties.Instance?.rotateInk([this.props.inkView], angle, { x: p2().X, y: p2().Y }); + return false; + }, action(() => { + this.controlUndo?.end(); + this.controlUndo = undefined; + UndoManager.FilterBatches(["data", "x", "y", "width", "height"]); + }), returnFalse); + } + + render() { + const hdl = (pt: PointData, dragFunc: (e: React.PointerEvent) => void) => this._overStart = false)} + onPointerEnter={action(() => this._overStart = true)} + onPointerDown={e => dragFunc(e)} + pointerEvents="all" + />; + return ( + {hdl(this.props.startPt, (e: React.PointerEvent) => this.dragRotate(e, () => this.props.startPt, () => this.props.endPt))} + {hdl(this.props.endPt, (e: React.PointerEvent) => this.dragRotate(e, () => this.props.endPt, () => this.props.startPt))} + + ); + } } \ No newline at end of file -- cgit v1.2.3-70-g09d2