1919 */
2020
2121import { ReactAdapterElement , RenderHooks } from 'Frontend/generated/flow/ReactAdapter' ;
22- import { JSXElementConstructor , ReactElement , useRef } from "react" ;
22+ import { JSXElementConstructor , ReactElement , useRef , useEffect } from "react" ;
2323import React from 'react' ;
2424import { type Crop , ReactCrop , PixelCrop , makeAspectCrop , centerCrop } from "react-image-crop" ;
2525
@@ -41,30 +41,82 @@ class ImageCropElement extends ReactAdapterElement {
4141 const [ maxWidth ] = hooks . useState < number > ( "maxWidth" ) ;
4242 const [ maxHeight ] = hooks . useState < number > ( "maxHeight" ) ;
4343 const [ ruleOfThirds ] = hooks . useState < boolean > ( "ruleOfThirds" , false ) ;
44+
45+ // Track previous image dimensions to adjust crop proportionally when resizing
46+ const prevImgSize = useRef < { width : number ; height : number } | null > ( null ) ;
4447
48+ /**
49+ * Handles intial calculations on image load.
50+ */
4551 const onImageLoad = ( ) => {
46- if ( imgRef . current && crop ) {
52+ if ( imgRef . current ) {
4753 const { width, height } = imgRef . current ;
48- const newcrop = centerCrop (
49- makeAspectCrop (
50- {
51- unit : crop . unit ,
52- width : crop . width ,
53- height : crop . height ,
54- x : crop . x ,
55- y : crop . y
56- } ,
57- aspect ,
54+ prevImgSize . current = { width, height } ;
55+ if ( crop ) {
56+ const newcrop = centerCrop (
57+ makeAspectCrop (
58+ {
59+ unit : crop . unit ,
60+ width : crop . width ,
61+ height : crop . height ,
62+ x : crop . x ,
63+ y : crop . y
64+ } ,
65+ aspect ,
66+ width ,
67+ height
68+ ) ,
5869 width ,
5970 height
60- ) ,
61- width ,
62- height
63- )
64- setCrop ( newcrop ) ;
71+ )
72+ setCrop ( newcrop ) ;
73+ }
6574 }
6675 } ;
6776
77+ /**
78+ * Adjusts the crop size proportionally when the image is resized.
79+ */
80+ const resizeCrop = ( newWidth : number , newHeight : number ) => {
81+ if ( ! crop || ! prevImgSize . current ) return ;
82+ const { width : oldWidth , height : oldHeight } = prevImgSize . current ;
83+
84+ const scaleX = newWidth / oldWidth ;
85+ const scaleY = newHeight / oldHeight ;
86+
87+ const resizedCrop : Crop = {
88+ unit : crop . unit ,
89+ width : crop . width * scaleX ,
90+ height : crop . height * scaleY ,
91+ x : crop . x * scaleX ,
92+ y : crop . y * scaleY ,
93+ } ;
94+
95+ setCrop ( resizedCrop ) ;
96+ prevImgSize . current = { width : newWidth , height : newHeight } ;
97+ } ;
98+
99+ /**
100+ * Observes image resizing and updates crop size dynamically.
101+ */
102+ useEffect ( ( ) => {
103+ if ( ! imgRef . current ) return ;
104+
105+ const resizeObserver = new ResizeObserver ( ( ) => {
106+ if ( imgRef . current && prevImgSize . current ) {
107+ const { width, height } = imgRef . current ;
108+ if ( width != prevImgSize . current . width &&
109+ height != prevImgSize . current . height ) {
110+ resizeCrop ( width , height ) ;
111+ }
112+ }
113+ } ) ;
114+
115+ resizeObserver . observe ( imgRef . current ) ;
116+
117+ return ( ) => resizeObserver . disconnect ( ) ;
118+ } , [ crop ] ) ;
119+
68120 const onChange = ( c : Crop ) => {
69121 setCrop ( c ) ;
70122 } ;
0 commit comments