<!-- 可拖拽的小球 封装 -->
<template>
  <div>
    <div ref="levitatedSphere"
      class="wrap"
      :style="{
        width: itemWidth + 'px',
        height: itemHeight + 'px',
        left: left + 'px',
        top: top + 'px',
      }"
      @click="handleClick">
      <svg-icon icon-class="tool"></svg-icon>
    </div>
    <!-- 工具抽屉 -->
    <el-drawer title="工具箱"
      v-model="drawer"
      append-to-body
      size="300px">
      <slot></slot>
    </el-drawer>
  </div>
</template>

<script setup>
const props = defineProps({
  itemWidth: {
    // 悬浮按钮宽度
    type: Number,
    default: 46,
  },
  itemHeight: {
    // 悬浮按钮高度
    type: Number,
    default: 46,
  },
  gapWidth: {
    // 距离屏幕左右两边距离
    type: Number,
    default: 10,
  },
  coefficientHeight: {
    // 从上到下距离比例
    type: Number,
    default: 0.85,
  }
})

const levitatedSphere = ref(null)
const top = ref(0)
const left = ref(0)
const clientWidth = ref(0)
const clientHeight = ref(0)
const drawer = ref(false)
const downPoint = reactive({})
const upPoint = reactive({})

const resize = () => {
  clientWidth.value = document.documentElement.clientWidth;
  clientHeight.value = document.documentElement.clientHeight;
  left.value = clientWidth.value - props.itemWidth - props.gapWidth;
  top.value = clientHeight.value * props.coefficientHeight;
}
resize()

onMounted(() => {
  window.addEventListener('resize', resize)
  nextTick(() => {
    const mousemove = (e) => {
      e.preventDefault();
        let touch = e;
        // 限制 left 和 top 的值，使其不会超出可视区域
        left.value = Math.max(props.gapWidth, Math.min(touch.clientX - 20, clientWidth.value - props.itemWidth - props.gapWidth));
        top.value = Math.max(0, Math.min(touch.clientY - 25, clientHeight.value - props.itemHeight));
    }
    levitatedSphere.value.addEventListener('mousedown', (e) => {
      e.preventDefault();
      levitatedSphere.value.style.transition = 'none';
      downPoint.x = e.clientX
      downPoint.y = e.clientY
      window.addEventListener('mousemove', mousemove);
    })
    levitatedSphere.value.addEventListener('mouseup', e => {
      levitatedSphere.value.style.transition = 'all 0.5s';
      if (left.value > document.documentElement.clientWidth / 2) {
        left.value = document.documentElement.clientWidth - props.itemWidth - props.gapWidth;
      } else {
        left.value = props.gapWidth;
      }
      upPoint.x = e.clientX
      upPoint.y = e.clientY
      window.removeEventListener('mousemove', mousemove);
    })
  });
})

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

const handleClick = () => {
  if (downPoint.x === upPoint.x && downPoint.y === upPoint.y) {
    drawer.value = !drawer.value
  }
}
</script>

<style lang="scss"
  scoped>
  .wrap {
    position: fixed;
    z-index: 9999;
    border-radius: 50%;
    background-color: var(--el-bg-color);
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
    display: flex;
    justify-content: center;
    align-items: center;
    transition: all 0.5s;
    font-size: 20px;
  }

  ::v-deep(.el-drawer__body) {
    padding: 10px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(auto-fill, 30px);
    /* 明确指定行高为100px */
    grid-auto-rows: 30px;
    /* 自动生成的行高也为100px */
    grid-gap: 20px 5px;
    /* 上下间距20px，左右间距5px */
    width: 100%;

    .el-button {
      width: 100%;
      margin: 0;
    }
  }

  @media (max-width: 768px) {
    .wrap {
      width: 30px;
      height: 30px;
      font-size: 16px;
    }
  }
</style>
