背景
数据大屏项目,需要适配不同屏幕,且在任意屏幕下保持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可以完全按照设计稿的尺寸去开发,缩放的是整个页面
可以减少不必要的回流重绘
效果预览-更高
效果预览-更宽
实现代码
新建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背景设置成黑色即可
<template>
<div id="app" ref="app">
<router-view />
</div>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped>
#app {
width: 100vw;
height: 100vh;
background-color: #020308;
overflow: hidden;
}
</style>
Layout.vue引入resizeMixin
<template>
<div id="index" ref="appRef">
<router-view />
</div>
</template>
<script>
import resizeMixin from '@/utils/resizeMixin ';
export default {
mixins: [resizeMixin]
}
</script>
<style lang="scss" scoped>
#index {
// 设计稿宽高
width: 1920px;
height: 1080px;
// 盒子水平垂直居中
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
& > div {
height: 100%;
width: 100%;
}
}
</style>