问题描述:
由于后台返回图片的大小不一致,但是前端要求把他们展示成大小一致且不变形。
小程序使用mode:aspectFill
但是如果是pc端和移动端。应该如何实现img标签图片的居中和自动裁切?
问题解决:
1. 非真正的裁剪
---------》即只进行前端预览时裁剪
1.1 使用css background
(不推荐,因为不方便维护。当需要动态改变时需要去操作单独的style)
<div style="background-image:url(这里填写图片的路径});
background-repeat: no-repeat;
background-position:center center;
background-size: cover;
width:100px;
height:100px;">
</div>
简单说明一下background-size 的属性,因为被W3C讲得有点绕,总结就是:
cover:让图片填充满父节点,超出部分隐藏,仅显示中间,这才是我们想要的效果。
contain:让图片根据父节点宽高等比例缩放。
1.2 使用css3 object-fit属性
(css3新增属性,可能会有浏览器兼容问题)
这个CSS属性可以达到最佳最完美的居中自动剪裁图片的功能。
.aspectFill img{
width: 200px;
height: 200px;
object-fit: cover;
}
object 属性有5个属性值,具体含义如下;
- fill: 中文释义“填充”。默认值。图片拉伸填满容器, 不保证保持原有的比例缩放。
- contain: 中文释义“包含”。保持原有尺寸比例缩放。长边匹配,短边留空。
- cover: 中文释义“覆盖”。保持原有尺寸比例缩放。短边匹配,裁剪过长区域。即是我们想要的效果
- none: 中文释义“无”。保持原有尺寸比例。不缩放。
- scale-down: 中文释义“降低”。如若依次设置了none或contain, 最终呈现的是尺寸比较小的那个。
1.3 套一个父级元素,居中定位,超出部分隐藏
---------》(不会有浏览器兼容问题)
使用一个与目标图片大小一致的div, 设置overflow: hidden;
里面的 img标签,图片用absolute定位设置为居中
将图片宽高按比例缩放。
html
<!-- 这个div设置为和img图片同样的宽高,并且用absolute定位设置为居中 -->
<div class="banner-img__wrapper">
<img src="url" class="banner-img">
</div>
css
.banner-img__wrapper {
position: relative;
/* 目标宽高 */
width: 100px;
height: 100px;
overflow: hidden;
}
.banner-img{
position: absolute;
left: 50%;
top: 50%;
transform-origin: left top;
/* 图片原宽高去缩放,选择宽高缩放比中较大的一个 */
/* 如这里图片原宽高是 496*640, 宽缩放比=100/496,高缩放比=100/640,则较大的为100/496~0.2 */
transform: scale(0.2) translate(-50%, -50%);
}
1.4 将1.3写成一个组件
待整理~
2. 真正的裁剪
2.1 利用canvas进行裁剪
利用wx.getImageInfo 获取图片信息res,如宽高等,然后锁定宽高比(按照 canvas_width / canvas_height)
进行图片缩放裁剪,满足短边全部显示,长边的裁剪两边,只显示中间
let img_width;
let img_height;
// 裁剪正方形/长方形
// 需设置图片有在合法域名中,才能拿到图片的信息!!
// res 为wx.getImageInfo 的返回值
img_width = res.width;
img_height = res.height;
let canvas_width = width; // 海报中给目标图片预留的宽、高
let canvas_height = height;
let clip_left,clip_top; //左偏移值,上偏移值
let clip_width,clip_height; //截取宽度,截取高度
// 按画布锁定宽高比, 满足短边,裁剪长边来剪裁图片,效果类似 aspectFill
clip_height = img_width * (canvas_height / canvas_width);
// 如果按照这个比例裁剪后的图片高度与原图高度还高,证明图片 高度是短边,宽度是长边
if(clip_height > img_height){
clip_height = img_height;
clip_width = img_height * (canvas_width / canvas_height);
clip_left = (img_width - clip_width) / 2 + left;
clip_top = 0 + top;
}else{
clip_width = img_width;
clip_left = 0 + left;
clip_top = (img_height - clip_height) / 2 + top;
}
// url,图片水平偏移,图片垂直偏移,图片截取宽度,图片高度,图片理想水平偏移,图片理想高度偏移,
this.ctx.drawImage(url, clip_left, clip_top, clip_width, clip_height, left, top, canvas_width, canvas_height);
this.ctx.restore();
如果文章对你有帮助,麻烦点赞哦,一起走花路吧~