可缩放大屏布局方式


实现思路

  • 默认按照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)
  },
}
相关推荐
Wang's Blog13 分钟前
前端FAQ: Vue 3 与 Vue 2 相⽐有哪些重要的改进?
前端·javascript·vue.js
再希29 分钟前
React+Tailwind CSS+Shadcn UI
前端·react.js·ui
用户47949283569151 小时前
JavaScript 的 NaN !== NaN 之谜:从 CPU 指令到 IEEE 754 标准的完整解密
前端·javascript
群联云防护小杜1 小时前
国产化环境下 Web 应用如何满足等保 2.0?从 Nginx 配置到 AI 防护实战
运维·前端·nginx
醉方休1 小时前
Web3.js 全面解析
前端·javascript·electron
前端开发爱好者2 小时前
前端新玩具:Vike 发布!
前端·javascript
今天也是爱大大的一天吖2 小时前
vue2中的.native修饰符和$listeners组件属性
前端·javascript·vue.js
fxshy2 小时前
在 Vue 3 + Vite 项目中使用 Less 实现自适应布局:VW 和 VH 的应用
前端·javascript·less
奇舞精选2 小时前
AI时代的前端知识拾遗:前端事件循环机制详解(基于 WHATWG 最新规范)
前端·javascript
小月鸭2 小时前
理解预处理器(Sass/Less)
前端