可缩放大屏布局方式


实现思路

  • 默认按照1920*1080设计大屏
  • 获取实际可视化区域的宽高,计算宽高比
  • 如果大于1920/1080,说明更宽,横向两边留白,否则纵向两边留白
  • 大屏内所有元素及其组件严格按照设计图px单位布局

父组件

javascript 复制代码
<template>
  <div class="w100 h100 bg-black">
    <div id="appRef" ref="appRef">
      <div style="height: 180px" class="bg-red w100 center size-30 bold">
        标题
      </div>
      <div style="height: 900px" class="flex">
        <div class="flex-1 bg-blue h100">
          <div class="w100 pd-20" style="height: 50%">
            <tab1-line ref="tab1LineRef" :list="res.upLargeScreen"></tab1-line>
          </div>
          <div class="w100 pd-20" style="height: 50%">
            <tab1-bar ref="tab1BarRef" :list="res.downLargeScreen"></tab1-bar>
          </div>
        </div>
        <div class="flex-1 center bg-yellow h100 size-18">中间内容区</div>
        <div class="flex-1 center bg-blue h100">右侧区域</div>
      </div>
    </div>
  </div>
</template>

<script>
import draw from "./draw";
import { getTab1Api } from "./components/js/api";
export default {
  mixins: [draw],
  components: {
    tab1Line: () => import("./components/index2-tab1-line.vue"),
    tab1Bar: () => import("./components/index2-tab1-bar.vue"),
  },
  data() {
    return {
      res: {},
    };
  },
  mounted() {
    console.log(window.innerWidth, window.innerHeight); //获取屏幕可视区域大小 1912*928
    console.log(window.screen.width, window.screen.height); //获取屏幕分辨率 1920*1080
    this.getData();
  },
  methods: {
    getData() {
      getTab1Api({
        dateType: 1,
        year: 2024,
      }).then((res) => {
        this.res = { ...this.res, ...res.data };
      });
    },
  },
};
</script>
<style lang="scss" scoped>
#appRef {
  width: 1920px;
  height: 1080px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transform-origin: left top;
  overflow: hidden;
}
</style>

draw.js

javascript 复制代码
// * 默认缩放值
const scale = {
  width: '1',
  height: '1',
}

// * 设计稿尺寸(px)
const baseWidth = 1920
const baseHeight = 1080

// * 需保持的比例
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))

export default {
  data() {
    return {
      drawTiming: null // 定时函数
    }
  },
  mounted() {
    this.calcRate()
    window.addEventListener('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)
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resize)
  },
}
相关推荐
程序员老赵6 小时前
Docker 部署 Dolibarr:轻松搭建开源 ERP/CRM 平台
运维·前端·后端
星禾元亨6 小时前
同一件事有三份资料,AI 该信哪一份?冲突判定、优先级链与处置流程
前端·人工智能
Dovis(誓平步青云)6 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
穆梓兰煊6 小时前
TS5.7 vs 裸JS:AI应用少3坑
前端
榆瓷6 小时前
闲着没事,我把 WebGPU 的样板代码封成了一个库
前端
136096757236 小时前
页面打不开不是 Nginx 的错
前端·后端
liangshanbo12157 小时前
高级前端面试题:package.json 常见字段
前端·json
CappuccinoRose7 小时前
输入事件进阶
前端·javascript·输入事件
liangshanbo12159 小时前
面试题:前端工程化中 Tree Shaking的原理是什么?
前端·treeshaking
补码缩写9 小时前
视频跳转触发了seeked,画面就到位了吗
前端