<template>
  <div class="ele-color-svpanel" :style="{backgroundColor: background}">
    <div class="ele-color-svpanel-white"></div>
    <div class="ele-color-svpanel-black"></div>
    <div
      class="ele-color-svpanel-cursor"
      :style="{top: cursorTop + 'px', left: cursorLeft + 'px'}">
    </div>
  </div>
</template>

<script>
import draggable from '../draggable';

export default {
  name: 'EleSvPanel',
  emits: ['change'],
  props: {
    // 色相
    hue: {
      type: Number,
      required: true
    },
    // 饱和度
    saturation: {
      type: Number,
      required: true
    },
    // 明度
    value: {
      type: Number,
      required: true
    }
  },
  data() {
    return {
      // 滑块位置top
      cursorTop: 0,
      // 滑块位置left
      cursorLeft: 0,
      // 色板背景色
      background: 'hsl(0, 100%, 50%)'
    };
  },
  mounted() {
    // 获取滑块的默认位置和色板的默认背景
    this.background = this.getBackground();
    this.cursorLeft = this.getCursorLeft();
    this.cursorTop = this.getCursorTop();
    // 色板绑定鼠标移动事件
    draggable(this.$el, {
      drag: (event) => {
        this.handleDrag(event);
      },
      end: (event) => {
        this.handleDrag(event);
      }
    });
  },
  methods: {
    /* 选中改变事件 */
    handleDrag(event) {
      const el = this.$el,
        rect = el.getBoundingClientRect();
      let left = event.clientX - rect.left;
      left = Math.max(0, left);
      left = Math.min(left, rect.width);
      let top = event.clientY - rect.top;
      top = Math.max(0, top);
      top = Math.min(top, rect.height);
      this.cursorLeft = left;
      this.cursorTop = top;
      this.$emit('change', {
        saturation: left / rect.width * 100,
        value: 100 - top / rect.height * 100
      });
    },
    /* 计算滑块位置top */
    getCursorTop() {
      let {clientHeight: height} = this.$el;
      return (100 - this.value) * height / 100;
    },
    /* 计算滑块位置left */
    getCursorLeft() {
      let {clientWidth: width} = this.$el;
      return this.saturation * width / 100;
    },
    /* 获取色板背景 */
    getBackground() {
      return 'hsl(' + this.hue + ', 100%, 50%)';
    }
  },
  watch: {
    hue() {
      this.background = this.getBackground();
    },
    saturation() {
      this.cursorLeft = this.getCursorLeft();
    },
    value() {
      this.cursorTop = this.getCursorTop();
    }
  }
};
</script>

<style>
.ele-color-picker .ele-color-svpanel {
  position: relative;
  height: 180px;
}

.ele-color-picker .ele-color-svpanel .ele-color-svpanel-white,
.ele-color-picker .ele-color-svpanel .ele-color-svpanel-black {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.ele-color-picker .ele-color-svpanel .ele-color-svpanel-white {
  background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
}

.ele-color-picker .ele-color-svpanel .ele-color-svpanel-black {
  background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
}

.ele-color-picker .ele-color-svpanel .ele-color-svpanel-cursor {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0, 0, 0, 0.3), 0 0 1px 2px rgba(0, 0, 0, 0.4);
  transform: translate(-2px, -2px);
  cursor: pointer;
}
</style>
