Renamed the CanvasMask class and file to MaskEditorIntegration for improved clarity and consistency. Updated all references in Canvas and SAMDetectorIntegration to use the new name.
Replaces full-canvas mask operations with getMaskForOutputArea() for significant performance improvements when processing masks for the output area. Refines shape mask removal and application logic to ensure correct mask state when changing expansion values or custom shapes, including auto-removal and re-application of masks. Adds throttling to shape preview rendering for better UI responsiveness. Improves mask removal to eliminate antialiasing artifacts and updates SAM mask integration to use correct output area positioning.
Introduces utility methods to eliminate code duplication in chunk operations, mask creation, and shape processing. Adds universal chunk processing, chunk operation, and canvas helper methods. Refactors shape mask application and removal to use unified logic, and consolidates morphological and feathering operations for masks. Improves maintainability and readability by centralizing repeated logic.
Introduces utility methods for chunk bounds calculation, intersection, and activation for better code reuse and clarity. Refactors shape mask application and removal to consistently account for output area extensions, and centralizes chunk empty status updates. Improves chunk activation logic for mask and shape operations to enhance visibility and maintainability.
Introduces active chunk management for mask drawing, activating only nearby chunks during drawing for performance. Updates the active mask canvas to show all chunks but optimizes updates to redraw only active chunks during drawing, reducing lag. Adds LRU-style tracking and safety limits for active chunks, and improves chunk activation logic for both drawing and mask application.
Introduces helper methods to reduce code duplication and improve readability in CanvasInteractions. Mouse coordinate extraction, event prevention, zoom operations, drag-and-drop styling, and layer wheel transformations are now handled by dedicated methods. This refactor centralizes logic, making the codebase easier to maintain and extend.
Cleaned up the codebase by removing unused or redundant methods from Canvas, CanvasIO, CanvasLayers, CanvasLayersPanel, CanvasRenderer, and MaskTool. This reduces code complexity and improves maintainability without affecting core functionality.
Refactors how custom output area shapes interact with extensions, ensuring the shape's position and mask application remain consistent when extensions are toggled. Moves output area shape logic to CanvasInteractions, tracks original shape position, and updates all rendering, IO, and mask operations to use the correct coordinates. Improves mask chunk clearing and adds chunked mask application/removal for shape masks, ensuring correct behavior with expansion and feathering.
Output area bounds are now positioned relative to the world, not always at (0,0), and are updated to match custom shape placement. Rendering and extension logic have been updated to respect the new bounds, and the mask tool now adjusts to the output area position. Also sets log level to DEBUG for development.
Replaces the single large mask canvas with a chunked system, where mask data is stored in 512x512 pixel chunks. Updates all mask drawing, compositing, and manipulation logic to operate on these chunks, improving performance and scalability for large or sparse masks. The active mask canvas is now a composite of all non-empty chunks, and all mask operations (drawing, setting, clearing) are adapted to the new chunked architecture.
This update introduces a unified output area bounds system, allowing the output area to be extended in all directions independently of the custom shape. All mask and layer operations now reference outputAreaBounds, ensuring correct alignment and rendering. The mask tool, mask editor, and export logic have been refactored to use these bounds, and a new UI for output area extension with live preview and tooltips has been added. The code also improves logging and visualization of mask and output area boundaries.
Consolidates shape mask controls into a styled container, improves UI logic for showing/hiding sub-options, and updates slider initialization to reflect current values. Mask removal now always uses a hard-edged shape, even if feathering was previously applied, ensuring complete erasure of feathered areas. The mask application logic also clears the maximum possible mask area before applying the new mask to prevent artifacts from previous slider values. Checkbox and slider labels are updated for clarity.
Implements a real-time blue outline preview when adjusting the expansion and feather sliders in the custom shape mask UI. The preview updates dynamically while dragging, and applies the mask only on mouse release. Adds a viewport change listener to keep the preview in sync during zooming or panning. Refactors mask expansion/contraction to use fast morphological operations for sharp edges and updates mask drawing to handle holes correctly.
Introduces a CustomShapeMenu UI component for managing custom output area shape masks, including options for auto-applying the mask, expansion/contraction, and feathering. Updates Canvas and MaskTool to support these new mask operations, and ensures the menu is shown or hidden based on shape presence. Adds distance transform-based algorithms for accurate mask expansion and feathering.
Introduces a 'blendArea' property to layers and UI controls for adjusting it. Implements distance field mask generation in ImageAnalysis.ts and applies the mask during layer rendering for smooth edge blending. Refactors CanvasRenderer to delegate layer drawing to CanvasLayers for proper blend area support.
Always prevent the default browser context menu and stop event propagation on right-click interactions and custom menus. This ensures that only the application's custom context menus are shown and avoids interference from the browser's native context menu.
Introduces a 'visible' property to layers and updates all relevant logic to support toggling layer visibility. Adds visibility toggle icons to the layers panel using a new IconLoader utility, with SVG and fallback canvas icons. Updates rendering, selection, and batch preview logic to respect layer visibility. Also improves blend mode menu UI and ensures new/pasted layers are always added on top with correct z-index.
Introduces ShapeTool to allow users to define custom polygonal output areas by holding Shift+S and clicking to add points. The selected shape is used to crop and mask images and layers, and is visualized on the canvas. Updates Canvas, CanvasIO, CanvasInteractions, CanvasLayers, CanvasRenderer, and types to support shape-based output areas, including shape-aware import, export, and rendering logic.
When the preview is disabled in the canvas widget, a 1x1 transparent PNG placeholder image is now set to node.imgs. This prevents issues with missing images and ensures consistent UI behavior.
Adds a window blur event listener to reset key states and interaction modes when the window loses focus. This prevents stuck key states and finalizes any in-progress cloning drags, improving interaction reliability.
Adds the willReadFrequently: true option to all getContext('2d') calls on temporary canvases in Canvas, CanvasLayers, and SAMDetectorIntegration modules. This improves performance for frequent pixel data reads, addressing potential browser optimization issues.
Moved all SAM Detector integration logic from CanvasView to a new SAMDetectorIntegration module for better maintainability and separation of concerns. Updated CanvasView to use the new integration functions and removed duplicate code.
Added debouncing to the updateOutput function to prevent excessive updates during rapid changes. Large images are now handled using blob URLs for better performance, while small images use data URIs. Also added logic to skip output updates when preview is disabled and improved cleanup of temporary file trackers when nodes are removed.
Introduces the addMask method to MaskTool in both JS and TS implementations, allowing new masks to be overlaid without clearing existing ones. Updates CanvasView to use addMask instead of setMask when applying SAM detector results.
Replaces polling-based monitoring of SAM Detector results with a MutationObserver that detects modal closure and style changes. Adds fallback to polling if modal is not found, and provides user notification if no mask is applied. This improves reliability and user feedback when applying masks from the SAM Detector.
Eliminates the sendCanvasToClipspace method and related UI/menu options from CanvasView and its TypeScript counterpart, as well as the associated type definition. Also removes the unused maskContext getter from MaskTool. This refactor likely reflects a change in feature requirements or a move away from Impact Pack compatibility.
Introduces automatic registration of canvas images in ComfyUI's clipspace for Impact Pack compatibility, including a new 'Send to Clipspace' menu option and a method on ComfyNode. Adds monitoring and mask application for SAM Detector results, ensuring seamless mask transfer to LayerForge. Also exposes MaskTool's maskContext property for external access.
Moved layer drawing logic into CanvasLayers._drawLayer and _drawLayers methods, replacing repeated rendering code in CanvasIO and CanvasLayers. This improves maintainability and ensures consistent handling of layer properties such as blend mode, opacity, rotation, and flipping. Also, fixed layer serialization to only generate imageId when missing, and ensured new layers have flipH/flipV set when created from matted images.
Refactors horizontal and vertical mirroring to toggle flipH/flipV properties on layers instead of modifying image data. Updates rendering logic in CanvasLayers and CanvasRenderer to apply horizontal/vertical flipping via canvas transforms. Adds flipH and flipV to Layer type and includes them in state signature calculation.
Replaces setPreviewVisibility(false) with direct assignment to previewVisible in Canvas and Canvas.ts. Adds initialization of preview state based on widget value in CanvasView and CanvasView.ts to ensure correct preview visibility on widget creation.
Replaces the local auto-refresh toggle with a node widget property 'auto_refresh_after_generation' in both JS and TS Canvas classes. Updates Python CanvasNode to include this property in the required config and removes 'hidden' from 'trigger' and 'node_id'. This change centralizes auto-refresh state in the node widget for better consistency and UI integration.
Adds specific handling for JSONDecodeError during model loading in Python, returning a clear error message if the model config is corrupted. Updates the JS/TS frontends to show a custom error dialog with details and copy-to-clipboard functionality instead of a simple alert, and ensures spinner removal is safe. This improves user experience and troubleshooting for matting model errors.
Moved inline CSS from CanvasView.js to a dedicated canvas_view.css file and added dynamic stylesheet loading. Extracted tooltip and shortcut HTML into separate template files and implemented a ResourceManager utility for loading stylesheets and templates. Updated CanvasInteractions.js and CanvasView.js to use the new resource management and template loading approach, improving maintainability and modularity.
Introduced LOG_LEVEL configuration in both Python and JavaScript to control logging verbosity. Updated logger initialization in canvas_node.py and LoggerUtils.js to use the new LOG_LEVEL from config files.
Introduces a 'generationArea' context for batch image generation, ensuring that batch preview outlines and image placement remain accurate when the canvas is moved or resized. Updates related logic in Canvas, CanvasInteractions, CanvasLayers, and CanvasRenderer to track and render the correct area, and synchronizes context updates across user interactions.
Refactored batch preview management to allow multiple BatchPreviewManager instances per canvas. Updated positioning logic to use an initial spawn position, adjusted UI updates, and ensured batch preview menus move correctly with canvas panning. Removed single-instance references and updated related event handling.
Added draggable functionality to the batch preview menu, allowing users to reposition it within the canvas using world coordinates. The menu's position now updates with viewport changes, and its initial placement is centered below the output area. Also refactored logic to show the menu with new layers instead of adding to an existing batch.
Introduces an addLayers method to BatchPreviewManager for adding new layers to an active batch preview or showing the UI if inactive. Updates Canvas to use addLayers instead of show, and fixes a bug where new layers were only added if more than one was present.
Introduces support for a 'drawingMask' interaction mode in CanvasInteractions. Mouse events are now delegated to the maskTool when in this mode, and the canvas is re-rendered after each relevant event.
BatchPreviewManager now automatically hides the mask overlay when batch preview starts and restores its previous state when preview ends. The mask toggle button's state and label are updated accordingly. Also, mask toggle button IDs are now unique per canvas node.
Introduces BatchPreviewManager for reviewing and confirming multiple imported layers after auto-refresh. Adds a toggle button for mask overlay visibility in the UI and updates mask rendering logic to respect overlay visibility. Also refactors image import to return new layers and adds a utility for removing layers by ID.
Introduces a new backend route and method to fetch all images created since a given timestamp, and updates the frontend to import all new images as layers on auto-refresh. This improves workflow by allowing multiple images generated in a single execution to be imported at once, rather than only the most recent image.
Introduces an 'Auto-refresh after generation' toggle to the Canvas. When enabled, the latest image is automatically imported after a successful execution event. Also ensures event listeners are properly cleaned up when the node is removed.
Adds checks for missing 'transformers' dependency and network errors in the matting endpoint, returning clear error messages for common failure cases. Updates the frontend to display more informative alerts to users when matting fails, including details from server responses.
Added calls to canvasLayersPanel.onLayersChanged() after pasting, adding, and fusing layers to ensure the layers panel updates its view in response to these actions.