仿微信小程序 aspectFitImg 算法,完美適配全尺寸公司Logo的處理

微信小程序的image組件中,有一個(gè)mode屬性,其設(shè)置如下:

mode 有 13 種模式,其中 4 種是縮放模式,9 種是裁剪模式。

模式 說明
縮放 scaleToFill. 不保持縱橫比縮放圖片,使圖片的寬高完全拉伸至填滿 image 元素
縮放 aspectFit 保持縱橫比縮放圖片,使圖片的長邊能完全顯示出來。也就是說,可以完整地將圖片顯示出來。
縮放 aspectFill 保持縱橫比縮放圖片,只保證圖片的短邊能完全顯示出來。也就是說,圖片通常只在水平或垂直方向是完整的,另一個(gè)方向?qū)?huì)發(fā)生截取。
縮放 widthFix 寬度不變,高度自動(dòng)變化,保持原圖寬高比不變
裁剪 top 不縮放圖片,只顯示圖片的頂部區(qū)域
裁剪 bottom 不縮放圖片,只顯示圖片的底部區(qū)域
裁剪 center 不縮放圖片,只顯示圖片的中間區(qū)域
裁剪 left 不縮放圖片,只顯示圖片的左邊區(qū)域
裁剪 right 不縮放圖片,只顯示圖片的右邊區(qū)域
裁剪 top left 不縮放圖片,只顯示圖片的左上邊區(qū)域
裁剪 top right 不縮放圖片,只顯示圖片的右上邊區(qū)域
裁剪 bottom left 不縮放圖片,只顯示圖片的左下邊區(qū)域
裁剪 bottom right 不縮放圖片,只顯示圖片的右下邊區(qū)域
原圖
0.jpg

scaleToFill

不保持縱橫比縮放圖片,使圖片完全適應(yīng)

1.png

aspectFit

保持縱橫比縮放圖片,使圖片的長邊能完全顯示出來(圖片可完整顯示,背景區(qū)域有留空)

2.png

aspectFill

保持縱橫比縮放圖片,只保證圖片的短邊能完全顯示出來(圖片被剪裁,丟失部分內(nèi)容)

3.png

為什么要仿造一個(gè)微信小程序的aspectFitImg算法?

在微信小程序頁面開發(fā)時(shí),以繪制公司logo為例,

我希望得到的顯示效果如下:

(Logo和公司名稱在視覺上完美左對(duì)齊)

對(duì)于公司Logo這樣的圖案,是必須完整顯示并保持比例的,任何對(duì)內(nèi)容的剪裁或比例失調(diào)都是無法令人接受的。

WeChatb80f558533af46c67164f35ad22c27a2.png

為實(shí)現(xiàn)這個(gè)效果,我們通常的做法是:直接指定圖片元素的顯示模式為aspectFit模式,然后將公司Logo和公司名稱左對(duì)齊。

但是這樣會(huì)產(chǎn)生排版上的瑕疵,例如:

假設(shè)圖片的缺省占位寬高為:100px * 40px;
但是從網(wǎng)絡(luò)加載的圖片實(shí)際只有40px * 40px

那么實(shí)際圖片的水平中心點(diǎn)將在占位寬度(100px)的水平正中間對(duì)齊顯示,看起來就好像實(shí)際圖片左邊被留出了30px的寬度,即:(100-40)/2,而這種情況不是我們想要的,因?yàn)槲覀兿胍氖菑囊曈X上看,圖片和底下的元素應(yīng)該可以左對(duì)齊,而不是僅從CSS的視角來看兩個(gè)元素是左對(duì)齊的;

此時(shí),肉眼看見的效果如下:

logo圖片占位和公司名稱在CSS的層面左對(duì)齊,但是從視覺上來看,logo和公司名稱并沒有左對(duì)齊;


WeChatd22b342f3426ec9f68f88235fc6f6463.png

在微信小程序中,我解決這個(gè)問題的方法是:

(1)首先,在CSS中使用默認(rèn)的占位寬高來設(shè)定圖片的顯示屬性,打比方:{100px,40px},并設(shè)置數(shù)據(jù)綁定屬性;
(2)從網(wǎng)絡(luò)下載圖片,然后根據(jù){100,40}這個(gè)初始限定來計(jì)算將實(shí)際圖片(可能是400px * 400px)縮放到剛好能塞進(jìn)這個(gè)占位框中時(shí)圖片應(yīng)該被顯示的尺寸,即(40px * 40px);
(3)使用微信小程序中css屬性綁定的機(jī)制來修改占位框的寬度和高度;即將{100px * 40px}動(dòng)態(tài)修改為 {40px * 40px};


在微信小程序中設(shè)置css屬性綁定、下載圖片并獲取圖片的寬高信息等都有現(xiàn)成的方法和完善的API說明文檔,不再言表,僅列出那個(gè)aspectFitImg的方法。

/**
 * imgSourceWidth,imgSourceHeight : 圖片的原始高度;
 * fitWidth,fitHeight: 圖片保持比例縮放后,要能夠塞進(jìn)這個(gè)大小范圍內(nèi);
 * 返回對(duì)象為適配處理后的圖片尺寸,該尺寸是剛剛好可以裝到fitWidth和fitHeight中的,不多一個(gè)像素,也不少一個(gè)像素,并且保持原始的圖片寬高顯示比例;
 * 返回示例:{width:100,height:100}
 * 如果計(jì)算失敗,返回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);
  }
}

浪費(fèi)了30分鐘修改文章,午飯要加個(gè)雞腿獎(jiǎng)勵(lì)一下自己..

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、屬性選擇器:id選擇器 # 通過id 來選擇類名選擇器 . 通過類名來選擇屬性選擇器 ...
    Yuann閱讀 1,752評(píng)論 0 7
  • 一、CSS入門 1、css選擇器 選擇器的作用是“用于確定(選定)要進(jìn)行樣式設(shè)定的標(biāo)簽(元素)”。 有若干種形式的...
    寵辱不驚丶?xì)q月靜好閱讀 1,720評(píng)論 0 6
  • 關(guān)鍵詞: 微信小程序 圖片真實(shí)大小 圖片模式詳解 這兩天自己設(shè)計(jì)了兩張微信廣告橫幅,電腦設(shè)計(jì)尺寸為750*300像...
    黃雨晴閱讀 2,910評(píng)論 1 0
  • 選擇qi:是表達(dá)式 標(biāo)簽選擇器 類選擇器 屬性選擇器 繼承屬性: color,font,text-align,li...
    love2013閱讀 2,429評(píng)論 0 11
  • 輸液真是等于自殺嗎?首先這個(gè)命題是完全荒唐的。難道不輸液什么病都可以靠吃藥、打針、或者其它方法治好嗎?外國人不主張...
    正舉閱讀 396評(píng)論 0 0

友情鏈接更多精彩內(nèi)容