Newer
Older
KaiFengPC / src / components / Map / TimeLine.vue
@zhangdeliang zhangdeliang on 23 May 6 KB 初始化项目
<template>
  <div class="nf-timeline flex-row">
    <div class="nf-timeline-list flex-row" ref="ppp">
      <div
        :style="{ width: 100 / Number(list.length ? list.length : 20) + '%' }"
        class="nf-timeline-item flex-row"
        :class="[`timelineItem${i}`, i == list.length - 1 ? 'w-20' : '', Math.floor(index / 100) >= i ? 'node-check' : '']"
        v-for="(item, i) in list"
        :ref="`timelineItem${i}`"
        @click="(index = i * 100), $emit('checkTimeLineNode', index)"
        :key="item.id"
        @mousedown="dragStart($event, i)"
        @mousemove="dragging($event, i)"
        @mouseup="dragEnd($event, i)"
      >
        <el-tooltip class="box-item" effect="dark" :content="item.name" placement="top">
          <div class="nf-timeline-item-node flex-row">
            <!-- <span>{{ item.name }}</span> -->
          </div>
        </el-tooltip>
        <div class="nf-timeline-item-line" v-if="i != list.length - 1">
          <div
            :style="{
              width: `${Math.floor(index / 100) - 1 >= i ? 100 : index % 100}%`,
            }"
            v-if="i * 100 < index"
          ></div>
        </div>
      </div>
    </div>
    <div
      class="nf-timeline-buttom flex-row"
      :class="{ 'nf-timeline-play': !status }"
      :title="!status ? '播放' : '暂停'"
      @click="status ? stop() : start()"
    >
      <!-- <div></div> -->
      <img
        :src="status ? getImageUrl('zanting_icon.png', 'newImgs/HaiMianScreen') : getImageUrl('kaisshi_icon.png', 'newImgs/HaiMianScreen')"
        alt=""
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'TimeLine',
  props: {
    list: {
      type: Array,
      default() {
        return [
          { id: 1, name: '2016', detail: '' },
          { id: 2, name: '2017', detail: '' },
          { id: 3, name: '2018', detail: '' },
          { id: 4, name: '2019', detail: '' },
          { id: 5, name: '2020', detail: '' },
          { id: 6, name: '2021', detail: '' },
        ];
      },
    },
    params: {
      type: Object,
      default() {
        return {
          nodeTime: 1,
        };
      },
    },
  },
  data() {
    return {
      interval: null,
      index: -1,
      draggingindex: 0,
      status: false,
      draggingElement: null,
      initialMousePosition: null,
      initialElementPosition: null,
    };
  },
  methods: {
    dragStart(event, index) {
      if (event.button !== 0 || !this.$refs[`timelineItem${index}`]) return; // Only handle left mouse button and ensure element ref exists
      const target = this.$refs[`timelineItem${index}`];
      if (!target) return;
      this.draggingElement = target;
    },
    dragging(event, indexs) {
      if (!this.draggingElement) return;
      this.index = indexs * 100;
      if (indexs == 0) {
        this.index = -1;
      }
    },
    dragEnd(event, indexs) {
      if (!this.draggingElement) return;

      this.draggingElement = null;
      this.initialMousePosition = null;
      this.initialElementPosition = null;

      // Restore text selection after dragging
      document.body.style.userSelect = '';
    },
    start() {
      let self = this;
      if (self.interval) {
        self.destroy();
        self.interval = null;
      }
      self.interval = setInterval(() => {
        self.index += 1;
        if (self.index >= (self.list.length - 1) * 100) (self.index = -1), (self.status = false), clearInterval(self.interval);
        // if (self.index >= (self.list.length - 1) * 100) self.index = 0;
        this.$emit('getTimeLineIndex', self.index);
      }, 10 * self.params.nodeTime);
      self.status = true;
    },
    stop() {
      let self = this;
      self.destroy();
      self.status = false;
    },
    destroy() {
      let self = this;
      clearInterval(self.interval);
    },
  },
  mounted() {},
  destroyed() {
    let self = this;
    self.destroy();
  },
};
</script>

<style scoped>
div {
  box-sizing: border-box;
}
.nf-timeline {
  /*position: absolute;*/
  z-index: 9999;
  bottom: 0px;
  left: 0;
  width: 100%;

  /*min-height: 100px;*/
  /*padding:15px 20px 0 20px;*/
  justify-content: flex-start !important;
  align-items: flex-start !important;
  /* background: rgba(6, 31, 64, 0.5); */
}

.nf-timeline-buttom {
  width: 40px;
  height: 40px;
  /* border: 3px solid rgba(12, 89, 165, 1); */
  margin-top: -8px;
  cursor: pointer;
  border-radius: 100%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

.nf-timeline-buttom > div {
  width: 50%;
  height: 50%;
  border: 1px solid rgba(12, 89, 165, 1);
  background: rgba(12, 89, 165, 1);
  transition: all 0.2s ease-in;
}

.nf-timeline-play > div {
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-left: 13px solid rgba(12, 89, 165, 1);
  border-right: 8px solid transparent;
  background: transparent;
  /*left: 50%;*/
  transform: translateX(25%);
  /*border: 0px solid transparent !important;*/
  /*border-left: 40px solid rgba(12,89,165,1) !important;*/
}

.nf-timeline-list {
  width: calc(100% - 40px);
  height: 80%;
  padding-left: 20px;
  /* border-radius: 10px; */
}
.nf-timeline-list > :first-child {
  /* 样式应用于.container的第一个子元素 */
  border-radius: 10px;
  .nf-timeline-item-node {
    border-radius: 40px 0 0 40px;
  }
}
.nf-timeline-list > :last-child {
  /* 样式应用于.container的最后一个子元素 */
  border-radius: 10px;
  .nf-timeline-item-node {
    border-radius: 0 40px 40px 0;
  }
}
.nf-timeline-item {
  width: 100%;
  height: 100%;
  align-items: flex-start !important;
  justify-content: flex-start !important;
  cursor: pointer;
}

.nf-timeline-item-node {
  width: 20px;
  height: 10px !important;
  top: 9px;
  /* border-radius: 100%;
  border: 2px solid rgba(192, 196, 204, 1);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04); */
  position: relative;
  color: rgba(192, 196, 204, 1);
  background: rgba(192, 196, 204, 1);
  cursor: pointer;
}

.node-check > .nf-timeline-item-node {
  /* border: 2px solid rgba(12, 89, 165, 1) !important; */
  width: 20px;
  height: 10px !important;
  top: 9px;
  position: relative;
  color: #37d9fa !important;
  background: #37d9fa;
}

.nf-timeline-item-node > span {
  position: relative;
  top: 30px;
}

.nf-timeline-item-line {
  height: 10px !important;
  /* width: calc(100% - 20px); */
  width: 100%;
  position: relative;
  top: 9px;
  background: rgba(192, 196, 204, 1);
}

.nf-timeline-item-line > div {
  height: 100%;
  width: 0;
  background: #37d9fa;
}

.flex-row {
  display: flex;
  justify-content: center;
  align-items: center;
}

.flex-column {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-flow: column nowrap;
}

.w-20 {
  width: 20px !important;
}

.node-check {
  width: 100%;
}
.node-check > div {
  height: 100%;
  width: 100%;
  background: #37d9fa;
}
</style>