From 0762985ca7ea576a8ad317249f15e31920662c31 Mon Sep 17 00:00:00 2001 From: Christian Byrne Date: Mon, 22 Dec 2025 06:17:31 -0800 Subject: [PATCH] cleanup: remove the legacy mask editor and all related code (#7370) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Removes the legacy mask editor. May also want to remove the "Beta" tags on all the current mask editor components/mentions in the app now as well. ## Context Telemetry data shows zero users using the legacy mask editor. It has been considerable time since we switched to the new one, and there really is no reason to use the legacy version given how lacking it is. In https://github.com/Comfy-Org/ComfyUI_frontend/pull/7332 (v1.35.2 - Dec 11, 2025), we added a final warning that the legacy mask editor is being removed. On 1.36, this PR can be merged, as more than enough warning will have been given. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7370-cleanup-remove-the-legacy-mask-editor-and-all-related-code-2c66d73d365081d58fbed0f3c84bcb0d) by [Unito](https://www.unito.io) --- CODEOWNERS | 1 - build/plugins/comfyAPIPlugin.ts | 6 +- docs/extensions/core.md | 3 +- src/extensions/core/maskEditorOld.ts | 1204 -------------------------- src/extensions/core/maskeditor.ts | 91 +- src/locales/ar/main.json | 1 - src/locales/ar/settings.json | 4 - src/locales/en/main.json | 3 +- src/locales/en/settings.json | 6 +- src/locales/es/main.json | 1 - src/locales/es/settings.json | 4 - src/locales/fr/main.json | 1 - src/locales/fr/settings.json | 4 - src/locales/ja/main.json | 1 - src/locales/ja/settings.json | 4 - src/locales/ko/main.json | 1 - src/locales/ko/settings.json | 4 - src/locales/ru/main.json | 1 - src/locales/ru/settings.json | 4 - src/locales/tr/main.json | 1 - src/locales/tr/settings.json | 4 - src/locales/zh-TW/main.json | 1 - src/locales/zh-TW/settings.json | 4 - src/locales/zh/main.json | 1 - src/locales/zh/settings.json | 4 - src/schemas/apiSchema.ts | 1 - 26 files changed, 10 insertions(+), 1350 deletions(-) delete mode 100644 src/extensions/core/maskEditorOld.ts diff --git a/CODEOWNERS b/CODEOWNERS index 05e8d324c..fcba1e400 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -46,7 +46,6 @@ # Mask Editor /src/extensions/core/maskeditor.ts @trsommer @brucew4yn3rp /src/extensions/core/maskEditorLayerFilenames.ts @trsommer @brucew4yn3rp -/src/extensions/core/maskEditorOld.ts @trsommer @brucew4yn3rp # 3D /src/extensions/core/load3d.ts @jtydhr88 diff --git a/build/plugins/comfyAPIPlugin.ts b/build/plugins/comfyAPIPlugin.ts index 1a3b8d93d..6441dd781 100644 --- a/build/plugins/comfyAPIPlugin.ts +++ b/build/plugins/comfyAPIPlugin.ts @@ -9,11 +9,7 @@ interface ShimResult { const SKIP_WARNING_FILES = new Set(['scripts/app', 'scripts/api']) /** Files that will be removed in v1.34 */ -const DEPRECATED_FILES = [ - 'scripts/ui', - 'extensions/core/maskEditorOld', - 'extensions/core/groupNode' -] as const +const DEPRECATED_FILES = ['scripts/ui', 'extensions/core/groupNode'] as const function getWarningMessage( fileKey: string, diff --git a/docs/extensions/core.md b/docs/extensions/core.md index 56f9ed28c..f7444ce76 100644 --- a/docs/extensions/core.md +++ b/docs/extensions/core.md @@ -41,7 +41,6 @@ The following table lists ALL core extensions in the system as of 2025-01-30: | groupOptions.ts | Handles group node configuration options | Graph | | index.ts | Main extension registration and coordination | Core | | load3d.ts | Supports 3D model loading and visualization | 3D | -| maskEditorOld.ts | Legacy mask editor implementation | Image | | maskeditor.ts | Implements the mask editor for image masking operations | Image | | nodeTemplates.ts | Provides node template functionality | Templates | | noteNode.ts | Adds note nodes for documentation within workflows | Graph | @@ -178,4 +177,4 @@ For more detailed information about ComfyUI's extension system, refer to the off - [JavaScript Settings](https://docs.comfy.org/custom-nodes/js/javascript_settings) - [JavaScript Examples](https://docs.comfy.org/custom-nodes/js/javascript_examples) -Also, check the main [README.md](https://github.com/Comfy-Org/ComfyUI_frontend#developer-apis) section on Developer APIs for the latest information on extension APIs and features. \ No newline at end of file +Also, check the main [README.md](https://github.com/Comfy-Org/ComfyUI_frontend#developer-apis) section on Developer APIs for the latest information on extension APIs and features. diff --git a/src/extensions/core/maskEditorOld.ts b/src/extensions/core/maskEditorOld.ts deleted file mode 100644 index e34c3f225..000000000 --- a/src/extensions/core/maskEditorOld.ts +++ /dev/null @@ -1,1204 +0,0 @@ -import { api } from '../../scripts/api' -import { app } from '../../scripts/app' -import { ComfyApp } from '../../scripts/app' -import { $el, ComfyDialog } from '../../scripts/ui' -import { ClipspaceDialog } from './clipspace' - -// Helper function to convert a data URL to a Blob object -// @ts-expect-error fixme ts strict error -function dataURLToBlob(dataURL) { - const parts = dataURL.split(';base64,') - const contentType = parts[0].split(':')[1] - const byteString = atob(parts[1]) - const arrayBuffer = new ArrayBuffer(byteString.length) - const uint8Array = new Uint8Array(arrayBuffer) - for (let i = 0; i < byteString.length; i++) { - uint8Array[i] = byteString.charCodeAt(i) - } - return new Blob([arrayBuffer], { type: contentType }) -} - -// @ts-expect-error fixme ts strict error -function loadImage(imagePath) { - return new Promise((resolve) => { - const image = new Image() - - image.onload = function () { - resolve(image) - } - - image.src = imagePath - }) -} - -// @ts-expect-error fixme ts strict error -async function uploadMask(filepath, formData) { - await api - .fetchApi('/upload/mask', { - method: 'POST', - body: formData - }) - .catch((error) => { - console.error('Error:', error) - }) - - // @ts-expect-error fixme ts strict error - ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']] = new Image() - // @ts-expect-error fixme ts strict error - ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src = api.apiURL( - '/view?' + - new URLSearchParams(filepath).toString() + - app.getPreviewFormatParam() + - app.getRandParam() - ) - - // @ts-expect-error fixme ts strict error - if (ComfyApp.clipspace.images) - // @ts-expect-error fixme ts strict error - ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']] = filepath - - ClipspaceDialog.invalidatePreview() -} - -// @ts-expect-error fixme ts strict error -function prepare_mask(image, maskCanvas, maskCtx, maskColor) { - // paste mask data into alpha channel - maskCtx.drawImage(image, 0, 0, maskCanvas.width, maskCanvas.height) - const maskData = maskCtx.getImageData( - 0, - 0, - maskCanvas.width, - maskCanvas.height - ) - - // invert mask - for (let i = 0; i < maskData.data.length; i += 4) { - if (maskData.data[i + 3] == 255) maskData.data[i + 3] = 0 - else maskData.data[i + 3] = 255 - - maskData.data[i] = maskColor.r - maskData.data[i + 1] = maskColor.g - maskData.data[i + 2] = maskColor.b - } - - maskCtx.globalCompositeOperation = 'source-over' - maskCtx.putImageData(maskData, 0, 0) -} - -// Define the PointerType enum -enum PointerType { - Arc = 'arc', - Rect = 'rect' -} - -enum CompositionOperation { - SourceOver = 'source-over', - DestinationOut = 'destination-out' -} - -export class MaskEditorDialogOld extends ComfyDialog { - static instance = null - static mousedown_x: number | null = null - static mousedown_y: number | null = null - - // @ts-expect-error fixme ts strict error - brush: HTMLDivElement - maskCtx: any - // @ts-expect-error fixme ts strict error - maskCanvas: HTMLCanvasElement - // @ts-expect-error fixme ts strict error - brush_size_slider: HTMLDivElement - // @ts-expect-error fixme ts strict error - brush_opacity_slider: HTMLDivElement - // @ts-expect-error fixme ts strict error - colorButton: HTMLButtonElement - // @ts-expect-error fixme ts strict error - saveButton: HTMLButtonElement - // @ts-expect-error fixme ts strict error - zoom_ratio: number - // @ts-expect-error fixme ts strict error - pan_x: number - // @ts-expect-error fixme ts strict error - pan_y: number - // @ts-expect-error fixme ts strict error - imgCanvas: HTMLCanvasElement - // @ts-expect-error fixme ts strict error - last_display_style: string - // @ts-expect-error fixme ts strict error - is_visible: boolean - // @ts-expect-error fixme ts strict error - image: HTMLImageElement - // @ts-expect-error fixme ts strict error - handler_registered: boolean - // @ts-expect-error fixme ts strict error - brush_slider_input: HTMLInputElement - // @ts-expect-error fixme ts strict error - cursorX: number - // @ts-expect-error fixme ts strict error - cursorY: number - // @ts-expect-error fixme ts strict error - mousedown_pan_x: number - // @ts-expect-error fixme ts strict error - mousedown_pan_y: number - // @ts-expect-error fixme ts strict error - last_pressure: number - // @ts-expect-error fixme ts strict error - pointer_type: PointerType - // @ts-expect-error fixme ts strict error - brush_pointer_type_select: HTMLDivElement - - static getInstance() { - if (!MaskEditorDialogOld.instance) { - // @ts-expect-error fixme ts strict error - MaskEditorDialogOld.instance = new MaskEditorDialogOld() - } - - return MaskEditorDialogOld.instance - } - - is_layout_created = false - - constructor() { - super() - this.element = $el('div.comfy-modal', { parent: document.body }, [ - $el('div.comfy-modal-content', [...this.createButtons()]) - ]) - } - - override createButtons() { - return [] - } - - // @ts-expect-error fixme ts strict error - createButton(name, callback): HTMLButtonElement { - var button = document.createElement('button') - button.style.pointerEvents = 'auto' - button.innerText = name - button.addEventListener('click', callback) - return button - } - - // @ts-expect-error fixme ts strict error - createLeftButton(name, callback) { - var button = this.createButton(name, callback) - button.style.cssFloat = 'left' - button.style.marginRight = '4px' - return button - } - - // @ts-expect-error fixme ts strict error - createRightButton(name, callback) { - var button = this.createButton(name, callback) - button.style.cssFloat = 'right' - button.style.marginLeft = '4px' - return button - } - - // @ts-expect-error fixme ts strict error - createLeftSlider(self, name, callback): HTMLDivElement { - const divElement = document.createElement('div') - divElement.id = 'maskeditor-slider' - divElement.style.cssFloat = 'left' - divElement.style.fontFamily = 'sans-serif' - divElement.style.marginRight = '4px' - divElement.style.color = 'var(--input-text)' - divElement.style.backgroundColor = 'var(--comfy-input-bg)' - divElement.style.borderRadius = '8px' - divElement.style.borderColor = 'var(--border-color)' - divElement.style.borderStyle = 'solid' - divElement.style.fontSize = '15px' - divElement.style.height = '25px' - divElement.style.padding = '1px 6px' - divElement.style.display = 'flex' - divElement.style.position = 'relative' - divElement.style.top = '2px' - divElement.style.pointerEvents = 'auto' - self.brush_slider_input = document.createElement('input') - self.brush_slider_input.setAttribute('type', 'range') - self.brush_slider_input.setAttribute('min', '1') - self.brush_slider_input.setAttribute('max', '100') - self.brush_slider_input.setAttribute('value', '10') - const labelElement = document.createElement('label') - labelElement.textContent = name - - divElement.appendChild(labelElement) - divElement.appendChild(self.brush_slider_input) - - self.brush_slider_input.addEventListener('change', callback) - - return divElement - } - - // @ts-expect-error fixme ts strict error - createOpacitySlider(self, name, callback): HTMLDivElement { - const divElement = document.createElement('div') - divElement.id = 'maskeditor-opacity-slider' - divElement.style.cssFloat = 'left' - divElement.style.fontFamily = 'sans-serif' - divElement.style.marginRight = '4px' - divElement.style.color = 'var(--input-text)' - divElement.style.backgroundColor = 'var(--comfy-input-bg)' - divElement.style.borderRadius = '8px' - divElement.style.borderColor = 'var(--border-color)' - divElement.style.borderStyle = 'solid' - divElement.style.fontSize = '15px' - divElement.style.height = '25px' - divElement.style.padding = '1px 6px' - divElement.style.display = 'flex' - divElement.style.position = 'relative' - divElement.style.top = '2px' - divElement.style.pointerEvents = 'auto' - self.opacity_slider_input = document.createElement('input') - self.opacity_slider_input.setAttribute('type', 'range') - self.opacity_slider_input.setAttribute('min', '0.1') - self.opacity_slider_input.setAttribute('max', '1.0') - self.opacity_slider_input.setAttribute('step', '0.01') - self.opacity_slider_input.setAttribute('value', '0.7') - const labelElement = document.createElement('label') - labelElement.textContent = name - - divElement.appendChild(labelElement) - divElement.appendChild(self.opacity_slider_input) - - self.opacity_slider_input.addEventListener('input', callback) - - return divElement - } - - createPointerTypeSelect(self: any): HTMLDivElement { - const divElement = document.createElement('div') - divElement.id = 'maskeditor-pointer-type' - divElement.style.cssFloat = 'left' - divElement.style.fontFamily = 'sans-serif' - divElement.style.marginRight = '4px' - divElement.style.color = 'var(--input-text)' - divElement.style.backgroundColor = 'var(--comfy-input-bg)' - divElement.style.borderRadius = '8px' - divElement.style.borderColor = 'var(--border-color)' - divElement.style.borderStyle = 'solid' - divElement.style.fontSize = '15px' - divElement.style.height = '25px' - divElement.style.padding = '1px 6px' - divElement.style.display = 'flex' - divElement.style.position = 'relative' - divElement.style.top = '2px' - divElement.style.pointerEvents = 'auto' - - const labelElement = document.createElement('label') - labelElement.textContent = 'Pointer Type:' - - const selectElement = document.createElement('select') - selectElement.style.borderRadius = '0' - selectElement.style.borderColor = 'transparent' - selectElement.style.borderStyle = 'unset' - selectElement.style.fontSize = '0.9em' - - const optionArc = document.createElement('option') - optionArc.value = 'arc' - optionArc.text = 'Circle' - optionArc.selected = true // Fix for TypeScript, "selected" should be boolean - - const optionRect = document.createElement('option') - optionRect.value = 'rect' - optionRect.text = 'Square' - - selectElement.appendChild(optionArc) - selectElement.appendChild(optionRect) - - selectElement.addEventListener('change', (event: Event) => { - const target = event.target as HTMLSelectElement - self.pointer_type = target.value - this.setBrushBorderRadius(self) - }) - - divElement.appendChild(labelElement) - divElement.appendChild(selectElement) - - return divElement - } - - setBrushBorderRadius(self: any): void { - if (self.pointer_type === PointerType.Rect) { - this.brush.style.borderRadius = '0%' - // @ts-expect-error - this.brush.style.MozBorderRadius = '0%' - // @ts-expect-error - this.brush.style.WebkitBorderRadius = '0%' - } else { - this.brush.style.borderRadius = '50%' - // @ts-expect-error - this.brush.style.MozBorderRadius = '50%' - // @ts-expect-error - this.brush.style.WebkitBorderRadius = '50%' - } - } - - setlayout(imgCanvas: HTMLCanvasElement, maskCanvas: HTMLCanvasElement) { - const self = this - self.pointer_type = PointerType.Arc - - // If it is specified as relative, using it only as a hidden placeholder for padding is recommended - // to prevent anomalies where it exceeds a certain size and goes outside of the window. - var bottom_panel = document.createElement('div') - bottom_panel.style.position = 'absolute' - bottom_panel.style.bottom = '0px' - bottom_panel.style.left = '20px' - bottom_panel.style.right = '20px' - bottom_panel.style.height = '50px' - bottom_panel.style.pointerEvents = 'none' - - var brush = document.createElement('div') - brush.id = 'brush' - brush.style.backgroundColor = 'transparent' - brush.style.outline = '1px dashed black' - brush.style.boxShadow = '0 0 0 1px white' - brush.style.position = 'absolute' - brush.style.zIndex = '8889' - brush.style.pointerEvents = 'none' - this.brush = brush - this.setBrushBorderRadius(self) - this.element.appendChild(imgCanvas) - this.element.appendChild(maskCanvas) - this.element.appendChild(bottom_panel) - document.body.appendChild(brush) - - var clearButton = this.createLeftButton('Clear', () => { - self.maskCtx.clearRect( - 0, - 0, - self.maskCanvas.width, - self.maskCanvas.height - ) - }) - - this.brush_size_slider = this.createLeftSlider( - self, - 'Thickness', - // @ts-expect-error fixme ts strict error - (event) => { - self.brush_size = event.target.value - self.updateBrushPreview(self) - } - ) - - this.brush_opacity_slider = this.createOpacitySlider( - self, - 'Opacity', - // @ts-expect-error fixme ts strict error - (event) => { - self.brush_opacity = event.target.value - if (self.brush_color_mode !== 'negative') { - self.maskCanvas.style.opacity = self.brush_opacity.toString() - } - } - ) - - this.brush_pointer_type_select = this.createPointerTypeSelect(self) - this.colorButton = this.createLeftButton(this.getColorButtonText(), () => { - if (self.brush_color_mode === 'black') { - self.brush_color_mode = 'white' - } else if (self.brush_color_mode === 'white') { - self.brush_color_mode = 'negative' - } else { - self.brush_color_mode = 'black' - } - - self.updateWhenBrushColorModeChanged() - }) - - var cancelButton = this.createRightButton('Cancel', () => { - document.removeEventListener('keydown', MaskEditorDialogOld.handleKeyDown) - self.close() - }) - - this.saveButton = this.createRightButton('Save', () => { - document.removeEventListener('keydown', MaskEditorDialogOld.handleKeyDown) - self.save() - }) - - this.element.appendChild(imgCanvas) - this.element.appendChild(maskCanvas) - this.element.appendChild(bottom_panel) - - bottom_panel.appendChild(clearButton) - bottom_panel.appendChild(this.saveButton) - bottom_panel.appendChild(cancelButton) - bottom_panel.appendChild(this.brush_size_slider) - bottom_panel.appendChild(this.brush_opacity_slider) - bottom_panel.appendChild(this.brush_pointer_type_select) - bottom_panel.appendChild(this.colorButton) - - imgCanvas.style.position = 'absolute' - maskCanvas.style.position = 'absolute' - - imgCanvas.style.top = '200' - imgCanvas.style.left = '0' - - maskCanvas.style.top = imgCanvas.style.top - maskCanvas.style.left = imgCanvas.style.left - - const maskCanvasStyle = this.getMaskCanvasStyle() - maskCanvas.style.mixBlendMode = maskCanvasStyle.mixBlendMode - maskCanvas.style.opacity = maskCanvasStyle.opacity.toString() - } - - override async show() { - this.zoom_ratio = 1.0 - this.pan_x = 0 - this.pan_y = 0 - - if (!this.is_layout_created) { - // layout - const imgCanvas = document.createElement('canvas') - const maskCanvas = document.createElement('canvas') - - imgCanvas.id = 'imageCanvas' - maskCanvas.id = 'maskCanvas' - - this.setlayout(imgCanvas, maskCanvas) - - // prepare content - this.imgCanvas = imgCanvas - this.maskCanvas = maskCanvas - this.maskCtx = maskCanvas.getContext('2d', { willReadFrequently: true }) - - this.setEventHandler(maskCanvas) - - this.is_layout_created = true - - // replacement of onClose hook since close is not real close - const self = this - const observer = new MutationObserver(function (mutations) { - mutations.forEach(function (mutation) { - if ( - mutation.type === 'attributes' && - mutation.attributeName === 'style' - ) { - if ( - self.last_display_style && - self.last_display_style != 'none' && - self.element.style.display == 'none' - ) { - self.brush.style.display = 'none' - ComfyApp.onClipspaceEditorClosed() - } - - self.last_display_style = self.element.style.display - } - }) - }) - - const config = { attributes: true } - observer.observe(this.element, config) - } - - // The keydown event needs to be reconfigured when closing the dialog as it gets removed. - document.addEventListener('keydown', MaskEditorDialogOld.handleKeyDown) - - if (ComfyApp.clipspace_return_node) { - this.saveButton.innerText = 'Save to node' - } else { - this.saveButton.innerText = 'Save' - } - this.saveButton.disabled = false - - this.element.style.display = 'block' - this.element.style.width = '85%' - this.element.style.margin = '0 7.5%' - this.element.style.height = '100vh' - this.element.style.top = '50%' - this.element.style.left = '42%' - this.element.style.zIndex = '8888' // NOTE: alert dialog must be high priority. - - await this.setImages(this.imgCanvas) - - this.is_visible = true - } - - isOpened() { - return this.element.style.display == 'block' - } - - // @ts-expect-error fixme ts strict error - invalidateCanvas(orig_image, mask_image) { - this.imgCanvas.width = orig_image.width - this.imgCanvas.height = orig_image.height - - this.maskCanvas.width = orig_image.width - this.maskCanvas.height = orig_image.height - - let imgCtx = this.imgCanvas.getContext('2d', { willReadFrequently: true }) - let maskCtx = this.maskCanvas.getContext('2d', { - willReadFrequently: true - }) - - // @ts-expect-error fixme ts strict error - imgCtx.drawImage(orig_image, 0, 0, orig_image.width, orig_image.height) - prepare_mask(mask_image, this.maskCanvas, maskCtx, this.getMaskColor()) - } - - // @ts-expect-error fixme ts strict error - async setImages(imgCanvas) { - let self = this - - const imgCtx = imgCanvas.getContext('2d', { willReadFrequently: true }) - const maskCtx = this.maskCtx - const maskCanvas = this.maskCanvas - - imgCtx.clearRect(0, 0, this.imgCanvas.width, this.imgCanvas.height) - maskCtx.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height) - - // image load - const alpha_url = new URL( - // @ts-expect-error fixme ts strict error - ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src - ) - alpha_url.searchParams.delete('channel') - alpha_url.searchParams.delete('preview') - alpha_url.searchParams.set('channel', 'a') - let mask_image = await loadImage(alpha_url) - - // original image load - const rgb_url = new URL( - // @ts-expect-error fixme ts strict error - ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src - ) - rgb_url.searchParams.delete('channel') - rgb_url.searchParams.set('channel', 'rgb') - this.image = new Image() - this.image.onload = function () { - maskCanvas.width = self.image.width - maskCanvas.height = self.image.height - - self.invalidateCanvas(self.image, mask_image) - self.initializeCanvasPanZoom() - } - this.image.src = rgb_url.toString() - } - - initializeCanvasPanZoom() { - // set initialize - let drawWidth = this.image.width - let drawHeight = this.image.height - - let width = this.element.clientWidth - let height = this.element.clientHeight - - if (this.image.width > width) { - drawWidth = width - drawHeight = (drawWidth / this.image.width) * this.image.height - } - - if (drawHeight > height) { - drawHeight = height - drawWidth = (drawHeight / this.image.height) * this.image.width - } - - this.zoom_ratio = drawWidth / this.image.width - - const canvasX = (width - drawWidth) / 2 - const canvasY = (height - drawHeight) / 2 - this.pan_x = canvasX - this.pan_y = canvasY - - this.invalidatePanZoom() - } - - invalidatePanZoom() { - let raw_width = this.image.width * this.zoom_ratio - let raw_height = this.image.height * this.zoom_ratio - - if (this.pan_x + raw_width < 10) { - this.pan_x = 10 - raw_width - } - - if (this.pan_y + raw_height < 10) { - this.pan_y = 10 - raw_height - } - - let width = `${raw_width}px` - let height = `${raw_height}px` - - let left = `${this.pan_x}px` - let top = `${this.pan_y}px` - - this.maskCanvas.style.width = width - this.maskCanvas.style.height = height - this.maskCanvas.style.left = left - this.maskCanvas.style.top = top - - this.imgCanvas.style.width = width - this.imgCanvas.style.height = height - this.imgCanvas.style.left = left - this.imgCanvas.style.top = top - } - - // @ts-expect-error fixme ts strict error - setEventHandler(maskCanvas) { - const self = this - - if (!this.handler_registered) { - // @ts-expect-error fixme ts strict error - maskCanvas.addEventListener('contextmenu', (event) => { - event.preventDefault() - }) - - this.element.addEventListener('wheel', (event) => - this.handleWheelEvent(self, event) - ) - this.element.addEventListener('pointermove', (event) => - this.pointMoveEvent(self, event) - ) - this.element.addEventListener('touchmove', (event) => - this.pointMoveEvent(self, event) - ) - - this.element.addEventListener('dragstart', (event) => { - if (event.ctrlKey) { - event.preventDefault() - } - }) - - // @ts-expect-error fixme ts strict error - maskCanvas.addEventListener('pointerdown', (event) => - this.handlePointerDown(self, event) - ) - // @ts-expect-error fixme ts strict error - maskCanvas.addEventListener('pointermove', (event) => - this.draw_move(self, event) - ) - // @ts-expect-error fixme ts strict error - maskCanvas.addEventListener('touchmove', (event) => - this.draw_move(self, event) - ) - maskCanvas.addEventListener('pointerover', () => { - this.brush.style.display = 'block' - }) - maskCanvas.addEventListener('pointerleave', () => { - this.brush.style.display = 'none' - }) - - document.addEventListener( - 'pointerup', - MaskEditorDialogOld.handlePointerUp - ) - - this.handler_registered = true - } - } - - getMaskCanvasStyle() { - if (this.brush_color_mode === 'negative') { - return { - mixBlendMode: 'difference', - opacity: '1' - } - } else { - return { - mixBlendMode: 'initial', - opacity: this.brush_opacity - } - } - } - - getMaskColor() { - if (this.brush_color_mode === 'black') { - return { r: 0, g: 0, b: 0 } - } - if (this.brush_color_mode === 'white') { - return { r: 255, g: 255, b: 255 } - } - if (this.brush_color_mode === 'negative') { - // negative effect only works with white color - return { r: 255, g: 255, b: 255 } - } - - return { r: 0, g: 0, b: 0 } - } - - getMaskFillStyle() { - const maskColor = this.getMaskColor() - - return 'rgb(' + maskColor.r + ',' + maskColor.g + ',' + maskColor.b + ')' - } - - getColorButtonText() { - let colorCaption = 'unknown' - - if (this.brush_color_mode === 'black') { - colorCaption = 'black' - } else if (this.brush_color_mode === 'white') { - colorCaption = 'white' - } else if (this.brush_color_mode === 'negative') { - colorCaption = 'negative' - } - - return 'Color: ' + colorCaption - } - - updateWhenBrushColorModeChanged() { - this.colorButton.innerText = this.getColorButtonText() - - // update mask canvas css styles - - const maskCanvasStyle = this.getMaskCanvasStyle() - this.maskCanvas.style.mixBlendMode = maskCanvasStyle.mixBlendMode - this.maskCanvas.style.opacity = maskCanvasStyle.opacity.toString() - - // update mask canvas rgb colors - - const maskColor = this.getMaskColor() - - const maskData = this.maskCtx.getImageData( - 0, - 0, - this.maskCanvas.width, - this.maskCanvas.height - ) - - for (let i = 0; i < maskData.data.length; i += 4) { - maskData.data[i] = maskColor.r - maskData.data[i + 1] = maskColor.g - maskData.data[i + 2] = maskColor.b - } - - this.maskCtx.putImageData(maskData, 0, 0) - } - - brush_opacity = 0.7 - brush_size = 10 - brush_color_mode = 'black' - drawing_mode = false - lastx = -1 - lasty = -1 - lasttime = 0 - - // @ts-expect-error fixme ts strict error - static handleKeyDown(event) { - const self = MaskEditorDialogOld.instance - if (event.key === ']') { - // @ts-expect-error fixme ts strict error - self.brush_size = Math.min(self.brush_size + 2, 100) - // @ts-expect-error fixme ts strict error - self.brush_slider_input.value = self.brush_size - } else if (event.key === '[') { - // @ts-expect-error fixme ts strict error - self.brush_size = Math.max(self.brush_size - 2, 1) - // @ts-expect-error fixme ts strict error - self.brush_slider_input.value = self.brush_size - } else if (event.key === 'Enter') { - // @ts-expect-error fixme ts strict error - self.save() - } - - // @ts-expect-error fixme ts strict error - self.updateBrushPreview(self) - } - - // @ts-expect-error fixme ts strict error - static handlePointerUp(event) { - event.preventDefault() - - this.mousedown_x = null - this.mousedown_y = null - - // @ts-expect-error fixme ts strict error - MaskEditorDialogOld.instance.drawing_mode = false - } - - // @ts-expect-error fixme ts strict error - updateBrushPreview(self) { - const brush = self.brush - - var centerX = self.cursorX - var centerY = self.cursorY - - brush.style.width = self.brush_size * 2 * this.zoom_ratio + 'px' - brush.style.height = self.brush_size * 2 * this.zoom_ratio + 'px' - brush.style.left = centerX - self.brush_size * this.zoom_ratio + 'px' - brush.style.top = centerY - self.brush_size * this.zoom_ratio + 'px' - } - - // @ts-expect-error fixme ts strict error - handleWheelEvent(_, event) { - event.preventDefault() - - if (event.ctrlKey) { - // zoom canvas - if (event.deltaY < 0) { - this.zoom_ratio = Math.min(10.0, this.zoom_ratio + 0.2) - } else { - this.zoom_ratio = Math.max(0.2, this.zoom_ratio - 0.2) - } - - this.invalidatePanZoom() - } else { - // adjust brush size - if (event.deltaY < 0) this.brush_size = Math.min(this.brush_size + 2, 100) - else this.brush_size = Math.max(this.brush_size - 2, 1) - - this.brush_slider_input.value = this.brush_size.toString() - - this.updateBrushPreview(this) - } - } - - // @ts-expect-error fixme ts strict error - pointMoveEvent(self, event) { - this.cursorX = event.pageX - this.cursorY = event.pageY - - self.updateBrushPreview(self) - - if (event.ctrlKey) { - event.preventDefault() - self.pan_move(self, event) - } - - let left_button_down = - (window.TouchEvent && event instanceof TouchEvent) || event.buttons == 1 - - if (event.shiftKey && left_button_down) { - self.drawing_mode = false - - const y = event.clientY - let delta = (self.zoom_lasty - y) * 0.005 - self.zoom_ratio = Math.max( - Math.min(10.0, self.last_zoom_ratio - delta), - 0.2 - ) - - this.invalidatePanZoom() - return - } - } - - // @ts-expect-error fixme ts strict error - pan_move(self, event) { - if (event.buttons == 1) { - if (MaskEditorDialogOld.mousedown_x) { - let deltaX = MaskEditorDialogOld.mousedown_x - event.clientX - // @ts-expect-error fixme ts strict error - let deltaY = MaskEditorDialogOld.mousedown_y - event.clientY - - self.pan_x = this.mousedown_pan_x - deltaX - self.pan_y = this.mousedown_pan_y - deltaY - - self.invalidatePanZoom() - } - } - } - - // @ts-expect-error fixme ts strict error - draw_move(self, event) { - if (event.ctrlKey || event.shiftKey) { - return - } - - event.preventDefault() - - this.cursorX = event.pageX - this.cursorY = event.pageY - - self.updateBrushPreview(self) - - let left_button_down = - (window.TouchEvent && event instanceof TouchEvent) || event.buttons == 1 - let right_button_down = [2, 5, 32].includes(event.buttons) - - if (!event.altKey && left_button_down) { - var diff = performance.now() - self.lasttime - - const maskRect = self.maskCanvas.getBoundingClientRect() - - var x = event.offsetX - var y = event.offsetY - - if (event.offsetX == null) { - x = event.targetTouches[0].clientX - maskRect.left - } - - if (event.offsetY == null) { - y = event.targetTouches[0].clientY - maskRect.top - } - - x /= self.zoom_ratio - y /= self.zoom_ratio - - var brush_size = this.brush_size - if (event instanceof PointerEvent && event.pointerType == 'pen') { - brush_size *= event.pressure - this.last_pressure = event.pressure - } else if ( - window.TouchEvent && - event instanceof TouchEvent && - diff < 20 - ) { - // The firing interval of PointerEvents in Pen is unreliable, so it is supplemented by TouchEvents. - brush_size *= this.last_pressure - } else { - brush_size = this.brush_size - } - - if (diff > 20 && !this.drawing_mode) - requestAnimationFrame(() => { - self.init_shape(self, CompositionOperation.SourceOver) - self.draw_shape(self, x, y, brush_size) - self.lastx = x - self.lasty = y - }) - else - requestAnimationFrame(() => { - self.init_shape(self, CompositionOperation.SourceOver) - - var dx = x - self.lastx - var dy = y - self.lasty - - var distance = Math.sqrt(dx * dx + dy * dy) - var directionX = dx / distance - var directionY = dy / distance - - for (var i = 0; i < distance; i += 5) { - var px = self.lastx + directionX * i - var py = self.lasty + directionY * i - self.draw_shape(self, px, py, brush_size) - } - self.lastx = x - self.lasty = y - }) - - self.lasttime = performance.now() - } else if ((event.altKey && left_button_down) || right_button_down) { - const maskRect = self.maskCanvas.getBoundingClientRect() - const x = - (event.offsetX || event.targetTouches[0].clientX - maskRect.left) / - self.zoom_ratio - const y = - (event.offsetY || event.targetTouches[0].clientY - maskRect.top) / - self.zoom_ratio - - var brush_size = this.brush_size - if (event instanceof PointerEvent && event.pointerType == 'pen') { - brush_size *= event.pressure - this.last_pressure = event.pressure - } else if ( - window.TouchEvent && - event instanceof TouchEvent && - // @ts-expect-error fixme ts strict error - diff < 20 - ) { - brush_size *= this.last_pressure - } else { - brush_size = this.brush_size - } - - // @ts-expect-error fixme ts strict error - if (diff > 20 && !this.drawing_mode) - // cannot tracking drawing_mode for touch event - requestAnimationFrame(() => { - self.init_shape(self, CompositionOperation.DestinationOut) - self.draw_shape(self, x, y, brush_size) - self.lastx = x - self.lasty = y - }) - else - requestAnimationFrame(() => { - self.init_shape(self, CompositionOperation.DestinationOut) - - var dx = x - self.lastx - var dy = y - self.lasty - - var distance = Math.sqrt(dx * dx + dy * dy) - var directionX = dx / distance - var directionY = dy / distance - - for (var i = 0; i < distance; i += 5) { - var px = self.lastx + directionX * i - var py = self.lasty + directionY * i - self.draw_shape(self, px, py, brush_size) - } - self.lastx = x - self.lasty = y - }) - - self.lasttime = performance.now() - } - } - - // @ts-expect-error fixme ts strict error - handlePointerDown(self, event) { - if (event.ctrlKey) { - if (event.buttons == 1) { - MaskEditorDialogOld.mousedown_x = event.clientX - MaskEditorDialogOld.mousedown_y = event.clientY - - this.mousedown_pan_x = this.pan_x - this.mousedown_pan_y = this.pan_y - } - return - } - - var brush_size = this.brush_size - if (event instanceof PointerEvent && event.pointerType == 'pen') { - brush_size *= event.pressure - this.last_pressure = event.pressure - } - - if ([0, 2, 5].includes(event.button)) { - self.drawing_mode = true - - event.preventDefault() - - if (event.shiftKey) { - self.zoom_lasty = event.clientY - self.last_zoom_ratio = self.zoom_ratio - return - } - - const maskRect = self.maskCanvas.getBoundingClientRect() - const x = - (event.offsetX || event.targetTouches[0].clientX - maskRect.left) / - self.zoom_ratio - const y = - (event.offsetY || event.targetTouches[0].clientY - maskRect.top) / - self.zoom_ratio - - if (!event.altKey && event.button == 0) { - self.init_shape(self, CompositionOperation.SourceOver) - } else { - self.init_shape(self, CompositionOperation.DestinationOut) - } - self.draw_shape(self, x, y, brush_size) - self.lastx = x - self.lasty = y - self.lasttime = performance.now() - } - } - - // @ts-expect-error fixme ts strict error - init_shape(self, compositionOperation) { - self.maskCtx.beginPath() - if (compositionOperation == CompositionOperation.SourceOver) { - self.maskCtx.fillStyle = this.getMaskFillStyle() - self.maskCtx.globalCompositeOperation = CompositionOperation.SourceOver - } else if (compositionOperation == CompositionOperation.DestinationOut) { - self.maskCtx.globalCompositeOperation = - CompositionOperation.DestinationOut - } - } - - // @ts-expect-error fixme ts strict error - draw_shape(self, x, y, brush_size) { - if (self.pointer_type === PointerType.Rect) { - self.maskCtx.rect( - x - brush_size, - y - brush_size, - brush_size * 2, - brush_size * 2 - ) - } else { - self.maskCtx.arc(x, y, brush_size, 0, Math.PI * 2, false) - } - self.maskCtx.fill() - } - - async save() { - const backupCanvas = document.createElement('canvas') - const backupCtx = backupCanvas.getContext('2d', { - willReadFrequently: true - }) - backupCanvas.width = this.image.width - backupCanvas.height = this.image.height - - // @ts-expect-error fixme ts strict error - backupCtx.clearRect(0, 0, backupCanvas.width, backupCanvas.height) - // @ts-expect-error fixme ts strict error - backupCtx.drawImage( - this.maskCanvas, - 0, - 0, - this.maskCanvas.width, - this.maskCanvas.height, - 0, - 0, - backupCanvas.width, - backupCanvas.height - ) - - // paste mask data into alpha channel - // @ts-expect-error fixme ts strict error - const backupData = backupCtx.getImageData( - 0, - 0, - backupCanvas.width, - backupCanvas.height - ) - - // refine mask image - for (let i = 0; i < backupData.data.length; i += 4) { - if (backupData.data[i + 3] == 255) backupData.data[i + 3] = 0 - else backupData.data[i + 3] = 255 - - backupData.data[i] = 0 - backupData.data[i + 1] = 0 - backupData.data[i + 2] = 0 - } - - // @ts-expect-error fixme ts strict error - backupCtx.globalCompositeOperation = CompositionOperation.SourceOver - // @ts-expect-error fixme ts strict error - backupCtx.putImageData(backupData, 0, 0) - - const formData = new FormData() - const filename = 'clipspace-mask-' + performance.now() + '.png' - - const item = { - filename: filename, - subfolder: 'clipspace', - type: 'input' - } - - // @ts-expect-error fixme ts strict error - if (ComfyApp.clipspace.images) ComfyApp.clipspace.images[0] = item - - // @ts-expect-error fixme ts strict error - if (ComfyApp.clipspace.widgets) { - // @ts-expect-error fixme ts strict error - const index = ComfyApp.clipspace.widgets.findIndex( - (obj) => obj.name === 'image' - ) - - // @ts-expect-error fixme ts strict error - if (index >= 0) ComfyApp.clipspace.widgets[index].value = item - } - - const dataURL = backupCanvas.toDataURL() - const blob = dataURLToBlob(dataURL) - - let original_url = new URL(this.image.src) - - type Ref = { filename: string; subfolder?: string; type?: string } - - const original_ref: Ref = { - // @ts-expect-error fixme ts strict error - filename: original_url.searchParams.get('filename') - } - - let original_subfolder = original_url.searchParams.get('subfolder') - if (original_subfolder) original_ref.subfolder = original_subfolder - - let original_type = original_url.searchParams.get('type') - if (original_type) original_ref.type = original_type - - formData.append('image', blob, filename) - formData.append('original_ref', JSON.stringify(original_ref)) - formData.append('type', 'input') - formData.append('subfolder', 'clipspace') - - this.saveButton.innerText = 'Saving...' - this.saveButton.disabled = true - await uploadMask(item, formData) - ComfyApp.onClipspaceEditorSave() - this.close() - } -} diff --git a/src/extensions/core/maskeditor.ts b/src/extensions/core/maskeditor.ts index 698653359..a0084cfb9 100644 --- a/src/extensions/core/maskeditor.ts +++ b/src/extensions/core/maskeditor.ts @@ -1,26 +1,10 @@ import _ from 'es-toolkit/compat' import type { LGraphNode } from '@/lib/litegraph/src/litegraph' -import { t } from '@/i18n' -import { useMaskEditor } from '@/composables/maskeditor/useMaskEditor' -import { useToastStore } from '@/platform/updates/common/toastStore' import { app } from '@/scripts/app' -import { ComfyApp } from '@/scripts/app' -import { useDialogStore } from '@/stores/dialogStore' import { useMaskEditorStore } from '@/stores/maskEditorStore' -import { ClipspaceDialog } from './clipspace' -import { MaskEditorDialogOld } from './maskEditorOld' - -const warnLegacyMaskEditorDeprecation = () => { - const warningMessage = t('toastMessages.legacyMaskEditorDeprecated') - console.warn(`[Comfy.MaskEditor] ${warningMessage}`) - useToastStore().add({ - severity: 'warn', - summary: 'Alert', - detail: warningMessage, - life: 4096 - }) -} +import { useDialogStore } from '@/stores/dialogStore' +import { useMaskEditor } from '@/composables/maskeditor/useMaskEditor' function openMaskEditor(node: LGraphNode): void { if (!node) { @@ -33,56 +17,23 @@ function openMaskEditor(node: LGraphNode): void { return } - const useNewEditor = app.extensionManager.setting.get( - 'Comfy.MaskEditor.UseNewEditor' - ) - - if (useNewEditor) { - useMaskEditor().openMaskEditor(node) - } else { - warnLegacyMaskEditorDeprecation() - // Use old editor - ComfyApp.copyToClipspace(node) - // @ts-expect-error clipspace_return_node is an extension property added at runtime - ComfyApp.clipspace_return_node = node - const dlg = MaskEditorDialogOld.getInstance() as any - if (dlg?.isOpened && !dlg.isOpened()) { - dlg.show() - } - } + useMaskEditor().openMaskEditor(node) } // Check if the dialog is already opened function isOpened(): boolean { - const useNewEditor = app.extensionManager.setting.get( - 'Comfy.MaskEditor.UseNewEditor' - ) - if (useNewEditor) { - return useDialogStore().isDialogOpen('global-mask-editor') - } else { - return (MaskEditorDialogOld.instance as any)?.isOpened?.() ?? false - } + return useDialogStore().isDialogOpen('global-mask-editor') } app.registerExtension({ name: 'Comfy.MaskEditor', settings: [ - { - id: 'Comfy.MaskEditor.UseNewEditor', - category: ['Mask Editor', 'NewEditor'], - name: 'Use new mask editor', - tooltip: 'Switch to the new mask editor interface', - type: 'boolean', - defaultValue: true, - experimental: true - }, { id: 'Comfy.MaskEditor.BrushAdjustmentSpeed', category: ['Mask Editor', 'BrushAdjustment', 'Sensitivity'], name: 'Brush adjustment speed multiplier', tooltip: 'Controls how quickly the brush size and hardness change when adjusting. Higher values mean faster changes.', - experimental: true, type: 'slider', attrs: { min: 0.1, @@ -99,8 +50,7 @@ app.registerExtension({ tooltip: 'When enabled, brush adjustments will only affect size OR hardness based on which direction you move more', type: 'boolean', - defaultValue: true, - experimental: true + defaultValue: true } ], commands: [ @@ -128,36 +78,7 @@ app.registerExtension({ label: 'Decrease Brush Size in MaskEditor', function: () => changeBrushSize((old) => _.clamp(old - 4, 1, 100)) } - ], - init() { - // Support for old editor clipspace integration - const openMaskEditorFromClipspace = () => { - const useNewEditor = app.extensionManager.setting.get( - 'Comfy.MaskEditor.UseNewEditor' - ) - if (!useNewEditor) { - warnLegacyMaskEditorDeprecation() - const dlg = MaskEditorDialogOld.getInstance() as any - if (dlg?.isOpened && !dlg.isOpened()) { - dlg.show() - } - } - } - - const context_predicate = (): boolean => { - return !!( - ComfyApp.clipspace && - ComfyApp.clipspace.imgs && - ComfyApp.clipspace.imgs.length > 0 - ) - } - - ClipspaceDialog.registerButton( - 'MaskEditor', - context_predicate, - openMaskEditorFromClipspace - ) - } + ] }) const changeBrushSize = async (sizeChanger: (oldSize: number) => number) => { diff --git a/src/locales/ar/main.json b/src/locales/ar/main.json index ac46da638..42c60facd 100644 --- a/src/locales/ar/main.json +++ b/src/locales/ar/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "محرر القناع", "Menu": "القائمة", "ModelLibrary": "مكتبة النماذج", - "NewEditor": "المحرر الجديد", "Node": "العقدة", "Node Search Box": "مربع بحث العقد", "Node Widget": "أداة العقدة", diff --git a/src/locales/ar/settings.json b/src/locales/ar/settings.json index 5f6dcafdc..d5e4704e5 100644 --- a/src/locales/ar/settings.json +++ b/src/locales/ar/settings.json @@ -181,10 +181,6 @@ "name": "تقييد تعديل الفرشاة إلى المحور السائد", "tooltip": "عند التمكين، تؤثر التعديلات على الحجم أو الصلابة فقط بناءً على الاتجاه الذي تتحرك فيه أكثر." }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "استخدام محرر القناع الجديد", - "tooltip": "التحويل إلى واجهة محرر القناع الجديدة" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "تحميل جميع مجلدات النماذج تلقائيًا", "tooltip": "إذا كانت صحيحة، سيتم تحميل جميع المجلدات عند فتح مكتبة النماذج (قد يسبب تأخيرًا أثناء التحميل). إذا كانت خاطئة، يتم تحميل مجلدات النماذج على مستوى الجذر فقط عند النقر عليها." diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 47f33b17b..837c36aa3 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -1203,7 +1203,6 @@ "Locale": "Locale", "Mask Editor": "Mask Editor", "BrushAdjustment": "Brush Adjustment", - "NewEditor": "New Editor", "ModelLibrary": "Model Library", "NodeLibrary": "Node Library", "Node Search Box": "Node Search Box", @@ -2428,4 +2427,4 @@ "recentReleases": "Recent releases", "helpCenterMenu": "Help Center Menu" } -} \ No newline at end of file +} diff --git a/src/locales/en/settings.json b/src/locales/en/settings.json index d9cc10306..0a3b21623 100644 --- a/src/locales/en/settings.json +++ b/src/locales/en/settings.json @@ -205,10 +205,6 @@ "name": "Lock brush adjustment to dominant axis", "tooltip": "When enabled, brush adjustments will only affect size OR hardness based on which direction you move more" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "Use new mask editor", - "tooltip": "Switch to the new mask editor interface" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "Automatically load all model folders", "tooltip": "If true, all folders will load as soon as you open the model library (this may cause delays while it loads). If false, root level model folders will only load once you click on them." @@ -464,4 +460,4 @@ "pysssss_SnapToGrid": { "name": "Always snap to grid" } -} \ No newline at end of file +} diff --git a/src/locales/es/main.json b/src/locales/es/main.json index fe91ca680..8ef2594e4 100644 --- a/src/locales/es/main.json +++ b/src/locales/es/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "Editor de Máscara", "Menu": "Menú", "ModelLibrary": "Biblioteca de Modelos", - "NewEditor": "Nuevo Editor", "Node": "Nodo", "Node Search Box": "Caja de Búsqueda de Nodo", "Node Widget": "Widget de Nodo", diff --git a/src/locales/es/settings.json b/src/locales/es/settings.json index 1628e9c94..0718932fb 100644 --- a/src/locales/es/settings.json +++ b/src/locales/es/settings.json @@ -181,10 +181,6 @@ "name": "Bloquear ajuste del pincel al eje dominante", "tooltip": "Cuando está habilitado, los ajustes del pincel solo afectarán el tamaño O la dureza según la dirección en la que te muevas más" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "Usar nuevo editor de máscara", - "tooltip": "Cambiar a la nueva interfaz del editor de máscaras" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "Cargar automáticamente todas las carpetas de modelos", "tooltip": "Si es verdadero, todas las carpetas se cargarán tan pronto como abras la biblioteca de modelos (esto puede causar retrasos mientras se carga). Si es falso, las carpetas de modelos de nivel raíz solo se cargarán una vez que hagas clic en ellas." diff --git a/src/locales/fr/main.json b/src/locales/fr/main.json index 2d88a759e..b255b4f63 100644 --- a/src/locales/fr/main.json +++ b/src/locales/fr/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "Éditeur de Masque", "Menu": "Menu", "ModelLibrary": "Bibliothèque de Modèles", - "NewEditor": "Nouvel Éditeur", "Node": "Nœud", "Node Search Box": "Boîte de Recherche de Nœud", "Node Widget": "Widget de Nœud", diff --git a/src/locales/fr/settings.json b/src/locales/fr/settings.json index ba9006ada..aaa973473 100644 --- a/src/locales/fr/settings.json +++ b/src/locales/fr/settings.json @@ -181,10 +181,6 @@ "name": "Verrouiller l'ajustement du pinceau sur l'axe dominant", "tooltip": "Lorsqu'il est activé, les ajustements du pinceau n'affecteront que la taille OU la dureté en fonction de la direction dans laquelle vous bougez le plus" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "Utiliser le nouvel éditeur de masque", - "tooltip": "Passer à la nouvelle interface de l'éditeur de masque" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "Charger automatiquement tous les dossiers de modèles", "tooltip": "Si vrai, tous les dossiers seront chargés dès que vous ouvrez la bibliothèque de modèles (cela peut causer des retards pendant le chargement). Si faux, les dossiers de modèles de niveau racine ne seront chargés que lorsque vous cliquerez dessus." diff --git a/src/locales/ja/main.json b/src/locales/ja/main.json index 0f5525097..4e326369b 100644 --- a/src/locales/ja/main.json +++ b/src/locales/ja/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "マスクエディタ", "Menu": "メニュー", "ModelLibrary": "モデルライブラリ", - "NewEditor": "新しいエディタ", "Node": "ノード", "Node Search Box": "ノード検索ボックス", "Node Widget": "ノードウィジェット", diff --git a/src/locales/ja/settings.json b/src/locales/ja/settings.json index 92cf77971..1d1fdeb1c 100644 --- a/src/locales/ja/settings.json +++ b/src/locales/ja/settings.json @@ -181,10 +181,6 @@ "name": "ブラシ調整を優先軸に固定する", "tooltip": "有効にすると、ブラシの調整は、どの方向に多く動かすかに基づいて、サイズまたは硬さのいずれかにのみ影響します。" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "新しいマスクエディタを使用する", - "tooltip": "新しいマスクエディタインターフェースに切り替えます。" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "すべてのモデルフォルダーを自動的に読み込む", "tooltip": "trueの場合、モデルライブラリを開くとすぐにすべてのフォルダーが読み込まれます(これにより読み込み中に遅延が発生する可能性があります)。falseの場合、ルートレベルのモデルフォルダーはクリックするまで読み込まれません。" diff --git a/src/locales/ko/main.json b/src/locales/ko/main.json index d6e6dfc1d..3a96c149b 100644 --- a/src/locales/ko/main.json +++ b/src/locales/ko/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "마스크 편집기", "Menu": "메뉴", "ModelLibrary": "모델 라이브러리", - "NewEditor": "새 편집기", "Node": "노드", "Node Search Box": "노드 검색 상자", "Node Widget": "노드 위젯", diff --git a/src/locales/ko/settings.json b/src/locales/ko/settings.json index 6cbdd17bb..aed056955 100644 --- a/src/locales/ko/settings.json +++ b/src/locales/ko/settings.json @@ -181,10 +181,6 @@ "name": "브러시 조정을 지배 축에 고정", "tooltip": "활성화하면 브러시 조정이 이동하는 방향에 따라 크기 또는 경도에만 영향을 미칩니다." }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "새 마스크 편집기 사용", - "tooltip": "새 마스크 편집기 인터페이스로 전환" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "모든 모델 폴더 자동 로드", "tooltip": "참이면 모든 폴더가 모델 라이브러리를 열 때 즉시 로드됩니다 (로드하는 동안 지연이 발생할 수 있습니다). 거짓이면 루트 수준 모델 폴더는 클릭할 때만 로드됩니다." diff --git a/src/locales/ru/main.json b/src/locales/ru/main.json index 0d74e2a7a..5867d9a53 100644 --- a/src/locales/ru/main.json +++ b/src/locales/ru/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "Редактор масок", "Menu": "Меню", "ModelLibrary": "Библиотека моделей", - "NewEditor": "Новый редактор", "Node": "Нода", "Node Search Box": "Поисковая строка нод", "Node Widget": "Виджет ноды", diff --git a/src/locales/ru/settings.json b/src/locales/ru/settings.json index 5ce93a984..3a467472d 100644 --- a/src/locales/ru/settings.json +++ b/src/locales/ru/settings.json @@ -181,10 +181,6 @@ "name": "Закрепить регулировку кисти по доминирующей оси", "tooltip": "При включении регулировки кисти будет влиять только на размер или жёсткость в зависимости от того, в каком направлении вы двигаетесь больше" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "Использовать новый редактор масок", - "tooltip": "Переключиться на новый интерфейс редактора масок" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "Автоматически загружать все папки моделей", "tooltip": "Если true, все папки будут загружены, как только вы откроете библиотеку моделей (это может вызвать задержки при загрузке). Если false, корневые папки моделей будут загружены только после нажатия на них." diff --git a/src/locales/tr/main.json b/src/locales/tr/main.json index 6bb1b543c..b23c9426d 100644 --- a/src/locales/tr/main.json +++ b/src/locales/tr/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "Maske Düzenleyici", "Menu": "Menü", "ModelLibrary": "Model Kütüphanesi", - "NewEditor": "Yeni Düzenleyici", "Node": "Düğüm", "Node Search Box": "Düğüm Arama Kutusu", "Node Widget": "Düğüm Widget'ı", diff --git a/src/locales/tr/settings.json b/src/locales/tr/settings.json index 07c191b4c..34a323fd4 100644 --- a/src/locales/tr/settings.json +++ b/src/locales/tr/settings.json @@ -181,10 +181,6 @@ "name": "Fırça ayarını baskın eksene kilitle", "tooltip": "Etkinleştirildiğinde, fırça ayarları yalnızca daha fazla hareket ettiğiniz yöne bağlı olarak boyutu VEYA sertliği etkileyecektir" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "Yeni maske düzenleyiciyi kullan", - "tooltip": "Yeni maske düzenleyici arayüzüne geç" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "Tüm model klasörlerini otomatik olarak yükle", "tooltip": "Doğruysa, model kütüphanesini açar açmaz tüm klasörler yüklenecektir (bu, yüklenirken gecikmelere neden olabilir). Yanlışsa, kök düzeyindeki model klasörleri yalnızca üzerlerine tıkladığınızda yüklenecektir." diff --git a/src/locales/zh-TW/main.json b/src/locales/zh-TW/main.json index 0c2f3d613..7a4693971 100644 --- a/src/locales/zh-TW/main.json +++ b/src/locales/zh-TW/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "遮罩編輯器", "Menu": "選單", "ModelLibrary": "模型庫", - "NewEditor": "新編輯器", "Node": "節點", "Node Search Box": "節點搜尋框", "Node Widget": "節點元件", diff --git a/src/locales/zh-TW/settings.json b/src/locales/zh-TW/settings.json index ca5ac2aa3..3e66a779d 100644 --- a/src/locales/zh-TW/settings.json +++ b/src/locales/zh-TW/settings.json @@ -181,10 +181,6 @@ "name": "鎖定筆刷調整至主軸", "tooltip": "啟用後,筆刷調整只會根據你移動較多的方向,分別影響大小或硬度" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "使用新遮罩編輯器", - "tooltip": "切換到新遮罩編輯器介面" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "自動載入所有模型資料夾", "tooltip": "若為開啟,當你打開模型庫時,所有資料夾將自動載入(這可能會導致載入時延遲)。若為關閉,只有在你點擊根目錄下的模型資料夾時才會載入。" diff --git a/src/locales/zh/main.json b/src/locales/zh/main.json index 9eed2ddd5..c736137ca 100644 --- a/src/locales/zh/main.json +++ b/src/locales/zh/main.json @@ -1567,7 +1567,6 @@ "Mask Editor": "遮罩编辑器", "Menu": "菜单", "ModelLibrary": "模型库", - "NewEditor": "新编辑器", "Node": "节点", "Node Search Box": "节点搜索框", "Node Widget": "节点组件", diff --git a/src/locales/zh/settings.json b/src/locales/zh/settings.json index c6c1855d0..90934b95a 100644 --- a/src/locales/zh/settings.json +++ b/src/locales/zh/settings.json @@ -181,10 +181,6 @@ "name": "将画笔调整锁定到主轴", "tooltip": "启用后,画笔调整将仅根据您移动的方向影响大小或硬度。" }, - "Comfy_MaskEditor_UseNewEditor": { - "name": "使用新画笔编辑器", - "tooltip": "切换到新的画笔编辑器界面" - }, "Comfy_ModelLibrary_AutoLoadAll": { "name": "自动加载所有模型文件夹", "tooltip": "开启后,打开模型库会加载所有文件夹内的模型(可能导致卡顿)。关闭后,仅加载当前文件夹内的模型。" diff --git a/src/schemas/apiSchema.ts b/src/schemas/apiSchema.ts index 7259be8b5..83c9890a8 100644 --- a/src/schemas/apiSchema.ts +++ b/src/schemas/apiSchema.ts @@ -497,7 +497,6 @@ const zSettings = z.object({ 'Comfy-Desktop.UV.PythonInstallMirror': z.string(), 'Comfy-Desktop.UV.PypiInstallMirror': z.string(), 'Comfy-Desktop.UV.TorchInstallMirror': z.string(), - 'Comfy.MaskEditor.UseNewEditor': z.boolean(), 'Comfy.MaskEditor.BrushAdjustmentSpeed': z.number(), 'Comfy.MaskEditor.UseDominantAxis': z.boolean(), 'Comfy.Load3D.ShowGrid': z.boolean(),