From a98099cc968b6da408ea3a7bf92c657529eb4626 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 23 May 2025 11:16:21 -0400 Subject: fixes to rotation center to reset when not shown --- src/client/views/DocumentDecorations.scss | 6 ++- src/client/views/DocumentDecorations.tsx | 71 ++++++++++++------------------- src/client/views/InkStrokeProperties.ts | 23 +++++----- 3 files changed, 44 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 09a13634f..55eb0b127 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -32,8 +32,10 @@ $resizeHandler: 8px; } .documentDecorations-rotationCenter { position: absolute; - width: 6px; - height: 6px; + width: 9px; + height: 9px; + left: -4.5px; + top: -4.5px; pointer-events: all; background: green; border-radius: 50%; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 1e7f4fb52..a94bee7cb 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -58,7 +58,7 @@ export class DocumentDecorations extends ObservableReactComponent { + setDocRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => { const selDoc = seldocview.Document; const newloccentern = seldocview.screenToViewTransform().transformPoint(rotCenter[0], rotCenter[1]); const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2]; const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.Document._rotation) / 180) * Math.PI); selDoc._rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width); selDoc._rotation_centerY = final.y / NumCast(seldocview.layoutDoc._height); + return false; }; @action @@ -365,10 +366,7 @@ export class DocumentDecorations extends ObservableReactComponent { - this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]); - return false; - }, + (moveEv) => this.setDocRotateCenter(seldocview, [moveEv.clientX, moveEv.clientY]), action(() => { this._isRotating = false; }), // upEvent action(() => { seldocview.Document._rotation_centerX = seldocview.Document._rotation_centerY = 0; }), true @@ -377,7 +375,7 @@ export class DocumentDecorations extends ObservableReactComponent { + onRotateHdlDown = (e: React.PointerEvent): void => { this._isRotating = true; const rcScreen = { X: this.rotCenter[0], Y: this.rotCenter[1] }; const rotateUndo = UndoManager.StartBatch('drag rotation'); @@ -393,17 +391,20 @@ export class DocumentDecorations extends ObservableReactComponent { - DocumentView.Selected().forEach( - action(dv => { - const { unrotatedDocPos, startRotCtr, accumRot } = infos.get(dv.Document)!; - const endRotCtr = Utils.rotPt(startRotCtr.x, startRotCtr.y, isAbs ? angle : accumRot + angle); - infos.set(dv.Document, { unrotatedDocPos, startRotCtr, accumRot: isAbs ? angle : accumRot + angle }); - dv.Document.x = infos.get(dv.Document)!.unrotatedDocPos.x - (endRotCtr.x - startRotCtr.x); - dv.Document.y = infos.get(dv.Document)!.unrotatedDocPos.y - (endRotCtr.y - startRotCtr.y); - dv.Document._rotation = ((isAbs ? 0 : NumCast(dv.Document._rotation)) + (angle * 180) / Math.PI) % 360; // Rotation between -360 and 360 - }) - ); + const rotateDocs = (angle: number, isAbs = false) => { + if (selectedInk.length) { + InkStrokeProperties.Instance.rotateInk(selectedInk, angle, rcScreen); // rotate ink + return this.setDocRotateCenter(seldocview, centerPoint); + } + DocumentView.Selected().forEach(action(dv => { + const { unrotatedDocPos, startRotCtr, accumRot } = infos.get(dv.Document)!; + const endRotCtr = Utils.rotPt(startRotCtr.x, startRotCtr.y, isAbs ? angle : accumRot + angle); + infos.set(dv.Document, { unrotatedDocPos, startRotCtr, accumRot: isAbs ? angle : accumRot + angle }); + dv.Document.x = infos.get(dv.Document)!.unrotatedDocPos.x - (endRotCtr.x - startRotCtr.x); + dv.Document.y = infos.get(dv.Document)!.unrotatedDocPos.y - (endRotCtr.y - startRotCtr.y); + dv.Document._rotation = ((isAbs ? 0 : NumCast(dv.Document._rotation)) + (angle * 180) / Math.PI) % 360; // Rotation between -360 and 360 + })); // prettier-ignore + return false; }; setupMoveUpEvents( this, @@ -411,34 +412,17 @@ export class DocumentDecorations extends ObservableReactComponent { const previousPoint = { X: moveEv.clientX, Y: moveEv.clientY }; const movedPoint = { X: moveEv.clientX - delta[0], Y: moveEv.clientY - delta[1] }; - const deltaAng = InkStrokeProperties.angleChange(movedPoint, previousPoint, rcScreen); - if (selectedInk.length) { - deltaAng && InkStrokeProperties.Instance.rotateInk(selectedInk, deltaAng, rcScreen); - this.setRotateCenter(seldocview, centerPoint); - } else { - infoRot(deltaAng); - } - return false; + return rotateDocs(InkStrokeProperties.angleChange(movedPoint, previousPoint, rcScreen)); }, // moveEvent action(() => { const oldRotation = NumCast(seldocview.Document._rotation); - const diff = oldRotation - Math.round(oldRotation / 45) * 45; - if (Math.abs(diff) < 5) { - if (selectedInk.length) { - InkStrokeProperties.Instance.rotateInk(selectedInk, ((Math.round(oldRotation / 45) * 45 - oldRotation) / 180) * Math.PI, rcScreen); - } else { - infoRot(((Math.round(oldRotation / 45) * 45) / 180) * Math.PI, true); - } - } - if (selectedInk.length) { - this.setRotateCenter(seldocview, centerPoint); - } + if (Math.abs(oldRotation - Math.round(oldRotation / 45) * 45) < 5) { // rptation witihin 5deg of a 45deg angle multiple + rotateDocs(((Math.round(oldRotation / 45) * 45) / 180) * Math.PI, true); + } // prettier-ignore this._isRotating = false; rotateUndo?.end(); }), // upEvent - action(() => { - this._showRotCenter = !this._showRotCenter; - }) // clickEvent + action(() => (this._showRotCenter = !this._showRotCenter)) // clickEvent ); }; @@ -695,7 +679,8 @@ export class DocumentDecorations extends ObservableReactComponent {this._isRotating ? null : ( tap to set rotate center, drag to rotate}> -
e.preventDefault()}> +
e.preventDefault()}> } color={SettingsManager.userColor} />
@@ -941,7 +926,7 @@ export class DocumentDecorations extends ObservableReactComponent e.preventDefault()} /> diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 41f38c008..9f2c1fc4e 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -209,17 +209,18 @@ export class InkStrokeProperties { * @param scrpt The center point of the rotation in screen coordinates */ rotateInk = undoable((inkStrokes: DocumentView[], angle: number, scrpt: PointData) => { - this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number /* , inkStrokeWidth: number */) => { - const inkCenterPt = view.ComponentView?.ptFromScreen?.(scrpt); - return !inkCenterPt - ? ink - : ink.map(i => { - const pt = { X: i.X - inkCenterPt.X, Y: i.Y - inkCenterPt.Y }; - const newX = Math.cos(angle) * pt.X - (Math.sin(angle) * pt.Y * yScale) / xScale; - const newY = (Math.sin(angle) * pt.X * xScale) / yScale + Math.cos(angle) * pt.Y; - return { X: newX + inkCenterPt.X, Y: newY + inkCenterPt.Y }; - }); - }); + angle && + this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number /* , inkStrokeWidth: number */) => { + const inkCenterPt = view.ComponentView?.ptFromScreen?.(scrpt); + return !inkCenterPt + ? ink + : ink.map(i => { + const pt = { X: i.X - inkCenterPt.X, Y: i.Y - inkCenterPt.Y }; + const newX = Math.cos(angle) * pt.X - (Math.sin(angle) * pt.Y * yScale) / xScale; + const newY = (Math.sin(angle) * pt.X * xScale) / yScale + Math.cos(angle) * pt.Y; + return { X: newX + inkCenterPt.X, Y: newY + inkCenterPt.Y }; + }); + }); }, 'rotate ink'); /** -- cgit v1.2.3-70-g09d2