mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-19 22:34:15 +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)
81 lines
1.7 KiB
TypeScript
81 lines
1.7 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import type { LGraphNode, NodeId } from '@/lib/litegraph/src/litegraph'
|
|
|
|
export interface ImageRef {
|
|
filename: string
|
|
subfolder?: string
|
|
type?: string
|
|
}
|
|
|
|
export interface ImageLayer {
|
|
image: HTMLImageElement
|
|
url: string
|
|
}
|
|
|
|
interface EditorInputData {
|
|
baseLayer: ImageLayer
|
|
maskLayer: ImageLayer
|
|
paintLayer?: ImageLayer
|
|
sourceRef: ImageRef
|
|
nodeId: NodeId
|
|
}
|
|
|
|
export interface EditorOutputLayer {
|
|
canvas: HTMLCanvasElement
|
|
blob: Blob
|
|
ref: ImageRef
|
|
}
|
|
|
|
export interface EditorOutputData {
|
|
maskedImage: EditorOutputLayer
|
|
paintLayer: EditorOutputLayer
|
|
paintedImage: EditorOutputLayer
|
|
paintedMaskedImage: EditorOutputLayer
|
|
}
|
|
|
|
export const useMaskEditorDataStore = defineStore('maskEditorData', () => {
|
|
const inputData = ref<EditorInputData | null>(null)
|
|
const outputData = ref<EditorOutputData | null>(null)
|
|
const sourceNode = ref<LGraphNode | null>(null)
|
|
|
|
const isLoading = ref(false)
|
|
const loadError = ref<string | null>(null)
|
|
|
|
const hasValidInput = computed(() => inputData.value !== null)
|
|
|
|
const hasValidOutput = computed(() => outputData.value !== null)
|
|
|
|
const isReady = computed(() => hasValidInput.value && !isLoading.value)
|
|
|
|
const reset = () => {
|
|
inputData.value = null
|
|
outputData.value = null
|
|
sourceNode.value = null
|
|
isLoading.value = false
|
|
loadError.value = null
|
|
}
|
|
|
|
const setLoading = (loading: boolean, error?: string) => {
|
|
isLoading.value = loading
|
|
if (error) {
|
|
loadError.value = error
|
|
}
|
|
}
|
|
|
|
return {
|
|
inputData,
|
|
outputData,
|
|
sourceNode,
|
|
isLoading,
|
|
loadError,
|
|
|
|
hasValidInput,
|
|
hasValidOutput,
|
|
isReady,
|
|
|
|
reset,
|
|
setLoading
|
|
}
|
|
})
|