Skip to content

Commit eb1f31d

Browse files
Fixed annotation getting rotated when moving between pages
1 parent 47791a4 commit eb1f31d

File tree

2 files changed

+96
-4
lines changed

2 files changed

+96
-4
lines changed

src/display/editor/annotation_editor_layer.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,13 +488,35 @@ class AnnotationEditorLayer {
488488

489489
this.attach(editor);
490490
editor.parent?.detach(editor);
491+
this.resetRotation(editor);
491492
editor.setParent(this);
492493
if (editor.div && editor.isAttachedToDOM) {
493494
editor.div.remove();
494495
this.div.append(editor.div);
495496
}
496497
}
497498

499+
/**
500+
* When a page is rotated, the editor must be rotated as well
501+
* to maintain the same orientation.
502+
* @param {AnnotationEditor} editor
503+
*/
504+
resetRotation(editor) {
505+
if (this.viewport.rotation === editor.parent.viewport.rotation) {
506+
return;
507+
}
508+
const rotationOfThisPage = this.viewport.rotation;
509+
const currentRotation =
510+
360 - Number(this.div.getAttribute("data-main-rotation"));
511+
512+
const pageRotation =
513+
(360 + rotationOfThisPage - editor._uiManager.viewParameters.rotation) %
514+
360;
515+
editor.pageRotation = pageRotation;
516+
editor.rotation = rotationOfThisPage;
517+
editor.div.setAttribute("data-editor-rotation", currentRotation);
518+
}
519+
498520
/**
499521
* Add a new editor in the current view.
500522
* @param {AnnotationEditor} editor

src/display/editor/editor.js

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,42 @@ class AnnotationEditor {
259259
return false;
260260
}
261261

262+
/**
263+
* Rotate a point about 0.5 0.5 origin
264+
* @param {number} x
265+
* @param {number} y
266+
* @param {number} angle
267+
* @returns {any} The rotated point
268+
*/
269+
static rotatePointByMidPoint(x, y, angle) {
270+
const originX = 0.5;
271+
const originY = 0.5;
272+
// Translate the point to the origin (originX, originY)
273+
const translatedX = x - originX;
274+
const translatedY = y - originY;
275+
let rotatedX, rotatedY;
276+
277+
// Perform the rotation based on the given angle
278+
switch (angle) {
279+
case 90:
280+
rotatedX = -translatedY;
281+
rotatedY = translatedX;
282+
break;
283+
case 270:
284+
rotatedX = translatedY;
285+
rotatedY = -translatedX;
286+
break;
287+
default:
288+
throw new Error("Invalid angle. Valid angles are 90 and 270 degrees.");
289+
}
290+
291+
// Translate the point back
292+
const finalX = rotatedX + originX;
293+
const finalY = rotatedY + originY;
294+
295+
return { x: finalX, y: finalY };
296+
}
297+
262298
/**
263299
* Extract the data from the clipboard item and delegate the creation of the
264300
* editor to the parent.
@@ -469,19 +505,53 @@ class AnnotationEditor {
469505
const [parentWidth, parentHeight] = this.parentDimensions;
470506
this.x += tx / parentWidth;
471507
this.y += ty / parentHeight;
508+
509+
const oldRotation = this.rotation;
510+
472511
if (this.parent && (this.x < 0 || this.x > 1 || this.y < 0 || this.y > 1)) {
473512
// It's possible to not have a parent: for example, when the user is
474513
// dragging all the selected editors but this one on a page which has been
475514
// destroyed.
476515
// It's why we need to check for it. In such a situation, it isn't really
477516
// a problem to not find a new parent: it's something which is related to
478517
// what the user is seeing, hence it depends on how pages are layed out.
479-
480-
// The element will be outside of its parent so change the parent.
481518
const { x, y } = this.div.getBoundingClientRect();
482519
if (this.parent.findNewParent(this, x, y)) {
483-
this.x -= Math.floor(this.x);
484-
this.y -= Math.floor(this.y);
520+
const newRotation = this.rotation;
521+
if (oldRotation !== newRotation) {
522+
const {
523+
x: layerX,
524+
y: layerY,
525+
width,
526+
height,
527+
} = this.parent.div.getBoundingClientRect();
528+
this.x = (x - layerX) / width;
529+
this.y = (y - layerY) / height;
530+
531+
if (newRotation === 90) {
532+
const points = AnnotationEditor.rotatePointByMidPoint(
533+
this.x,
534+
this.y,
535+
270
536+
);
537+
this.x = points.x;
538+
this.y = points.y;
539+
} else if (newRotation === 270) {
540+
const points = AnnotationEditor.rotatePointByMidPoint(
541+
this.x,
542+
this.y,
543+
90
544+
);
545+
this.x = points.x;
546+
this.y = points.y;
547+
} else if (newRotation === 180) {
548+
this.x = 1 - this.x;
549+
this.y = 1 - this.y;
550+
}
551+
} else {
552+
this.x -= Math.floor(this.x);
553+
this.y -= Math.floor(this.y);
554+
}
485555
}
486556
}
487557

0 commit comments

Comments
 (0)