Skip to content

Commit

Permalink
Fix resizing container
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 authored and ajlende committed Aug 1, 2024
1 parent d0d9963 commit 797ec46
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 53 deletions.
59 changes: 31 additions & 28 deletions packages/components/src/image-cropper/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { animate } from 'framer-motion';
/**
* WordPress dependencies
*/
import { forwardRef, useContext, useRef, useEffect } from '@wordpress/element';
import {
forwardRef,
useContext,
useRef,
useEffect,
useMemo,
} from '@wordpress/element';
import { useMergeRefs } from '@wordpress/compose';
/**
* Internal dependencies
Expand Down Expand Up @@ -153,11 +159,14 @@ const Cropper = forwardRef< HTMLDivElement >( ( {}, ref ) => {
originalWidth,
originalHeight,
refs: { imageRef },
getState,
dispatch,
} = useContext( ImageCropperContext );
const isAxisSwapped = rotations % 2 !== 0;
const degree = angle + rotations * 90;
const aspectRatio = useMemo(
() => originalWidth / originalHeight,
[ originalWidth, originalHeight ]
);

const squareImageHorizontalOffset = ( image.width - image.height ) / 2;
const paddingY = Math.max(
Expand All @@ -178,37 +187,34 @@ const Cropper = forwardRef< HTMLDivElement >( ( {}, ref ) => {
const containerRef = useRef< HTMLDivElement >( null! );
useEffect( () => {
const container = containerRef.current;
const aspectRatio = originalWidth / originalHeight;

const resizeObserver = new ResizeObserver( ( [ entry ] ) => {
const [ { inlineSize: width } ] = entry.contentBoxSize;
const _isAxisSwapped = getState().transforms.rotations % 2 !== 0;
const { width: imageWidth, height: imageHeight } = getState().image;
const imageDimensions = _isAxisSwapped
? {
width: imageHeight,
height: imageWidth,
}
: {
width: imageWidth,
height: imageHeight,
};
const [ { inlineSize } ] = entry.contentBoxSize;
const originalInlineSize = isAxisSwapped
? originalHeight
: originalWidth;

if ( width < imageDimensions.width ) {
dispatch( {
type: 'RESIZE_CONTAINER',
width: _isAxisSwapped ? width * aspectRatio : width,
height: _isAxisSwapped ? width : width / aspectRatio,
} );
}
dispatch( {
type: 'RESIZE_CONTAINER',
width:
inlineSize < originalInlineSize
? inlineSize
: originalInlineSize,
} );
} );

resizeObserver.observe( container );

return () => {
resizeObserver.disconnect();
};
}, [ getState, dispatch, originalWidth, originalHeight ] );
}, [
dispatch,
originalWidth,
originalHeight,
aspectRatio,
isAxisSwapped,
] );

return (
<Container
Expand All @@ -230,12 +236,9 @@ const Cropper = forwardRef< HTMLDivElement >( ( {}, ref ) => {
style={ {
width: `${
paddingInline * 2 +
( isAxisSwapped ? image.height : image.width )
}px`,
height: `${
paddingBlock * 2 +
( isAxisSwapped ? image.width : image.height )
( isAxisSwapped ? originalHeight : originalWidth )
}px`,
aspectRatio: '1 / 1',
'--wp-cropper-image-x': `${ image.x }px`,
'--wp-cropper-image-y': `${ image.y }px`,
'--wp-cropper-scale-x': scale.x,
Expand Down
17 changes: 2 additions & 15 deletions packages/components/src/image-cropper/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@ import {
/**
* WordPress dependencies
*/
import {
useRef,
useMemo,
useReducer,
useCallback,
useEffect,
} from '@wordpress/element';
import { useRef, useMemo, useReducer, useCallback } from '@wordpress/element';

/**
* Internal dependencies
Expand Down Expand Up @@ -146,12 +140,6 @@ export const useImageCropper = ( {
return blob;
}, [] );

const stateRef = useRef< State >( state );
useEffect( () => {
stateRef.current = state;
}, [ state ] );
const getState = useCallback( () => stateRef.current, [] );

return useMemo(
() => ( {
state,
Expand All @@ -162,10 +150,9 @@ export const useImageCropper = ( {
imageRef,
cropperWindowRef,
},
getState,
dispatch,
getImageBlob,
} ),
[ state, src, width, height, getImageBlob, getState ]
[ state, src, width, height, getImageBlob ]
);
};
21 changes: 11 additions & 10 deletions packages/components/src/image-cropper/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ type Action =
direction: ResizeDirection;
delta: { width: number; height: number };
}
// Resize the container and image to a new width.
| { type: 'RESIZE_CONTAINER'; width: number }
// Reset the state to the initial state.
| { type: 'RESET' }
// Resize the container and image to a new width and height.
| { type: 'RESIZE_CONTAINER'; width: number; height: number };
| { type: 'RESET' };

function createInitialState( {
width,
Expand Down Expand Up @@ -382,19 +382,20 @@ function imageCropperReducer( state: State, action: Action ) {
};
}
case 'RESIZE_CONTAINER': {
if (
action.width === image.width &&
action.height === image.height
) {
const isAxisSwapped = rotations % 2 !== 0;
const imageInlineSize = isAxisSwapped ? image.height : image.width;
const ratio = action.width / imageInlineSize;

if ( ratio === 1 ) {
return state;
}
const ratio = action.width / image.width;

return {
...state,
image: {
...state.image,
width: action.width,
height: action.height,
width: image.width * ratio,
height: image.height * ratio,
x: image.x * ratio,
y: image.y * ratio,
},
Expand Down

0 comments on commit 797ec46

Please sign in to comment.