Screen adaptation solution for front-end large-screen projects

Recently I am working on a large-screen project. The technology stack is echarts+vue. I have been researching screen adaptation for a long time. There are many solutions on the Internet, but they all have their own limitations. For example, the amount of CSS media query code is huge, and the change process is not smooth. vw is suitable for fixed-width components that are inconvenient to scale. It is not suitable for scaling all components equally. Finally, I found that it is more suitable to use css variables to set the scale attribute if all components are scaled equally.

Idea:

1. Obtain the ratio of the large screen during initialization

2. Set this ratio to the scale variable of css

3. Monitor the browser window size and assign the new ratio to the scale variable

In this way, no matter how big the screen is or how high the resolution is, as long as the ratio of the screen is consistent with the ratio you set, it will fit.

This is roughly implemented in 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)) ;
}

Several knowledge points are involved here

  1. Get dom in vue.
    The dom in vue should be defined with ref, and then called with this.$refs.XXX in the function. The ref here is equivalent to the id.

2. How to define and use variables in css

  • Variable definition in css: --XXX:XXX;

  • Use of variables in css: var(--XXX)

  • Assign a value to the variable in the style attribute of the dom element, and use js to call the css variable: this.$refs.ScaleBox.style.setProperty("--scale", this.scale);

3. The getScale function is to obtain an edge with a smaller ratio, so that an edge with a larger ratio can be scaled according to the established ratio. Width and height are the default ratios set, and window.innerWidth and window.innerHeight are for large screens. If you don't understand scaling, try taking them to the limit and it will be easy to understand.

4. Vertical and horizontal centering in css

{

transform: scale(var(--scale)) translate(-50%, -50%);

position: absolute;

left: 50%;

top: 50%;

}

The above four sentences mean vertical and horizontal centering after scaling, left: 50%; top: 50%; these two sentences mean centering the upper left fixed point of the element, and transform: translate(-50%, -50%); this sentence will Move the element left and up by half the width and height of the element

Then add a throttling function, and a simple VUE component is encapsulated.

<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>

Original link: https://www.jianshu.com/p/03103d274065

Source: Jianshu

Guess you like

Origin blog.csdn.net/H_shaohui/article/details/129498410