可视化大屏自适应
示例项目
<template> <div ref="wrapRef" class="screen"> <div ref="screenRef" class="screen-inner"> <div class="screen-header">{{ title }}</div> <div class="screen-body"> <el-row :gutter="20" class="s-h"> <el-col :span="7"> <div class="s-h screen-left"> <div class="screen-left-item">模块信息</div> <div class="screen-left-item">模块信息</div> <div class="screen-left-item">模块信息</div> </div> </el-col> <el-col :span="10"> <div class="s-h screen-center"> <div class="screen-center-header">模块信息</div> <div class="screen-center-map">地图展示???</div> <div class="screen-center-footer">模块信息</div> </div> </el-col> <el-col :span="7"> <div class="s-h screen-right"> <div class="screen-right-item">模块信息</div> <div class="screen-right-item">模块信息</div> <div class="screen-right-item">模块信息</div> </div> </el-col> </el-row> </div> </div> </div> </template> <script setup> const props = defineProps({ isNest: { type: Boolean, default: true } }); const title = ref('可视化大屏平台展示'); const wrapRef = ref(null) const screenRef = ref(null); // * 默认缩放 const scaleWidth = ref('1'); const scaleHeight = ref('1'); // * 定时器 const drawTiming = ref(null); // * 设计稿尺寸(px) const baseWidth = ref(1920); const baseHeight = ref(1080); // * 需保持的比例 const baseProportion = computed(() => parseFloat((baseWidth.value / baseHeight.value).toFixed(5))); // 初始化页面比例 function calcRate() { if (!screenRef.value) return; const containerW = props.isNest ? wrapRef.value.offsetWidth : window.innerWidth; const containerH = props.isNest ? wrapRef.value.offsetHeight : window.innerHeight; // 当前宽高比 const currentRate = parseFloat((containerW / containerH).toFixed(5)); if (screenRef.value) { if (currentRate > baseProportion.value) { // 表示更宽 scaleWidth.value = ((containerH * baseProportion.value) / baseWidth.value).toFixed(5); scaleHeight.value = (containerH / baseHeight.value).toFixed(5) screenRef.value.style.transform = `scale(${scaleWidth.value}, ${scaleHeight.value}) translate(-50%, -50%)`; } else { // 表示更高 scaleHeight.value = ((containerW / baseProportion.value) / baseHeight.value).toFixed(5); scaleWidth.value = (containerW / baseWidth.value).toFixed(5); screenRef.value.style.transform = `scale(${scaleWidth.value}, ${scaleHeight.value}) translate(-50%, -50%)`; } } } // 窗口大小变化 function resize() { clearTimeout(drawTiming.value); drawTiming.value = setTimeout(() => { calcRate(); }, 200); } onMounted(() => { calcRate(); window.addEventListener('resize',resize); }); onBeforeUnmount(() => { window.removeEventListener('resize', resize) }) </script> <style lang="scss" scopes> .s-h { height: 100%; } .screen { position: relative; min-width: 100%; max-width: 100vw; min-height: 100%; max-height: 100vh; background: #060c32; .screen-inner { /* 设计图宽、高 */ width: 1920px; height: 1080px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); transform-origin: left top; overflow: hidden; font-size: 14px; // color: #fff; .screen-header { height: 84px; padding: 20px 34px 24px; margin-bottom: 8px; line-height: 40px; font-size: 40px; text-align: center; background-image: linear-gradient(to top, #a3bded 0%, #6991c7 100%); } .screen-body { height: calc(100% - 84px - 8px); padding: 10px 34px 20px; background-image: linear-gradient(to top, #a3bded 0%, #6991c7 100%); } .screen-left { display: flex; flex-direction: column; .screen-left-item { flex: 1; &:nth-of-type(1) { background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } &:nth-of-type(2) { margin: 15px 0; background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } &:nth-of-type(3) { background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } } } .screen-right { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; .screen-right-item { flex: 1; &:nth-of-type(1) { background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } &:nth-of-type(2) { margin: 15px 0; background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } &:nth-of-type(3) { background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } } } .screen-center { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; .screen-center-header { flex: 1; background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } .screen-center-footer { flex: 3; background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } .screen-center-map { flex: 5; margin: 15px 0; background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%); } } } } </style>