zoukankan      html  css  js  c++  java
  • 必应首页平铺背景图片的实现方案

    近期某个项目中需要实现以下需求:

    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%;
    	 100%;
    	margin: auto;
    	position: relative;
    	min- 1115px;
    	max- 1366px;
    	min-height: 599px;
    	max-height: 768px;
    }
    #bgDiv {
    	position: absolute;
    	top: 0;
    	overflow: hidden;
    	 100%;
    	height: 100%;
    	max- 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-1433px) and (orientation:landscape) {
    	#bgBox, #bgDiv {
    		max- 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({
             imgWidh,
            height: imgHeight
          });
        } else {
          if (winRatio > imgRatio) {
            // 屏幕宽高比大于图片宽高比,屏幕高度不足,图片向上偏移
            offsetLeft = 0;
            offsetTop = (Math.ceil(winWidth / imgRatio) - winHeight) / 2;
            $bgDiv.css({
               winWidth,
              height: winWidth / imgRatio,
              top: -offsetTop,
              left: offsetLeft
            });
          } else if (winRatio < imgRatio) {
            // 屏幕宽高比大于图片宽高比,屏幕宽度不足,图片向左偏移
            offsetLeft = (Math.ceil(winHeight * imgRatio) - winWidth) / 2;
            offsetTop = 0;
            $bgDiv.css({
               winHeight * imgRatio,
              height: winHeight,
              top: offsetTop,
              left: -offsetLeft
            });
          }
        }
      };
      resize();
      $(window).on("resize", resize);
    })(jQuery);
    

    算法的基本流程为:

    1. 获取图片原始宽高比。当然有工具可以实现,本例中用的是现成的数据;
    2. 获取浏览器可视区域的尺寸,并计算宽高比;
    3. 如果屏幕宽高比大于图片宽高比,将图片宽度撑满浏览器视窗,此时屏幕高度不足,图片向上偏移;
    4. 如果屏幕宽高比小于图片宽高比,将图片高度撑满浏览器视窗,此时屏幕宽度不足,图片向左偏移;

    以上算法可以基本满足项目需求。

    响应式

    我们注意到上文提到的css中有一些宽高尺寸的限制,这些数值有一部分是为了满足必应首页具体需求的,有一部分是自适应屏幕尺寸的。

    比如min-1115px是因为必应首页的nav全部展开时恰好是1115px,如果小于这个尺寸就会出现item重叠,造成样式混乱。

    另外,媒体查询中的两个边界值min-height:806pxmin-1433px,本人还未弄清楚为何这两个边界值如此奇怪,但是必应这样做的目的是很清楚的。

    标准13寸屏幕的分辨率为1366×768,媒体查询的两个边界值最接近标准14寸屏幕分辨率1440×900,也就是说,在14寸以下屏幕保持背景图片宽度显示不超过1366px。

    请注意背景区域bgDiv并没有max-height的限制,这是因为不论什么尺寸的屏幕,都要保持背景图片的宽高比。

    媒体查询超出边界值的屏幕下,背景图片的宽高限制在图片的原始尺寸,这是为了不拉伸图片造成失真,超过1920×1080的屏幕始终居中显示原始图片尺寸。

  • 相关阅读:
    Linux学习(一)-安装vm虚拟机以及如何在虚拟机上安装Centos系统
    HTML DOM总结
    如何在eclipse中安装angularjs插件
    wfp(Application的运用)
    wpf(第一章 基础知识)
    二叉搜索树的深度&广度优先遍历 C++实现
    Python 实现公式图像识别转 Latex(Mathpix)
    机器学习基石 之 逻辑回归(Logistic Regression)
    机器学习技法 之 聚合模型(Aggregation Model)
    机器学习技法 之 决策树(Decision Tree)
  • 原文地址:https://www.cnblogs.com/ihardcoder/p/4894194.html
Copyright © 2011-2022 走看看