数据可视化大屏,屏幕多分辨率适配方案,且在任意屏幕下保持16:9的比例等比缩放

背景

数据大屏项目,需要适配不同屏幕,且在任意屏幕下保持16:9的比例,保持显示效果一致,屏幕比例不一致两边留黑即可

分析

 不同屏幕宽高比例(和设计稿16:9)相比会有两种情况:

1、更宽:(window.innerWidth / window.innerHeight) > 16/9 ,以高度为基准,去适配宽度

2、更高:(window.innerWidth / window.innerHeight) < 16/9 ,以宽度为基准,去适配高度

选择方案:

计算需要缩放的比例,利用transform的scale属性缩放即可

为什么不用px->rem、viewport或媒体查询?

因为用rem起来太麻烦了;媒体查询代码大量书写 比较繁琐;而且echarts里面的东西不好适配

使用transform可以完全按照设计稿的尺寸去开发,缩放的是整个页面

可以减少不必要的回流重绘

效果预览-更高

 数据可视化大屏,屏幕多分辨率适配方案,且在任意屏幕下保持16:9的比例等比缩放_第1张图片

效果预览-更宽

数据可视化大屏,屏幕多分辨率适配方案,且在任意屏幕下保持16:9的比例等比缩放_第2张图片

实现代码

 新建resizeMixin.js

// * 默认缩放值
const scale = {
  width: '1',
  height: '1',
};

// * 设计稿尺寸(px)
const baseWidth = 1920;
const baseHeight = 1080;

// * 需保持的比例(默认16:9)
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5));

export default {
  data() {
    return {
      drawTiming: null,
    };
  },
  mounted() {
    this.calcRate();
    window.addEventListener('resize', this.resize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resize);
  },
  methods: {
    calcRate() {
      const appRef = this.$refs['appRef'];
      if (!appRef) return;
      // 当前宽高比
      const currentRate = parseFloat(
        (window.innerWidth / window.innerHeight).toFixed(5)
      );
      if (appRef) {
        if (currentRate > baseProportion) {
          // 表示更宽
          scale.width = (
            (window.innerHeight * baseProportion) /
            baseWidth
          ).toFixed(5);
          scale.height = (window.innerHeight / baseHeight).toFixed(5);
          appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`;
        } else {
          // 表示更高
          scale.height = (
            window.innerWidth /
            baseProportion /
            baseHeight
          ).toFixed(5);
          scale.width = (window.innerWidth / baseWidth).toFixed(5);
          appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`;
        }
      }
    },
    resize() {
      clearTimeout(this.drawTiming);
      this.drawTiming = setTimeout(() => {
        this.calcRate();
      }, 200);
    },
  },
};

 App.vue,body背景设置成黑色即可




 Layout.vue引入resizeMixin 





你可能感兴趣的:(vue,vue.js,javascript,前端)