<script>
/**
 * vs-timeaxis 2022-05-27
 *
 * marks 时间轴刻度值 []
 * autoplay 是否自动播放 true
 * duration 播放间隔时间 1000ms
 * cbplay 是否使用回调模式 false  //为true时则duration属性无效
 * tooltip 是否始终展示tooltip true
 * loop 是否循环播放 false
 *
 * @change 手动改变时间轴回调
 * @play 播放时回调
 * @suspend 暂停时回调
 *
 * listener 触发回调告知组件调用方法
 *
 */
export default {
  name: "vs-timeaxis",
};
</script>
<script setup>
import {
  ref,
  reactive,
  onMounted,
  onBeforeUnmount,
  watch,
  nextTick,
  getCurrentInstance
} from "vue";
const props = defineProps({
  marks: {
    type: Array,
    default: () => [],
  },
  autoplay: {
    type: Boolean,
    default: true,
  },
  duration: {
    type: Number,
    default: 1000,
  },
  cbplay: {
    type: Boolean,
    default: false,
  },
  tooltip: {
    type: Boolean,
    default: true,
  },
  loop: {
    type: Boolean,
    default: false,
  },
});

const { proxy } = getCurrentInstance();

const slider = reactive({
  value: 0,
  step: 1,
  marks: {},
  max: props.marks.length - 1,
  tooltip: [],
});

props.marks.forEach((item, index) => {
  slider.marks[index] = item;
  slider.tooltip.push(item.label);
});

const formatTooltip = function (item) {
  return slider.tooltip[item];
};

const emit = defineEmits(["change", "play", "suspend"]);

//动态设置展示文字数量
const vsTimeaxis = ref(null);

onMounted(() => {
  const _wTimeaxis = vsTimeaxis.value.offsetWidth;
  let _wMarks = vsTimeaxis.value.getElementsByClassName(
    "el-slider__marks-text"
  )[0].offsetWidth;
  const num = Math.floor(_wTimeaxis / _wMarks);

  if (props.marks.length / num > 1) {
    const len = Math.floor(props.marks.length / num);
    const split = len % 2 === 0 ? len + 1 : len + 2;
    for (let key in props.marks) {
      if (key % split !== 0) {
        props.marks[key].label = "";
      }
    }
  }
  if (props.autoplay) {
    autoplay();
  }
});

//组件销毁
onBeforeUnmount(() => {
  if (!props.cbplay) {
    clearInterval(plays.interval);
    plays.interval = null;
  }
});

//拖动滑块监听
//tooltip
const style = reactive({
  tooltip: {
    left: "0px",
    top: "-35px",
  },
});
watch(
  () => slider.value,
  (item) => {
    // //深拷贝，移除响应式
    // const _itemClone = proxy.$lodash.cloneDeep(slider.marks[item]);

    emit("change", slider.marks[item]);

    //tooltip实时改变位置
    if (props.tooltip) {
      nextTick(() => {
        const _w =
          document.getElementsByClassName("el-slider__bar")[0].offsetWidth;
        style.tooltip.left = _w + "px";
      });
    }
  }
);

//时间轴播放事件
const plays = reactive({
  interval: null,
  show: false,
});
plays.show = props.autoplay;
const sliderUp = function () {
  //暂停下return
  if (!plays.show) return;

  if (!props.loop && slider.value === slider.max) {
    if (!props.cbplay) {
      clearInterval(plays.interval);
      plays.interval = null;
    }
    plays.show = !plays.show;
    return;
  }

  if (slider.value === slider.max) {
    slider.value = 0;
  } else {
    slider.value += 1;
  }

  // //深拷贝，移除响应式
  // const _itemClone = proxy.$lodash.cloneDeep(slider.marks[slider.value]);

  emit("play", slider.marks[slider.value]);
};

const autoplay = function () {
  if (!props.cbplay) {
    plays.interval = setInterval(() => {
      sliderUp();
    }, props.duration);
  }
};

//暂停
const suspendHandle = function () {
  if (!props.cbplay) {
    clearInterval(plays.interval);
    plays.interval = null;
  }

  plays.show = !plays.show;


  // //深拷贝，移除响应式
  // const _itemClone = proxy.$lodash.cloneDeep(slider.marks[slider.value]);

  emit("suspend", slider.marks[slider.value]);
};

//播放
const playHandle = function () {
  if (slider.value === slider.max) {
    slider.value = 0;
  }

  if (props.cbplay) {
    sliderUp();
  } else {
    autoplay();
  }
  plays.show = !plays.show;
};

//父组件回调触发更新
const listener = function () {
  if (props.cbplay) {
    sliderUp();
  }
};

defineExpose({
  listener,
});
</script>

<template>
  <div class="vs-timeaxis" ref="vsTimeaxis">
    <div class="vs-timeaxis--left">
      <el-icon v-if="plays.show" @click="suspendHandle">
        <VideoPlay />
      </el-icon>
      <el-icon v-else @click="playHandle">
        <VideoPause />
      </el-icon>
    </div>

    <div class="vs-timeaxis--right">
      <el-slider v-model="slider.value" :step="slider.step" :max="slider.max" show-stops :marks="marks"
        :format-tooltip="formatTooltip" />
      <div v-if="props.tooltip" :style="style.tooltip" class="vs-timeaxis--tooltip">
        {{ slider.tooltip[slider.value] }}
      </div>
    </div>
  </div>
</template>

<style  lang="scss" scope>
$main: var(--main);
$auxiliary: var(--auxiliary);
$light: var(--light);

.vs-timeaxis {
  padding: 0px 15px;
  box-sizing: border-box;
  display: flex;
  justify-content: space-around;

  .vs-timeaxis--left {
    width: 10%;

    i {
      font-size: 25px;
      font-weight: bold;
      margin-top: 4px;
      cursor: pointer;
    }
  }

  .vs-timeaxis--right {
    width: 90%;
    position: relative;

    .vs-timeaxis--tooltip {
      position: absolute;
      background: $main;
      color: #fff;
      padding: 10px;
      border-radius: 3px;
      transform: translateX(-50%);
      white-space: nowrap;
      text-align: center;
    }

    .vs-timeaxis--tooltip::after {
      content: "";
      position: absolute;
      top: 100%;
      left: 50%;
      transform: translateX(-50%);
      width: 0px;
      height: 0px;
      border: 5px solid $main;
      border-top-color: $main;
      border-bottom-color: transparent;
      border-left-color: transparent;
      border-right-color: transparent;
    }
  }

  .el-slider__button {
    border: 2px $main solid;
    width: 18px;
    height: 18px;
  }

  .el-slider__bar {
    background: $main;
    border-radius: 0;
  }

  .el-slider__stop {
    background: $auxiliary;
    border-radius: 0;
    width: 2px;
  }

  .el-slider__marks-text {
    color: #fff;
    white-space: nowrap;
  }

  .el-slider__marks-text:nth-child(even) {
    margin-top: -25px;
  }
}
</style>
