pc项目自适应

920 阅读2分钟

需求:

  • 需要满足市场上不同比例的大屏(5:4、4:3(较少)、16:10、16:9(新品))
  • 需要满足不同分辨率的屏幕 (1080px 2K 4K) 125% 175%...等

问题:

如果按照设计稿1920*1080开发 ,就不适用于2k 4K,展示效果不好或者是需要用% 或者 vh vw等比例去写css, 这样的方法不仅笨拙 而且代码量增加了不少,而且计算复杂,存在兼容性问题,字体大小不对等问题

1、方式一(采用zoom)

缺点:鼠标经过会存在位置偏移,例如echart的tooltip位置、select/dropdown等弹出框位置

  • 没有地图可直接设置body
 // index.html
 <script>
          window.onload = function() {
              document.body.style.zoom = "normal"; //避免zoom尺寸叠加
              let scale = 1 / window.devicePixelRatio
              document.body.style.zoom = scale;
          };
          //防抖,避免resize占用过多资源
          (function() {
              var throttle = function(type, name, obj) {
                  obj = obj || window;
                  var running = false;
                  var func = function() {
                      if (running) {
                          return;
                      }
                      running = true;
                      requestAnimationFrame(function() {
                          obj.dispatchEvent(new CustomEvent(name));
                          running = false;
                      });
                  };
                  obj.addEventListener(type, func);
              };

              throttle("resize", "optimizedResize");
          })();

          // 获取当前屏幕分辨率
          (function() {
              var ratio=0;
              var screen=window.screen;
              var ua=navigator.userAgent.toLowerCase();
              if(window.devicePixelRatio !== undefined){
                  ratio=window.devicePixelRatio;
              }else if(~ua.indexOf('msie')){
                  if(screen.deviceXDPI && screen.logicalXDPI)
                  {
                      ratio=screen.deviceXDPI/screen.logicalXDPI;
                  }

              }else if(window.outerWidth !== undefined && window.innerWidth !== undefined){
                  ratio=window.outerWidth/window.innerWidth;
              }
              console.log(ratio)
              if(ratio){
                  ratio=Math.round(ratio*100);
              }
              window.screenRatio = ratio
              console.log(ratio)
              return ratio;
          })()
          // optimizedResize
          window.addEventListener("optimizedResize", function() {
              document.body.style.zoom = "normal";
              let scale = 1 / window.devicePixelRatio
              document.body.style.zoom = scale;
          });
      </script>
  • 有地图页面则设置在无地图页面(单独给每块添加)

image.png

image.png

// 每块写死宽度
<template>
    <div class="xzjc">
        <!-- 视图 -->
        <router-view class="routerView"></router-view>
        <!-- 地图 -->
        <div id="map" class="map"></div>
    </div>
</template>

export default {
    methods: {
        // 窗口分辨率缩放 内容大小高度保持不变
        resizeScale () {
            if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {
                var header = document.querySelector(".common-header")
                var left = document.querySelector(".routerView .common-index-left")
                var right = document.querySelector(".routerView .common-index-right")
                var legend = document.querySelector(".routerView .common-index-legend")
                var center = document.querySelector(".routerView .common-index-center")

                let scale = 1 / window.devicePixelRatio
              
                if(header) {
                    header.style.zoom = "normal"; //避免zoom尺寸叠加
                    header.style.zoom = scale;
                }
                if(left) {
                    left.style.zoom = "normal"; //避免zoom尺寸叠加
                    left.style.zoom = scale;
                }
                if(right) {
                    right.style.zoom = "normal"; //避免zoom尺寸叠加
                    right.style.zoom = scale;
                }
                if(legend) {
                    legend.style.zoom = "normal"; //避免zoom尺寸叠加
                    legend.style.zoom = scale;
                }

                if(center) {
                    center.style.zoom = "normal"; //避免zoom尺寸叠加
                    center.style.zoom = scale;
                }
            }
        },
    }
}

2、方式二(采用transform:scale(n)

参考百度云的 SugerBi可视化

  1. sugar.aipage.com/dashboard/5…
  2. sugar.aipage.com/dashboard/9…

以及阿里的datav可视化

  1. datav.aliyuncs.com/share/464d4…

优点:鼠标经过会不存在位置偏移,字体也能很完美的适配

  • 没有地图可直接设置body
 // index.html
 <script>
          function resize () {
              document.body.style.width = '1920px';
              document.body.style.height = 1080px';
              var winHeight = document.documentElement.clientHeight; //浏览器的高度
              var winWidth = document.documentElement.clientWidth; //浏览器的宽度
              var sw = winWidth / 1920
              var sh = winHeight / 1080
              ducument.body.style.transition = 'all 0.5s'
              document.body.style.transformOrigin = 'left top'
              document.body.style.transform = `scale(${sw},${sh})`
              document.body.style.WebkitTransform = `scale(${sw},${sh})`
          }
          
          window.onload = function() {
              resize()
          };
          //防抖,避免resize占用过多资源
          (function() {
              var throttle = function(type, name, obj) {
                  obj = obj || window;
                  var running = false;
                  var func = function() {
                      if (running) {
                          return;
                      }
                      running = true;
                      requestAnimationFrame(function() {
                          obj.dispatchEvent(new CustomEvent(name));
                          running = false;
                      });
                  };
                  obj.addEventListener(type, func);
              };

              throttle("resize", "optimizedResize");
          })();
          // optimizedResize
          window.addEventListener("optimizedResize", resize);
      </script>
  • 有地图页面则设置在无地图页面
<template>
    <div class="xzjc">
        <!-- 视图 -->
        <router-view class="routerView"></router-view>
        <!-- 地图 -->
        <div id="map" class="map"></div>
    </div>
</template>

export default {
    methods: {
        // 窗口分辨率缩放 内容大小高度保持不变
        resizeScale () {
            if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {
                var winHeight = document.documentElement.clientHeight; //浏览器的高度
                var winWidth = document.documentElement.clientWidth; //浏览器的宽度
                var sw = winWidth / 1920
                var sh = winHeight / 1080
              
                var content = document.querySelector(".routerView")

               if (content) {
                    content.style.transform = `scale(${sw},${sh})`
                    content.style.WebkitTransform = `scale(${sw},${sh})`
                }
            }
        },
    }
}

// css部分
.common-index {
		width: 1920px !important;
    height: 1080px !important;
    transform-origin: left top;
    position: absolute;
    transition: all 0.5s;
    
    &-header {
    		height: 84px;
    }
    
    &-left {
        position: absolute;
        top: 85px;
        left: 0 !important;
        z-index: 1;
        height: calc(100% - 110px) !important;
        pointer-events: auto;
    }
    
     &-right {
        position: absolute;
        top: 85px;
        left: 0 !important;
        z-index: 1;
        height: calc(100% - 110px) !important;
        pointer-events: auto;
    }
    
    .common-index-part {
        width: 100%;
        padding: 0 16px;
        box-sizing: border-box;

        /*  第一块 */
        &_1 {
            width: 100%;
            height: 323px;
            // height: calc(100% / 3 + 13px) !important;
        }
        /*  第二块 */
        &_2 {
            width: 100%;
            // height: calc(100% / 3 - 30px) !important;
            height: 323px;
        }
        /*  第三块 */
        &_3 {
            width: 100%;
            // height: calc(100% / 3 + 17px) !important;
            height: 323px;
        }
  }
    
}


image.png 效果图

GIF 2021-12-24 18-17-22.gif