Centralizes layer movement logic in CanvasLayers with a new moveLayers function, supporting both up/down and drag-and-drop reordering. Updates selection logic in Canvas to only trigger updates when selection changes, and improves event handling in CanvasLayersPanel for more responsive selection and drag operations. Removes redundant moveLayersToPosition method in favor of the new unified approach.
Introduces a new CanvasLayersPanel component for managing layers visually, including selection, renaming, reordering via drag-and-drop, and deletion. Integrates the panel into the main Canvas and CanvasView, synchronizes selection and state changes, and adds logic for duplicating layers and debounced state saving. Moves IndexedDB state saving to a Web Worker for better performance. Also sets default logger level to DEBUG for improved diagnostics.
Added documentation files for ComfyApi, ComfyApp, LitegraphService, and MaskEditor, summarizing their main functions and usage. Refactored js/Canvas.js to improve mask processing logic, using viewport pan for cropping and applying mask color only to non-transparent pixels. Also made minor formatting and logging consistency improvements throughout Canvas.js.
Refactored the Canvas class to act as a facade, providing a simplified high-level interface and delegating detailed operations to internal modules. Added Polish documentation, grouped and clarified main operations, and moved legacy/delegation methods to the end for backward compatibility. Removed unused or redundant methods from CanvasLayers.js, such as removeLayer, moveLayer, addMattedLayer, isRotationHandle, getResizeHandle, handleBlendModeSelection, and getFlattenedCanvasAsDataURL, to streamline the codebase.
Introduces the ability to open the current canvas in a mask editor, upload and retrieve mask edits, and apply them to the mask layer. Adds utility functions for mask editor state detection and control, a new 'Edit Mask' button in the UI, and methods for handling mask updates and preview refresh. Also adds a setMask method to MaskTool for precise mask placement.
Introduces a 'fit_on_add' boolean option to control whether images are fit to the canvas when added or pasted. Updates image addition and paste logic in Canvas, CanvasLayers, and CanvasView to support new placement modes ('fit', 'center', 'mouse', 'default').
The handlePaste method now accepts a pasteMode parameter to control image placement, allowing images to be pasted either at the mouse position or centered on the canvas. This improves user control when pasting images via keyboard shortcuts or UI buttons.
Introduces a brush preview overlay using a separate preview canvas in MaskTool. Mouse event handlers in CanvasInteractions and MaskTool are updated to support passing both world and view coordinates, enabling accurate brush preview rendering. The preview is shown or hidden appropriately on mouse enter/leave and while drawing.
Set logging level to DEBUG in both Python and JavaScript loggers for improved debugging. Updated MaskTool to accept an onStateChange callback and trigger it after mask state changes, allowing Canvas to respond to mask updates.
Replaces the onInteractionEnd callback with onStateChange for more consistent state change notifications. Adds a removeSelectedLayers method to Canvas for cleaner layer removal logic. Updates UI event handlers to use the new methods and callbacks, and ensures state is saved after relevant operations. Cleans up redundant updateOutput calls and streamlines output update logic.
Introduces an optional onInteractionEnd callback to the Canvas class, which is triggered at the end of user interactions. CanvasView now uses this callback to update output after interactions, improving responsiveness to user actions.
This commit applies consistent code formatting across multiple files, including spacing, indentation, and object destructuring. No functional changes were made; the update improves code readability and maintainability.
Introduces a WebSocket-based mechanism for CanvasNode to send and receive canvas image and mask data in RAM, enabling fast, diskless data transfer between frontend and backend. Adds a new WebSocketManager utility, updates CanvasIO to support RAM output mode, and modifies CanvasView to send canvas data via WebSocket before prompt execution. The backend (canvas_node.py) is updated to handle WebSocket data storage and retrieval, with improved locking and cleanup logic. This change improves workflow speed and reliability by avoiding unnecessary disk I/O and ensuring up-to-date canvas data is available during node execution.
Introduces an operation counter and threshold in ImageReferenceManager to trigger automatic garbage collection after a set number of canvas operations. Canvas now increments the operation count on save, undo, and redo, and exposes methods to set the operation threshold and retrieve stats including operation count. CanvasView displays the operation count and threshold after manual garbage collection.
Introduced ImageReferenceManager to track and clean up unused images from the database and cache. Added manual garbage collection controls to the UI and exposed related stats and cleanup methods in Canvas. Updated db.js with a method to retrieve all image IDs for cleanup purposes.
Refactored method and variable names from 'canvas size' to 'output area size' across multiple files for clarity. Updated UI labels and related function calls to reflect this terminology change.
Eliminated the applyBlendMode method from Canvas and CanvasLayers, along with related unused imports in CanvasIO and CanvasLayers. This streamlines the code by removing dead code and unnecessary dependencies.
Renamed Mask_tool.js to MaskTool.js and Canvas_view.js to CanvasView.js for consistency. Removed unused imports and redundant properties/methods from Canvas.js and CanvasState.js to streamline the codebase.
Removed Polish-language and redundant comments from multiple modules, including Canvas, CanvasInteractions, CanvasLayers, CanvasRenderer, CanvasState, Canvas_view, Mask_tool, and CommonUtils. This improves code readability and maintainability by reducing clutter and focusing on self-explanatory code.
Moved CommonUtils.js, ImageUtils.js, and LoggerUtils.js to a new utils/ directory and updated all import paths accordingly throughout the codebase. Also increased the default canvas width in Canvas.js from 512 to 1024.
Refactors CanvasState to maintain independent undo/redo stacks for mask editing and layer editing. Updates all relevant logic to use the correct history depending on the active mode, ensuring undo/redo and history buttons work as expected in both modes. MaskTool now saves history on activation, clear, and mouse up, and history info is reported per mode. Improves user experience when switching between mask and layer editing.
Moved all input/output related methods from Canvas.js to a new CanvasIO.js module and delegated corresponding Canvas class methods to CanvasIO. This improves code organization and separation of concerns, making Canvas.js more focused on core canvas logic and CanvasIO.js responsible for I/O operations.
Moved all rendering-related methods from Canvas.js to a new CanvasRenderer.js module. Canvas now delegates rendering to CanvasRenderer, improving separation of concerns and maintainability.
Replaces per-layer mask processing with a single visibility canvas that composites all layers, then generates the mask based on the resulting alpha values. This simplifies the logic and ensures correct handling of partial transparency across all layers.
Enhanced the canvas save mechanism to ensure unique file names per node, prevent concurrent saves and executions, and handle missing files more robustly. Switched all logger levels to DEBUG for detailed tracing. Added fallback logic for file naming, improved error handling, and ensured that empty canvases are not saved. These changes improve reliability and traceability of canvas operations, especially in multi-node scenarios.
Moved all layer-related logic from Canvas.js to a new CanvasLayers.js module, including blend modes, clipboard operations, transformations, and utility functions. Canvas.js now delegates these operations to CanvasLayers, improving code organization and maintainability.
Moved all user interaction handling (mouse, keyboard, panning, resizing, dragging, etc.) from Canvas.js to a new CanvasInteractions.js module. Canvas.js now delegates interaction events to CanvasInteractions, improving code organization and maintainability.
Moved undo/redo history and IndexedDB state logic from Canvas.js to a new CanvasState.js module. Canvas now delegates state persistence and history operations to CanvasState, improving separation of concerns and maintainability.
Introduces concurrency locks in Python and JavaScript to prevent simultaneous processing and saving operations in canvas-related workflows. Adds extensive logging throughout the canvas image processing, saving, and matting routines to aid debugging and trace execution flow. Also improves error handling and state management in both backend and frontend code.
Images used in canvas layers are now stored in a dedicated 'CanvasImages' object store in IndexedDB, referenced by unique imageId. The Canvas class and db.js were updated to support saving, loading, and removing images by imageId, improving performance and scalability. Legacy imageSrc handling is preserved for backward compatibility, and the database schema version was incremented to 2 to support the new store.
Standardized spacing and object literal formatting across multiple JS files for improved readability and consistency. No functional changes were made. Minor Python formatting adjustment for line length in canvas_node.py.
Introduces a new MaskTool for interactive mask drawing with adjustable brush size, strength, and softness. Updates Canvas.js to integrate mask editing, rendering, and saving, including support for saving images with and without masks. Enhances the UI in Canvas_view.js with mask controls and a dialog for canvas resizing. Updates canvas_node.py to load images without masks for processing. These changes improve user control over mask creation and management in the canvas workflow.
Added getStateSignature to compare layer states by serializing relevant properties, avoiding issues with image object references. Refactored mirrorHorizontal and mirrorVertical to be async and await all image updates before rendering and saving state, ensuring consistency and preventing race conditions.
Simplifies and corrects the logic for maintaining the original aspect ratio when resizing objects with the Shift key pressed. Ensures consistent behavior regardless of handle or direction.
Added calls to saveState() after scaling, rotating, and removing layers to ensure changes are properly recorded in the undo/redo history. Also refactored the matting button UI for better layout and ensured saveState is called after matting results are applied.
Replaced localStorage usage in Canvas.js with asynchronous IndexedDB operations for saving, loading, and removing canvas state. Added a new db.js module to handle IndexedDB interactions, improving scalability and reliability of state persistence.
Introduces methods to save and load canvas state to localStorage, enabling persistence across sessions. Refactors image loading for drag-and-drop, file input, and clipboard paste to use FileReader and data:URL, improving compatibility and reliability. Updates layer addition to consistently update selection and save state. Calls loadInitialState on widget creation to restore previous state if available.
Implemented undo and redo history stacks in Canvas.js, including keyboard shortcuts (Ctrl+Z, Ctrl+Y/Shift+Z), and state saving on relevant actions. Added Undo and Redo buttons to the UI in Canvas_view.js, with dynamic enable/disable based on history state.