Implemented dynamic brush cursor with visual feedback for size (circle radius), strength (opacity), and hardness (solid/dashed border with gradient). Added overlay canvas system for smooth cursor updates without affecting main rendering performance.
Implemented centralized modifier state management with ModifierState interface and getModifierState() method. This eliminates inconsistencies between event-based and state-based modifier checking across mouse, wheel, and keyboard interactions.
Fixed all TypeScript compilation errors by defining a dedicated TransformOrigin type and adding proper null checks. Implemented comprehensive event handler cleanup to prevent memory leaks and improved cross-platform support with Meta key handling for macOS users.
Enhanced the system to always select the best available cache based on both blend area and crop, prioritizing exact matches. Prevented costly operations and live rendering during scaling for optimal performance and smooth user experience.
Redesigned the positioning system for the Blend Mode menu, inspired by the "Custom Output Area" logic. The menu now anchors precisely to the top-right corner of the viewport and stays in place during panning and zooming.
Added a clear first point distinction when drawing a custom shape: if the mouse cursor is near the beginning of a line (the shape can be closed), the first point is drawn in yellow and larger. This allows the user to see when they can close the shape with a single click. The code has been compiled and is ready to use. The functionality works as expected.
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 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.
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.
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.
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.
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 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.
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.