微信小程序 aspectFitImg 算法
2018-07-24 本文已影响40人
zhangyin
aspectFit是图片显示时的一种布局方式,意思是要在显示图片时,要保持图片内容的比例关系,并且内容不被剪裁掉任何地方;
在微信小程序页面开发时,我们可以直接指定图片元素的显示模式为aspectFit模式,但是这种方式在进行图片的左对齐时,可能会有一些瑕疵:
假设图片的缺省占位宽高为:100px * 40px;
但是从网络加载的图片实际只有40px * 40px,
那么实际图片的水平中心点将在占位宽度(100px)的水平正中间对齐显示,看起来就好像实际图片左边被留出了30px的宽度,即:(100-40)/2,而这种情况不是我们想要的,因为我们想要的是从视觉上看,图片和底下的元素应该可以左对齐,而不是仅从CSS的视角来看两个元素是左对齐的;
在微信小程序中,我解决这个问题的处理方法是:
(1)首先,在CSS中使用默认的占位宽高来设定图片的显示属性,打比方:{100px,40px},并设置数据绑定属性;
(2)从网络下载图片,然后根据{100,40}这个初始限定来计算将实际图片(可能是400px * 400px)缩放到刚好能塞进这个占位框中时图片应该被显示的尺寸,即(40px * 40px);
(3)使用css属性绑定的机制来修改占位框的宽度和高度;即将{100px * 40px}动态修改为 {40px * 40px};
我希望得到的显示效果:
(Logo和公司名称在视觉上完美左对齐)
WeChatb80f558533af46c67164f35ad22c27a2.png
下面是可能会遇见的情况,这种情况不是我想要的:
logo图片占位和公司名称在CSS的层面左对齐,但是从视觉上来看,logo和公司名称并没有左对齐;
WeChatd22b342f3426ec9f68f88235fc6f6463.png
在微信小程序中设置css属性绑定、下载图片并获取图片的宽高信息等都有现成的方法和完善的API说明文档,不再言表,仅列出那个aspectFitImg的方法。
/**
* imgSourceWidth,imgSourceHeight : 图片的原始高度;
* fitWidth,fitHeight: 图片保持比例缩放后,要能够塞进这个大小范围内;
* 返回对象为适配处理后的图片尺寸,该尺寸是刚刚好可以装到fitWidth和fitHeight中的,不多一个像素,也不少一个像素,并且保持原始的图片宽高显示比例;
* 返回示例:{width:100,height:100}
* 如果计算失败,返回null
*/
function aspectFitImg(imgSourceWidth, imgSourceHeight, fitWidth, fitHeight) {
if (isNull(imgSourceWidth) || isNull(imgSourceHeight) || isNull(fitWidth) || isNull(fitHeight)) {
return null;
}
if (imgSourceWidth > fitWidth) {
let d = imgSourceWidth / fitWidth;
let th = imgSourceHeight / d;
return this.aspectFitImg(fitWidth, th, fitWidth, fitHeight);
} else if (imgSourceHeight > fitHeight) {
let d = imgSourceHeight / fitHeight;
let tw = imgSourceWidth / d;
return this.aspectFitImg(tw, fitHeight, fitWidth, fitHeight);
} else if (imgSourceWidth <= fitWidth && imgSourceHeight <= fitHeight) {
return { width: imgSourceWidth, height: imgSourceHeight };
} else {
return this.aspectFitImg(imgSourceWidth, imgSourceWidth, fitWidth, fitHeight);
}
}