feat(Viewer): add rotate left/right to image viewer#1758
Conversation
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
left a comment
There was a problem hiding this comment.
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?
| <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> |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
issue(blocking): to use the theming variable:
| transition: transform 0.3s ease; | |
| transition: transform var(--animation-slow) ease; |
|
Hello there, 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.) |
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/rotateRightexposed viadefineExpose; CSStransform: rotate()applied to<img>with a 0.3s transition; rotation resets when switching imagesViewerApp.vue— twoNcActionButtonentries wired toviewerRef.rotateLeft/Right; buttons are shown only for handlers that expose these methods, so video and other viewers are unaffectedRotation 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
Fixes #1757