大屏适配方案
数据可视化大屏需要适配不同的比例,现记录俩种觉得不错的方案
项目地址:https://github.com/zhaobao1830/echarts-zb autoResize.js和resizeMixin
备注
下面俩种方案,都是以16:9比例(一般用1920*1080)进行开发的,之后适配不同分辨率的大屏 如果大屏分辨率也是16:9,那没什么大问题,俩种方案都可以 如果大屏分辨率不是16:9,那就需要专门开发
以宽或高为准,去适配高或宽
resizeMixin.js
js
import {onBeforeUnmount, onMounted, ref} from 'vue'
/**
* 是先按照1920*1080尺寸的设计图开发,然后进行等比例缩放
* 在大屏展示的时候,计算大屏的宽高比,
* 如果大于16:9,以高度为基准,去适配宽度
* 如果小于16:9,以宽度为基准,去适配高度
*/
export default function resizeMixin() {
const baseWidth = 1920
const baseHeight = 1080
// * 需保持的比例(默认16:9)
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
const largeScreenRef = ref(null)
const drawTiming = ref(null)
onMounted(() => {
calcRate()
window.addEventListener('resize', resize)
})
onBeforeUnmount(() => {
clearTimeout(drawTiming.value)
window.removeEventListener('resize', resize)
})
function calcRate() {
if (!largeScreenRef.value) {
return
}
// 当前宽高比
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
// 宽缩放比例
let widthScale = ''
// 高缩放比例
let heightScale = ''
if (currentRate > baseProportion) {
widthScale = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
heightScale = (window.innerHeight / baseHeight).toFixed(5)
} else {
heightScale = (window.innerWidth / baseProportion / baseHeight).toFixed(5)
widthScale = (window.innerWidth / baseWidth).toFixed(5)
}
largeScreenRef.value.style.transform = `scale(${widthScale}, ${heightScale}) translate(-50%, -50%)`
}
function resize() {
clearTimeout(drawTiming.value)
setTimeout(() => {
calcRate()
}, 200)
}
return {
largeScreenRef
}
}
备注
这种方案会在左右俩侧或上下俩侧出现空白,解决方法是背景设置为深颜色,这样看着不影响
固定宽高比进行缩放
autoResize.js
js
import {nextTick, onMounted, onUnmounted, ref} from 'vue'
import { debounce } from '@/utils/util'
/**
* 固定宽高比,等比例进行缩放(这种方式开发的大屏,在浏览器进行缩放,页面的内容不变)
* 可以手动传入宽高,比如1920*1080或者3940*2160,
* 以传入的尺寸进行开发
* 如果没有传入,就默认电脑屏幕的宽高(以我的电脑为例,就是1920*1080)
* 通过计算宽高和实际展示尺寸的比例,进行宽高的缩放
*/
export default function autoResize(props) {
const largeScreenConRef = ref(null)
const width = ref(0)
const height = ref(0)
// 可视区域的宽高
const originalWidth = ref(0)
const originalHeight = ref(0)
onMounted(async () => {
await initSize()
updateSize()
updateScale()
// 使用debounce方法,页面进行缩放的时候,会出现先放大后缩小的情况,如果对这种情况敏感,可以将debounce方法去掉
window.addEventListener('resize', debounce(1000, onResize))
})
onUnmounted(() => {
window.removeEventListener('resize', onResize)
})
async function onResize() {
await initSize()
updateScale()
}
function initSize() {
return new Promise((resolve) => {
nextTick(() => {
const dom = largeScreenConRef.value
// 获取大屏尺寸
if (props.options.width && props.options.height) {
width.value = props.options.width
height.value = props.options.height
} else {
width.value = dom.clientWidth
height.value = dom.clientHeight
}
// 获取画布尺寸
// 只要赋值了,就不会再重复赋值了
if (!originalWidth.value || !originalHeight.value) {
originalWidth.value = window.screen.width
originalHeight.value = window.screen.height
}
resolve()
})
})
}
function updateSize() {
const dom = largeScreenConRef.value
if (width.value && height.value) {
dom.style.width = `${width.value}px`
dom.style.height = `${height.value}px`
} else {
dom.style.width = `${originalWidth.value}px`
dom.style.height = `${originalHeight.value}px`
}
}
// 计算宽高比
function updateScale() {
// 获取真实的视口尺寸
const currentWidth = document.body.clientWidth
const currentHeight = document.body.clientHeight
// 获取大屏最终的宽高
const realWidth = width.value || originalWidth.value
const realHeight = height.value || originalHeight.value
// 计算缩放比
const widthScale = currentWidth / realWidth
const heightScale = currentHeight / realHeight
const dom = largeScreenConRef.value
dom.style.transform = `scale(${widthScale}, ${heightScale})`
}
return {
largeScreenConRef
}
}
备注
这种方案开发的大屏,在浏览器进行缩放,页面的内容不变