@@ -1000,7 +1000,12 @@ export const canvasSlice = createSlice({
1000
1000
return ;
1001
1001
}
1002
1002
1003
- // Create a rectangle covering the current bounding box
1003
+ // If there are no objects to invert, do nothing
1004
+ if ( entity . objects . length === 0 ) {
1005
+ return ;
1006
+ }
1007
+
1008
+ // Create a rectangle covering the current bounding box relative to the entity position
1004
1009
const bboxRect = state . bbox . rect ;
1005
1010
const fillRectObject = {
1006
1011
id : getPrefixedId ( 'rect' ) ,
@@ -1014,14 +1019,52 @@ export const canvasSlice = createSlice({
1014
1019
color : { r : 255 , g : 255 , b : 255 , a : 1 } ,
1015
1020
} ;
1016
1021
1017
- // Convert existing objects to eraser effect by creating a composite inverted mask
1018
- // The strategy is to replace all existing objects with:
1019
- // 1. A full rectangle covering the bbox
1020
- // 2. The original objects as "erasers" to punch holes through the rectangle
1021
- const originalObjects = [ ...entity . objects ] ;
1022
+ // To invert a mask, we need to:
1023
+ // 1. Start with a full rectangle covering the bbox (this becomes the "base mask")
1024
+ // 2. Convert existing brush/rect objects to eraser lines to "punch holes" in the base mask
1025
+ const convertedObjects = entity . objects . map ( ( obj ) => {
1026
+ if ( obj . type === 'brush_line' ) {
1027
+ // Convert brush lines to eraser lines
1028
+ return {
1029
+ ...obj ,
1030
+ id : getPrefixedId ( 'eraser_line' ) ,
1031
+ type : 'eraser_line' as const ,
1032
+ } ;
1033
+ } else if ( obj . type === 'brush_line_with_pressure' ) {
1034
+ // Convert brush lines with pressure to eraser lines with pressure
1035
+ return {
1036
+ ...obj ,
1037
+ id : getPrefixedId ( 'eraser_line' ) ,
1038
+ type : 'eraser_line_with_pressure' as const ,
1039
+ } ;
1040
+ } else if ( obj . type === 'rect' ) {
1041
+ // Convert rectangles to eraser "rectangles" by making them transparent
1042
+ return {
1043
+ ...obj ,
1044
+ id : getPrefixedId ( 'rect' ) ,
1045
+ color : { ...obj . color , a : 0 } , // Make transparent to act as eraser
1046
+ } ;
1047
+ } else if ( obj . type === 'eraser_line' ) {
1048
+ // Convert eraser lines to brush lines
1049
+ return {
1050
+ ...obj ,
1051
+ id : getPrefixedId ( 'brush_line' ) ,
1052
+ type : 'brush_line' as const ,
1053
+ } ;
1054
+ } else if ( obj . type === 'eraser_line_with_pressure' ) {
1055
+ // Convert eraser lines with pressure to brush lines with pressure
1056
+ return {
1057
+ ...obj ,
1058
+ id : getPrefixedId ( 'brush_line' ) ,
1059
+ type : 'brush_line_with_pressure' as const ,
1060
+ } ;
1061
+ }
1062
+ // Keep images and other objects as is
1063
+ return obj ;
1064
+ } ) ;
1022
1065
1023
- // Start with the full rectangle, then "erase" the original painted areas
1024
- entity . objects = [ fillRectObject , ...originalObjects ] ;
1066
+ // Replace all objects with the base rectangle followed by converted objects
1067
+ entity . objects = [ fillRectObject , ...convertedObjects ] ;
1025
1068
} ,
1026
1069
//#region BBox
1027
1070
bboxScaledWidthChanged : ( state , action : PayloadAction < number > ) => {
0 commit comments