Skip to content

feat(Viewer): add rotate left/right to image viewer#1758

Open
vladopol wants to merge 2 commits into
nextcloud:mainfrom
vladopol:feat/image-viewer-rotate
Open

feat(Viewer): add rotate left/right to image viewer#1758
vladopol wants to merge 2 commits into
nextcloud:mainfrom
vladopol:feat/image-viewer-rotate

Conversation

@vladopol

@vladopol vladopol commented Jun 8, 2026

Copy link
Copy Markdown

Summary

Adds rotate left and rotate right controls to the image viewer actions menu, so users can correct the orientation of images received in Talk chats without leaving the app.

Changes:

  • ViewerHandlerImages.vue — rotation state; rotateLeft/rotateRight exposed via defineExpose; CSS transform: rotate() applied to <img> with a 0.3s transition; rotation resets when switching images
  • ViewerApp.vue — two NcActionButton entries wired to viewerRef.rotateLeft/Right; buttons are shown only for handlers that expose these methods, so video and other viewers are unaffected

Rotation uses unbounded angle increments (+90, +180, ...) so the CSS transition always animates in the correct direction regardless of how many times the button is pressed.

Depends on #1756 (zoom/pan).

Test plan

  • Open an image in the viewer — actions menu shows Rotate left, Rotate right, Open in browser
  • Rotate right repeatedly — image turns clockwise in 90° steps with smooth animation, direction never reverses
  • Rotate left repeatedly — same counter-clockwise
  • Mix left and right — always rotates in the correct direction
  • Switch to another image — rotation resets to 0°
  • Open a video in the viewer — rotate buttons are not shown
  • Zoom in, then rotate — both transforms apply independently

Fixes #1757

vladopol added 2 commits June 8, 2026 12:38
Install panzoom library (9.4.4, 6 kB) and apply it to the image
viewer wrapper in ViewerHandlerImages.vue:

- Scroll wheel to zoom in/out (1× – 8×)
- Drag to pan when zoomed in
- Double-click to zoom in 3× at cursor, double-click again to reset
- Auto-center image when zoom returns to 1×
- Pan blocked at minimum zoom to prevent accidental shifts
- Cursor changes: zoom-in at 1×, grab/grabbing when zoomed

Fixes nextcloud#1535

Signed-off-by: Vladimir Poluliashenko <vladopol@gmail.com>
Add rotate left (−90°) and rotate right (+90°) buttons to the image
viewer actions menu alongside the existing "Open in web browser" action.

- ViewerHandlerImages: rotation state with rotateLeft/rotateRight exposed
  via defineExpose; CSS transform applied to <img> with 0.3s transition;
  rotation resets to 0 when switching images
- ViewerApp: NcActionButton entries wired to viewerRef.rotateLeft/Right;
  buttons only appear for handlers that expose these methods (image viewer)

Rotation uses unbounded angle increments so CSS transition always
animates in the correct direction regardless of how many times the
button is pressed.

Fixes nextcloud#1757

Signed-off-by: Vladimir Poluliashenko <vladopol@gmail.com>
@ShGKme ShGKme added the enhancement New feature or request label Jun 17, 2026

@ShGKme ShGKme left a comment

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.

Thank you, I think we can add it. I'd only refactor this part a little bit to avoid extending a generic component with image-specific features, keeping everything in the image viewer.


Depends on #1756 (zoom/pan).

Thank you for initially splitting it into 2 PRs. Though, these 2 features are related. To simplify it, we can merge it in a single PR feat(Viewer): add image panzoom and rotation


We have a new AI Policy. If this was created with AI, could you mention it in the PR description and add the Assisted-by: git trailer?

Comment on lines +78 to +89
<NcActionButton v-if="viewerRef?.rotateLeft" @click="viewerRef.rotateLeft()">
<template #icon>
<IconRotateLeft :size="20" />
</template>
{{ t('talk_desktop', 'Rotate left') }}
</NcActionButton>
<NcActionButton v-if="viewerRef?.rotateRight" @click="viewerRef.rotateRight()">
<template #icon>
<IconRotateRight :size="20" />
</template>
{{ t('talk_desktop', 'Rotate right') }}
</NcActionButton>

@ShGKme ShGKme Jun 17, 2026

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.

issue(blocking): This component is a generic viewer component and shouldn't know anything about a specific view - image viewer and its operations.

Instead of conditionally rendering buttons here, we can add a slot, for example, #actions, and pass the necessary buttons directly in the ViewerHandlerImages. Exposing public methods also won't be necessary in this case.

.viewer-image {
max-width: 100%;
max-height: 100%;
transition: transform 0.3s ease;

@ShGKme ShGKme Jun 17, 2026

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.

issue(blocking): to use the theming variable:

Suggested change
transition: transform 0.3s ease;
transition: transform var(--animation-slow) ease;

@ShGKme ShGKme added the AI assisted This PR contains AI-assisted commits label Jun 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI assisted This PR contains AI-assisted commits enhancement New feature or request feedback-requested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image viewer: add rotate left/right buttons

2 participants