Added MaskEditor Rotate and Mirror Functions (#7841)

# Canvas Rotation and Mirroring

## Overview
Adds rotation (90° left/right) and mirroring (horizontal/vertical)
capabilities to the mask editor canvas. All three layers (image, mask,
RGB) transform together. Redo and Undo respect transformations as new
states. Keyboard shortcuts also added for all four functions in
Keybinding settings.

Additionally, fixed the issue of ctrl+z and ctrl+y keyboard commands not
restricting to the mask editor canvas while opened.


https://github.com/user-attachments/assets/fb8d5347-b357-4a3a-840a-721cdf8a6125

## What Changed

### New Files
- **`src/composables/maskeditor/useCanvasTransform.ts`**
  - Core transformation logic for rotation and mirroring
  - GPU texture recreation after transformations

### Modified Files
#### **`src/composables/useCoreCommands.ts`**
- Added check to see if Mask Editor is opened for undo and redo commands

#### **`src/stores/maskEditorStore.ts`**
- Added GPU texture recreation signals

#### **`src/composables/maskeditor/useBrushDrawing.ts`**
- Added watcher for `gpuTexturesNeedRecreation` signal
- Handles GPU texture recreation when canvas dimensions change
- Recreates textures with new dimensions after rotation
- Updates preview canvas and readback buffers accordingly
- Ensures proper ArrayBuffer backing for WebGPU compatibility

#### **`src/components/maskeditor/TopBarHeader.vue`**
- Added 4 new transform buttons with icons:
  - Rotate Left (counter-clockwise)
  - Rotate Right (clockwise)
  - Mirror Horizontal
  - Mirror Vertical
- Added visual separators between button groups

#### **`src/extensions/core/maskEditor.ts`**
- Added keyboard shortcut settings for rotate and mirror

#### **Translation Files** (e.g., `src/locales/en.json`)
- Added i18n keys:

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7841-Added-MaskEditor-Rotate-and-Mirror-Functions-2de6d73d365081bc9b84ea4919a3c6a1)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
brucew4yn3rp
2026-01-10 15:45:08 -05:00
committed by GitHub
parent 8086f977c9
commit 7bc6334065
11 changed files with 1648 additions and 128 deletions

View File

@@ -5,6 +5,7 @@ import { app, ComfyApp } from '@/scripts/app'
import { useMaskEditorStore } from '@/stores/maskEditorStore'
import { useDialogStore } from '@/stores/dialogStore'
import { useMaskEditor } from '@/composables/maskeditor/useMaskEditor'
import { useCanvasTransform } from '@/composables/maskeditor/useCanvasTransform'
function openMaskEditor(node: LGraphNode): void {
if (!node) {
@@ -109,6 +110,42 @@ app.registerExtension({
const store = useMaskEditorStore()
store.colorInput?.click()
}
},
{
id: 'Comfy.MaskEditor.Rotate.Right',
icon: 'pi pi-refresh',
label: 'Rotate Right in MaskEditor',
function: async () => {
if (!isOpened()) return
await useCanvasTransform().rotateClockwise()
}
},
{
id: 'Comfy.MaskEditor.Rotate.Left',
icon: 'pi pi-undo',
label: 'Rotate Left in MaskEditor',
function: async () => {
if (!isOpened()) return
await useCanvasTransform().rotateCounterclockwise()
}
},
{
id: 'Comfy.MaskEditor.Mirror.Horizontal',
icon: 'pi pi-arrows-h',
label: 'Mirror Horizontal in MaskEditor',
function: async () => {
if (!isOpened()) return
await useCanvasTransform().mirrorHorizontal()
}
},
{
id: 'Comfy.MaskEditor.Mirror.Vertical',
icon: 'pi pi-arrows-v',
label: 'Mirror Vertical in MaskEditor',
function: async () => {
if (!isOpened()) return
await useCanvasTransform().mirrorVertical()
}
}
],
init() {