程序猿的纸条屋

微信小程序 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);
  }
}
上一篇下一篇

猜你喜欢

热点阅读