From 62f143a6daf4e396ef031cfae70150fc122a0ecc Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 8 May 2021 11:24:13 -0400 Subject: fixed ink control point selection to not change scale of ink stroke --- src/client/views/InkStrokeProperties.ts | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'src/client/views/InkStrokeProperties.ts') diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 9257ee4e6..358cce35b 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -222,26 +222,18 @@ export class InkStrokeProperties { { X: ink[i].X - xDiff, Y: ink[i].Y - yDiff } : { X: ink[i].X, Y: ink[i].Y }); } - const oldx = doc.x; - const oldy = doc.y; - const oldxs = ink.map(p => p.X); - const oldys = ink.map(p => p.Y); - const oldleft = Math.min(...oldxs); - const oldtop = Math.min(...oldys); - Doc.GetProto(doc).data = new InkField(newPoints); - const newxs = newPoints.map(p => p.X); - const newys = newPoints.map(p => p.Y); - const newleft = Math.min(...newxs); - const newtop = Math.min(...newys); - const newright = Math.max(...newxs); - const newbottom = Math.max(...newys); - //if points move out of bounds - doc._height = (newbottom - newtop) * inkView.props.ScreenToLocalTransform().Scale; - doc._width = (newright - newleft) * inkView.props.ScreenToLocalTransform().Scale; + const oldXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X)); + const oldYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y)); + const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); + const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); - doc.x = oldx - (oldleft - newleft) * inkView.props.ScreenToLocalTransform().Scale; - doc.y = oldy - (oldtop - newtop) * inkView.props.ScreenToLocalTransform().Scale; + //if points move out of bounds + doc._height = (newYrange.max - newYrange.min) * NumCast(doc._height) / (oldYrange.max - oldYrange.min); + doc._width = (newXrange.max - newXrange.min) * NumCast(doc._width) / (oldXrange.max - oldXrange.min); + doc.x = doc.x - (oldXrange.min - newXrange.min); + doc.y = doc.y - (oldYrange.min - newYrange.min); + Doc.GetProto(doc).data = new InkField(newPoints); } } } -- cgit v1.2.3-70-g09d2 From 47006b0025ae9ea13313900124ca097227be50a2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 8 May 2021 11:33:20 -0400 Subject: fixed deleting ink stroke points. --- src/client/views/InkStrokeProperties.ts | 3 +++ src/client/views/InkingStroke.tsx | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/client/views/InkStrokeProperties.ts') diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 358cce35b..5cbfa65cd 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -117,6 +117,7 @@ export class InkStrokeProperties { @undoBatch @action deletePoints = () => { + var deleted = false; this.selectedInk?.forEach(action(inkView => { if (this.selectedInk?.length === 1 && this._currPoint !== -1) { const doc = Document(inkView.rootDoc); @@ -141,10 +142,12 @@ export class InkStrokeProperties { Doc.GetProto(doc).data = new InkField(newerPoints); } + deleted = true; } } } })); + return deleted; } @undoBatch diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 966abc0e7..b97d09fda 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -81,9 +81,9 @@ export class InkingStroke extends ViewBoxBaseComponent { - if (InkStrokeProperties.Instance && (e instanceof KeyboardEvent ? e.key === "-" : true)) { - InkStrokeProperties.Instance.deletePoints(); + delPts = (e: KeyboardEvent) => { + if (["-", "Backspace", "Delete"].includes(e.key)) { + if (InkStrokeProperties.Instance?.deletePoints()) e.stopPropagation(); } } -- cgit v1.2.3-70-g09d2 From 249a63d204068660d4a86578f49b67c2df1adbf4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 10 May 2021 13:42:38 -0400 Subject: fixes to editing curve UI - handle sizes, no jumping when changing/deleting a boundary point. Rotation of curves is really broken -- needs to be redone. --- src/client/views/InkStrokeProperties.ts | 32 +++++++++---- src/client/views/InkingStroke.tsx | 85 ++++++++++++++------------------- 2 files changed, 59 insertions(+), 58 deletions(-) (limited to 'src/client/views/InkStrokeProperties.ts') diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 5cbfa65cd..f400eb863 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -121,13 +121,17 @@ export class InkStrokeProperties { this.selectedInk?.forEach(action(inkView => { if (this.selectedInk?.length === 1 && this._currPoint !== -1) { const doc = Document(inkView.rootDoc); - if (doc.type === DocumentType.INK) { + if (doc.type === DocumentType.INK && doc.width && doc.height) { const ink = Cast(doc.data, InkField)?.inkData; if (ink && ink.length > 4) { + 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 ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min); + const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min); const newPoints: { X: number, Y: number }[] = []; const toRemove = Math.floor(((this._currPoint + 2) / 4)); for (var i = 0; i < ink.length; i++) { - if (Math.floor((i + 2) / 4) !== toRemove) { + if (Math.floor((i + 2) / 4) !== toRemove && (toRemove !== 0 || i > 3)) { newPoints.push({ X: ink[i].X, Y: ink[i].Y }); } } @@ -142,6 +146,12 @@ export class InkStrokeProperties { Doc.GetProto(doc).data = new InkField(newerPoints); } + const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); + const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); + doc._width = (newXrange.max - newXrange.min) * ptsXscale; + doc._height = (newYrange.max - newYrange.min) * ptsYscale; + doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale); + doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale); deleted = true; } } @@ -206,9 +216,13 @@ export class InkStrokeProperties { this.selectedInk?.forEach(action(inkView => { if (this.selectedInk?.length === 1) { const doc = Document(inkView.rootDoc); - if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + if (doc.type === DocumentType.INK && doc._width && doc._height) { const ink = Cast(doc.data, InkField)?.inkData; if (ink) { + 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 ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min); + const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min); const newPoints: { X: number, Y: number }[] = []; const order = controlNum % 4; for (var i = 0; i < ink.length; i++) { @@ -222,20 +236,18 @@ export class InkStrokeProperties { (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, Y: ink[i].Y - yDiff } : + { X: ink[i].X - xDiff / ptsXscale, Y: ink[i].Y - yDiff / ptsYscale } : { X: ink[i].X, Y: ink[i].Y }); } - const oldXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X)); - const oldYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y)); const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); //if points move out of bounds - doc._height = (newYrange.max - newYrange.min) * NumCast(doc._height) / (oldYrange.max - oldYrange.min); - doc._width = (newXrange.max - newXrange.min) * NumCast(doc._width) / (oldXrange.max - oldXrange.min); - doc.x = doc.x - (oldXrange.min - newXrange.min); - doc.y = doc.y - (oldYrange.min - newYrange.min); + doc._width = (newXrange.max - newXrange.min) * ptsXscale; + doc._height = (newYrange.max - newYrange.min) * ptsYscale; + doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale); + doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale); Doc.GetProto(doc).data = new InkField(newPoints); } } diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index b97d09fda..6a4afbb5c 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -41,45 +41,29 @@ export class InkingStroke extends ViewBoxBaseComponent { - //TODO:renew points before controlling - InkStrokeProperties.Instance?.control(0.001, 0.001, 1); - setupMoveUpEvents(this, e, this.onControlMove, this.onControlup, (e) => { }); - this._controlUndo = UndoManager.StartBatch("DocDecs set radius"); - this._prevX = e.clientX; - this._prevY = e.clientY; - this._controlNum = i; + onControlDown = (e: React.PointerEvent, controlNum: number): void => { + if (InkStrokeProperties.Instance) { + InkStrokeProperties.Instance.control(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); + return false; + }, + () => controlUndo?.end(), emptyFunction); + } } @action changeCurrPoint = (i: number) => { - if (!InkStrokeProperties.Instance) return; - InkStrokeProperties.Instance._currPoint = i; - document.addEventListener("keydown", this.delPts, true); - } - - @action - onControlMove = (e: PointerEvent, down: number[]): boolean => { - if (!InkStrokeProperties.Instance) return false; - const xDiff = this._prevX - e.clientX; - const yDiff = this._prevY - e.clientY; - InkStrokeProperties.Instance.control(xDiff, yDiff, this._controlNum); - this._prevX = e.clientX; - this._prevY = e.clientY; - return false; + if (InkStrokeProperties.Instance) { + InkStrokeProperties.Instance._currPoint = i; + document.addEventListener("keydown", this.delPts, true); + } } - onControlup = (e: PointerEvent) => { - this._prevX = 0; - this._prevY = 0; - this._controlNum = 0; - this._controlUndo?.end(); - this._controlUndo = undefined; - } @action delPts = (e: KeyboardEvent) => { if (["-", "Backspace", "Delete"].includes(e.key)) { @@ -88,9 +72,10 @@ export class InkingStroke extends ViewBoxBaseComponent { - this.props.isSelected(true) && setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e: PointerEvent, doubleTap: boolean | undefined) => { - doubleTap && InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true); - })); + if (this.props.isSelected(true)) { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e: PointerEvent, doubleTap: boolean | undefined) => + doubleTap && InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true))); + } } public static MaskDim = 50000; @@ -152,6 +137,10 @@ export class InkingStroke extends ViewBoxBaseComponent - { formatInstance.addPoints(pts.X, pts.Y, apoints, i, controlPoints); }} pointerEvents="all" cursor="all-scroll" /> ); + const handles = handlePoints.map((pts, i) => + + this.onControlDown(e, pts.I)} pointerEvents="all" cursor="default" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> + ); const controls = controlPoints.map((pts, i) => - { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="all-scroll" + { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="default" /> ); - const handles = handlePoints.map((pts, i) => - - this.onControlDown(e, pts.I)} pointerEvents="all" cursor="all-scroll" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> - ); const handleLines = handleLine.map((pts, i) => ); @@ -216,9 +205,9 @@ export class InkingStroke extends ViewBoxBaseComponent ); -- cgit v1.2.3-70-g09d2 From 846f3e6acda0ea568441a4b5f3765e98634d6d19 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 11 May 2021 00:18:34 -0400 Subject: fixed ink rotation to maintain center point --- src/client/views/DocumentDecorations.tsx | 31 ++---- src/client/views/InkStrokeProperties.ts | 176 +++++++++++-------------------- src/client/views/InkingStroke.tsx | 4 +- 3 files changed, 75 insertions(+), 136 deletions(-) (limited to 'src/client/views/InkStrokeProperties.ts') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 959b44f98..bf939d57c 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -197,8 +197,15 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onRotateDown = (e: React.PointerEvent): void => { this._rotateUndo = UndoManager.StartBatch("rotatedown"); - - setupMoveUpEvents(this, e, this.onRotateMove, () => this._rotateUndo?.end(), emptyFunction); + setupMoveUpEvents(this, e, + (e: PointerEvent, down: number[], delta: number[]) => { + const movement = { X: delta[0], Y: e.clientY - down[1] }; + const angle = Math.max(1, Math.abs(movement.Y / 10)); + InkStrokeProperties.Instance?.rotate(2 * movement.X / angle * (Math.PI / 180)); + return false; + }, + () => this._rotateUndo?.end(), + emptyFunction); this._prevY = e.clientY; this._inkCenterPts = SelectionManager.Views() .filter(dv => dv.rootDoc.type === DocumentType.INK) @@ -206,26 +213,6 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b .map(({ ink, doc }) => ({ doc, X: Math.min(...ink.map(p => p.X)), Y: Math.min(...ink.map(p => p.Y)) })); } - @action - onRotateMove = (e: PointerEvent, down: number[]): boolean => { - const distance = Math.abs(this._prevY - e.clientY); - const angle = e.clientY > this._prevY ? distance * (Math.PI / 180) : e.clientY < this._prevY ? - distance * (Math.PI / 180) : 0; - this._prevY = e.clientY; - this._inkCenterPts.map(({ doc, X, Y }) => ({ doc, X, Y, inkData: Cast(doc.data, InkField)?.inkData })) - .forEach(pair => { - const newPoints = pair.inkData?.map(ink => ({ - X: Math.cos(angle) * (ink.X - pair.X) - Math.sin(angle) * (ink.Y - pair.Y) + pair.X, - Y: Math.sin(angle) * (ink.X - pair.X) + Math.cos(angle) * (ink.Y - pair.Y) + pair.Y - })) || []; - Doc.GetProto(pair.doc).data = new InkField(newPoints); - - pair.doc._width = ((xs) => (Math.max(...xs) - Math.min(...xs)))(newPoints.map(p => p.X) || [0]); - pair.doc._height = ((ys) => (Math.max(...ys) - Math.min(...ys)))(newPoints.map(p => p.Y) || [0]); - pair.doc.rotation = NumCast(pair.doc.rotation) + angle; - }); - return false; - } - @action onPointerDown = (e: React.PointerEvent): void => { DragManager.docsBeingDragged = SelectionManager.Views().map(dv => dv.rootDoc); diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index f400eb863..1261921ba 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -2,11 +2,12 @@ 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 } from "../../fields/InkField"; +import { InkField, InkData } 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; @@ -114,146 +115,97 @@ export class InkStrokeProperties { })); } - @undoBatch - @action - deletePoints = () => { - var deleted = false; + applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[], requireCurrPoint: boolean = false) => { + var appliedFunc = false; this.selectedInk?.forEach(action(inkView => { - if (this.selectedInk?.length === 1 && this._currPoint !== -1) { + if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currPoint !== -1)) { const doc = Document(inkView.rootDoc); if (doc.type === DocumentType.INK && doc.width && doc.height) { const ink = Cast(doc.data, InkField)?.inkData; - if (ink && ink.length > 4) { + if (ink) { 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 ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min); const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min); - const newPoints: { X: number, Y: number }[] = []; - const toRemove = Math.floor(((this._currPoint + 2) / 4)); - for (var i = 0; i < ink.length; i++) { - if (Math.floor((i + 2) / 4) !== toRemove && (toRemove !== 0 || i > 3)) { - newPoints.push({ X: ink[i].X, Y: ink[i].Y }); - } - } - this._currPoint = -1; - Doc.GetProto(doc).data = new InkField(newPoints); - if (newPoints.length === 4) { - const newerPoints: { X: number, Y: number }[] = []; - newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y }); - newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y }); - newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y }); - newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y }); - Doc.GetProto(doc).data = new InkField(newerPoints); - - } + const newPoints = func(doc, ink, ptsXscale, ptsYscale); const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); doc._width = (newXrange.max - newXrange.min) * ptsXscale; doc._height = (newYrange.max - newYrange.min) * ptsYscale; doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale); doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale); - deleted = true; + Doc.GetProto(doc).data = new InkField(newPoints); + appliedFunc = true; } } } })); - return deleted; + return appliedFunc; } @undoBatch @action - rotate = (angle: number) => { - const _centerPoints: { X: number, Y: number }[] = []; - SelectionManager.Views().forEach(action(inkView => { - const doc = Document(inkView.rootDoc); - if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { - const ink = Cast(doc.data, InkField)?.inkData; - if (ink) { - const xs = ink.map(p => p.X); - const ys = ink.map(p => p.Y); - const left = Math.min(...xs); - const top = Math.min(...ys); - const right = Math.max(...xs); - const bottom = Math.max(...ys); - _centerPoints.push({ X: left, Y: top }); - } + deletePoints = () => this.applyFunction((doc: Doc, ink: InkData) => { + var newPoints: { X: number, Y: number }[] = []; + const toRemove = Math.floor(((this._currPoint + 2) / 4)); + for (var i = 0; i < ink.length; i++) { + if (Math.floor((i + 2) / 4) !== toRemove && (toRemove !== 0 || i > 3)) { + newPoints.push({ X: ink[i].X, Y: ink[i].Y }); } - })); - - var index = 0; - SelectionManager.Views().forEach(action(inkView => { - const doc = Document(inkView.rootDoc); - if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { - doc.rotation = NumCast(doc.rotation) + angle; - const ink = Cast(doc.data, InkField)?.inkData; - if (ink) { - - const newPoints: { X: number, Y: number }[] = []; - ink.forEach(i => { - const newX = Math.cos(angle) * (i.X - _centerPoints[index].X) - Math.sin(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].X; - const newY = Math.sin(angle) * (i.X - _centerPoints[index].X) + Math.cos(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].Y; - newPoints.push({ X: newX, Y: newY }); - }); - Doc.GetProto(doc).data = new InkField(newPoints); - const xs = newPoints.map(p => p.X); - const ys = newPoints.map(p => p.Y); - const left = Math.min(...xs); - const top = Math.min(...ys); - const right = Math.max(...xs); - const bottom = Math.max(...ys); + } + this._currPoint = -1; + Doc.GetProto(doc).data = new InkField(newPoints); + if (newPoints.length === 4) { + const newerPoints: { X: number, Y: number }[] = []; + newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y }); + newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y }); + newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y }); + newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y }); + return newerPoints; + } + return newPoints; + }, true); - doc._height = (bottom - top); - doc._width = (right - left); - } - index++; - } - })); + @undoBatch + @action + rotate = (angle: number) => { + this.applyFunction((doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { + 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 }); + }); + doc.rotation = NumCast(doc.rotation) + angle; + return newPoints; + }); } @undoBatch @action - control = (xDiff: number, yDiff: number, controlNum: number) => { - this.selectedInk?.forEach(action(inkView => { - if (this.selectedInk?.length === 1) { - const doc = Document(inkView.rootDoc); - if (doc.type === DocumentType.INK && doc._width && doc._height) { - const ink = Cast(doc.data, InkField)?.inkData; - if (ink) { - 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 ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min); - const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min); - const newPoints: { X: number, Y: number }[] = []; - const order = controlNum % 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 newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); - const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); - - //if points move out of bounds - doc._width = (newXrange.max - newXrange.min) * ptsXscale; - doc._height = (newYrange.max - newYrange.min) * ptsYscale; - doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale); - doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale); - Doc.GetProto(doc).data = new InkField(newPoints); - } - } + control = (xDiff: number, yDiff: number, controlNum: number) => + this.applyFunction((doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { + const newPoints: { X: number, Y: number }[] = []; + const order = controlNum % 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 }); } - })); - } + return newPoints; + }); @undoBatch @action diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 6a4afbb5c..449019ca8 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -161,13 +161,13 @@ export class InkingStroke extends ViewBoxBaseComponent); const handles = handlePoints.map((pts, i) => - this.onControlDown(e, pts.I)} pointerEvents="all" cursor="default" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} /> ); const controls = controlPoints.map((pts, i) => - { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="default" /> ); -- cgit v1.2.3-70-g09d2 From 695463cdebce073c219b68feac4f56fd5ad5283d Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 11 May 2021 01:28:56 -0400 Subject: from last --- src/client/views/InkStrokeProperties.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/client/views/InkStrokeProperties.ts') diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 1261921ba..b13b04f68 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -115,7 +115,7 @@ export class InkStrokeProperties { })); } - applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[], requireCurrPoint: boolean = false) => { + applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => { var appliedFunc = false; this.selectedInk?.forEach(action(inkView => { if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currPoint !== -1)) { @@ -128,14 +128,16 @@ export class InkStrokeProperties { const ptsXscale = NumCast(doc._width) / (oldXrange.max - oldXrange.min); const ptsYscale = NumCast(doc._height) / (oldYrange.max - oldYrange.min); const newPoints = func(doc, ink, ptsXscale, ptsYscale); - const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); - const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); - doc._width = (newXrange.max - newXrange.min) * ptsXscale; - doc._height = (newYrange.max - newYrange.min) * ptsYscale; - doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale); - doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale); - Doc.GetProto(doc).data = new InkField(newPoints); - appliedFunc = true; + if (newPoints) { + const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); + const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); + doc._width = (newXrange.max - newXrange.min) * ptsXscale; + doc._height = (newYrange.max - newYrange.min) * ptsYscale; + doc.x = (oldXrange.coord + (newXrange.min - oldXrange.min) * ptsXscale); + doc.y = (oldYrange.coord + (newYrange.min - oldYrange.min) * ptsYscale); + Doc.GetProto(doc).data = new InkField(newPoints); + appliedFunc = true; + } } } } @@ -154,7 +156,7 @@ export class InkStrokeProperties { } } this._currPoint = -1; - Doc.GetProto(doc).data = new InkField(newPoints); + if (newPoints.length < 4) return undefined; if (newPoints.length === 4) { const newerPoints: { X: number, Y: number }[] = []; newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y }); -- cgit v1.2.3-70-g09d2