Skip to content

Commit

Permalink
fix: replace objectFit: 'auto-cover' by 'cover' with adjusted logic (#…
Browse files Browse the repository at this point in the history
…466)

# Release notes

the `objectFit` `auto-cover` option was removed and replaced by  `cover`. While doing so, the logic detecting the right value to choose between `horizontal` and  `vertical` was rewritten from scratch. The algorithm is now much better at picking the right choice.

---------

Co-authored-by: Valentin Hervieu <valentin@hervi.eu>
  • Loading branch information
kruchkou and ValentinH committed Jun 26, 2023
1 parent 8dcdec2 commit 010888b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ This component requires some styles to be available in the document. By default,
| `cropSize` | `{ width: number, height: number }` | | Size of the crop area (in pixels). If you don't provide it, it will be computed automatically using the `aspect` prop and the media size. **You should probably not use this option and should rely on aspect instead. See https://github.com/ValentinH/react-easy-crop/issues/186.** |
| `showGrid` | boolean | | Whether to show or not the grid (third-lines). Defaults to `true`. |
| `zoomSpeed` | number | | Multiplies the value by which the zoom changes. Defaults to 1. |
| `objectFit` [demo](https://codesandbox.io/s/react-easy-crop-forked-p9r34) | 'contain', 'horizontal-cover', 'vertical-cover' or 'auto-cover' | | Specifies how the image is shown in the cropper:. `contain`: the image will be adjusted to be fully visible, `horizontal-cover`: the image will horizontally fill the cropper, `vertical-cover`: the image will vertically fill the cropper, `auto-cover`: we automatically pick between `horizontal-cover` or `vertical-cover` based on the dimensions of the image. Defaults to "contain". |
| `objectFit` [demo](https://codesandbox.io/s/react-easy-crop-forked-p9r34) | 'contain', 'cover', 'horizontal-cover' or 'vertical-cover' | | Specifies how the image is shown in the cropper. `contain`: the image will be adjusted to be fully visible, `horizontal-cover`: the image will horizontally fill the cropper, `vertical-cover`: the image will vertically fill the cropper, `cover`: we automatically pick between `horizontal-cover` or `vertical-cover` to have a fully visible image inside the cropper area. Defaults to "contain". |
| `onCropChange` | crop => void || Called every time the crop is changed. Use it to update your `crop` state. |
| `onZoomChange` | zoom => void | | Called every time the zoom is changed. Use it to update your `zoom` state. |
| `onRotationChange` | rotation => void | | Called every time the rotation is changed (with mobile or multi-fingers gestures). Use it to update your `rotation` state. |
Expand Down
49 changes: 26 additions & 23 deletions src/Cropper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type CropperProps = {
maxZoom: number
cropShape: 'rect' | 'round'
cropSize?: Size
objectFit?: 'contain' | 'horizontal-cover' | 'vertical-cover' | 'auto-cover'
objectFit?: 'contain' | 'cover' | 'horizontal-cover' | 'vertical-cover'
showGrid?: boolean
zoomSpeed: number
zoomWithScroll?: boolean
Expand Down Expand Up @@ -298,6 +298,27 @@ class Cropper extends React.Component<CropperProps, State> {
return aspect
}

getObjectFit() {
if (this.props.objectFit === 'cover') {
const mediaRef = this.imageRef.current || this.videoRef.current

if (mediaRef && this.containerRef) {
this.containerRect = this.containerRef.getBoundingClientRect()
const containerAspect = this.containerRect.width / this.containerRect.height
const naturalWidth =
this.imageRef.current?.naturalWidth || this.videoRef.current?.videoWidth || 0
const naturalHeight =
this.imageRef.current?.naturalHeight || this.videoRef.current?.videoHeight || 0
const mediaAspect = naturalWidth / naturalHeight

return mediaAspect < containerAspect ? 'horizontal-cover' : 'vertical-cover'
}
return 'horizontal-cover'
}

return this.props.objectFit
}

computeSizes = () => {
const mediaRef = this.imageRef.current || this.videoRef.current

Expand All @@ -321,7 +342,8 @@ class Cropper extends React.Component<CropperProps, State> {
let renderedMediaSize: Size

if (isMediaScaledDown) {
switch (this.props.objectFit) {
const objectFit = this.getObjectFit()
switch (objectFit) {
default:
case 'contain':
renderedMediaSize =
Expand All @@ -347,18 +369,6 @@ class Cropper extends React.Component<CropperProps, State> {
height: this.containerRect.height,
}
break
case 'auto-cover':
renderedMediaSize =
naturalWidth > naturalHeight
? {
width: this.containerRect.width,
height: this.containerRect.width / mediaAspect,
}
: {
width: this.containerRect.height * mediaAspect,
height: this.containerRect.height,
}
break
}
} else {
renderedMediaSize = {
Expand Down Expand Up @@ -701,9 +711,10 @@ class Cropper extends React.Component<CropperProps, State> {
showGrid,
style: { containerStyle, cropAreaStyle, mediaStyle },
classes: { containerClassName, cropAreaClassName, mediaClassName },
objectFit,
} = this.props

const objectFit = this.getObjectFit()

return (
<div
onMouseDown={this.onMouseDown}
Expand All @@ -721,10 +732,6 @@ class Cropper extends React.Component<CropperProps, State> {
objectFit === 'contain' && 'reactEasyCrop_Contain',
objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal',
objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical',
objectFit === 'auto-cover' &&
(this.mediaSize.naturalWidth > this.mediaSize.naturalHeight
? 'reactEasyCrop_Cover_Horizontal'
: 'reactEasyCrop_Cover_Vertical'),
mediaClassName
)}
{...(mediaProps as React.ImgHTMLAttributes<HTMLElement>)}
Expand All @@ -748,10 +755,6 @@ class Cropper extends React.Component<CropperProps, State> {
objectFit === 'contain' && 'reactEasyCrop_Contain',
objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal',
objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical',
objectFit === 'auto-cover' &&
(this.mediaSize.naturalWidth > this.mediaSize.naturalHeight
? 'reactEasyCrop_Cover_Horizontal'
: 'reactEasyCrop_Cover_Vertical'),
mediaClassName
)}
{...mediaProps}
Expand Down

0 comments on commit 010888b

Please sign in to comment.