react实现图片预览时截取展示部分图片,不压缩
/* eslint-disable react/no-unescaped-entities */
/* eslint-disable react-hooks/exhaustive-deps */
import React, { memo, useEffect, useRef, useState } from 'react'
import { Image } from 'antd'
import styles from './index.less'
const ImageBox = ({ src, width = 184, imgStyle, style }) => {
const [minHeight, setHeight] = useState(false)
const [wid, setW] = useState('')
const myHeight = style?.height?.includes('px') ? style?.height?.replace('px', '') : style.height
const imageSize = (url) => {
const nImg = new window.Image()
nImg.src = url
return new Promise((resolve, reject) => {
nImg.onload = () => {
resolve({ success: true, width: nImg.width, height: nImg.height })
}
nImg.onerror = () => {
reject(new Error('imageError'))
}
})
}
useEffect(() => {
if (!src) return
imageSize(src).then((size) => {
const { width = 0, height = 1 } = size
const proportion = height / width
const h = proportion * (myHeight || 184)
const w = (myHeight || 184) / proportion
if (h < (myHeight || 184)) {
setHeight(true)
setW(w)
} else {
setHeight(false)
setW('')
}
})
}, [src])
return (
<div className={styles.imgContainerBox} style={{ width, ...style }}>
<div
className={styles.imgContainer}
style={{
...(minHeight && {
minHeight: myHeight || 184,
width: wid || width,
minWidth: width,
}),
}}
>
<Image
style={{
...imgStyle,
borderRadius: '4px',
...(minHeight && {
minHeight: myHeight || 184,
width: wid || width,
minWidth: width,
}),
}}
src={src}
/>
</div>
</div>
)
}
export default memo(ImageBox)
css样式
.imgContainerBox {
position: relative;
display: block;
width: 100%;
overflow: hidden;
border-radius: 4px;
.imgContainer {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
transform: translate(-50%, -50%);
}
}