必應首頁平鋪背景圖片的實現方案


近期某個項目中需要實現以下需求:

  1. 保持背景圖片原始寬高比;
  2. 如果屏幕寬高比與背景圖片寬高比不一致,則以圖片中心為基點等比縮放背景圖片,以適應屏幕尺寸。

以上需求的原則就是始終保持背景圖片寬高比,居中等比縮放填滿屏幕。

我們知道background-size: cover;是在背景圖片保持原始比例的基礎上,等比縮放覆蓋背景區域。但是縮放的基點是左上角(0,0),並不是居中縮放的。這樣的機制下,屏幕顯示的始終是背景圖片的左上部分,並不能滿足項目的需求。

后來無意中注意到必應首頁的背景圖片是居中平鋪的,行為表現與項目需求完全一致。遂研究了以下必應首頁的實現方案,大體能夠解惑,但仍有些許細節未能參透,今日記錄於此。

必應的實現方案其實很簡單,總結一句話就是:使用background-size: cover;覆蓋背景區域,使用JavaScript根據屏幕尺寸動態計算背景圖片的偏移量。

必應有很多細節做的很好,下面通過demo做簡單分析。

基本算法

demo的結構非常簡單,如下:

<div id="bgBox">
	<div id="bgDiv"></div>
</div>

bgDiv是背景區域節點,bgBox的作用是在某些屏幕尺寸下令背景圖片居中顯示

樣式文件如下:

body {
	margin: 0;
	overflow: hidden;
	background-color: #333;
}
#bgBox {
	height: 100%;
	width: 100%;
	margin: auto;
	position: relative;
	min-width: 1115px;
	max-width: 1366px;
	min-height: 599px;
	max-height: 768px;
}
#bgDiv {
	position: absolute;
	top: 0;
	overflow: hidden;
	width: 100%;
	height: 100%;
	max-width: 1366px;
	background-image: url("BingWallpaper.jpg");
	background-repeat: no-repeat;
	background-color: #666;
	-webkit-background-size: cover;
	-moz-background-size: cover;
	-o-background-size: cover;
	background-size: cover;
}
@media only screen and (min-height:806px) and (orientation:landscape), screen and (min-width:1433px) and (orientation:landscape) {
	#bgBox, #bgDiv {
		max-width: 1920px;
		max-height: 1080px;
	}
}

背景圖片的原始尺寸為1920×1080,css中一些寬高尺寸以及寬高限制在下一節中講解。

JavaScript腳本如下:

(function($) {
  // 背景圖片尺寸
  var imgWidh = 1920,
    imgHeight = 1080;
  // 圖片寬高比
  var imgRatio = imgWidh / imgHeight;

  var $bgDiv = $("#bgDiv");

  var offsetLeft = 0,
    offsetTop = 0;

  var resize = function() {
    // 瀏覽器viewport尺寸
    var winWidth = window.innerWidth,
      winHeight = window.innerHeight;
    // 瀏覽器viewport寬高比
    var winRatio = winWidth / winHeight;
    if (winWidth > imgWidh) {
      $bgDiv.css({
        width: imgWidh,
        height: imgHeight
      });
    } else {
      if (winRatio > imgRatio) {
        // 屏幕寬高比大於圖片寬高比,屏幕高度不足,圖片向上偏移
        offsetLeft = 0;
        offsetTop = (Math.ceil(winWidth / imgRatio) - winHeight) / 2;
        $bgDiv.css({
          width: winWidth,
          height: winWidth / imgRatio,
          top: -offsetTop,
          left: offsetLeft
        });
      } else if (winRatio < imgRatio) {
        // 屏幕寬高比大於圖片寬高比,屏幕寬度不足,圖片向左偏移
        offsetLeft = (Math.ceil(winHeight * imgRatio) - winWidth) / 2;
        offsetTop = 0;
        $bgDiv.css({
          width: winHeight * imgRatio,
          height: winHeight,
          top: offsetTop,
          left: -offsetLeft
        });
      }
    }
  };
  resize();
  $(window).on("resize", resize);
})(jQuery);

算法的基本流程為:

  1. 獲取圖片原始寬高比。當然有工具可以實現,本例中用的是現成的數據;
  2. 獲取瀏覽器可視區域的尺寸,並計算寬高比;
  3. 如果屏幕寬高比大於圖片寬高比,將圖片寬度撐滿瀏覽器視窗,此時屏幕高度不足,圖片向上偏移;
  4. 如果屏幕寬高比小於圖片寬高比,將圖片高度撐滿瀏覽器視窗,此時屏幕寬度不足,圖片向左偏移;

以上算法可以基本滿足項目需求。

響應式

我們注意到上文提到的css中有一些寬高尺寸的限制,這些數值有一部分是為了滿足必應首頁具體需求的,有一部分是自適應屏幕尺寸的。

比如min-width:1115px是因為必應首頁的nav全部展開時恰好是1115px,如果小於這個尺寸就會出現item重疊,造成樣式混亂。

另外,媒體查詢中的兩個邊界值min-height:806pxmin-width:1433px,本人還未弄清楚為何這兩個邊界值如此奇怪,但是必應這樣做的目的是很清楚的。

標准13寸屏幕的分辨率為1366×768,媒體查詢的兩個邊界值最接近標准14寸屏幕分辨率1440×900,也就是說,在14寸以下屏幕保持背景圖片寬度顯示不超過1366px。

請注意背景區域bgDiv並沒有max-height的限制,這是因為不論什么尺寸的屏幕,都要保持背景圖片的寬高比。

媒體查詢超出邊界值的屏幕下,背景圖片的寬高限制在圖片的原始尺寸,這是為了不拉伸圖片造成失真,超過1920×1080的屏幕始終居中顯示原始圖片尺寸。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM