
入门篇跑通了基础功能但实际监控回放场景还需要全天录像概览双进度条、播放指针居中跟随、点击空白自动续播。这篇文章把这些进阶功能都实现了。一、双进度条主时间轴全天概览1.1 什么是双进度条┌─────────────────────────────────────────┐ ← 主时间轴可缩放 │ ████ ████████████ ████████ │ ├─────────────────────────────────────────┤ ← 概览条全天 │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ │ ↑可视窗口 ↑播放位置 │ └─────────────────────────────────────────┘主时间轴可缩放、可拖动显示当前视口的细节概览条显示全天的录像分布可快速跳转1.2 启用概览条VueTimeAxisPlus :start-timestartTime :segmentssegments :overviewtrue :overview-height20 /1.3 运行时动态开关template VueTimeAxisPlus reftimeline :segmentssegments / button click$refs.timeline.updateOptions({ overview: true })显示概览条/button button click$refs.timeline.updateOptions({ overview: false })隐藏概览条/button /template1.4 概览条点击跳转点击概览条会触发changeTime事件可以实现快速跳转onChangeTime(data){// 点击概览条时mode为click// timestamp为点击位置对应的时间this.seekTo(data.timestamp)}二、播放指针居中跟随2.1 问题播放时指针移动到视口边缘就看不到了。2.2 解决方案启用centerPointer播放时自动滚动视口使指针居中VueTimeAxisPlus reftimeline :center-pointertrue playTimeonPlayTime /2.3 播放逻辑实现data(){return{playing:false,playTimer:null,playTime:0}},methods:{onPlayTime(data){// data.timestamp: 当前播放时间// data.valid: 是否在有效录像内if(!data.valid){// 进入空白区域查下一段续播constnextthis.$refs.timeline.getNextSegment(data.timestamp)if(next){this.playTimenext.beginthis.$refs.timeline.updateTime(this.playTime)}}},startPlay(){this.playingtruethis.playTimersetInterval((){this.playTime1000// 每秒前进1秒if(this.playTimethis.maxTime){this.stopPlay()return}this.$refs.timeline.updateTime(this.playTime)},1000)},stopPlay(){this.playingfalseclearInterval(this.playTimer)}}2.4 手势让位后自动恢复用户拖动时间轴时播放指针暂停跟随松手后自动恢复VueTimeAxisPlus :center-pointertrue :center-resume-delay3000 // 3秒后自动恢复居中 /三、跨空白续播3.1 问题录像有空白时段如夜间无录像用户点击空白区域时怎么处理3.2 解决方案启用snapToNearest点击空白自动吸附到最近的片段起点VueTimeAxisPlus :snap-to-nearesttrue changeTimeonChangeTime /3.3 续播逻辑onChangeTime(data){if(data.modesnap){// 被吸附到了下一段起点console.log(自动跳转到${newDate(data.nextBegin.begin).toLocaleTimeString()})// 开始播放下一段this.playTimedata.nextBegin.beginthis.startPlay()}}3.4 getNextSegment查询不依赖snap手动查询下一段// 从当前时间往后找最近的录像片段constnextthis.$refs.timeline.getNextSegment(this.playTime)if(next){console.log(下一段:${newDate(next.begin).toLocaleTimeString()}-${newDate(next.end).toLocaleTimeString()})console.log(业务字段:${next.id})}3.5 getNextSegments批量查询获取从当前时间往后的所有片段可做播放列表constplaylistthis.$refs.timeline.getNextSegments(this.playTime)console.log(还有${playlist.length}段录像)四、自定义样式4.1 axisStyle配置VueTimeAxisPlus :axis-style{ borderColor: #333, graduationColor: #666, tickTextColor: #fff, hoverLineColor: #00ff00, hoverTextColor: #00ff00, overviewBg: #1a1a1a, overviewWindowColor: rgba(64, 196, 255, 0.2), overviewWindowBorder: #40c4ff, overviewPlayColor: #ff5c5c } /4.2 片段样式每个片段可以独立设置样式segments:[{begin:t(6),end:t(7),style:{background:rgba(24,208,217,0.5)}// 青色},{begin:t(7),end:t(8),style:{background:rgba(255,77,79,0.6)}// 红色},{begin:t(8),end:t(9),style:{background:rgba(255,165,0,0.5)}// 橙色}]4.3 主题切换constdarkTheme{tickTextColor:#ccc,overviewBg:#1a1a1a,overviewWindowColor:rgba(64, 196, 255, 0.15)}constlightTheme{tickTextColor:#333,overviewBg:#f5f5f5,overviewWindowColor:rgba(64, 196, 255, 0.1)}constswitchTheme(theme){this.$refs.timeline.updateOptions({axisStyle:theme})}五、踩坑记录坑1播放指针居中与手势冲突现象用户拖动时间轴时播放指针还在居中跟随导致视口跳动。原因centerPointer和用户手势同时生效。解决组件内部已处理用户手势时自动暂停居中松手后延迟恢复。坑2概览条动态开关后高度不对现象运行时切换overview后时间轴高度没有变化。原因没有调用updateOptions。解决this.$refs.timeline.updateOptions({overview:true})// 组件内部会自动重算画布高度坑3getNextSegment返回null现象调用getNextSegment后返回null。原因当前时间已经是最后一段之后。解决判断返回值constnextthis.$refs.timeline.getNextSegment(time)if(next){// 有下一段}else{// 已经是最后一段之后}六、总结功能配置关键点概览条overview: true支持运行时动态开关播放指针居中centerPointer: true手势时自动暂停跨空白续播snapToNearest: true点击空白自动吸附查询下一段getNextSegment(time)返回完整片段信息主题切换updateOptions({axisStyle})支持部分字段覆盖更新日期2026年9月调试版本vue-time-axis-plus 1.x / Vue 3.4