<template>
  <div>
    <el-input :value="input" :placeholder="placeholder" disabled>
      <template slot="append">
        <el-popover
          placement="right-start"
          title=""
          width="240"
          trigger="click"
        >
          <div
            style="display: flex;justify-content: space-around;    align-items: center;"
          >
            <div class="" style="width: 50px;text-align: left;">
              <el-row>
                <el-col>
                  <span>X</span>
                  <el-input v-model="shadowData.x" size="mini" />
                </el-col>
                <el-col>
                  <span>Y</span>
                  <el-input v-model="shadowData.y" size="mini" />
                </el-col>
              </el-row>
            </div>
            <div
              ref="box"
              class="box"
              :class="down?'down':''"
              :style="{height:size+'px',width:size+'px'}"
              @click="getMouseXY($event,1)"
              @mousedown="getMouseXY($event,1);down=true"
              @mouseup="down=false"
              @mousemove="getMouseXY($event)"
            >
              <span id="spot" :style="spotStyle">
                <i id="center" />
              </span>
              <span id="center-spot" :style="{top:size/2+'px',left:size/2+'px'}" />
              <div class="x-hr" :style="{top:size/2+'px'}" />
              <div class="y-hr" :style="{left:size/2+'px'}" />
              <div class="line" :style="lineStyle" />
            </div>
          </div>
          <div style="padding: 0 10px">
            <div style="display: flex;align-items: center;">
              <span class="u-m-r-10" style="width: 40px;">模糊</span>
              <el-slider v-model="shadowData.blur" style="width: calc(100% - 80px)" :max="20" @input="emitValue" />
            </div>
            <div style="display: flex;align-items: center;">
              <span class="u-m-r-10">颜色</span>
              <el-color-picker v-model="shadowData.color" size="mini" :show-alpha="true" @change="emitValue" />
            </div>
          </div>
          <el-button slot="reference">设置</el-button>
        </el-popover>
      </template>
    </el-input>
    <!--    <el-dialog :visible.sync="show" width="400px" append-to-body title="自定义海报" top="10vh" />-->
  </div>

</template>

