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

下面说下有两种方式计算sacle,结果相同,只是方式不大同:

第一种:

一、在App.vue的props注入宽高

 1  props: {
 2     width: {
 3       type: String,
 4       default: "1920"
 5     },
 6     height: {
 7       type: String,
 8       default: "1080"
 9     }
10   },

二、在data中定义style

1 style: {
2         width: this.width + "px",
3         height: this.height + "px",
4         transform: "scale(1) translate(-50%, -50%)"
5       }

三、在methods中定义方法

Debounce: (fn, t) => {
      const delay = t || 500;
      let timer;
      return function() {
        const args = arguments;
        if (timer) {
          clearTimeout(timer);
        }
        const context = this;
        timer = setTimeout(() => {
          timer = null;
          fn.apply(context, args);
        }, delay);
      };
    },
getScale() {
      const w = window.innerWidth / this.width;
      const h = window.innerHeight / this.height;
      return w < h ? w : h;
    },
    setScale() {
      this.style.transform =
        "scale(" + this.getScale() + ") translate(-50%, -50%)";
    }

四、给html标签动态绑定 style

  注意:如果宽高不够等比,给最大的盒子一个背景色,下面的例子就是      

 <div id="app" style="background:linear-gradient(#112550, #0F2C74)">
    <div class="ScreenAdapter" :style="style">
      <router-view />
    </div>
  </div>

五、给类名 ScreenAdapter 添加css样式

.ScreenAdapter {
  transform-origin: 0 0;
  position: absolute;
  left: 50%;
  top: 50%;
  transition: 0.3s;
}

六、在 mounted 中调用 setScale()方法、和使用window.onresize 方法

this.setScale();
window.onresize = this.Debounce(this.setScale, 1000);

 

 

第二种:

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

分析:

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

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

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

选择方案:

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

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

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

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

 

效果预览更高:

 

效果预览更宽:

 

实现代码:

 新建resizeMixin.js

 1 // * 默认缩放值
 2 const scale = {
 3   width: '1',
 4   height: '1',
 5 };
 6  
 7 // * 设计稿尺寸(px)
 8 const baseWidth = 1920;
 9 const baseHeight = 1080;
10  
11 // * 需保持的比例(默认16:9)
12 const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5));
13  
14 export default {
15   data() {
16     return {
17       drawTiming: null,
18     };
19   },
20   mounted() {
21     this.calcRate();
22     window.addEventListener('resize', this.resize);
23   },
24   beforeDestroy() {
25     window.removeEventListener('resize', this.resize);
26   },
27   methods: {
28     calcRate() {
29       const appRef = this.$refs['appRef'];
30       if (!appRef) return;
31       // 当前宽高比
32       const currentRate = parseFloat(
33         (window.innerWidth / window.innerHeight).toFixed(5)
34       );
35       if (appRef) {
36         if (currentRate > baseProportion) {
37           // 表示更宽
38           scale.width = (
39             (window.innerHeight * baseProportion) /
40             baseWidth
41           ).toFixed(5);
42           scale.height = (window.innerHeight / baseHeight).toFixed(5);
43           appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`;
44         } else {
45           // 表示更高
46           scale.height = (
47             window.innerWidth /
48             baseProportion /
49             baseHeight
50           ).toFixed(5);
51           scale.width = (window.innerWidth / baseWidth).toFixed(5);
52           appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`;
53         }
54       }
55     },
56     resize() {
57       clearTimeout(this.drawTiming);
58       this.drawTiming = setTimeout(() => {
59         this.calcRate();
60       }, 200);
61     },
62   },
63 };

在app的路由下使用,body背景设置成黑色即可

 1 <template>
 2   <div  ref="appRef">
 3     <router-view />
 4   </div>
 5 </template>
 6  
 7 <script>
 8 import resizeMixin from '@/utils/resizeMixin ';
 9  
10 export default {
11   mixins: [resizeMixin]
12 }

以上就是两种方式实现,其根本都是利用transform:scale属性去实现的,个人仅为第二种更好理解,第一种代码较为简洁!

 

posted @ 2022-06-21 16:03  yuwenjing  阅读(1915)  评论(0编辑  收藏  举报