大屏屏幕自适应大小的JS写法(带滚动条)

目前已知的可以让大屏实现缩放的vue插件有:
vue3-scale-box  等
具体可以在npm上找一下相关文档参考,
他们有一个问题就是所有内容只能显示在一屏里,这不免会造成图像的拉伸,所以解决方案就是采用滚动条的设计去容纳大屏的更多内容,直接上代码:
 
// web定稿尺寸 1920*1080
let initPageW = 1920,
  initPageH = 1080

class ResizeBox {
  _contentApp = ''
  _content = ''
  constructor(contentApp: string, content: string) {
    this._contentApp = contentApp
    this._content = content
  }

  animateResize() {
    var _jsc: any = document.getElementById(this._contentApp),
      _body: any = document.getElementById(this._content)
    if (!_jsc || !_body) {
      return
    }
    let WH = window.innerHeight,
      WW = window.innerWidth,
      _jscH = _jsc.offsetHeight
    // 缩放
    if (this._contentApp.indexOf('header-') > -1) {
      //头部的高度就是160px固定的
      WH = 160
    } else {
      WH = WH - 160
    }
    let minScale = Math.floor((WW / initPageW) * 10000) / 10000
    let minHeightScale = Math.floor((WH / initPageH) * 10000) / 10000
    // 浏览器的滚滚动条宽度 8px,这里的8是因为css对滚动条的样式做了调整
    // 内容区高度缩放后如果超过窗口高度,说明出现滚动条,可视区域宽度会缩小8px 重新计算缩放比,
    if (_jscH * minScale > WH) {
      minScale = Math.floor(((WW - 8) / initPageW) * 10000) / 10000
    }
    _jsc.style.transform = 'scale(' + minScale + ',' + minScale + ')'
    _jsc.style.margin = '0 0'
    if (_body) {
      _body.style.height = _jscH * minHeightScale + 'px'
    }
  }

  debounce(func: any, wait?: any, immediate?: any) {
    let timeout: any, args: any, context: any, timestamp: any, result: any
    const later = function () {
      // 据上一次触发时间间隔
      const last = +new Date() - timestamp

      // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
      if (last < wait && last > 0) {
        timeout = setTimeout(later, wait - last)
      } else {
        timeout = null
        // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
        if (!immediate) {
          result = func.apply(context, args)
          if (!timeout) context = args = null
        }
      }
    }
    return function (...args: any) {
      // @ts-ignore
      context = this
      timestamp = +new Date()
      const callNow = immediate && !timeout
      // 如果延时不存在,重新设定延时
      if (!timeout) timeout = setTimeout(later, wait)
      if (callNow) {
        result = func.apply(context, args)
        context = args = null
      }
      return result
    }
  }
}
export { ResizeBox }

调用:

<template>
  <!-- 我的头部组件,高度是160px -->
  <digital-header />
  <div id="industry-content" style="position: relative">
    <div
      id="industry-content-app"
      style="
        width: 1920px;
        margin: 0 auto;
        transform: scale(1);
        transform-origin: 0 0;
      "
    >
      <div class="industry">

      这里就写具体内容,样式大小之类的都按照设计稿的宽高写即可
       </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import digitalHeader from '~/views/digitalCockpit/components/header.vue'
import { onMounted } from 'vue-demi'
import { ResizeBox } from '~/utils/resize'

onMounted(() => {
  const resizeBox = new ResizeBox('industry-content-app', 'industry-content')
  // 初始化调用
  resizeBox.animateResize()
  // 这里用addEventListener方法添加resize是因为每个页面都需要一个resize方法,如果用window.onresize的话就只能有一个页面是生效的
  window.addEventListener(
    'resize',
    resizeBox.debounce(function () {
      resizeBox.animateResize()
    }, 500)
  )
})

</script>

<style scoped lang="scss">
.industry {
  &::before{
    content: '';
    height: 160px;
    display: block;
  }
}

</style>

 其中头部组件的实现ID要加个header-的前缀,内容如下:

<template>
  <div
    id="header-content"
    style="position: fixed; top: 0; z-index: 1; background: #fff"
  >
    <div
      id="header-content-app"
      style="
        width: 1920px;
        margin: 0 auto;
        transform: scale(1);
        transform-origin: 0 0;
      "
    >
    头部的内容
    </div>
  </div>
</template>

<script setup lang="ts">
import { h, onMounted } from 'vue-demi'
import { ResizeBox } from '~/utils/resize'

onMounted(() => {
  const resizeBox = new ResizeBox('header-content-app', 'header-content')
  resizeBox.animateResize()
  window.addEventListener(
    'resize',
    resizeBox.debounce(function () {
      resizeBox.animateResize()
    }, 500)
  )
})


</script>

<style scoped lang="scss">
.big-screen-header {
  padding: 10px;
  box-sizing: border-box;
  width: 100%;
  height: 160px;
}
</style>
<style lang="scss"></style>

 

posted @ 2023-09-11 14:28  洛晨随风  阅读(724)  评论(0编辑  收藏  举报