Skip to content

大屏适配方案

数据可视化大屏需要适配不同的比例,现记录俩种觉得不错的方案

项目地址:https://github.com/zhaobao1830/echarts-zb autoResize.js和resizeMixin

备注

下面俩种方案,都是以16:9比例(一般用1920*1080)进行开发的,之后适配不同分辨率的大屏 如果大屏分辨率也是16:9,那没什么大问题,俩种方案都可以 如果大屏分辨率不是16:9,那就需要专门开发

以宽或高为准,去适配高或宽

resizeMixin.js

js
import {onBeforeUnmount, onMounted, ref} from 'vue'

/**
 * 是先按照1920*1080尺寸的设计图开发,然后进行等比例缩放
 * 在大屏展示的时候,计算大屏的宽高比,
 * 如果大于16:9,以高度为基准,去适配宽度
 * 如果小于16:9,以宽度为基准,去适配高度
*/

export default function resizeMixin() {
  const baseWidth = 1920
  const baseHeight = 1080

// * 需保持的比例(默认16:9)
  const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))

  const largeScreenRef = ref(null)
  const drawTiming = ref(null)

  onMounted(() => {
    calcRate()
    window.addEventListener('resize', resize)
  })

  onBeforeUnmount(() => {
    clearTimeout(drawTiming.value)
    window.removeEventListener('resize', resize)
  })

  function calcRate() {
    if (!largeScreenRef.value) {
      return
    }
    // 当前宽高比
    const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))

    // 宽缩放比例
    let widthScale = ''
    // 高缩放比例
    let heightScale = ''

    if (currentRate > baseProportion) {
      widthScale = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
      heightScale = (window.innerHeight / baseHeight).toFixed(5)
    } else {
      heightScale = (window.innerWidth / baseProportion / baseHeight).toFixed(5)
      widthScale = (window.innerWidth / baseWidth).toFixed(5)
    }

    largeScreenRef.value.style.transform = `scale(${widthScale}, ${heightScale}) translate(-50%, -50%)`
  }

  function resize() {
    clearTimeout(drawTiming.value)

    setTimeout(() => {
      calcRate()
    }, 200)
  }

  return {
    largeScreenRef
  }
}

备注

这种方案会在左右俩侧或上下俩侧出现空白,解决方法是背景设置为深颜色,这样看着不影响

固定宽高比进行缩放

autoResize.js

js
import {nextTick, onMounted, onUnmounted, ref} from 'vue'
import { debounce } from '@/utils/util'

/**
 * 固定宽高比,等比例进行缩放(这种方式开发的大屏,在浏览器进行缩放,页面的内容不变)
 * 可以手动传入宽高,比如1920*1080或者3940*2160,
 * 以传入的尺寸进行开发
 * 如果没有传入,就默认电脑屏幕的宽高(以我的电脑为例,就是1920*1080)
 * 通过计算宽高和实际展示尺寸的比例,进行宽高的缩放
 */
export default function autoResize(props) {
  const largeScreenConRef = ref(null)
  const width = ref(0)
  const height = ref(0)
  // 可视区域的宽高
  const originalWidth = ref(0)
  const originalHeight = ref(0)

  onMounted(async () => {
    await initSize()
    updateSize()
    updateScale()
    // 使用debounce方法,页面进行缩放的时候,会出现先放大后缩小的情况,如果对这种情况敏感,可以将debounce方法去掉
    window.addEventListener('resize', debounce(1000, onResize))
  })

  onUnmounted(() => {
    window.removeEventListener('resize', onResize)
  })

  async function onResize() {
    await initSize()
    updateScale()
  }

  function initSize() {
    return new Promise((resolve) => {
      nextTick(() => {
        const dom = largeScreenConRef.value
        // 获取大屏尺寸
        if (props.options.width && props.options.height) {
          width.value = props.options.width
          height.value = props.options.height
        } else {
          width.value = dom.clientWidth
          height.value = dom.clientHeight
        }

        // 获取画布尺寸
        // 只要赋值了,就不会再重复赋值了
        if (!originalWidth.value || !originalHeight.value) {
          originalWidth.value = window.screen.width
          originalHeight.value = window.screen.height
        }
        resolve()
      })
    })
  }

  function updateSize() {
    const dom = largeScreenConRef.value
    if (width.value && height.value) {
      dom.style.width = `${width.value}px`
      dom.style.height = `${height.value}px`
    } else {
      dom.style.width = `${originalWidth.value}px`
      dom.style.height = `${originalHeight.value}px`
    }
  }

  // 计算宽高比
  function updateScale() {
    // 获取真实的视口尺寸
    const currentWidth = document.body.clientWidth
    const currentHeight = document.body.clientHeight

    // 获取大屏最终的宽高
    const realWidth = width.value || originalWidth.value
    const realHeight = height.value || originalHeight.value

    // 计算缩放比
    const widthScale = currentWidth / realWidth
    const heightScale = currentHeight / realHeight

    const dom = largeScreenConRef.value
    dom.style.transform = `scale(${widthScale}, ${heightScale})`
  }

  return {
    largeScreenConRef
  }
}

备注

这种方案开发的大屏,在浏览器进行缩放,页面的内容不变

如有转载或 CV 的请标注本站原文地址