@@ -73,7 +73,6 @@ export class Editor {
73
73
private konva : KonvaObjects | null = null ;
74
74
private originalImage : HTMLImageElement | null = null ;
75
75
private isCropping = false ;
76
- private appliedCrop : CropBox | null = null ;
77
76
78
77
// Constants
79
78
private readonly MIN_CROP_DIMENSION = 64 ;
@@ -630,52 +629,6 @@ export class Editor {
630
629
this . resetView ( ) ;
631
630
} ;
632
631
633
- // Crop Mode
634
- startCrop = ( crop ?: CropBox ) => {
635
- if ( ! this . konva ?. image . image || this . isCropping ) {
636
- return ;
637
- }
638
-
639
- this . unfreezeCropOverlay ( ) ;
640
- this . isCropping = true ;
641
-
642
- // Calculate initial crop dimensions
643
- let cropX : number ;
644
- let cropY : number ;
645
- let cropWidth : number ;
646
- let cropHeight : number ;
647
-
648
- if ( crop ) {
649
- cropX = crop . x ;
650
- cropY = crop . y ;
651
- cropWidth = crop . width ;
652
- cropHeight = crop . height ;
653
- } else if ( this . appliedCrop ) {
654
- // Use the applied crop as starting point
655
- cropX = this . appliedCrop . x ;
656
- cropY = this . appliedCrop . y ;
657
- cropWidth = this . appliedCrop . width ;
658
- cropHeight = this . appliedCrop . height ;
659
- } else {
660
- // Create default crop box (centered, 80% of image)
661
- const imgWidth = this . konva . image . image . width ( ) ;
662
- const imgHeight = this . konva . image . image . height ( ) ;
663
- cropWidth = imgWidth * this . DEFAULT_CROP_BOX_SCALE ;
664
- cropHeight = imgHeight * this . DEFAULT_CROP_BOX_SCALE ;
665
- cropX = ( imgWidth - cropWidth ) / 2 ;
666
- cropY = ( imgHeight - cropHeight ) / 2 ;
667
- }
668
-
669
- this . updateCropBox ( {
670
- x : cropX ,
671
- y : cropY ,
672
- width : cropWidth ,
673
- height : cropHeight ,
674
- } ) ;
675
-
676
- this . callbacks . onCropStart ?.( ) ;
677
- } ;
678
-
679
632
private resizeCropBox = ( handleName : HandleName , handleRect : Konva . Rect ) => {
680
633
if ( ! this . konva ) {
681
634
return ;
@@ -972,60 +925,81 @@ export class Editor {
972
925
}
973
926
} ;
974
927
975
- private freezeCropOverlay = ( ) => {
976
- if ( ! this . konva ) {
928
+ // Crop Mode
929
+ startCrop = ( crop ?: CropBox ) => {
930
+ if ( ! this . konva ?. image . image || this . isCropping ) {
977
931
return ;
978
932
}
979
933
980
- this . konva . crop . interaction . group . visible ( false ) ;
981
- } ;
934
+ // Calculate initial crop dimensions
935
+ let cropX : number ;
936
+ let cropY : number ;
937
+ let cropWidth : number ;
938
+ let cropHeight : number ;
982
939
983
- private unfreezeCropOverlay = ( ) => {
984
- if ( ! this . konva ) {
985
- return ;
940
+ if ( crop ) {
941
+ cropX = crop . x ;
942
+ cropY = crop . y ;
943
+ cropWidth = crop . width ;
944
+ cropHeight = crop . height ;
945
+ } else if ( this . cropBox ) {
946
+ // Use the current crop as starting point
947
+ cropX = this . cropBox . x ;
948
+ cropY = this . cropBox . y ;
949
+ cropWidth = this . cropBox . width ;
950
+ cropHeight = this . cropBox . height ;
951
+ } else {
952
+ // Create default crop box (centered, 80% of image)
953
+ const imgWidth = this . konva . image . image . width ( ) ;
954
+ const imgHeight = this . konva . image . image . height ( ) ;
955
+ cropWidth = imgWidth * this . DEFAULT_CROP_BOX_SCALE ;
956
+ cropHeight = imgHeight * this . DEFAULT_CROP_BOX_SCALE ;
957
+ cropX = ( imgWidth - cropWidth ) / 2 ;
958
+ cropY = ( imgHeight - cropHeight ) / 2 ;
986
959
}
987
960
961
+ this . updateCropBox ( {
962
+ x : cropX ,
963
+ y : cropY ,
964
+ width : cropWidth ,
965
+ height : cropHeight ,
966
+ } ) ;
967
+ this . isCropping = true ;
988
968
this . konva . crop . interaction . group . visible ( true ) ;
989
- } ;
990
969
991
- resetEphemeralCropState = ( ) => {
992
- this . isCropping = false ;
970
+ this . callbacks . onCropStart ?.( ) ;
993
971
} ;
994
972
995
973
cancelCrop = ( ) => {
996
- if ( ! this . isCropping || ! this . konva ?. crop ) {
974
+ if ( ! this . isCropping || ! this . konva ) {
997
975
return ;
998
976
}
999
- this . resetEphemeralCropState ( ) ;
1000
-
977
+ this . isCropping = false ;
978
+ this . konva . crop . interaction . group . visible ( false ) ;
1001
979
this . callbacks . onCropCancel ?.( ) ;
1002
980
} ;
1003
981
1004
982
applyCrop = ( ) => {
1005
- if ( ! this . isCropping || ! this . cropBox ) {
983
+ if ( ! this . isCropping || ! this . cropBox || ! this . konva ) {
1006
984
return ;
1007
985
}
1008
986
1009
- // Store the crop dimensions
1010
- this . appliedCrop = { ...this . cropBox } ;
1011
-
1012
- // Freeze the crop overlay instead of redisplaying image
1013
- this . freezeCropOverlay ( ) ;
1014
-
1015
987
this . isCropping = false ;
1016
- this . callbacks . onCropApply ?.( this . appliedCrop ) ;
988
+ this . konva . crop . interaction . group . visible ( false ) ;
989
+ this . callbacks . onCropApply ?.( this . cropBox ) ;
1017
990
} ;
1018
991
1019
992
resetCrop = ( ) => {
1020
- this . appliedCrop = null ;
1021
-
993
+ if ( this . konva ?. image . image ) {
994
+ this . updateCropBox ( {
995
+ x : 0 ,
996
+ y : 0 ,
997
+ ...this . konva . image . image . size ( ) ,
998
+ } ) ;
999
+ }
1022
1000
this . callbacks . onCropReset ?.( ) ;
1023
1001
} ;
1024
1002
1025
- hasCrop = ( ) : boolean => {
1026
- return ! ! this . appliedCrop ;
1027
- } ;
1028
-
1029
1003
// Export
1030
1004
exportImage = < T extends 'canvas' | 'blob' | 'dataURL' > (
1031
1005
format : T = 'blob' as T
@@ -1045,20 +1019,20 @@ export class Editor {
1045
1019
}
1046
1020
1047
1021
try {
1048
- if ( this . appliedCrop ) {
1049
- canvas . width = this . appliedCrop . width ;
1050
- canvas . height = this . appliedCrop . height ;
1022
+ if ( this . cropBox ) {
1023
+ canvas . width = this . cropBox . width ;
1024
+ canvas . height = this . cropBox . height ;
1051
1025
1052
1026
ctx . drawImage (
1053
1027
this . originalImage ,
1054
- this . appliedCrop . x ,
1055
- this . appliedCrop . y ,
1056
- this . appliedCrop . width ,
1057
- this . appliedCrop . height ,
1028
+ this . cropBox . x ,
1029
+ this . cropBox . y ,
1030
+ this . cropBox . width ,
1031
+ this . cropBox . height ,
1058
1032
0 ,
1059
1033
0 ,
1060
- this . appliedCrop . width ,
1061
- this . appliedCrop . height
1034
+ this . cropBox . width ,
1035
+ this . cropBox . height
1062
1036
) ;
1063
1037
} else {
1064
1038
canvas . width = this . originalImage . width ;
@@ -1321,7 +1295,7 @@ export class Editor {
1321
1295
// Clear all references
1322
1296
this . konva = null ;
1323
1297
this . originalImage = null ;
1324
- this . appliedCrop = null ;
1298
+ this . cropBox = null ;
1325
1299
this . callbacks = { } ;
1326
1300
} ;
1327
1301
}
0 commit comments