可缩放大屏布局方式


实现思路

  • 默认按照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)
  },
}
相关推荐
kymjs张涛13 分钟前
零一开源|前沿技术周报 #7
android·前端·ios
爱编程的喵18 分钟前
React入门实战:从静态渲染到动态状态管理
前端·javascript
Tttian62230 分钟前
npm init vue@latestnpm error code ETIMEDOUT
前端·vue.js·npm
患得患失94937 分钟前
【前端】【组件库开发】【原理】【无框架开发】现代网页弹窗开发指南:从基础到优化
前端
运维咖啡吧1 小时前
给朋友们分享个好消息 7天时间23.5k
前端·程序员·ai编程
元气小嘉1 小时前
前端技术小结
开发语言·前端·javascript·vue.js·人工智能
神仙别闹1 小时前
基于ASP.NET+SQL Server实现(Web)企业进销存管理系统
前端·后端·asp.net
江城开朗的豌豆2 小时前
Vue计算属性:为什么我的代码突然变优雅了?
前端·javascript·vue.js
Sun_light2 小时前
5 个理由告诉你为什么有了 JS 还要用 TypeScript
前端·typescript
陈随易2 小时前
Kimi k2发布,效果比肩Sonnet4,价格与DeepSeek一致
前端·后端·程序员