本来是不想画轮子的,接口搜一些文章要么没有自己想要的,要么就是开通VIP才能观看。本着白嫖党永不为奴的原则,只能自己搞了开源给大家提供思路一起进步了!!!
本组件使用vue+canvas构建,开箱即用,模仿海康视频监控中心类似的功能一把手搭建,有大大优化或者改进了更好的版本也请求开源共享哦。
如果有帮助或者给了思路请英雄点个赞吧
白嫖党永不为奴!!!
视频监控时间进度条
<template>
<div>
<div>
<button @click="onTime(12, 24)">12小时</button>
<button @click="onTime(24, 12)">24小时</button>
<button @click="onTime(48, 6)">30分钟</button>
<button @click="onTime(144, 2)">10分钟</button>
<button @click="onTime(288, 1)">5分钟</button>
</div>
<canvas
style="background: #fff"
id="mymyCanvas"
:width="width"
:height="height"
ref="canvasRef"
></canvas>
</div>
</template>
<script>
export default {
data() {
return {
// 画布实例
myCanvas: null,
ctx: null,
width: 1200,
height: 50,
// 偏移量的copy
curOffset: {
x: 600,
},
// 最终偏移量,默认600(width/2为画布的中心)
offset: {
x: 600,
},
x: 0,//鼠标按下的e.x值(用于计算最终偏移量)
timeNum: 12,//时间间隙 12=2小时一个间隔 1px=24s;24=1小时 1=12s;48=30分钟 1=6s;144=10分钟 1=2s;288=5分钟 1=1s
timeRatio: 24,//时间比值,1px等于多少秒
ymd: '2022-10-27',//根据选中的日期进行传入
hms: null,//存中心基准线上的时分秒-转换成秒后根据切换的时间比值来得到px偏移量
};
},
watch: {
hms(val) {
// console.log('监听的时分秒===',val,this.offset.x)
},
timeNum(val) {
// console.log('-----timeNum----',val)
},
timeRatio(val) {
// console.log('-----timeRatio----',val)
},
},
mounted() {
// 画布初始化
this.canvasInit();
this.canvasSize();
// 画布坐标便宜量
this.ctx.translate(this.offset.x, 0);
// 基准线
this.baselineFun(this.offset.x)
// 水平线
this.horizontalLine();
// 刻度线
this.scaleLine();
// 模拟播放效果
// this.playFun()
},
methods: {
// 画布初始化
canvasInit() {
this.myCanvas = this.$refs.canvasRef;
this.ctx = this.myCanvas.getContext("2d");
console.log("ctx=", this.ctx, "myCanvas=", this.myCanvas);
if (this.myCanvas) {
// 鼠标移入滑动移出事件
this.myCanvas.addEventListener("mouseover", overFun);
this.myCanvas.addEventListener("mouseleave", leaveFun);
// 添加按下,滑动,抬起事件
this.myCanvas.addEventListener("mousedown", downFun);
const _this = this;
// 按下
function downFun(e) {
_this.x = e.x;
window.addEventListener("mousemove", moveFun);
window.addEventListener("mouseup", upFun);
};
// 按下滑动
function moveFun(e) {
_this.vueMoveFun(e);
};
// 抬起
function upFun(e) {
_this.curOffset.x = _this.offset.x;
window.removeEventListener("mousemove", moveFun);
window.removeEventListener("mouseup", upFun);
};
// 移入
function overFun(e) {
// console.log('移入===',)
window.addEventListener("mousemove", slidingFun);
};
// 移入滑动
function slidingFun(e) {
// console.log('---移入滑动',e)
};
// 移出
function leaveFun(e) {
// console.log('移出===',)
window.removeEventListener("mousemove", slidingFun);
};
}
},
// 重设canvas尺寸会清空地图并重置canvas
canvasSize() {
this.myCanvas.width = this.width;
},
// 中心基准线
baselineFun(x) {
// 绘制一条在固定在中心竖着的基准线,并且带有时间
this.ctx.beginPath();
this.ctx.strokeStyle = "#FF0000";
this.ctx.lineWidth = 1;
this.ctx.moveTo(600-x, 0);
this.ctx.lineTo(600-x, 50);
// 基准线固定时间
this.ctx.font = "14px SimSun, Songti SC";
this.ctx.fillText( this.fixedTime(this.offset.x), 600-x-73, 25 );
this.ctx.stroke();
},
// 水平线
horizontalLine() {
// 绘制一条直线
this.ctx.beginPath();
this.ctx.strokeStyle = "#000";
this.ctx.lineWidth = 1;
this.ctx.lineCap = "round";
this.ctx.moveTo(0, 50);
this.ctx.lineTo(this.timeNum * 300, 50);
this.ctx.stroke();
},
// 刻度线
scaleLine() {
for (var i = 0; i <= this.timeNum; ++i) {
this.ctx.beginPath(); //新建一条path
this.ctx.lineWidth = 1;
this.ctx.moveTo((0 + i) * 300, 50); //把画笔移动到指定的坐标
this.ctx.lineTo((0 + i) * 300, 40); //绘制一条从当前位置到指定坐标的直线.
this.ctx.font = "12px SimSun, Songti SC";
this.ctx.fillText(
this.computationTime(i),
(0 + i) * 300 - 15,
37
);
this.ctx.stroke(); //绘制路径。
}
},
// 事件处理
// 滑动
vueMoveFun(e) {
this.canvasSize();
this.offset.x = this.curOffset.x + e.x - this.x;
// 默认先让00:00居中,并且控制不能在向右移(600),左移的最大长度为num-2的长度(600),一个间隔为300
if (this.offset.x > 600) {
this.offset.x = 600;
} else if (this.offset.x < -(this.timeNum - 2) * 300) {
this.offset.x = -(this.timeNum - 2) * 300;
}
this.ctx.translate(this.offset.x, 0);
this.baselineFun(this.offset.x)
this.horizontalLine();
this.scaleLine();
console.log("滑动==", this.offset.x, this.curOffset.x, e.x, this.x);
},
// 切换时间间隔
onTime(num, gap) {
console.log('timeNum---',num)
this.timeNum = num;
// 转换时间计算比值 12=2小时一个间隔 1px=24s;24=1小时 1=12s;48=30分钟 1=6s;144=10分钟 1=2s;288=5分钟 1=1s
this.timeRatio = gap
console.log('查看时间',this.hms)
var date = this.hms.split(':')
var h = date[0]
var m = date[1]
var s = date[2]
var all = (s-0) + (m*60-0) + (h*3600-0)
console.log('总共秒=',all,'-=-=-',h*3600,m*60,s,'----this.offset.x=', Math.round(600- all/this.timeRatio) )
this.offset.x = Math.round(600- all/this.timeRatio)
this.curOffset.x = Math.round(600- all/this.timeRatio)
// 刷新画布
this.canvasSize();
this.ctx.translate(this.offset.x, 0);
this.baselineFun(this.offset.x)
this.horizontalLine();
this.scaleLine();
},
// 计算时间
computationTime(num) {
if (this.timeNum === 12) {
return `${num * 2 < 10 ? "0" + num * 2 : num * 2}:00`;
} else if (this.timeNum === 24) {
return `${num < 10 ? "0" + num : num}:00`;
} else if (this.timeNum === 48) {
return this.toHourMinute(num * 30);
} else if (this.timeNum === 144) {
return this.toHourMinute(num * 10);
} else if (this.timeNum === 288) {
return this.toHourMinute(num * 5);
}
},
// 分钟转化 时:分
toHourMinute(minutes) {
let h, m;
h = Math.floor(minutes / 60);
m = minutes % 60;
return `${h < 10 ? "0" + h : h}:${m < 10 ? "0" + m : m}`;
},
// 水平固定时间
fixedTime(x) {
let origin = x - 600;
if(origin === 0){
this.hms = '00:00:00'
return `${this.ymd} 00:00:00`
}else{
let h,m,s,time;
time = Math.abs( origin ) * this.timeRatio
h = Math.floor( time / 3600 )
m = Math.floor( time / 60 % 60)
s = time % 60;
this.hms = `${h < 10 ? "0" + h : h}:${m < 10 ? "0" + m : m}:${s < 10 ? "0" + s : s}`
return `${this.ymd} ${h < 10 ? "0" + h : h}:${m < 10 ? "0" + m : m}:${s < 10 ? "0" + s : s}`;
}
},
// 模拟播放
playFun() {
setInterval(() => {
this.offset.x -= 1;
this.canvasSize();
this.ctx.translate(this.offset.x, 0);
this.horizontalLine();
this.scaleLine();
}, 100);
},
},
};
</script>
<style lang="scss" scoped>
</style>