<!--
 * @Author: ShawnPhang
 * @Date: 2023-11-29 10:34:54
 * @Description: 角度手柄
 * @LastEditors: ShawnPhang <https://m.palxp.cn>
 * @LastEditTime: 2023-11-29 19:24:14
-->
<template>
  <div class="angle-input-box">
    <input ref="numInput" v-model="num" class="angle-input" @focus="visiable = true" @blur="visiable = false" @input="inputChange" />
    <div v-show="visiable" class="AngleHandle" @mousedown="touch($event, true)" @mouseup="touch($event, false)">
      <div class="angle" @mouseup="turn" @mousemove="turn">
        <div :style="`transform: rotate(${angleInDegrees}deg)`" class="line"></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch, computed } from 'vue'

export default defineComponent({
  props: ['modelValue'],
  emits: ['change', 'update:modelValue'],
  setup(props, { emit }) {
    const num = ref(90)
    const numInput = ref(null)
    const angleInDegrees = computed(() => {
      return num.value - 90
    })
    let inProcess = false
    const visiable = ref(false)

    const inputChange = (e: any) => {
      emit('change', e)
    }
    watch(
      () => num.value,
      (v) => {
        props.modelValue !== num.value && emit('update:modelValue', v)
        emit('change')
      },
    )
    watch(
      () => props.modelValue,
      (v) => {
        num.value = v
      },
    )

    const turn = (e: any) => {
      if (!inProcess) {
        return
      }
      const origin = { x: 27, y: 27 }
      // 计算相对于原点的坐标差值
      const deltaX = e.offsetX - origin.x
      const deltaY = e.offsetY - origin.y
      // 计算夹角（弧度）
      const angleInRadians = Math.atan2(deltaY, deltaX)
      // 将弧度转换为角度
      const angleInDegrees = (angleInRadians * 180) / Math.PI
      num.value = Math.round(angleInDegrees + 90)
    }

    const touch = (e: any, isHandle: boolean) => {
      e.preventDefault()
      inProcess = isHandle
    }
    return { inputChange, num, turn, touch, angleInDegrees, numInput, visiable }
  },
})
</script>

<style lang="less">
.angle-input {
  width: 38px;
  margin-left: 5px;
  padding: 0 0 0 4px;
  border: 1px solid #e8eaec;
  border-radius: 4px;
  position: relative;
}
.angle-input-box {
  position: relative;
}
.angle-input-box::after {
  content: '°';
  width: 5px;
  height: 2px;
  position: absolute;
  right: 2px;
  top: 0;
}

.AngleHandle {
  position: absolute;
  z-index: 2;
  right: 2px;
  margin-top: 3px;
  background: #ffffff;
  width: 60px;
  height: 60px;
  border-radius: 7px;
  box-shadow: 0 0 2px rgb(0 0 0 / 60%);
  display: flex;
  align-items: center;
  justify-content: center;
  .angle {
    width: 54px;
    height: 54px;
    position: relative;
    overflow: hidden;
    background: #f1f2f4;
    border-radius: 50%;
    user-select: none;
    cursor: pointer;
  }
  .line {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 50%;
    height: 1px;
    background: #999999;
    pointer-events: none;
    transform-origin: left top;
  }
  .line::before {
    position: absolute;
    content: '';
    left: -1px;
    top: -1px;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: #999999;
  }
  .line::after {
    position: absolute;
    content: '';
    right: 0;
    top: -2px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #999999;
  }
}
</style>
