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";
// 將當前時間減去到時間軸中部所需秒,得到時間軸起點秒數(shù)
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);
}
}
},
// 有視頻的區(qū)域渲染顏色
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);
// 起點不能為負數(shù)草姻,
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;
}