mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-10 01:50:08 +00:00
## Summary
This PR refactors the mask editor from a vanilla JavaScript
implementation to Vue 3 + Composition API, aligning it with the ComfyUI
frontend's modern architecture. This is a structural refactor without UI
changes - all visual appearances and user interactions remain identical.
Net change: +1,700 lines (mostly tests)
## Changes
- Converted from class-based managers to Vue 3 Composition API
- Migrated state management to Pinia stores (maskEditorStore,
maskEditorDataStore)
- Split monolithic managers into focused composables:
- useBrushDrawing - Brush rendering and drawing logic
- useCanvasManager - Canvas lifecycle and operations
- useCanvasTools - Tool-specific canvas operations
- usePanAndZoom - Pan and zoom functionality
- useToolManager - Tool selection and coordination
- useKeyboard - Keyboard shortcuts
- useMaskEditorLoader/Saver - Data loading and saving
- useCoordinateTransform - Coordinate system transformations
- Replaced imperative DOM manipulation with Vue components
- Added comprehensive test coverage
## What This PR Does NOT Change
Preserved Original Styling:
- Original CSS retained in packages/design-system/src/css/style.css
- Some generic controls (DropdownControl, SliderControl, ToggleControl)
preserved as-is
- Future migration to Tailwind and PrimeVue components is planned but
out of scope for this PR
Preserved Core Functionality:
- Drawing algorithms and brush rendering logic remain unchanged
- Pan/zoom calculations preserved
- Canvas operations (composite modes, image processing) unchanged
- Tool behaviors (brush, color select, paint bucket) identical
- No changes to mask generation or export logic
DO NOT Review:
- CSS styling choices (preserved from original)
- Drawing algorithm implementations (unchanged)
- Canvas rendering logic (ported as-is)
- UI/UX changes (none exist)
- Component library choices (future work)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6629-fully-refactor-mask-editor-into-vue-based-2a46d73d36508114ab8bd2984b4b54e4)
by [Unito](https://www.unito.io)
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
|
import { useMaskEditorDataStore } from '@/stores/maskEditorDataStore'
|
|
import { createSharedComposable } from '@vueuse/core'
|
|
import { useCanvasManager } from '@/composables/maskeditor/useCanvasManager'
|
|
|
|
function useImageLoaderInternal() {
|
|
const store = useMaskEditorStore()
|
|
const dataStore = useMaskEditorDataStore()
|
|
const canvasManager = useCanvasManager()
|
|
|
|
const loadImages = async (): Promise<HTMLImageElement> => {
|
|
const inputData = dataStore.inputData
|
|
|
|
if (!inputData) {
|
|
throw new Error('No input data available in dataStore')
|
|
}
|
|
|
|
const { imgCanvas, maskCanvas, rgbCanvas, imgCtx, maskCtx } = store
|
|
|
|
if (!imgCanvas || !maskCanvas || !rgbCanvas || !imgCtx || !maskCtx) {
|
|
throw new Error('Canvas elements or contexts not available')
|
|
}
|
|
|
|
imgCtx.clearRect(0, 0, imgCanvas.width, imgCanvas.height)
|
|
maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height)
|
|
|
|
const baseImage = inputData.baseLayer.image
|
|
const maskImage = inputData.maskLayer.image
|
|
const paintImage = inputData.paintLayer?.image
|
|
|
|
maskCanvas.width = baseImage.width
|
|
maskCanvas.height = baseImage.height
|
|
rgbCanvas.width = baseImage.width
|
|
rgbCanvas.height = baseImage.height
|
|
|
|
store.image = baseImage
|
|
|
|
await canvasManager.invalidateCanvas(
|
|
baseImage,
|
|
maskImage,
|
|
paintImage || null
|
|
)
|
|
|
|
await canvasManager.updateMaskColor()
|
|
|
|
return baseImage
|
|
}
|
|
|
|
return {
|
|
loadImages
|
|
}
|
|
}
|
|
|
|
export const useImageLoader = createSharedComposable(useImageLoaderInternal)
|