可视化大屏自适应

示例项目

<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>

 

posted @ 2023-07-11 10:41  YINGYAN  阅读(41)  评论(0编辑  收藏  举报