Skip to content

feat(annotations): add logic for drawing/region annotation cursor input on rotated files#748

Merged
kduncanhsu merged 6 commits into
box:masterfrom
kduncanhsu:fix/annotation-drawing-rotation-coordinate-transform
May 13, 2026
Merged

feat(annotations): add logic for drawing/region annotation cursor input on rotated files#748
kduncanhsu merged 6 commits into
box:masterfrom
kduncanhsu:fix/annotation-drawing-rotation-coordinate-transform

Conversation

@kduncanhsu
Copy link
Copy Markdown
Contributor

@kduncanhsu kduncanhsu commented May 8, 2026

Summary

Adds support for live annotation drawing on rotated pages/images. This is in preparation for enabling annotation creation on rotated PDFs and images, where the annotation controls were previously hidden. Without this change, simply re-enabling annotation creation controls in the rotated state would cause the live drawing input to be offset from the user’s cursor.

This PR:

  • Correctly maps window/browser mouse coordinates to annotation layer's local coordinate system, ensuring that live drawing/region input is correct when files are rotated
  • Uses offsetWidth/offsetHeight (pre-transform dimensions) for percentage instead of getBoundingClientRect() which returns post-transform axis-aligned bounding box dimensions
  • Removes the isRotated guard that blocked region annotation creation on rotated files

For further clarity, here is the live pointer capture flow when drawing annotations:

  1. Mouse events provide clientX/clientY coordinates in screen space.
  2. getPosition applies the inverse rotation transform to convert window/browser coordinates into the annotation layer’s local coordinate space.
  3. getPoints/getShape normalize those local-space pixel coordinates into percentages using the annotation layer’s pre-transform (unrotated) offsetWidth/offsetHeight.

Test plan

  • Rotate a PDF 90°, 180°, 270° counterclockwise and verify drawing annotations follow the cursor
  • Rotate an image 90°, 180°, 270° and verify region annotations follow the cursor
  • Verify annotations on unrotated (0°) files still work correctly
  • Verify stored annotations remain anchored to content when rotation changes

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Duncan Hsu seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@kduncanhsu kduncanhsu force-pushed the fix/annotation-drawing-rotation-coordinate-transform branch from f70e8c5 to 4039be9 Compare May 11, 2026 19:59
@kduncanhsu kduncanhsu changed the title feat(annotations): correct drawing coords on rotated pages feat(annotations): correct live drawing input coords on rotated pages May 12, 2026
@kduncanhsu kduncanhsu marked this pull request as ready for review May 12, 2026 01:03
@kduncanhsu kduncanhsu requested a review from a team as a code owner May 12, 2026 01:03
@kduncanhsu kduncanhsu changed the title feat(annotations): correct live drawing input coords on rotated pages feat(annotations): add logic for drawing/region annotations on rotated files correct live drawing input coords on rotated pages May 12, 2026
@kduncanhsu kduncanhsu changed the title feat(annotations): add logic for drawing/region annotations on rotated files correct live drawing input coords on rotated pages feat(annotations): add logic for drawing/region annotation input on rotated files May 12, 2026
@kduncanhsu kduncanhsu changed the title feat(annotations): add logic for drawing/region annotation input on rotated files feat(annotations): add logic for drawing/region annotation cursor input on rotated files May 12, 2026
Comment thread src/drawing/DrawingCreator.tsx Outdated
const local = rotatePoint({ x: relX, y: relY }, -rotation);

// Convert from center-relative to top-left-relative using pre-transform dimensions
return [local.x + creatorEl.offsetWidth / 2, local.y + creatorEl.offsetHeight / 2];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a comment explaining this whole algorithm? I'm finding it hard to follow even with the comments here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried incorporating clearer comments explaining the algorithm in the shared helper function within utils/rotate.ts. Let me know if it's easier to follow now, even with clear comments the logic can be quite confusing without diagrams so I could also walk through it in a watercooler session if that's helpful

Copy link
Copy Markdown

@jmcbgaston jmcbgaston left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix — the inverse-rotation approach is the correct way to handle CSS-rotated interaction layers, and using offsetWidth/offsetHeight for normalization is the right call. The math is duplicated almost verbatim between DrawingCreator and RegionCreator, and the rotated code path has no unit test coverage — worth addressing before merge. A few other smaller concerns inline.

Approve with minor changes.

Comment thread src/drawing/DrawingCreator.tsx Outdated
Comment thread src/drawing/DrawingCreator.tsx Outdated
Comment thread src/drawing/DrawingCreator.tsx Outdated
Comment thread src/drawing/__tests__/DrawingCreator-test.tsx
Comment thread src/drawing/__tests__/DrawingCreator-test.tsx
Comment thread src/region/__tests__/RegionCreationContainer-test.tsx Outdated
Duncan Hsu and others added 4 commits May 13, 2026 15:23
When the annotation layer has a CSS rotation transform, mouse coordinates
from getBoundingClientRect() are in screen space but the drawing layer
interprets them in its rotated local frame. This causes live drawing to
appear offset by the rotation angle. Fix by applying the inverse rotation
to convert screen-space coordinates into the element local coordinate
system, and use offsetWidth/offsetHeight for percentage normalization
since these report pre-transform dimensions.

Also removes the isRotated guard that previously blocked region creation
on rotated files, enabling annotations at all rotation angles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kduncanhsu kduncanhsu force-pushed the fix/annotation-drawing-rotation-coordinate-transform branch from 6f500bf to 516d9c4 Compare May 13, 2026 22:29
@kduncanhsu kduncanhsu merged commit b2832c5 into box:master May 13, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants