纯css实现图片在固定大小下的最大展示--img-fit实现

1,305 阅读1分钟

我们经常会有这样一个需求,不可控的图片出现在一个指定方框内的最佳展示

一般来说我们需要这样做(获取img大小,判断是width还是height比较大,根据比较大的一方设置最大值,其他的设置自适应)

export function AutoStretchBaseWidthOrHeightImg ({ src, width, height }) {
  const [imgWidth, setImgWidth] = useState('auto')
  const [imgHeight, setImgHeight] = useState('auto')
  useEffect(() => {
    const img = document.createElement('img')
    img.src = src
    document.body.appendChild(img)
    const imgRect = img.getBoundingClientRect()
    if (imgRect.width > imgRect.height) {
      setImgWidth(width + 'px')
    }
    if (imgRect.width <= imgRect.height) {
      setImgHeight(height + 'px')
    }
    document.body.removeChild(img)
  }, [width, height, src])
  return <div style={{ width: `${width}px`, height: `${height}px` }} className="flex flex-center-y flex-center-x">
    <img src={src} width={imgWidth} height={imgHeight} alt="" />
  </div>
}

但是这样会有一个问题,就是需要发起两个请求,这样导致服务器压力增大,或者对象存储多收钱,或者展示慢的问题。

这时候如果不依赖JS,那就很完美,比如backgroundImage实现,实现代码

const AutoStretchBaseWidthOrHeightImgStyled = styled.div`
div{
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
}
`
export function AutoStretchBaseWidthOrHeightImg ({ src, width, height }) {
  return <AutoStretchBaseWidthOrHeightImgStyled>
    <div style={{ width: `${width}px`, height: `${height}px`, backgroundColor: 'rgba(0,0,0,.03)', backgroundImage: `url(${src})` }}></div>
  </AutoStretchBaseWidthOrHeightImgStyled>
}

这时候是完成了,但是假如我们需要给图片不展示的时候出现一个默认图,怎么办?backgroundImage可没有imgonError.

于是这时候object-fit出场了

object-fit是什么?

MDN这样说的object-fit CSS 属性指定可替换元素的内容应该如何适应到其使用的高度和宽度确定的框

我们也不管啥意思,反正可以解决目前问题,具体查看MDN objecr-fit

于是backgroundImage+object-fit+onError 就可以实现不可控的图片以最合适的位置展示在方框内,并可以设置黑边颜色,并可以设置图片加载异常的展示,下面看下代码吧。

const AutoStretchBaseWidthOrHeightImgStyled = styled.div`
div{
  background-repeat: no-repeat;
  background-size: 63px;
  background-position: center;
  background-color: rgba(0, 0, 0, 1);
  img{
    background-color: rgb(247, 247, 247);
    object-fit: contain;
  }
}
`
export function AutoStretchBaseWidthOrHeightImg ({ src, width, height }) {
  const [imgShow, setImgShow] = useState(true)
  return <AutoStretchBaseWidthOrHeightImgStyled>
    <div style={{ width: `${width}px`, height: `${height}px`, backgroundImage: `url(${errorImg})` }}>
      {imgShow && <img width={width} height={height} src={src} alt="" onError={() => setImgShow(false)} />}
    </div>
  </AutoStretchBaseWidthOrHeightImgStyled>
}

--完--