css之object-fit

405 阅读3分钟

最近有个需求是上传图片后,并等比例裁剪显示。接到这个需求后,和后端先做了技术方案讨论,因为上传是上传一组6张照片,我借助iview的upload组件来完成图片上传:

1.选择图片后,点击按钮,把图片地址上传到后端指定的接口,后端返回一个url和图片的width和height,前端接收后 存入一个数组中。这里有个小小的坑需要注意一下,应该之前的其他接口 header中的content-type 都是 application/json 协定好的,但是后端在处理图片格式只能采取multipart/form-data格式来接收,那我们只能在当前模板中改一下content-type,像这样.

2.图片上传完成后,有个等比裁剪缩放的需求,根据具体业务这里会有两种情况:

I.手机正常竖着拍照,照片会是375*667px 我们会取图片中间240*180的部分,这样的话会造成两边空白的情况,如图,这样肯定是不行的,理想情况是图片自动拉伸填满整个红色区域,并且图片不变形。

II.手机横着拍照,照片会是667*375px 刚好符合我们的需求,我们只用做等比例缩小就可以了,如图

我原本的做法是给img标签添加onload事件,待图片加载完成后根据js算法来处理,具体代码:


setOfCertificationsImg (index) {

let pictureSize = document.getElementsByClassName('pictureSize')


let item = pictureSize[index]


let width = 244


let height = 162


let oldWidth = item.width


let oldHeight = item.height


let scale = Math.max(width / oldWidth, height / oldHeight)


let newWidth = oldWidth * scale


let newHeight = oldHeight * scale


this.$set(this.styleOfCertifications, index, {


width: Math.round(newWidth) + 'px',


height: Math.round(newHeight) + 'px',


left: Math.round((width - newWidth) / 2) + 'px',


top: Math.round((height - newHeight) / 2) + 'px'


})


},


onImgLoad (index) {


console.log('on image load: ' + index)


this.setOfCertificationsImg(index)


}

新旧宽相除,新旧高相除,算出一个比例,在根据上传图片大小来进行position位移。但是这种做法会造成一个bug,在单个图片的处理上,是正常的,上传完毕后裁剪正常。但是存在一个数组中,连续处理6张图片的时候,前五张是处理好的的但最后一张是变形图片。应该是图片处理也需要时间,在显示前若图片没有计算完成则会变形,最后我采取设置setTimeout时间来处理,也可以用promise。

但是!!!重点来了,一个偶然的发现,css3中有个属性object-fit出现在我眼前,我们来看一下MDN上是怎么定义这个属性的:

The object-fit CSS property specifies how the contents of a replaced element, such as an <img> or <video>, should be resized to fit its container.

翻译过来就是,对象CSS属性指定替换元素的内容(如<img>)应如何调整大小以适合其容器。

object-fit具体有5个值, object-fit: fill; object-fit: contain; object-fit: cover; object-fit: scale-down; 还有none.

在这里我们用到了object-fit: cover; 被替换的内容大小保持其纵横比,同时填充元素的整个内容框。如果对象的宽高比与其长宽比不匹配,则对象将被剪裁以适合其宽高比。

完美解决图片的裁剪缩放问题!仅1行代码解决了30行代码的事!完美!