<template>
  <div
    :style="[isShow]"
    class="sliderContainer"
    :class="sliderType == 'h' ? 'scroll-h' : 'scroll-v'"
    ref="sliderContainer"
    @wheel.capture.stop="handlewheel"
  >
    <div
      class="scroll-slider"
      :style="[initSize, initLength, loc]"
      @mousedown.stop="sliderMousedown"
    ></div>
  </div>
</template>
<script>
function on(dom, eventType, callback) {
  if (document.addEventListener) {
    dom.addEventListener(eventType, callback);
  } else {
    dom.attachEvent("on" + eventType, callback);
  }
}
function off(dom, eventType, callback) {
  if (document.removeEventListener) {
    dom.removeEventListener(eventType, callback);
  } else {
    dom.detachEvent("on" + eventType, callback);
  }
}

export default {
  props: {
    //滚动条类型：h:水平滚动条，v:垂直滚动条
    sliderType: {
      type: String,
      default: "v",
    },
    //滚动条最小长度
    minLength: {
      type: Number,
      default: 20,
    },
    size: {
      type: Number,
      default: 8,
    },
    scrollTop: {
      type: Number,
      default: 0,
    },
    scrollLeft: {
      type: Number,
      default: 0,
    },
    color: {
      type: String,
      default: "#000000",
    },
    opacity: {
      type: Number,
      default: 0.3,
    },
  },
  created() {
    //水平滚动条配置
    let h = {
      clientSize: "clientWidth",
      loc: "top",
      scrollSize: "scrollWidth",
      locsSize: "scrollHeight",
      loccSize: "clientHeight",
    };
    let v = {
      clientSize: "clientHeight",
      loc: "left",
      scrollSize: "scrollHeight",
      locsSize: "scrollWidth",
      loccSize: "clientWidth",
    };
    this.config = this.sliderType === "h" ? h : v;
  },
  data() {
    return {
      isBind: false, //标识是否已经绑定拖动事件，避免重复绑定
      percentage: 0,
      length: 0,
      startMove: false,
      offset: 0,
      position: {},
      config: {},
      isShowSilider: true,
      locValue: 0,
    };
  },
  computed: {
    initSize() {
      return {
        [this.sliderType === "h" ? "height" : "width"]: this.size + "px",
      };
    },
    //初始长度
    initLength() {
      return {
        [this.sliderType === "h" ? "width" : "height"]: this.length + "px",
      };
    },
    //初始位置
    loc() {
      return {
        [this.sliderType === "h" ? "left" : "top"]: this.offset + "px",
      };
    },
    //是否显示，隐藏即放到视野外
    isShow() {
      return {
        [this.config.loc]: this.isShowSilider
          ? this.locValue - this.size + "px"
          : "-" + this.siz + "px",
      };
    },
  },
  methods: {
    sliderMousedown(event) {
      // 只有鼠标左键可以拖动
      if (event.button !== 0) {
        return;
      }
      event.preventDefault();
      event.stopPropagation();
      event.stopImmediatePropagation();

      this.startMove = true;
      this.position.x = event.clientX;
      this.position.y = event.clientY;
      this.bindEvent();
    },
    bindEvent() {
      if (this.isBind) {
        return;
      }
      on(document, "mouseup", this.mouseup);
      on(document, "mousemove", this.mousemove);
      this.isBind = true;
      this.startMove = true;
    },
    mouseup() {
      this.startMove = false;
      this.isBind = false;
      off(document, "mouseup", this.mouseup);
      off(document, "mousemove", this.mousemove);
    },
    mousemove(event) {
      if (!this.startMove) return;
      let x = event.clientX;
      let y = event.clientY;
      let moveX = x - this.position.x;
      let moveY = y - this.position.y;
      this.position.x = x;
      this.position.y = y;
      let move = this.sliderType === "h" ? moveX : moveY;
      this.computePosition(move);
    },
    computePosition(move) {
      let newloc = this.offset + move;
      if (newloc > this.maxOffset) {
        newloc = this.maxOffset;
      }
      if (newloc < 0) newloc = 0;
      this.offset = newloc;
      this.$emit("change", newloc / this.percentage);
    },
    //计算滑块的一些属性
    computeSlider(scroll, client) {
      //内容真实长度或宽度
      let scrollSize = scroll[this.config.scrollSize];
      //容器的长度或宽度
      let clientSize = client[this.config.clientSize];
      let containerSize = this.$refs.sliderContainer[this.config.clientSize];
      this.length = containerSize * (clientSize / scrollSize);
      if (this.length < this.minLength) {
        this.length = this.minLength;
      }
      if (clientSize >= scrollSize) {
        this.length = 0;
      }
      //最大偏移距离
      this.maxOffset = containerSize - this.length;
      if (scrollSize - clientSize == 0) {
        this.percentage = 0;
      } else {
        this.percentage = this.maxOffset / (scrollSize - clientSize);
      }
      this.isShowSilider = this.percentage > 0 && this.percentage < 1;
      let locsSize = scroll[this.config.locsSize];
      let loccSize = client[this.config.loccSize];
      //防止内容宽度比容器小的时候垂直滚动条和内容有距离
      this.locValue = locsSize < loccSize ? locsSize : loccSize;
    },
    handlewheel(event) {
      console.log(event);
    },
  },
  watch: {
    scrollTop() {
      this.offset = this.scrollTop * this.percentage;
    },
    scrollLeft() {
      this.offset = this.scrollLeft * this.percentage;
    },
  },
  destroyed() {
    off(document, "mouseup", this.mouseup);
    off(document, "mousemove", this.mousemove);
  },
};
</script>