可视化大屏适配方案

234 阅读1分钟

scale方案

公用组件 ScreenAdapter.vue

<template>
    <div
      id="adapter"
      class="ScreenAdapter"
      :style="style"
    >
      <slot />
    </div>
  </template>
  <script>
  export default {
    name: '',
    // 参数注入
    props: {
      width: {
        type: String,
        required: true
      },
      height: {
        type: String,
        required: true
      },
      // 外边距
      outer: {
        type: Number,
        default: 0
      }
    },
    data() {
      return {
        transform: 'scale(1) translate(-50%, -50%)'
      }
    },
    computed: {
      style() {
        return {
          width: this.width + 'px',
          height: this.height + 'px',
          transform: this.transform
        }
      }
    },
    watch: {
      style: {
        handler() {
          this.setScale()
        },
        deep: true
      }
    },
    mounted() {
      this.setScale()
      window.onresize = this.Debounce(this.setScale, 1000)
    },
    methods: {
      Debounce: (fn, t) => {
        const delay = t || 500
        let timer
        return function() {
          const args = arguments
          if (timer) {
            clearTimeout(timer)
          }
          const context = this
          timer = setTimeout(() => {
            timer = null
            fn.apply(context, args)
          }, delay)
        }
      },
      // 获取放大缩小比例(谁小把谁撑满)
      getScale() {
        var ele = this.$el.parentNode
        // console.log(ele.getBoundingClientRect())
        // 获取父容器元素的宽高
        const w = (ele.getBoundingClientRect().width - this.outer) / this.width
        const h = (ele.getBoundingClientRect().height - this.outer) / this.height
        return w < h ? w : h
      },
      // 设置比例
      setScale() {
        const scale = this.getScale()
        this.transform = 'scale(' + scale + ') translate(-50%, -50%)'
        this.$emit('scaleChange', scale)
      }
    }
  }
  </script>
  <style lang="scss" scoped>
  .ScreenAdapter {
    transform-origin: 0 0;
    position: absolute;
    // 配合translate(-50%, -50%) 进行剧中
    left: 50%;
    top: 50%;
    transition: 0.3s;
    background: #F5F5F5;
  }
  </style>

使用组件index.vue

<template>
  <AutoFit :width="1920" :height="1080">
    <div class="screen-body">
      <h1>可视化大屏</h1>
    </div>
  </AutoFit>
</template>
  
<script setup>
import AutoFit from '../components/ScreenAdapter'

</script>
  
<style lang="scss" scoped>
.screen-body {
  width: 1920px;
  height: 1080px;
  background-color: #42b983;
  display: flex;
  justify-content: center;
  align-items: center;
}
h1 {
  margin: 0;
  padding: 0;
}
</style>