aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-05-23 11:16:21 -0400
committerbobzel <zzzman@gmail.com>2025-05-23 11:16:21 -0400
commita98099cc968b6da408ea3a7bf92c657529eb4626 (patch)
tree9113886289c47b2eaea1c72660ea1c63aca60052
parentec30cdb94b9418a952643d016fa7e78955f5f9ab (diff)
fixes to rotation center to reset when not shown
-rw-r--r--src/client/views/DocumentDecorations.scss6
-rw-r--r--src/client/views/DocumentDecorations.tsx71
-rw-r--r--src/client/views/InkStrokeProperties.ts23
3 files changed, 44 insertions, 56 deletions
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<DocumentDecora
private _inkDragDocs: { doc: Doc; x: number; y: number; width: number; height: number }[] = [];
private _interactionLock?: boolean;
- @observable _showNothing = true;
+ @observable private _showNothing = true;
@observable private _forceRender = 0;
@observable private _accumulatedTitle = '';
@observable private _titleControlString: string = '$title';
@@ -349,13 +349,14 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
e.stopPropagation();
};
- setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => {
+ 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<DocumentDecora
setupMoveUpEvents(
this,
e,
- (moveEv: PointerEvent, down: number[], delta: number[]) => {
- 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<DocumentDecora
};
@action
- onRotateDown = (e: React.PointerEvent): void => {
+ 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<DocumentDecora
const unrotatedDocPos = { x: NumCast(dv.Document.x) + localRotCtrOffset[0] - startRotCtr.x, y: NumCast(dv.Document.y) + localRotCtrOffset[1] - startRotCtr.y };
infos.set(dv.Document, { unrotatedDocPos, startRotCtr, accumRot });
});
- const infoRot = (angle: number, isAbs = false) => {
- 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<DocumentDecora
(moveEv: PointerEvent, down: number[], delta: number[]) => {
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<DocumentDecora
if (lastView) {
const invXf = lastView.screenToViewTransform().inverse();
const seldoc = lastView.layoutDoc;
- const loccenter = Utils.rotPt(NumCast(seldoc._rotation_centerX) * NumCast(seldoc._width), NumCast(seldoc._rotation_centerY) * NumCast(seldoc._height), invXf.Rotate);
+ const rcent = this._showRotCenter ? [NumCast(seldoc._rotation_centerX), NumCast(seldoc._rotation_centerY)] : [0, 0];
+ const loccenter = Utils.rotPt(rcent[0] * NumCast(seldoc._width), rcent[1] * NumCast(seldoc._height), invXf.Rotate);
return invXf.transformPoint(loccenter.x + NumCast(seldoc._width) / 2, loccenter.y + NumCast(seldoc._height) / 2);
}
return this._rotCenter;
@@ -932,7 +917,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
}}>
{this._isRotating ? null : (
<Tooltip enterDelay={750} title={<div className="dash-tooltip">tap to set rotate center, drag to rotate</div>}>
- <div className="documentDecorations-rotation" onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
+ <div className="documentDecorations-rotation" onPointerDown={this.onRotateHdlDown} onContextMenu={e => e.preventDefault()}>
<IconButton icon={<FaUndo />} color={SettingsManager.userColor} />
</div>
</Tooltip>
@@ -941,7 +926,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
{!this._showRotCenter ? null : (
<div
className="documentDecorations-rotationCenter"
- style={{ transform: `translate(${this.rotCenter[0] - 3}px, ${this.rotCenter[1] - 3}px)` }}
+ style={{ transform: `translate(${this.rotCenter[0]}px, ${this.rotCenter[1]}px)` }}
onPointerDown={this.onRotateCenterDown}
onContextMenu={e => 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');
/**