美文网首页js css html
前端大屏项目的屏幕适配方案

前端大屏项目的屏幕适配方案

作者: 千茉紫依 | 来源:发表于2020-07-22 15:18 被阅读0次

    最近在写大屏项目, 技术栈是echarts+vue, 在屏幕适配调研了很久, 网上有多种方案, 但都有自己的局限性,比如css媒体查询代码量巨大,且变化过程不平滑, vw适合定宽的不方便缩放的组件. 并不适合等比例缩放所有组件, 最后,我发现等比例缩放所有组件的话更适合用css变量来设置scale属性

    思路:
    1.初始化的时候获得大屏幕的比例
    2.把这个比例设置给css的scale变量
    3.监听浏览器的窗口大小, 将新的比例赋给scale变量
    这样不管屏幕有多大,分辨率有多高,只要屏幕的比例跟你定的比例一致,就都能适配了

    在vue中大致是这样实现的:

     <div class="ScaleBox"
             ref="ScaleBox"
     >
    
     mounted() {
        this.setScale();
        window.addEventListener("resize", this.setScale);
      },
     methods: {
        getScale() {
          const { width, height } = this;
          let ww = window.innerWidth / width;
          let wh = window.innerHeight / height;
          return ww < wh ? ww : wh;
        },
       setScale() {
          this.scale = this.getScale();
          this.$refs.ScaleBox.style.setProperty("--scale", this.scale);
        },
    }
    
    #ScaleBox {
      --scale: 1;
    }
    .ScaleBox {
      transform: scale(var(--scale)) ;
    }
    
    

    这里涉及到几个知识点

    1. 在vue中获取dom
      vue中的dom应该用ref来定义, 然后在在函数中用this.$refs.XXX来调用,这里的ref相当于id

    2.css中定义和使用变量的方法

    • css中变量定义: --XXX:XXX;
    • css中变量使用: var(--XXX)
    • 在dom元素的style属性中给变量赋值, 用js调用css变量: this.$refs.ScaleBox.style.setProperty("--scale", this.scale);

    3.getScale函数是在获取较小比例的一条边, 这样较大比例的一条边就可以按照既定的比例缩放了, width和height是设置的默认比例, window.innerWidth和window.innerHeight 是大屏幕的缩放尺寸, 如果不理解,试着把他们都取极限,就很容易理解了.

    4.css中的垂直水平居中
    {
    transform: scale(var(--scale)) translate(-50%, -50%);
    position: absolute;
    left: 50%;
    top: 50%;
    }
    上面这四句是缩放过后垂直水平居中的意思, left: 50%; top: 50%;这两句是该元素的左上定点居中, 而transform: translate(-50%, -50%);这句会将元素向左向上移动半个元素的width和height

    然后再加一个节流函数, 一个简单的VUE组件就封装好了

    <template>
      <div class="wrap">
        <div class="ScaleBox"
             ref="ScaleBox"
             :style="{
              width,
              height
            }">
          <BigScreen></BigScreen>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: "ScaleBox",
      props: {
        width: {
          type: Number,
          default: 1920
        },
        height: {
          type: Number,
          default: 1080
        }
      },
      data() {
        return {
          scale: null
        };
      },
      mounted() {
        this.setScale();
        window.addEventListener("resize", this.setScale);
      },
      methods: {
        getScale() {
          const { width, height } = this;
          let ww = window.innerWidth / width;
          let wh = window.innerHeight / height;
          return ww < wh ? ww : wh;
        },
        setScale() {
          this.scale = this.getScale();
          this.$refs.ScaleBox.style.setProperty("--scale", this.scale);
        },
        debounce(fn, delay) {
          let delays = delay || 500;
          let timer;
          return function() {
            let th = this;
            let args = arguments;
            if (timer) {
              clearTimeout(timer);
            }
            timer = setTimeout(function() {
              timer = null;
              fn.apply(th, args);
            }, delays);
          };
        }
      }
    };
    </script>
    
    <style >
    #ScaleBox {
      --scale: 1;
    }
    .wrap {
      background: #eee;
      width: 100%;
      height: 5000px;
    }
    .ScaleBox {
      transform: scale(var(--scale)) translate(-50%, -50%);
      display: flex;
      height: 100%;
      flex-direction: column;
      transform-origin: 0 0;
      position: absolute;
      left: 50%;
      top: 50%;
      transition: 0.3s;
      z-index: 999;
    }
    </style>
    

    相关文章

      网友评论

        本文标题:前端大屏项目的屏幕适配方案

        本文链接:https://www.haomeiwen.com/subject/ivazkktx.html