<script>
export default {
  name: 'DkDropShadowInput',
  props: {
    placeholder: {
      default: '',
      type: String
    },
    value: {
      default: '0px 0px 0px rgba(0, 0, 0, 0)',
      type: String
    },
    size: {
      default: 120,
      type: Number
    },
    max: {
      default: 24,
      type: Number
    }
  },
  data() {
    return {
      show: false,
      down: false,
      position: {
        left: 0,
        top: 0
      },
      lineStyle: '',
      shadowData: {
        x: 0,
        y: 0,
        blur: 0,
        color: 'rgba(0, 0, 0, 0)'
      },
      input: ''
    }
  },
  computed: {
    spotStyle() {
      return {
        left: this.position.left + 'px',
        top: this.position.top + 'px'
      }
    }
  },
  watch: {
    'shadowData.x'() {
      this.position.left = (this.size / 2 + (this.shadowData.x / this.max) * this.size) || 0
      this.emitValue()
    },
    'shadowData.y'() {
      this.position.top = (this.size / 2 + (this.shadowData.y / this.max) * this.size) || 0
      this.emitValue()
    },
    'position.left'(val) {
      if (val > this.size) {
        this.position.left = this.size
      }
      if (val < 0) {
        this.position.left = 0
      }
      this.shadowData.x = parseInt((this.position.left - this.size / 2) / this.size * this.max)
    },
    'position.top'(val) {
      if (val > this.size) {
        this.position.top = this.size
      }
      if (val < 0) {
        this.position.top = 0
      }
      this.shadowData.y = parseInt((this.position.top - this.size / 2) / this.size * this.max)
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      var value = (this.value || '0px 0px 0px #000').trim()
      var match = value.match(/^(\d+px) (\d+px) (\d+px) (.+)$/)
      if (match) {
        this.shadowData.x = parseInt(match[1])
        this.shadowData.y = parseInt(match[2])
        this.shadowData.blur = parseInt(match[3])
        this.shadowData.color = match[4]
      } else {
        this.shadowData.x = 0
        this.shadowData.y = 0
        this.shadowData.blur = 0
        this.shadowData.color = '#000'
      }
      this.position.top = (this.size / 2 + (this.shadowData.y / this.max) * this.size) || 0
      this.position.left = (this.size / 2 + (this.shadowData.x / this.max) * this.size) || 0
    },
    getMouseXY(e, force) {
      if (this.down || force) {
        var box = this.$refs.box.getBoundingClientRect()
        this.position.left = parseInt(e.pageX - box.x)
        this.position.top = parseInt(e.pageY - box.y)
      }
    },
    emitValue() {
      this.input = this.shadowData.x + 'px ' + this.shadowData.y + 'px ' + (this.shadowData.blur || 5) + 'px ' + (this.shadowData.color || '#000')
      this.$emit('input', this.input)
    },
    createLineElement(x, y, length, angle) {
      var box = this.$refs.box.getBoundingClientRect()
      this.lineStyle =
        'width: ' + length + 'px; ' +
        'height: 1px; background:#1989fa;' +
        '-moz-transform: rotate(' + angle + 'rad); ' +
        '-webkit-transform: rotate(' + angle + 'rad); ' +
        '-o-transform: rotate(' + angle + 'rad); ' +
        '-ms-transform: rotate(' + angle + 'rad); ' +
        'position: absolute; ' +
        'top: ' + (y - box.y) + 'px; ' +
        'left: ' + (x - box.x) + 'px; '
    },
    createLine(x1, y1, x2, y2) {
      var a = x1 - x2
      var b = y1 - y2
      var c = Math.sqrt(a * a + b * b)

      var sx = (x1 + x2) / 2
      var sy = (y1 + y2) / 2

      var x = sx - c / 2
      var y = sy

      var alpha = Math.PI - Math.atan2(-b, a)

      return this.createLineElement(x, y, c, alpha)
    },
    getElementOffset(element) {
      const offset = { left: 0, top: 0 }
      let current = element.offsetParent

      offset.left += element.offsetLeft
      offset.top += element.offsetTop

      while (current !== null) {
        offset.left += current.offsetLeft
        offset.top += current.offsetTop
        current = current.offsetParent
      }
      return offset
    },
    drawLine(id1, id2) {
      var xy1 = this.getElementOffset(document.getElementById(id1))
      var xy2 = this.getElementOffset(document.getElementById(id2))
      var height1 = document.getElementById(id1).offsetHeight
      var w1 = document.getElementById(id1).offsetWidth
      var w2 = document.getElementById(id2).offsetWidth
      this.createLine(xy1.left + (w1 / 2), xy1.top + height1, xy2.left + (w2 / 2), xy2.top)
    }
  }
}
</script>

<style scoped lang="scss">
.box {
  border: 1px solid #ccc;
  border-radius: 5px;
  background: #f6f6f6;
  position: relative;
  cursor: pointer;
  overflow: hidden;

  #spot {
    position: absolute;
    width: 0;
    height: 0;
    border-radius: 100%;

    #center {
      position: absolute;
      top: -5px;
      left: -5px;
      width: 10px;
      height: 10px;
      background: #1989fa;
      border-radius: 100%;
      z-index: 9;
    }
  }

  &.down #center {
    box-shadow: 1px 1px 10px 2px #1989fa;
  }

  #center-spot {
    position: absolute;
    width: 0;
    height: 0;
    border-radius: 100%;
    background: #1989fa;
  }

  .x-hr {
    width: 100%;
    position: absolute;
    height: 1px;
    background: #ccc;
  }

  .y-hr {
    height: 100%;
    position: absolute;
    width: 1px;
    background: #ccc;
  }
}
</style>
