diff --git a/CODEOWNERS b/CODEOWNERS index 05e8d324c68..fcba1e4005e 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 1a3b8d93d58..6441dd7816f 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 56f9ed28c30..f7444ce76ad 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 e34c3f225a6..00000000000 --- 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 6986533597d..a0084cfb9f4 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 ac46da638a2..42c60facd51 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 5f6dcafdc17..d5e4704e5b8 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 47f33b17bee..837c36aa315 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 d9cc103060f..0a3b21623f8 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 fe91ca68041..8ef2594e462 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 1628e9c94d9..0718932fbe9 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 2d88a759e67..b255b4f63b1 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 ba9006adabb..aaa97347309 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 0f5525097aa..4e326369bce 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 92cf77971e4..1d1fdeb1c92 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 d6e6dfc1d49..3a96c149b37 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 6cbdd17bbd1..aed0569553d 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 0d74e2a7aab..5867d9a535e 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 5ce93a9845a..3a467472d93 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 6bb1b543cc5..b23c9426db3 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 07c191b4cdc..34a323fd47d 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 0c2f3d61392..7a4693971b5 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 ca5ac2aa3c4..3e66a779da5 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 9eed2ddd541..c736137ca6c 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 c6c1855d093..90934b95a7b 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 7259be8b5fa..83c9890a8bf 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(),