<template>
  <div
    ref="ScaleBox"
    v-dragbox
    class="ScaleBox"
    :style="{
      width: boxWidth + 'px',
      height: boxHeight + 'px'
    }"
  >
    <slot v-if="inited" />
  </div>
</template>

<script>
import { createDebounce } from '@/utils'

export default {
  name: 'ScaleBox',
  props: {
    /**
     * 使用父元素的宽高计算缩放比例
     */
    useParentSize: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    width: {
      type: Number,
      default: () => {
        return 0
      }
    },
    height: {
      type: Number,
      default: () => {
        return 0
      }
    },
    // width/height
    screenRatio: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  emits: ['inited'],
  data() {
    return {
      boxHeight: 0,
      boxWidth: 0,
      inited: false
    }
  },
  mounted() {
    this.setScale()
    window.addEventListener('resize', createDebounce(this.setScale, 300))
  },
  methods: {
    getRatio() {
      const ratioValue = this.useParentSize ? this.$el.parentElement.clientWidth / this.$el.parentElement.clientHeight : window.innerWidth / window.innerHeight
      let result = 0
      let minDiff = Infinity
      for (const ratio of this.screenRatio) {
        if (Math.abs(ratio - ratioValue) < minDiff) {
          result = ratio
          minDiff = Math.abs(ratio - ratioValue)
        }
      }
      return result
    },
    setScale() {
      // 获取到缩放比例，设置它

      let { width, height } = this
      const ratio = this.getRatio()
      if (ratio && width && !height) {
        height = width / ratio
      }
      if (ratio && !width && height) {
        width = ratio * height
      }
      this.boxHeight = height
      this.boxWidth = width
      const wh = (this.useParentSize ? this.$el.parentElement.clientHeight : window.innerHeight) / height
      const ww = (this.useParentSize ? this.$el.parentElement.clientWidth : window.innerWidth) / width

      const scale = ww < wh ? ww : wh
      if (this.$refs.ScaleBox) {
        this.$refs.ScaleBox.style.setProperty('--scale', scale)
      }
      this.$nextTick(() => {
        let clientHeight = this.$el.clientHeight
        let clientWidth = this.$el.clientWidth
        const timer = setInterval(() => {
          if (this.$el.clientHeight && this.$el.clientWidth) {
            if (this.$el.clientHeight === clientHeight && this.$el.clientWidth === clientWidth) {
              if (!this.inited) {
                this.$nextTick(() => {
                  this.$emit('inited')
                })
              }
              this.inited = true
              clearInterval(timer)
            } else {
              clientHeight = this.$el.clientHeight
              clientWidth = this.$el.clientWidth
            }
          }
        }, 1000)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
#ScaleBox {
  --scale: 1;
}
.ScaleBox {
  position: absolute;
  transform: scale(var(--scale)) translate(-50%, -50%);
  transform-origin: 0 0;
  left: 50%;
  top: 50%;
  transition: 0.3s;
  z-index: 999;
  // background: rgba(255, 0, 0, 0.3);
}
</style>
