@@ -759,6 +759,8 @@ const ImageCanvas = memo(
759759 const [ isFadingIn , setIsFadingIn ] = useState ( false ) ;
760760 const prevImageIdentityRef = useRef ( selectedImage . thumbnailUrl ) ;
761761
762+ const [ baseTool , setBaseTool ] = useState < ToolType > ( brushSettings ?. tool ?? ToolType . Brush ) ;
763+
762764 useEffect ( ( ) => {
763765 const newSrc = finalPreviewUrl || selectedImage . thumbnailUrl ;
764766 const isNewImage = prevImageIdentityRef . current !== selectedImage . thumbnailUrl ;
@@ -804,6 +806,32 @@ const ImageCanvas = memo(
804806 }
805807 } , [ finalPreviewUrl , selectedImage . thumbnailUrl , isSliderDragging ] ) ;
806808
809+ useEffect ( ( ) => {
810+ setBaseTool ( brushSettings ?. tool ?? ToolType . Brush ) ;
811+ } , [ brushSettings ?. tool ] ) ;
812+
813+ useEffect ( ( ) => {
814+ const handleKeyDown = ( e : KeyboardEvent ) => {
815+ if ( e . key === 'Alt' ) {
816+ e . preventDefault ( ) ;
817+ ( window as any ) . altKeyDown = true ;
818+ }
819+ } ;
820+ const handleKeyUp = ( e : KeyboardEvent ) => {
821+ if ( e . key === 'Alt' ) {
822+ e . preventDefault ( ) ;
823+ ( window as any ) . altKeyDown = false ;
824+ }
825+ } ;
826+ window . addEventListener ( 'keydown' , handleKeyDown ) ;
827+ window . addEventListener ( 'keyup' , handleKeyUp ) ;
828+ return ( ) => {
829+ window . removeEventListener ( 'keydown' , handleKeyDown ) ;
830+ window . removeEventListener ( 'keyup' , handleKeyUp ) ;
831+ delete ( window as any ) . altKeyDown ;
832+ } ;
833+ } , [ ] ) ;
834+
807835 const activeContainer = useMemo ( ( ) => {
808836 if ( isMasking ) {
809837 return adjustments . masks . find ( ( c : MaskContainer ) => c . id === activeMaskContainerId ) ;
@@ -1088,7 +1116,16 @@ const ImageCanvas = memo(
10881116 return ;
10891117 }
10901118
1091- const toolType = isAiSubjectActive ? ToolType . AiSeletor : ToolType . Brush ;
1119+ const isAltPressed = e . evt . altKey ;
1120+ let effectiveTool ;
1121+
1122+ if ( isAiSubjectActive ) {
1123+ effectiveTool = ToolType . AiSeletor ;
1124+ } else if ( isAltPressed ) {
1125+ effectiveTool = baseTool === ToolType . Brush ? ToolType . Eraser : ToolType . Brush ;
1126+ } else {
1127+ effectiveTool = baseTool ;
1128+ }
10921129 const isShiftClick = isBrushActive && e . evt . shiftKey && lastBrushPoint . current ;
10931130
10941131 if ( isShiftClick ) {
@@ -1121,7 +1158,7 @@ const ImageCanvas = memo(
11211158 brushSize : brushImageSpaceSize ,
11221159 feather : brushSettings ?. feather ? brushSettings ?. feather / 100 : 0 ,
11231160 points : interpolatedPoints ,
1124- tool : brushSettings ?. tool ?? ToolType . Brush ,
1161+ tool : effectiveTool ,
11251162 } ;
11261163
11271164 const activeId = isMasking ? activeMaskId : activeAiSubMaskId ;
@@ -1146,7 +1183,7 @@ const ImageCanvas = memo(
11461183 const newLine : DrawnLine = {
11471184 brushSize : isBrushActive && brushSettings ?. size ? brushStageSize : 2 ,
11481185 points : [ pos ] ,
1149- tool : toolType ,
1186+ tool : effectiveTool ,
11501187 } ;
11511188 currentLine . current = newLine ;
11521189 } else {
@@ -1182,6 +1219,7 @@ const ImageCanvas = memo(
11821219 isToolActive ,
11831220 brushImageSpaceSize ,
11841221 brushStageSize ,
1222+ baseTool ,
11851223 ] ,
11861224 ) ;
11871225
@@ -1302,14 +1340,24 @@ const ImageCanvas = memo(
13021340 const cropX = crop ? ( isPercent ? ( crop . x / 100 ) * effectiveImageDimensions . width : crop . x ) : 0 ;
13031341 const cropY = crop ? ( isPercent ? ( crop . y / 100 ) * effectiveImageDimensions . height : crop . y ) : 0 ;
13041342
1343+ const isAltPressedDuringMove = ( window as any ) . altKeyDown || false ;
1344+ let effectiveToolForPreview ;
1345+
1346+ if ( isAltPressedDuringMove ) {
1347+ // Alt toggles: Brush -> Eraser, Eraser -> Brush
1348+ effectiveToolForPreview = baseTool === ToolType . Brush ? ToolType . Eraser : ToolType . Brush ;
1349+ } else {
1350+ effectiveToolForPreview = baseTool ;
1351+ }
1352+
13051353 const imageSpaceLine : DrawnLine = {
13061354 brushSize : brushImageSpaceSize ,
13071355 feather : brushSettings ?. feather ? brushSettings ?. feather / 100 : 0 ,
13081356 points : updatedLine . points . map ( ( p : Coord ) => ( {
13091357 x : p . x / scale + cropX ,
13101358 y : p . y / scale + cropY ,
13111359 } ) ) ,
1312- tool : brushSettings ?. tool ?? ToolType . Brush ,
1360+ tool : effectiveToolForPreview ,
13131361 } ;
13141362
13151363 const existingLines = activeSubMask . parameters ?. lines || [ ] ;
@@ -1351,6 +1399,7 @@ const ImageCanvas = memo(
13511399 isMasking ,
13521400 localInitialDrawParams ,
13531401 brushImageSpaceSize ,
1402+ baseTool ,
13541403 ] ,
13551404 ) ;
13561405
@@ -1458,14 +1507,17 @@ const ImageCanvas = memo(
14581507 const activeId = isMasking ? activeMaskId : activeAiSubMaskId ;
14591508
14601509 if ( isBrushActive ) {
1510+ const wasAltPressed = ( window as any ) . altKeyDown || false ;
1511+ const effectiveToolForFinal = wasAltPressed ? ( baseTool === ToolType . Brush ? ToolType . Eraser : ToolType . Brush ) : baseTool ;
1512+
14611513 const imageSpaceLine : DrawnLine = {
14621514 brushSize : brushImageSpaceSize ,
14631515 feather : brushSettings ?. feather ? brushSettings ?. feather / 100 : 0 ,
14641516 points : line . points . map ( ( p : Coord ) => ( {
14651517 x : p . x / scale + cropX ,
14661518 y : p . y / scale + cropY ,
14671519 } ) ) ,
1468- tool : brushSettings ?. tool ?? ToolType . Brush ,
1520+ tool : effectiveToolForFinal ,
14691521 } ;
14701522
14711523 const existingLines = activeSubMask ?. parameters . lines || [ ] ;
@@ -1503,6 +1555,7 @@ const ImageCanvas = memo(
15031555 localInitialDrawParams ,
15041556 brushImageSpaceSize ,
15051557 brushStageSize ,
1558+ baseTool ,
15061559 ] ) ;
15071560
15081561 const handleMouseEnter = useCallback ( ( ) => {
@@ -1903,7 +1956,6 @@ const ImageCanvas = memo(
19031956 ) ;
19041957 } ) }
19051958
1906- { /* Visualizer for drawing new AI Bounding Box */ }
19071959 { previewBox && (
19081960 < Rect
19091961 x = { Math . min ( previewBox . start . x , previewBox . end . x ) }
@@ -1920,7 +1972,9 @@ const ImageCanvas = memo(
19201972 < Circle
19211973 listening = { false }
19221974 perfectDrawEnabled = { false }
1923- stroke = { brushSettings ?. tool === ToolType . Eraser ? '#f43f5e' : '#0ea5e9' }
1975+ stroke = { ( window as any ) . altKeyDown ?
1976+ ( baseTool === ToolType . Brush ? '#f43f5e' : '#0ea5e9' ) :
1977+ ( baseTool === ToolType . Eraser ? '#f43f5e' : '#0ea5e9' ) }
19241978 radius = { brushStageSize / 2 }
19251979 strokeWidth = { 1 }
19261980 x = { cursorPreview . x }
0 commit comments