美文网首页
vue2 视频时间轴/时间刻度尺组件

vue2 视频时间轴/时间刻度尺组件

作者: 时间煮鱼 | 来源:发表于2023-03-24 13:52 被阅读0次
    20230325_134435_convert_1.gif

    借鉴代码gitee地址,vue3版本,改写成vue2并修改部分方法

    <video-timeline ref="videoTimeLine" @changCurrentTime="changCurrentTime" :videoRecords="videoRecords" />
    
    data() {
        return {
          videoRecords: {}
        };
      },
    methods: {
      changCurrentTime(time) {
          console.log(this.$moment(new Date(time * 1000)).format('YYYY-MM-DD hh:mm:ss'))
        }
    }
    
    
    <template>
      <div>
        <div v-if="tipShow" id="tooltip_div">{{ pointTime }}</div>
        <canvas id="is_select_time" :width="width" height="50"></canvas>
        <canvas id="time_line" :width="width" height="50"></canvas>
        <canvas id="time_line_layer" :width="width" height="50"></canvas>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        width: {
          //时间轴宽度
          default: 1000
        },
        videoRecords: {
          type: Object,
          default: () => {
            return {};
          }
        }
      },
      data() {
        return {
          currentTime: parseInt(new Date().getTime() / 1000),
          mouseSite: 0,
          tipShow: false,
          allowDarw: true
        };
      },
      computed: {
        pointTime() {
          let d = this.getTime(
            this.currentTime +
              this.mouseSite * 2 -
              (this.currentTime % 2) -
              parseInt(this.width)
          );
          return `${d[0]}-${d[1]}-${d[2]} ${d[3]}:${d[4]}:${d[5]}`;
        }
      },
      watch: {
        currentTime(val) {
          if (this.allowDarw) {
            this.timeChange(this.width, val);
          }
        },
        width(val) {
          if (this.allowDarw) {
            this.timeChange(val, this.currentTime);
          }
        },
        videoRecords(val) {
          if (this.allowDarw) {
            const currentTime = (val.startTime + val.endTime) / 2;
            this.currentTime = currentTime;
            this.timeChange(this.width, currentTime);
          }
        }
      },
      mounted() {
        this.timeChange(this.width, this.currentTime);
        this.addanvasEvent();
      },
      methods: {
        drawLine(beginX, beginY, endX, endY, color, width) {
          let canvasId = document.getElementById("time_line");
          let ctx = canvasId.getContext("2d");
          ctx.beginPath();
          ctx.moveTo(beginX, beginY);
          ctx.lineTo(endX, endY);
          ctx.strokeStyle = color;
          ctx.lineWidth = width;
          ctx.stroke();
        },
        pointSite(e) {
          this.mouseSite = e.layerX;
          this.tipShow = true;
          this.$nextTick(() => {
            let ele = document.getElementById("tooltip_div");
            ele.style.left = e.x - 200 + "px";
            ele.style.top = e.y - e.layerY - 132 + "px";
          });
        },
        // canvas 事件
        addanvasEvent() {
          let canvasId = document.getElementById("time_line_layer");
          canvasId.onmouseleave = e => {
            this.tipShow = false;
            canvasId.onmousemove = e => {
              this.pointSite(e);
            };
          };
          // 鼠标按下时的位置;
          let start = 0;
          // 鼠标按下时的currentTime
          let oldTime = 0;
          canvasId.onmousedown = e => {
            // this.allowDarw = false;
            start = e.layerX;
            oldTime = this.currentTime;
            canvasId.onmousemove = e1 => {
              this.tipShow = false;
              let end = e1.layerX;
              let current = (start - end) / 2 + oldTime;
    
              this.currentTime = current;
              // this.timeChange(this.width, current);
            };
          };
          // 鼠标弹起向外传出当前时间
          canvasId.onmouseup = e => {
            let end = e.layerX;
            let current = (start - end) / 2 + oldTime;
            this.$emit("changCurrentTime", current);
            this.allowDarw = true;
            canvasId.onmousemove = e1 => {
              this.pointSite(e1);
            };
          };
    
          canvasId.onmousemove = e => {
            this.pointSite(e);
          };
        },
        // 计算时间偏移并画线,时间刻度线,半时短线,小时长线,2像素代表1秒钟
        carveTimeScale(width, currentTime) {
          let canvasId = document.getElementById("time_line");
          let ctx = canvasId.getContext("2d");
          ctx.clearRect(0, 0, width, 50);
          ctx.font = "12px Arial";
    
          // 将当前时间减去到时间轴中部所需秒,得到时间轴起点秒数
          let remainder = parseInt(currentTime) - parseInt((width / 2) * 2);
          for (var i = 0; i < width * 2; i++) {
            // 分;
            if ((remainder + i) % 60 == 0) {
              this.drawLine(i / 2, 0, i / 2, 5, "white", 1);
            }
            // 刻;
            if ((remainder + i) % (60 * 15) == 0) {
              this.drawLine(i / 2, 0, i / 2, 10, "white", 1);
              let d = this.getTime(remainder + i);
              ctx.fillStyle = "white";
              ctx.fillText(`${d[3]}:${d[4]}:${d[5]}`, i / 2, 25);
            }
    
            // 半时;
            if ((remainder + i) % (60 * 30) == 0) {
              this.drawLine(i / 2, 0, i / 2, 15, "white", 1);
              let d = this.getTime(remainder + i);
              ctx.fillStyle = "white";
              ctx.fillText(`${d[3]}:${d[4]}:${d[5]}`, i / 2, 25);
            }
    
            // 时;
            if ((remainder + i) % (60 * 60) == 0) {
              this.drawLine(i / 2, 0, i / 2, 20, "white", 1);
              let d = this.getTime(remainder + i);
              ctx.fillStyle = "white";
              ctx.fillText(`${d[3]}:${d[4]}:${d[5]}`, i / 2, 25);
            }
          }
        },
        // 有视频的区域渲染颜色
        carveVideoScope(width, currentTime) {
          let canvas = document.getElementById("is_select_time");
          let ctx = canvas.getContext("2d");
          ctx.clearRect(0, 0, width, 50);
    
          if (this.$isEmpty(this.videoRecords)) {
            return;
          }
          let startPoint =
            parseInt(this.videoRecords.startTime) -
            currentTime +
            parseInt(width / 2);
          let endPoint =
            parseInt(this.videoRecords.endTime) - currentTime + parseInt(width / 2);
    
          // 起点不能为负数,
          startPoint = startPoint > 0 ? startPoint : 0;
          // 终点不能超出时间尺总长度。
          endPoint = endPoint < width ? endPoint : width;
          let w = endPoint - startPoint;
          ctx.fillStyle = "rgba(230,162,60, 0.7)";
          ctx.fillRect(startPoint, 0, w, 50);
        },
        getTime(timeStamp) {
          let date = new Date(timeStamp * 1000);
          let year = date.getFullYear();
          let month =
            date.getMonth() + 1 < 10
              ? "0" + (date.getMonth() + 1)
              : date.getMonth() + 1;
          let currentDate =
            date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
          let hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
          let minute =
            date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
          let second =
            date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
          return [year, month, currentDate, hour, minute, second];
        },
        // 时间轴中间指示当前时间刻度
        pointCurrent(width, time) {
          let canvasId = document.getElementById("is_select_time");
          let ctx = canvasId.getContext("2d");
          ctx.beginPath();
          ctx.moveTo(parseInt(width / 2), 0);
          ctx.lineTo(parseInt(width / 2), 35);
          ctx.strokeStyle = "blue";
          ctx.lineWidth = 1;
          ctx.stroke();
          ctx.font = "12px Arial";
          ctx.fillStyle = "white";
          let d = this.getTime(time);
          ctx.fillText(
            `${d[0]}-${d[1]}-${d[2]} ${d[3]}:${d[4]}:${d[5]}`,
            parseInt(width / 2) - 50,
            48
          );
        },
        // 当前时间改变,重绘刻度,指针,时间
        timeChange(width, time) {
          this.carveVideoScope(width, time);
          this.carveTimeScale(width, time);
          this.pointCurrent(width, time);
        }
      }
    };
    </script>
    
    <style scoped>
    #time_line {
      background-color: rgb(0, 255, 234, 0);
      position: absolute;
    }
    #is_select_time {
      background-color: gray;
      position: absolute;
    }
    #time_line_layer {
      background-color: rgb(0, 255, 234, 0);
      position: absolute;
    }
    #tooltip_div {
      background-color: rgb(50, 121, 115);
      color: #fff;
      position: absolute;
      width: 100px;
      text-align: center;
      padding: 10px;
      z-index: 2;
    }
    </style>
    

    this.$isEmpty是判断为空

    export function isEmpty(value) {
      switch (typeof value) {
        case 'undefined':
          return true;
        case 'string':
          if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
          break;
        case 'boolean':
          if (!value) return true;
          break;
        case 'number':
          if (0 === value || isNaN(value)) return true;
          break;
        case 'object':
          if (null === value || value.length === 0) return true;
          for (var i in value) {
            return false;
          }
          return true;
      }
      return false;
    }
    

    相关文章

      网友评论

          本文标题:vue2 视频时间轴/时间刻度尺组件

          本文链接:https://www.haomeiwen.com/subject/bcowrdtx.html