可缩放大屏布局方式


实现思路

  • 默认按照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)
  },
}
相关推荐
yuhaiqiang7 分钟前
为什么这道初中数学题击溃了所有 AI
前端·后端·面试
djk88889 分钟前
支持手机屏幕的layui后台html模板
前端·html·layui
紫_龙11 分钟前
最新版vue3+TypeScript开发入门到实战教程之watch详解
前端·javascript·typescript
默默学前端41 分钟前
ES6模板语法与字符串处理详解
前端·ecmascript·es6
lxh01131 小时前
记忆函数 II 题解
前端·javascript
我不吃饼干1 小时前
TypeScript 类型体操练习笔记(三)
前端·typescript
华仔啊1 小时前
除了防抖和节流,还有哪些 JS 性能优化手段?
前端·javascript·vue.js
CHU7290351 小时前
随时随地学新知——线上网课教学小程序前端功能详解
前端·小程序
清粥油条可乐炸鸡1 小时前
motion入门教程
前端·css·react.js
这是个栗子1 小时前
【Vue3项目】电商前台项目(四)
前端·vue.js·pinia·表单校验·面包屑导航