【数据大屏】大屏多尺寸屏幕兼容方案(适配任何屏,包括手机)scale
本方案采用vue3编写,主要利用css3的scale方法,
直接上代码:
// drawMixin.js
// 屏幕适配 mixin 函数// * 默认缩放值
const scale = {width: '1',height: '1',
}// * 设计稿尺寸(px)
// const baseWidth = 1920
// const baseHeight = 1080export default function (baseWidth = 1920, baseHeight = 1080) {// * 需保持的比例(默认1.77778)const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))let innerAppRef = nullconst calcRate = (appRef) => {if (!appRef.value) returnif (!innerAppRef) { innerAppRef = appRef }// 当前宽高比const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))if (appRef.value) {if (currentRate > baseProportion) {// 表示更宽scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)scale.height = (window.innerHeight / baseHeight).toFixed(5)appRef.value.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.value.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`}}};let drawTiming = null;const resize = () => {clearTimeout(drawTiming)drawTiming = setTimeout(() => {innerAppRef && calcRate(innerAppRef)}, 200)};/*** @param {date} time 需要转换的时间* @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss*/
const formatTime = (time, fmt) => {if (!time) return '';else {const date = new Date(time);const o = {'M+': date.getMonth() + 1,'d+': date.getDate(),'H+': date.getHours(),'m+': date.getMinutes(),'s+': date.getSeconds(),'q+': Math.floor((date.getMonth() + 3) / 3),S: date.getMilliseconds(),};if (/(y+)/.test(fmt))fmt = fmt.replace(RegExp.$1,(date.getFullYear() + '').substr(4 - RegExp.$1.length));for (const k in o) {if (new RegExp('(' + k + ')').test(fmt)) {fmt = fmt.replace(RegExp.$1,RegExp.$1.length === 1? o[k]: ('00' + o[k]).substr(('' + o[k]).length));}}return fmt;}
}return {calcRate,resize,formatTime}
}
使用方式:
<template><div id="app"><div class="index" ref="appRef"><div class="bg-class"><v-loading v-if="loading">Loading...</v-loading><div v-else class="host-body"><!-- 具体的大屏内容 --></div></div></div></div>
</template><script setup>
import drawMixin from '@/mixins/drawMixin.js'
import { useRouter } from 'vue-router';
const { currentRoute } = useRouter();
const route = currentRoute.value;const baseData = {baseWidth: 1920, baseHeight: 1064
};
Object.assign(baseData, route.query || {});
// 通过浏览器动态设置基础宽高尺寸。
const { calcRate, resize, formatTime } = drawMixin(baseData.baseWidth, baseData.baseHeight);
const loading = ref(true);const cancelLoading = () => {setTimeout(() => {loading.value = false}, 500)
}onMounted(() => {// timeFn()cancelLoading()calcRate(appRef)window.addEventListener('resize', resize)
})onBeforeUnmount(() => {window.removeEventListener('resize', resize)clearInterval(timing)
})</script>
<style lang='less' scoped>
.index {color: #d3d6dd;width: 1920px;height: 1080px;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);transform-origin: left top;overflow: hidden;}
.bg-class {width: 100%;height: 100%;padding: 16px 20px 0 20px;
}
</style>