@@ -40,6 +40,55 @@ export function calculateCenteredCrop(
4040 } ;
4141}
4242
43+ function isCropWithinBounds ( crop : Crop , imageW : number , imageH : number , rotation : number ) : boolean {
44+ const cx = imageW / 2 ;
45+ const cy = imageH / 2 ;
46+ const rad = ( - rotation * Math . PI ) / 180 ;
47+ const cos = Math . cos ( rad ) ;
48+ const sin = Math . sin ( rad ) ;
49+ const pts = [
50+ { x : crop . x , y : crop . y } ,
51+ { x : crop . x + crop . width , y : crop . y } ,
52+ { x : crop . x , y : crop . y + crop . height } ,
53+ { x : crop . x + crop . width , y : crop . y + crop . height } ,
54+ ] ;
55+ for ( let i = 0 ; i < 4 ; i ++ ) {
56+ const nx = cos * ( pts [ i ] . x - cx ) - sin * ( pts [ i ] . y - cy ) + cx ;
57+ const ny = sin * ( pts [ i ] . x - cx ) + cos * ( pts [ i ] . y - cy ) + cy ;
58+ if ( nx < - 1 || nx > imageW + 1 || ny < - 1 || ny > imageH + 1 ) return false ;
59+ }
60+ return true ;
61+ }
62+
63+ export function calculateAreaPreservingCrop (
64+ imageWidth : number ,
65+ imageHeight : number ,
66+ orientationSteps : number ,
67+ aspectRatio : number | null ,
68+ rotation : number ,
69+ currentCrop : Crop | null | undefined ,
70+ ) : Crop | null {
71+ if ( ! aspectRatio || aspectRatio <= 0 || ! currentCrop || ! currentCrop . width || ! currentCrop . height ) return null ;
72+
73+ const { width : W , height : H } = getOrientedDimensions ( imageWidth , imageHeight , orientationSteps ) ;
74+
75+ const area = currentCrop . width * currentCrop . height ;
76+ const newH = Math . sqrt ( area / aspectRatio ) ;
77+ const newW = aspectRatio * newH ;
78+ const centerX = currentCrop . x + currentCrop . width / 2 ;
79+ const centerY = currentCrop . y + currentCrop . height / 2 ;
80+
81+ const candidate : Crop = {
82+ unit : 'px' ,
83+ x : Math . round ( centerX - newW / 2 ) ,
84+ y : Math . round ( centerY - newH / 2 ) ,
85+ width : Math . round ( newW ) ,
86+ height : Math . round ( newH ) ,
87+ } ;
88+
89+ return isCropWithinBounds ( candidate , W , H , rotation ) ? candidate : null ;
90+ }
91+
4392export function rotateCropCenter (
4493 crop : Crop ,
4594 orientedWidth : number ,
0 commit comments