Commit ffdcf115 by 李乾广

整合pc端nvs播放器

1 parent 721b27f7
......@@ -5,7 +5,7 @@ module.exports = {
},
extends: [
'plugin:vue/essential',
'@vue/standard'
// '@vue/standard'
],
parserOptions: {
parser: '@babel/eslint-parser'
......
......@@ -10,6 +10,9 @@
"dependencies": {
"core-js": "^3.8.3",
"element-ui": "^2.15.14",
"less": "^4.2.0",
"less-loader": "^11.1.3",
"moment": "^2.29.4",
"vue": "^2.6.14",
"vue-router": "^3.5.1"
},
......
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
router,
render: h => h(App)
......
......@@ -39,6 +39,16 @@ const routes = [
name: 'ElTableDemo',
component: () => import('../views/ElTableDemo.vue')
}, */
{
path: '/jplayer-web',
name: 'jplayerWeb',
component: () => import('../views/pc/index.vue')
},
{
path: '/jplayer-web-demo',
name: 'jplayerWebDemo',
component: () => import('../views/pc/pcdemo.vue')
}
]
const router = new VueRouter({
......
<template>
<div class="video-page" :style="{height:isFullScreen?'100%':allVideoHeight?allVideoHeight:videoHeight+'px'}">
<div class="video-box" :style="{height:isShowTime?'calc(100% - 128px)':'100%'}">
<div v-if="playerNum == 1" class="video-split-one">
<div v-if="isShowTitle&&videoObj.channelId" class="elRow">
<div class="gateName">
{{videoObj.name||''}}
</div>
<div class="closeIcon" @click="stopPlay">
<i class="el-icon-close"></i>
</div>
</div>
<j-player v-if="videoObj.channelId" ref="jPlayer" :type="jPlayerType" :channel-id="videoObj.channelId" :datetime-range="jPlayerTimeRange" :prefix-url="videoObj.prefixUrl" :player-address="videoObj.address"/>
<div class="cameraTool" v-show="isShowJT">
<p class="screenshot" @click="screenshot()"><i class="el-icon-camera"></i></p>
</div>
</div>
<div v-else class="video-split-box">
<div class="video-split-line">
<div class="video-split-one" @click="selectVideoChange(0)">
<div v-if="isShowTitle&&videoArrObj[0]&&videoArrObj[0].id" class="elRow">
<div class="gateName">
{{videoArrObj[0].name||''}}
</div>
<div class="closeIcon" @click="stopPlay(0)">
<i class="el-icon-close"></i>
</div>
</div>
<j-player ref="jPlayer0" v-if="videoArrObj[0]" :type="jPlayerType" :channel-id="videoArrObj[0].channelId" :datetime-range="jPlayerTimeRange" :prefix-url="videoArrObj[0].prefixUrl" :player-address="videoArrObj[0].address"/>
<div class="cameraTool" v-show="isShowJT&&videoArrObj[0]">
<p class="screenshot" @click="screenshot(0)"><i class="el-icon-camera"></i></p>
</div>
</div>
<div class="video-split-one" @click="selectVideoChange(1)">
<div v-if="isShowTitle&&videoArrObj[1]&&videoArrObj[1].id" class="elRow">
<div class="gateName">
{{videoArrObj[1].name||''}}
</div>
<div class="closeIcon" @click="stopPlay(1)">
<i class="el-icon-close"></i>
</div>
</div>
<j-player ref="jPlayer1" v-if="videoArrObj[1]" :type="jPlayerType" :channel-id="videoArrObj[1].channelId" :datetime-range="jPlayerTimeRange" :prefix-url="videoArrObj[1].prefixUrl" :player-address="videoArrObj[1].address"/>
<div class="cameraTool" v-show="isShowJT&&videoArrObj[1]">
<p class="screenshot" @click="screenshot(1)"><i class="el-icon-camera"></i></p>
</div>
</div>
</div>
<div class="video-split-line">
<div class="video-split-one" @click="selectVideoChange(2)">
<div v-if="isShowTitle&&videoArrObj[2]&&videoArrObj[2].id" class="elRow">
<div class="gateName">
{{videoArrObj[2].name||''}}
</div>
<div class="closeIcon" @click="stopPlay(2)">
<i class="el-icon-close"></i>
</div>
</div>
<j-player ref="jPlayer2" v-if="videoArrObj[2]" :type="jPlayerType" :channel-id="videoArrObj[2].channelId" :datetime-range="jPlayerTimeRange" :prefix-url="videoArrObj[2].prefixUrl" :player-address="videoArrObj[2].address"/>
<div class="cameraTool" v-show="isShowJT&&videoArrObj[2]">
<p class="screenshot" @click="screenshot(2)"><i class="el-icon-camera"></i></p>
</div>
</div>
<div class="video-split-one" @click="selectVideoChange(3)">
<div v-if="isShowTitle&&videoArrObj[3]&&videoArrObj[3].id" class="elRow">
<div class="gateName">
{{videoArrObj[3].name||''}}
</div>
<div class="closeIcon" @click="stopPlay(3)">
<i class="el-icon-close"></i>
</div>
</div>
<j-player ref="jPlayer3" v-if="videoArrObj[3]" :type="jPlayerType" :channel-id="videoArrObj[3].channelId" :datetime-range="jPlayerTimeRange" :prefix-url="videoArrObj[3].prefixUrl" :player-address="videoArrObj[3].address"/>
<div class="cameraTool" v-show="isShowJT&&videoArrObj[3]">
<p class="screenshot" @click="screenshot(3)"><i class="el-icon-camera"></i></p>
</div>
</div>
</div>
</div>
</div>
<div class="time-box" v-if="isShowTime">
<videoTime ref="videoTime" @videoTimeChange="videoTimeChange" @videoTimeSync="videoTimeSync" @allVideoFullScreen="allVideoFullScreen" @allVideoExitFullScreen="allVideoExitFullScreen" @splitScreenChange="splitScreenChange" :isShowSplit="isShowSplit"/>
</div>
</div>
</template>
<script>
import videoTime from './videoTime.vue'
import jPlayer from '@/components/jPlayer';
// import jPlayer0 from '../jPlayer/index.vue'
// import jPlayer1 from '../jPlayer/index.vue'
// import jPlayer2 from '../jPlayer/index.vue'
// import jPlayer3 from '../jPlayer/index.vue'
import moment from 'moment'
export default {
name: 'JPlayerWeb',
components:{
videoTime,
jPlayer,
// jPlayer0,
// jPlayer1,
// jPlayer2,
// jPlayer3
},
data() {
return {
videoArrObj:[],
isFullScreen:false,
jPlayerType:'live',
videoObj: {
channelId: '',
address: '52.130.155.147',
prefixUrl: '',
},
jPlayerTimeRange:[],
playerNum:1,
splitNum:0,
videoPlayTime:'',
}
},
props:{
// 是否显示时间操作区,默认为true
isShowTime: {
type: Boolean,
default: true,
},
// 设置组件高度
allVideoHeight:{
type: String,
default: '',
},
// 是否显示截图按钮,默认为false
isShowJT: {
type: Boolean,
default: false,
},
// 是否显示头部标题栏,默认为false
isShowTitle: {
type: Boolean,
default: false,
},
// 是否支持四分屏,默认为true
isShowSplit: {
type: Boolean,
default: true,
},
},
computed: {
videoHeight() {
const windowInnerHeight = window.innerHeight;
return windowInnerHeight - 80;
}
},
mounted() {
},
methods: {
init(obj) {
if (!obj.address || !obj.channelId) {
console.error('传递URL参数有误,请确认 address 和 channelId 是否正确。');
return false
}
if(obj.splitNum >=0) {
this.splitNum = obj.splitNum
}
console.log(obj)
if(this.$refs.videoTime) {
this.$refs.videoTime.stopPlay()
}
this.jPlayerTimeRange = [];
this.jPlayerType = 'live';
obj.prefixUrl = obj.prefixUrl||'';
if(this.playerNum == 4) {
this.videoArrObj[this.splitNum] = Object.assign({}, obj)
} else {
this.videoObj = Object.assign({}, obj);
}
console.log(this.videoObj)
this.$forceUpdate()
if(this.isShowTime) {
this.$refs.videoTime.startPlay()
}
this.splitNumChange()
},
// 分屏时选中屏数自动改变
splitNumChange() {
if(this.playerNum == 4) {
for(let i=0;i<5;i++){
if(!this.videoArrObj[i]){
this.splitNum = i
break;
}
}
if(this.splitNum== 5) {
this.splitNum = 0
}
}
},
allVideoExitFullScreen(){
this.isFullScreen = false
this.$emit('exitFullScreen')
},
allVideoFullScreen(val){
this.isFullScreen = true
this.$emit('fullScreen')
},
// 四分屏,单屏切换
splitScreenChange(val) {
if(val == 4) {
if(this.$refs.jPlayer) {
this.$refs.jPlayer.stopPlay();
}
} else {
if(this.$refs.jPlayer0) {
this.$refs.jPlayer0.stopPlay();
}
if(this.$refs.jPlayer1) {
this.$refs.jPlayer1.stopPlay();
}
if(this.$refs.jPlayer2) {
this.$refs.jPlayer2.stopPlay();
}
if(this.$refs.jPlayer3) {
this.$refs.jPlayer3.stopPlay();
}
}
this.$refs.videoTime.stopPlay()
// console.log(val)
this.playerNum = val
this.videoArrObj = []
this.splitNum = 0
},
// 分屏单个播放窗口点击
selectVideoChange(val) {
this.splitNum = val
},
// 时间线改变
videoTimeChange(val) {
this.videoPlayTime = val
let isNoBack = moment(this.videoPlayTime).format('YYYY-MM-DD HH:mm:ss') == moment().format('YYYY-MM-DD HH:mm:ss')
this.jPlayerType = isNoBack?'live':'playback'
if(!isNoBack){
let startTime = new Date(moment(this.videoPlayTime).format("YYYY-MM-DD HH:mm:ss")).getTime()
let endTime = new Date().getTime()
this.jPlayerTimeRange = [startTime,endTime]
}
},
videoTimeSync(val) {
this.videoPlayTime = val
},
// 暴露方法
/**
* 截图
* num为分屏时的窗口序号,从0开始;不传则认为是单屏
*/
screenshot(num) {
let imgInfo = ''
if(num === 0) {
imgInfo = this.$refs.jPlayer0.screenshot()
} else if(num === 1) {
imgInfo = this.$refs.jPlayer1.screenshot()
} else if(num === 2) {
imgInfo = this.$refs.jPlayer2.screenshot()
} else if(num === 3) {
imgInfo = this.$refs.jPlayer3.screenshot()
} else {
imgInfo = this.$refs.jPlayer.screenshot()
}
return imgInfo;
},
/**
* 关闭视频播放
* num为分屏时的窗口序号,从0开始;不传则认为是单屏
*/
stopPlay(val) {
if(val >=0) {
if(val === 0) {
this.$refs.jPlayer0.stopPlay();
} else if(val === 1) {
this.$refs.jPlayer1.stopPlay();
} else if(val === 2) {
this.$refs.jPlayer2.stopPlay();
} else if(val === 3) {
this.$refs.jPlayer3.stopPlay();
}
this.videoArrObj[val] = null
this.splitNum = val
} else {
this.$refs.jPlayer.stopPlay();
}
if(this.playerNum == 1||(this.playerNum == 4&&!this.videoArrObj[0]&&!this.videoArrObj[1]&&!this.videoArrObj[2]&&!this.videoArrObj[3])) {
this.$refs.videoTime.stopPlay()
}
},
}
}
</script>
<style scoped lang="less">
.video-page{
background-color: rgba(0, 0, 0, 0.7);
.video-box{
width: 100%;
position: relative;
border-bottom: 1px solid #666666;
.video-split-one{
height: 100%;
&:hover{
.cameraTool{
display: block;
}
.elRow{
display: flex;
}
}
}
.cameraTool{
position: absolute;
right: 15px;
top: 40%;
display: none;
z-index: 9999;
color: #fff;
.screenshot{
width: 40px;
height: 40px;
background: rgba(0,0,0,.7);
line-height: 40px;
text-align: center;
font-size: 25px;
cursor: pointer;
margin-bottom: 3px;
border-radius: 5px;
}
}
.elRow{
width: calc(100% - 60px);
position: absolute;
top:0px;
left:0px;
z-index: 99;
height: 48px;
line-height: 48px;
display: none;
align-items: center;
justify-content: space-between;
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: 0 30px;
font-size: 18px;
.closeIcon{
height: 48px;
line-height: 48px;
cursor: pointer;
padding: 0 10px;
}
}
}
.time-box{
width: 100%;
}
.video-split-box{
width: 100%;
height: 100%;
.video-split-line{
width: 100%;
height: calc(50% - 2px);
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 4px;
}
.video-split-one{
width: calc(50% - 2px);
height: 100%;
position: relative;
}
}
}
</style>
\ No newline at end of file
<template>
<div>
<!-- 添加视频测试 -->
<div>
<el-button type="primary" @click="addPlayer({channelId: '20000000001310000008',address: '52.130.155.147'})">添加视频一</el-button>
<el-button type="primary" @click="addPlayer({channelId: '20000000001310000008',address: '52.130.155.147'})">添加视频二</el-button>
</div>
<indexPlayer ref="indexPlayer" />
</div>
</template>
<script>
import indexPlayer from './index.vue';
export default {
name: 'jplayerWebDemo',
components: {
indexPlayer,
},
data() {
return {
}
},
created() {
},
methods: {
addPlayer(obj) {
this.$refs.indexPlayer.init(obj);
},
},
}
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<canvas
class="timeline-canvas"
@touchmove="touchmove"
@touchend="touchend"
@touchstart="touchstart"
onselectstart="return false;"
:style="`background-color: ${this.colors.background}; cursor: ${isMobile ? 'default' : 'pointer'}`"
:height="height"
ref="canvas"
></canvas>
</template>
<script>
import moment from "moment";
/**
* timeline-canvas canvas的绘制的时间轴组件
* @description 可用于视频、录像播放或实时数据展示等业务
* @tutorial https://gitee.com/my87/timeline-canvas
* @property {Number String} width 时间轴宽度,支持固定(不需要带单位)和百分比,默认自适应父容 (默认100%)
* @property {String Number} height 时间轴高度,非必要可以忽 (默认60)
* @property {String} startMeddleTime启动时间,未传参时会根据 timeRange 计算;timeRange 参数也未传采用当前时间
* @property {Array String } timeRange 时间轴绘制的时间范 (默认当天)
* @property {Array} markTime 区域进行标记,可以自定义背景颜色和文
* @property {Boolean} isAutoPlay 开启后时间轴将以 1s 的速度前进进(默认false)
* @property {Object} colors 自定义颜色
* @Methods {Function} play(date) 当未开启自动播放,时可以手动播放 date:播放的起始时间
* @Methods {Function} stop 手动暂停播放
* @event {Function} click 当时间和播放状态发生变化时触发,只有当开启 isAutoPlay=true 才有状态变化
* @event {Function} change 图片上传成功时触发
* @example <TimeLineCanvas ref="time_line" @click="clickCanvas" @change="changeDate" :mark-time="markTime" :time-range="time_range" :isAutoPlay="isAutoPlay" :startMeddleTime="startMeddleTime"/>
*/
export default {
name:'TimeLineCanvas',
props: {
width: {
type: [Number, String],
default: "100%",
},
//
height: {
type:[Number, String],
default: 40,
},
// 中间的时间,
startMeddleTime: String,
// 时间范围
timeRange: {
type: [Array, String],
default() {
return "";
},
},
// 需要标记的时间
markTime: {
type: Array,
default() {
return [];
},
},
//是否自动播放
isAutoPlay: {
type: Boolean,
default: false,
},
colors: {
type: Object,
default() {
return {
//背景
background: "transparent",
//中间线
meddleLine: "rgba(255,17,17,0.95)",
//中间时间
meddleDate: "red", // "rgb(64, 196, 255)",
//移动线
moveLine: "rgba(255,17,17,0.95)",
//移动时间
moveDate: "#009966",
//刻度线
scaleLine: "rgba(255,255,255,0.9)",
// 小刻度线
minscaleLine: "rgba(255,255,255,0.5)",
//刻度条
scaleBar: "transparent",
};
},
},
//最小像素秒(每1px对应的秒数,保证时间轴的宽度缩小情况下时间刻度不会压缩在一起)
minPxSecond: {
type: Number,
default: 120,
},
},
data() {
return {
//像素比
dpr: 1,
// realTimeRange: [],
// 整个canvas显示多少个小时
whole_hour: 24,
// canvas的画布宽度
canvasWidth: 1000,
//中间时间
meddleTime: "",
// 移动时鼠标有没有按下
mouseDown: false,
// 鼠标按下时的位置
mouseDownPosition: "",
// 鼠标按下时中间的时间,
mouseDownMeddleTime: "",
// 鼠标按下时有没有移动
isMove: false,
//是否手机端
isMobile: false,
//两端之间距离
distance: 0,
//是否在播放中
isPlay: false,
// 鼠标移动时移动到的时间
mouseMoveTime:"",
};
},
beforeDestroy() {
this.stop()
},
mounted() {
this.canvas = this.$refs.canvas;
//是否为手机端
this.isMobile = /Mobi/i.test(navigator.userAgent); //navigator.userAgent.match(/Mobi/i);
//移动端如不禁止,在滑动时会触发鼠标事件与滑动事件冲突
if (!this.isMobile) {
// this.canvas.addEventListener("mousewheel", this.mousewheel);
this.canvas.addEventListener("mousemove", this.mousemove);
// this.canvas.addEventListener("mousedown", this.mousedown);
// this.canvas.addEventListener("mouseup", this.mouseup);
this.canvas.addEventListener("mouseup", this.mouseClick);
this.canvas.addEventListener("mouseleave", this.mouseleave);
}
// 屏幕大小监听
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", this.resize, false);
// 计算默认中间时间
this.setStartMeddleTime();
this.ctx = this.canvas.getContext("2d");
//初始化
this.init();
// 自动播放
if (this.isAutoPlay) {
this.play();
}
},
methods: {
init() {
this.canvas = this.$refs.canvas;
let width = this.width;
//自适应父容器宽度 this.width参数支持百分比设置
let parentWidth = this.canvas.parentElement.clientWidth;
if (/^(\d|[1-9]\d|100)%$/.test(this.width)) {
width = Math.floor((this.width.replace("%", "") / 100) * parentWidth);
}
//移动端像素模糊问题处理
//是由于dpr像素比造成的,扩大canvas画布的像素,使1个canvas像素和1个物理像素相等
this.dpr = window.devicePixelRatio; // 假设dpr为2
// //获取css的宽高
// const { width: cssWidth, height: cssHeight } = this.canvas.getBoundingClientRect();
// // 设置图像大小
this.canvas.style.width = `${width}px`;
this.canvas.style.height = `${this.height}px`;
// 设置画布大小
this.canvas.width = Math.round(width * this.dpr);
this.canvas.height = Math.round(this.height * this.dpr);
// 由于画布扩大,canvas的坐标系也跟着扩大,
// 按照原先的坐标系绘图内容会缩小, 所以需要将绘制比例放大
this.ctx.scale(this.dpr, this.dpr);
this.canvasWidth = this.canvas.width / this.dpr;
this.drow();
},
// 监听窗口大小
resize() {
if (window.orientation === 180 || window.orientation === 0) {
// "竖屏";
}
if (window.orientation === 90 || window.orientation === -90) {
//"横屏";
}
//有时屏幕尺寸变化了,而容器的尺寸还未改变的情况下的处理
if (this.canvas.style.width === this.canvas.parentElement.clientWidth + "px") {
setTimeout(() => {
this.resize();
}, 10);
} else {
//重新初始化
this.init();
}
},
//进度条停止播放
stop() {
if (this.isPlay) {
this.isPlay = false;
this.$emit("change", this.meddleTime, "stop");
}
if (this.interval_play) clearInterval(this.interval_play);
},
/**
* 进度条播放(每次走一秒)
* @param {String|Date} date 启动时间,不传启动时间为this.meddleTime
*/
play(date) {
this.isPlay = true;
clearInterval(this.interval_play);
if (date) {
this.meddleTime = date;
}
this.interval_play = setInterval(() => {
//中间时间增加1s
this.meddleTime = moment(this.meddleTime).add(1, "s").format("YYYY-MM-DD HH:mm:ss");
let status =
this.realTimeRange[1] && new Date(this.meddleTime).getTime() >= new Date(this.realTimeRange[1]).getTime()
? "end"
: "play";
this.$emit("change", this.meddleTime, status);
// 开发过程中热更新时,会在每更新一次就开启一个setInterval,前面又不释放
// 没有释放定时任务会报错,所有在异常就视为前个任务并清理掉
try {
this.drow();
} catch (ee) {
console.log(ee);
clearInterval(this.interval_play);
}
if (!this.isPlay || status == "end") {
clearInterval(this.interval_play);
}
}, 1000);
},
//移动端滑动
touchmove(e) {
let touches = e.touches;
e.offsetX = touches[0].pageX;
e.offsetY = touches[0].pageY;
//双指缩放 (在本组件上因区域的限制不适合用双指缩放手势)
if (touches.length >= 2) {
e.preventDefault();
let now = Date.now();
if (!this._moveTime) {
this._moveTime = now;
}
//抖动处理
else if (now - this._moveTime > 100) {
let _hypot = this.getDistance({ x: e.offsetX, y: e.offsetY }, { x: touches[1].pageX, y: touches[1].pageY });
if (_hypot > this.distance) {
//放大
e.wheelDelta = 1;
} else {
//缩小
e.wheelDelta = -1;
}
this.distance = _hypot;
this._moveTime = null;
this.mousewheel(e);
}
} else {
this.mousemove(e);
}
},
//滑动结束
touchend(e) {
let touches = e.changedTouches;
e.offsetX = touches[0].pageX;
e.offsetY = touches[0].pageY; //pc 与m的值是否相同
// this.mouseup(e);
},
//滑动开始
touchstart(e) {
let touches = e.touches;
e.offsetX = touches[0].pageX;
e.offsetY = touches[0].pageY;
//双指事件(在本组件上因区域的限制不适合用双指缩放手势)
if (touches.length >= 2) {
e.preventDefault();
this.distance = this.getDistance({ x: e.offsetX, y: e.offsetY }, { x: touches[1].pageX, y: touches[1].pageX });
}
this.mousedown(e);
},
//鼠标离开
mouseleave(e) {
this.drow();
this.$emit("mouseMove", '');
//鼠标离开无法在触发mouseup,所以当拖动时将离开视释放
// if (this.mouseDown) {
// this.mouseup(e);
// } else {
// this.mouseDown = false;
// }
},
// 鼠标移动
mousemove(e) {
this.drow();
//PC滑动显示时间
if (!this.isMobile) {
this.drowMoveLine(e);
}
// if (this.mouseDown) {
// this.mouseDownMove(e);
// this.isMove = true;
// }
}, //126 10:00
// 滚动鼠标滚轮
mousewheel(e) {
e.preventDefault();
if (e.wheelDelta > 0) {
// 时间变短
this.whole_hour -= 4;
this.whole_hour < 1 && (this.whole_hour = 1);
} else {
// 时间变长
if (this.whole_hour < 4) {
this.whole_hour = 4;
} else {
this.whole_hour += 4;
this.whole_hour > 24 && (this.whole_hour = 24);
}
}
this.drow();
},
// 滚动鼠标滚轮--外部指定小时
mousewheelBtn(val) {
this.whole_hour = val
// this.drow();
},
// 按下鼠标
mousedown(e) {
this.mouseDown = true;
this.mouseDownPosition = e.offsetX;
this.mouseDownMeddleTime = this.meddleTime;
this.isMove = false;
},
// 抬起鼠标
mouseup(e) {
this.mouseDown = false;
// 没有滑动或鼠标移动(视为点击操作),就渲染中间时间(另外的是在移动事件里渲染)。
if (!this.isMove) {
let date = e.offsetX * this.px_second * 1000 + this.firstTime;
date = this.boundary_time(date);
let _date = moment(date).format("YYYY-MM-DD HH:mm:ss");
this.meddleTime = _date;
this.drow();
//PC滑动显示时间
if (!this.isMobile) {
this.drowMoveLine(e);
}
}
// 释放时确定时间选择
// change事件会在自动播放返回播放中的实时时间
this.$emit("change", this.meddleTime, "start");
//click事件只有在释放时才返回时间
this.$emit("click", this.meddleTime);
// 自动播放
if (this.isAutoPlay) {
this.play();
}
},
// 鼠标按下移动(组合事件)
mouseDownMove(e) {
this.stop();
// 记录点击位置与滑动后的坐标距离
let offset = this.mouseDownPosition - e.offsetX;
// console.log(offset)
// 点击时的中间时间 + 坐标距离差转换后的时间 = 移动后的中间时间
let date = new Date(this.mouseDownMeddleTime).getTime() + offset * this.px_second * 1000;
date = this.boundary_time(date);
this.meddleTime = moment(date).format("YYYY-MM-DD HH:mm:ss");
},
// 鼠标单击事件
mouseClick(offset) {
if(new Date(this.mouseMoveTime).getTime() > new Date().getTime()) {
return false
}
this.stop();
this.meddleTime = moment(this.mouseMoveTime).format("YYYY-MM-DD HH:mm:ss");
// console.log(this.meddleTime)
// change事件会在自动播放返回播放中的实时时间
this.$emit("change", this.meddleTime, "start");
//click事件只有在释放时才返回时间
this.$emit("click", this.meddleTime);
// 自动播放
if (this.isAutoPlay) {
this.play();
}
},
drow() {
//重置高宽清空画布
this.canvas.width = this.canvas.width;
this.canvas.height = this.canvas.height;
this.ctx.scale(this.dpr, this.dpr);
this.drowMark();
this.drowScaleLine();
this.drowMeddleLine(this.meddleTime);
},
// 画鼠标移上去的线
drowMoveLine(e) {
let date = e.offsetX * this.px_second * 1000 + this.firstTime;
// 超出有效时间范围就不做渲染
if (
(this.realTimeRange[0] && date < new Date(this.realTimeRange[0]).getTime()) ||
(this.realTimeRange[1] && date > new Date(this.realTimeRange[1]).getTime())
) {
return;
}
this.ctx.beginPath();
this.ctx.moveTo(e.offsetX - 1, 0);
this.ctx.lineTo(e.offsetX - 1, 30);
this.ctx.strokeStyle = this.colors.moveLine;
this.ctx.lineWidth = 2;
this.ctx.stroke();
this.ctx.fillStyle = this.colors.moveDate;
let text = this.getMark(date)?this.getMark(date).text:'';
text = text ? ` (${text})` : "";
this.ctx.font = `${12}px serif`;
this.mouseMoveTime = moment(date).format("YYYY-MM-DD HH:mm:ss")
this.$emit("mouseMove", this.mouseMoveTime);
// console.log(this.mouseMoveTime)
// this.ctx.fillText(moment(date).format("YYYY-MM-DD HH:mm:ss") + text, e.offsetX - 50, 5);
},
// 画中间时间的线
drowMeddleLine(time) {
let time0 = new Date(moment(this.realTimeRange[0]).format("YYYY-MM-DD HH:mm:ss")).getTime()
let nowTime = new Date(moment(time).format("YYYY-MM-DD HH:mm:ss")).getTime()
let width = this.canvasWidth * ((nowTime - time0)/(this.whole_hour*3600*1000))
this.ctx.beginPath();
this.ctx.moveTo(width, 0);
this.ctx.lineTo(width, 30);
this.ctx.strokeStyle = this.colors.meddleLine;
this.ctx.lineWidth = 3
this.ctx.stroke();
this.ctx.fillStyle = this.colors.meddleLine;
this.ctx.font = `12px serif`;
// this.ctx.fillText(time, this.canvasWidth / 2 - 50, 40);
},
// 画刻度线
drowScaleLine() {
// // 画canvas上部分的颜色
// this.ctx.fillStyle = "rgba(69, 72, 76, 0.5)";
// this.ctx.fillRect(0, 0, this.canvasWidth, 20);
// 画第一个刻度线
let time = new Date(this.getFirstLineTime()).getTime() - this.firstTime;
//几个像素点后画第一个刻度
let p = time / 1000 / this.px_second;
// 每条线之间的间隔 scaleLine_minute来确定每个格代表多长时间
let line_px = (this.scaleLine_minute * 60) / this.px_second;
for (let i = p; i <= (this.canvasWidth + 1); i += line_px) {
let date = this.firstTime + i * this.px_second * 1000;
let time1 = moment(date).format("HH:mm");
if (
(this.realTimeRange[0] && date < new Date(this.realTimeRange[0]).getTime()) ||
(this.realTimeRange[1] && date > (new Date(this.realTimeRange[1]).getTime() + 1000))
) {
continue;
}
let time = moment(date).format("HH:mm");
this.ctx.beginPath();
this.ctx.moveTo(i, 5);
this.ctx.lineTo(i, this.showTime(time) ? 17 : 10);
this.ctx.strokeStyle = this.showTime(time)?this.colors.scaleLine:this.colors.minscaleLine;
this.ctx.lineWidth = 1;
this.ctx.stroke();
this.ctx.fillStyle = this.colors.scaleLine;
this.ctx.font = `12px serif`;
if (i==0&&time == "00:00") {
// let show_time = moment(date).format("YYYY-MM-DD");
this.ctx.fillText(time, i, 32);
} else if (time == "00:00") {
// let show_time = moment(date).format("YYYY-MM-DD");
this.ctx.fillText(time, i- 30, 32);
} else if (this.showTime(time)) {
this.ctx.fillText(time, i - 15, 32);
}
}
},
// 计算默认中间时间
setStartMeddleTime() {
//根据可活动时间范围计算中间值
let time;
if (this.realTimeRange[0] && this.realTimeRange[1]) {
time = moment(
(new Date(this.realTimeRange[0]).getTime() + new Date(this.realTimeRange[1]).getTime()) / 2
).format("YYYY-MM-DD HH:mm:ss");
}
//设置默认中间时间(优先级:startMeddleTime参数指定>按有可活动时间范围计算>当前时间)
this.meddleTime = this.startMeddleTime || time || moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
},
//获取刻度上的第一个时间
getFirstLineTime() {
const start = moment(this.firstTime);
//第一个时间不一定刚好落在刻度上,计算少了多少分才能到第一个刻度上(开始位置留白)
let remainder = this.scaleLine_minute - (start.minute() % this.scaleLine_minute);
remainder = remainder == this.scaleLine_minute ? 0:remainder;
return start.add(remainder, "minutes").format("YYYY-MM-DD HH:mm");
},
// 刻度时间显示(按级别显示)
showTime(time) {
// 每2时级
if (this.whole_hour >= 16) {
return [
"00:00",
"01:00",
"02:00",
"03:00",
"04:00",
"05:00",
"06:00",
"07:00",
"08:00",
"09:00",
"10:00",
"11:00",
"12:00",
"13:00",
"14:00",
"15:00",
"16:00",
"17:00",
"18:00",
"19:00",
"20:00",
"21:00",
"22:00",
"23:00",
].includes(time);
}
// 每1时级
if (this.whole_hour >= 8) {
return [
"00:00",
"01:00",
"02:00",
"03:00",
"04:00",
"05:00",
"06:00",
"07:00",
"08:00",
"09:00",
"10:00",
"11:00",
"12:00",
"13:00",
"14:00",
"15:00",
"16:00",
"17:00",
"18:00",
"19:00",
"20:00",
"21:00",
"22:00",
"23:00",
].includes(time);
}
// 每20分
if (this.whole_hour >= 4) {
return ["00", "20", "40"].find((item) => time.endsWith(item));
}
// 每10分
return ["00", "10", "20", "30", "40", "50"].find((item) => time.endsWith(item));
},
// 画标记的时间
drowMark() {
// 画canvas上部分的颜色
this.ctx.fillStyle = this.colors.scaleBar;
this.ctx.fillRect(0, 5, this.canvasWidth, 10);
this.markTime.forEach((item) => {
//标签所有范围超出时间区域(realTimeRange)就不渲染
if (
(this.realTimeRange[0] && new Date(item.endTime).getTime() < new Date(this.realTimeRange[0]).getTime()) ||
(this.realTimeRange[1] && new Date(item.beginTime).getTime() > new Date(this.realTimeRange[1]).getTime())
) {
return;
}
this.ctx.fillStyle = item.bgColor;
// 标签起点超时间效区域realTimeRange[0]就用realTimeRange[0]做为起点时间
let beginTime =
this.realTimeRange[0] && new Date(item.beginTime).getTime() < new Date(this.realTimeRange[0]).getTime()
? this.realTimeRange[0]
: item.beginTime;
// 标签终点超时间效区域realTimeRange[1]就用realTimeRange[1]做为终点时间
let endTime =
this.realTimeRange[1] && new Date(item.endTime).getTime() > new Date(this.realTimeRange[1]).getTime()
? this.realTimeRange[1]
: item.endTime;
let sx = (new Date(beginTime).getTime() - this.firstTime) / 1000 / this.px_second;
let ex = (new Date(endTime).getTime() - this.firstTime) / 1000 / this.px_second;
this.ctx.fillRect(sx, 5, ex - sx, 10);
});
},
//获取点坐标的距离(用于移动端双指放大缩小手势识别)
getDistance(a, b) {
const x = a.x - b.x;
const y = a.y - b.y;
return Math.hypot(x, y); // Math.sqrt(x * x + y * y);
},
//超出有效时间范围,返回边界值
boundary_time(date) {
//超出起点有效区域
if (this.realTimeRange[0] && date < new Date(this.realTimeRange[0]).getTime()) {
return new Date(this.realTimeRange[0]).getTime();
}
// 超出端点有效区域
else if (this.realTimeRange[1] && date > new Date(this.realTimeRange[1]).getTime()) {
return new Date(this.realTimeRange[1]).getTime();
} else {
return date;
}
},
//获取标记对象
getMark(date) {
return this.markTime.find(
(item) =>
new Date(item.beginTime).getTime() < new Date(date).getTime() &&
new Date(date).getTime() < new Date(item.endTime).getTime()
);
},
/**
*设置时间
* @param {String} date 中间时间
* @param @param {String| Array} timeRange 可切换到新时间范围(如下个录像时段),可选参数
*/
// setDate(date, timeRange) {
// if (timeRange) {
// this.setTimeRange(timeRange);
// }
// this.meddleTime = date;
// this.drow();
// },
/**
*设置时间轴可活动的时间区域
* @param {String| Array} timeRange 时间范围,不传默认组件timeRange参数原始值
*/
// setTimeRange(timeRange) {
// this.realTimeRange = timeRange || this.timeRange;
// if (typeof this.realTimeRange == "string") {
// let date = this.realTimeRange ? moment(this.realTimeRange).format("YYYY-MM-DD") : moment().format("YYYY-MM-DD");
// this.realTimeRange = [date + " 00:00:00", date + " 23:59:59:59"];
// }
// },
},
computed: {
// canvas最左边的时间的时间戳(滑动计算时间)
firstTime() {
return new Date(this.realTimeRange[0]).getTime();
},
// firstTime() {
// return new Date(this.meddleTime).getTime() - ((this.px_second * this.canvasWidth) / 2) * 1000;
// },
// 每个像素点对应多少秒(像素转时间和刻度)
px_second() {
let second = (this.whole_hour * 60 * 60) / this.canvasWidth;
// 保证不管缩小到什么宽度,刻度线都不会挤压在一起
if (second > this.minPxSecond) second = this.minPxSecond;
return second;
},
// 计算timeRange 兼容string |Array转换
realTimeRange() {
if (typeof this.timeRange == "string") {
let date = this.timeRange ? moment(this.timeRange).format("YYYY-MM-DD") : moment().format("YYYY-MM-DD");
return [date + " 00:00:00", date + " 23:59:59:59"];
} else {
return this.timeRange;
}
},
// 每个刻度线之间的多分钟(画刻度)
scaleLine_minute() {
if (this.whole_hour >= 20) {
//30分钟半小时
return 10;
}
if (this.whole_hour >= 16) {
return 20;
}
if (this.whole_hour >= 12) {
return 15;
}
if (this.whole_hour >= 8) {
return 10;
}
if (this.whole_hour >= 4) {
return 5;
}
return 2;
},
//计算需要重新绘制的参数,方便统一监听
changeProps() {
let { startMeddleTime, timeRange } = this;
this.setStartMeddleTime();
return { startMeddleTime, timeRange };
},
},
watch: {
//监听需要重新绘制的参数
changeProps: function (newV) {
this.drow();
},
},
};
// import Hammer from "./assets/hammerjs";
</script>
<style scoped lang="less">
.timeline-canvas{
// width:calc(100% - 80px)!important;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="time-page">
<!-- 操作区 -->
<div class="time-operation-module">
<!-- 左侧操作栏 -->
<div class="operation-module-left">
</div>
<div v-if="isAutoPlay&&!isNoBack" class="operation-module-center">
<div class="time-input-box">
<div class="time-input-list">
<el-input ref="mouseTimeHour" v-model="mouseTimeHour" @change="mouseTimeHourChange" size="small" @focus="mouseTimeFocus"/><span class="time-input-line">:</span><el-input ref="mouseTimeMin" v-model="mouseTimeMin" @change="mouseTimeMinChange" size="small" @focus="mouseTimeFocus"/><span class="time-input-line">:</span><el-input ref="mouseTimeSec" v-model="mouseTimeSec" @change="mouseTimeSecChange" size="small" @focus="mouseTimeFocus"/>
</div>
<i class="el-icon-search time-input-btn" @click="mouseTimeBtnClick"></i>
</div>
<el-button class="go-back-realtime-btn" size="mini" type="primary" @click="backRealTime">返回实时</el-button>
</div>
<!-- 右侧操作栏 -->
<div class="operation-module-right">
<!-- 分屏控制 -->
<div class="split-screen-control" v-if="isShowSplit">
<i class="el-icon-arrow-left"></i>
<el-dropdown size="mini" trigger="click" placement="top" @command="splitScreenClick">
<span class="split-screen-text">
<img v-if="splitScreen==1" class="split-screen-img" src="./split/split1.png" alt="">
<img v-if="splitScreen==4" class="split-screen-img" src="./split/split4.png" alt="">
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="1"><img class="split-screen-img" src="./split/split1_blank.png" alt=""></el-dropdown-item>
<el-dropdown-item :command="4"><img class="split-screen-img" src="./split/split4_blank.png" alt=""></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<i class="el-icon-arrow-right"></i>
</div>
<!-- 时间轴精度选择 -->
<div class="time-line-accuracy" v-if="false">
<i class="el-icon-arrow-left"></i>
<el-dropdown trigger="click" placement="top" @command="timeAccuracyChange">
<span class="time-accuracy-text">
{{timeAccuracy}}小时
</span>
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item command="1">1小时</el-dropdown-item>
<el-dropdown-item command="2">2小时</el-dropdown-item>
<el-dropdown-item command="4">4小时</el-dropdown-item>
<el-dropdown-item command="6">6小时</el-dropdown-item>
<el-dropdown-item command="8">8小时</el-dropdown-item>
<el-dropdown-item command="10">10小时</el-dropdown-item>
<el-dropdown-item command="12">12小时</el-dropdown-item> -->
<el-dropdown-item command="24">24小时</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<i class="el-icon-arrow-right"></i>
</div>
<span @click="fullScreen" class="fullScreen" v-if="!isFullScreen"><i class="el-icon-full-screen"></i></span>
<span @click="exitFullScreen" class="fullScreen" v-if="isFullScreen"><i class="el-icon-full-screen"></i></span>
<!-- 播放时间显示 -->
<!-- <div class="play-time-show">{{nowPlayTime}}</div> -->
<!-- 返回实时按钮 -->
</div>
</div>
<!-- 时间轴 -->
<div class="time-axis">
<!-- <div class="timeline-icon-box" @click="timeLineMove(-1)">
<i class="el-icon-arrow-left"></i>
</div> -->
<div class="timeline-canvas-box">
<TimeLineCanvas id="timeline-canvas" ref="time_line" @click="clickCanvas" @change="changeDate" :mark-time="markTime" :time-range="timeRange" :isAutoPlay="isAutoPlay" :startMeddleTime="startMeddleTime" @mouseMove="mouseMoveDate"/>
</div>
<!-- <div class="timeline-icon-box" @click="timeLineMove(1)">
<i class="el-icon-arrow-right"></i>
</div> -->
</div>
<!-- 日期轴 -->
<div class="date-axis">
<div class="dayline-icon-box" @click="dayLineMove(1)">
<i class="el-icon-arrow-left"></i>
</div>
<div class="dayline-list-box">
<div class="dayline-list-one" v-for="(item,index) in dayList" :key="index" @click="showDayChange(item.value)" :class="[showDayShow==item.value?'dayline-list-one-select':'']">
{{item.label}}
</div>
</div>
<div v-if="daySubtractNum > 0" class="dayline-icon-box" @click="dayLineMove(-1)">
<i class="el-icon-arrow-right"></i>
</div>
<div v-else class="dayline-icon-box"></div>
</div>
<!-- 时间日期蒙版 -->
<div class="timeline-canvas-bg" v-if="!isAutoPlay"></div>
</div>
</div>
</template>
<script>
import TimeLineCanvas from "./timeline-canvas.vue";
import moment from "moment";
export default {
name:'videoTime',
data() {
return {
startTimePickerOptions: {
selectableRange: '00:00:00 - 00:00:01'
},
showDayShow: moment().format('YYYY-MM-DD'),
nowPlayTime: '',
timeAccuracy: '24',
splitScreen: 1,
startTime: '',
isAutoPlay: false,
width: "100%",
startMeddleTime: "",
timeRange: [],
markTime: [],
dayList:[],
daySubtractNum: 0,
isNoBack:true,
isFullScreen:false,
screenImgTotal:0,
screenImgList:[],
mouseMoveTime:'',
isMouseMove:false,
mouseMoveTimeFocus:false,
mouseTimeHour:0,
mouseTimeMin:0,
mouseTimeSec:0,
}
},
props:['isShowScreenImg','isShowSplit'],
components: {
TimeLineCanvas,
},
mounted() {
let that = this
window.addEventListener('resize', function () {
if (!that.isFullScreenFun()) {
// 非全屏状态
//业务逻辑
that.exitFullScreen()
}
});
window.addEventListener('keydown', this.timeInputKeyCode)
this.timeRange = [moment().format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD 23:59:59')]
// this.markTime = [{
// beginTime: moment().format('YYYY-MM-DD 00:00:00'),
// endTime: moment().format('YYYY-MM-DD HH:mm:ss'),
// bgColor: "rgba(255,153,0,0.9)",
// text: "",
// }]
this.startTimePickerOptions.selectableRange = '00:00:00 - ' + moment().format('HH:mm:ss')
this.startTime = moment().format('HH:mm:ss')
this.mouseTimeHour = moment().format('HH')
this.mouseTimeMin = moment().format('mm')
this.mouseTimeSec = moment().format('ss')
this.nowPlayTime = moment(this.startTime).format('HH:mm:ss')
this.mouseMoveTime = moment(this.startTime).format('HH:mm:ss')
this.initTimeLine()
this.initDay()
},
beforeDestroy() {
window.removeEventListener("resize", this.isFullScreenFun, true);
window.removeEventListener("keydown", this.timeInputKeyCode, true);
this.stopPlay()
},
methods: {
// 时间输入回车事件
timeInputKeyCode(e) {
if (e.keyCode === 13&&this.mouseMoveTimeFocus) {
this.mouseTimeBtnClick()
}
},
initTimeLine() {
this.startMeddleTime = moment().format('YYYY-MM-DD HH:mm:ss')
},
startPlay() {
if(this.isAutoPlay) {
this.stopPlay()
}
this.isNoBack = true
this.timeRange = [moment().format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD 23:59:59')]
this.markTime = [{
beginTime: moment().format('YYYY-MM-DD 00:00:00'),
endTime: moment().format('YYYY-MM-DD HH:mm:ss'),
bgColor: "rgba(255,153,0,0.9)",
text: "",
}]
this.startTimePickerOptions.selectableRange = '00:00:00 - ' + moment().format('HH:mm:ss')
this.startTime = moment().format('HH:mm:ss')
this.mouseTimeHour = moment().format('HH')
this.mouseTimeMin = moment().format('mm')
this.mouseTimeSec = moment().format('ss')
this.showDayShow = moment().format('YYYY-MM-DD')
this.startMeddleTime = moment().format('YYYY-MM-DD HH:mm:ss')
this.daySubtractNum = 0
this.initDay()
this.$refs.time_line.play(moment().format('YYYY-MM-DD HH:mm:ss'));
this.isAutoPlay = true
},
stopPlay() {
this.isAutoPlay = false
this.isNoBack = true
this.markTime = []
this.timeRange = [moment().format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD 23:59:59')]
this.startTime = moment().format('HH:mm:ss')
this.mouseTimeHour = moment().format('HH')
this.mouseTimeMin = moment().format('mm')
this.mouseTimeSec = moment().format('ss')
this.showDayShow = moment().format('YYYY-MM-DD')
this.startMeddleTime = moment().format('YYYY-MM-DD HH:mm:ss')
this.daySubtractNum = 0
if(this.$refs.time_line) {
this.$refs.time_line.stop();
}
},
showDayChange(val) {
this.showDayShow = val
if (val == moment().format('YYYY-MM-DD')) {
this.isNoBack = true
this.startTime = moment().format('HH:mm:ss')
this.mouseTimeHour = moment().format('HH')
this.mouseTimeMin = moment().format('mm')
this.mouseTimeSec = moment().format('ss')
this.startTimePickerOptions.selectableRange = '00:00:00 - ' + moment().format('HH:mm:ss')
this.markTime = [{
beginTime: moment().format('YYYY-MM-DD 00:00:00'),
endTime: moment().format('YYYY-MM-DD HH:mm:ss'),
bgColor: "rgba(255,153,0,0.9)",
text: "",
}]
} else {
this.isNoBack = false
this.startTimePickerOptions.selectableRange = '00:00:00 - 23:59:59'
this.markTime = [{
beginTime: val + ' 00:00:00',
endTime: val + ' 23:59:59',
bgColor: "rgba(255,153,0,0.9)",
text: "",
}]
}
this.startMeddleTime = moment(val + ' ' + this.startTime).format('YYYY-MM-DD HH:mm:ss')
this.$emit('videoTimeChange',this.startMeddleTime)
if(this.timeAccuracy == '24') {
this.timeRange = [val + ' 00:00:00', val + ' 23:59:59']
} else {
let startTime = moment(this.startMeddleTime).subtract((this.timeAccuracy/2), "hours").format('YYYY-MM-DD HH:mm:ss')
let endTime = moment(this.startMeddleTime).add((this.timeAccuracy/2), "hours").format('YYYY-MM-DD HH:mm:ss')
startTime = moment(startTime).format('YYYY-MM-DD') != val?val + ' 00:00:00':startTime;
endTime = moment(endTime).format('YYYY-MM-DD') != val?val + ' 23:59:59':endTime;
this.timeRange = [startTime, endTime]
}
this.nowPlayTime = moment(this.startMeddleTime).format('HH:mm:ss')
},
// 开始播放时间改变
startTimeChange(val) {
this.startTime = val
this.startMeddleTime = moment(this.showDayShow + ' ' + val).format('YYYY-MM-DD HH:mm:ss')
this.$emit('videoTimeChange',this.startMeddleTime)
this.nowPlayTime = moment(val).format('HH:mm:ss')
this.isNoBack = this.startMeddleTime == moment().format('YYYY-MM-DD HH:mm:ss')
},
// 时间轴点击
// 时间精度改变
timeAccuracyChange(val) {
// console.log(val)
this.timeAccuracy = val
this.$refs.time_line.mousewheelBtn(val)
if(this.timeAccuracy == '24') {
this.timeRange = [this.showDayShow + ' 00:00:00', this.showDayShow + ' 23:59:59']
} else {
let startTime = moment(this.startMeddleTime).subtract((this.timeAccuracy/2), "hours").format('YYYY-MM-DD HH:mm:ss')
let endTime = moment(this.startMeddleTime).add((this.timeAccuracy/2), "hours").format('YYYY-MM-DD HH:mm:ss')
startTime = moment(startTime).format('YYYY-MM-DD') != this.showDayShow?this.showDayShow + ' 00:00:00':startTime;
endTime = moment(endTime).format('YYYY-MM-DD') != this.showDayShow?this.showDayShow + ' 23:59:59':endTime;
this.timeRange = [startTime, endTime]
}
},
// 分屏改变
splitScreenClick(val) {
this.splitScreen = val
this.$emit('splitScreenChange',val)
},
// 输入框获取焦点
mouseTimeFocus() {
this.mouseMoveTimeFocus = true
},
// 返回实时
backRealTime() {
this.daySubtractNum = 0
this.initDay()
this.startTime = moment().format('HH:mm:ss')
this.mouseTimeHour = moment().format('HH')
this.mouseTimeMin = moment().format('mm')
this.mouseTimeSec = moment().format('ss')
this.showDayChange(moment().format('YYYY-MM-DD'))
},
// 时间轴方法
clickCanvas(date) {
// console.log(date);
this.startTime = moment(date).format('HH:mm:ss')
this.mouseTimeHour = moment(date).format('HH')
this.mouseTimeMin = moment(date).format('mm')
this.mouseTimeSec = moment(date).format('ss')
this.isNoBack = moment(date).format('YYYY-MM-DD HH:mm:ss') == moment().format('YYYY-MM-DD HH:mm:ss')
this.$emit('videoTimeChange',date)
},
changeDate(date, status) {
// console.log("选择时间:" + date + " 播放状态:" + status);
this.nowPlayTime = moment(date).format('HH:mm:ss')
if(!this.isMouseMove&&!this.mouseMoveTimeFocus) {
this.mouseMoveTime = this.nowPlayTime
this.mouseTimeHour = moment(date).format('HH')
this.mouseTimeMin = moment(date).format('mm')
this.mouseTimeSec = moment(date).format('ss')
this.$forceUpdate()
}
// console.log(this.nowPlayTime)
this.$emit('videoTimeSync',date)
if (moment(date).format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
this.markTime = [{
beginTime: moment().format('YYYY-MM-DD 00:00:00'),
endTime: moment().format('YYYY-MM-DD HH:mm:ss'),
bgColor: "rgba(255,153,0,0.9)",
text: "",
}]
}
},
// 时间线移动
mouseMoveDate(date) {
if(date) {
this.isMouseMove = true
this.mouseMoveTime = moment(date).format('HH:mm:ss')
if(!this.mouseMoveTimeFocus) {
this.mouseTimeHour = moment(date).format('HH')
this.mouseTimeMin = moment(date).format('mm')
this.mouseTimeSec = moment(date).format('ss')
}
} else {
this.isMouseMove = false
this.mouseMoveTime = this.nowPlayTime
if(!this.mouseMoveTimeFocus) {
let nowPlayTimeArr = this.nowPlayTime.split(':')
this.mouseTimeHour = nowPlayTimeArr[0]
this.mouseTimeMin = nowPlayTimeArr[1]
this.mouseTimeSec = nowPlayTimeArr[2]
}
}
this.$forceUpdate()
},
// 时间线左右点击
timeLineMove(val) {
let width = document.getElementById('timeline-canvas').clientWidth
this.$refs.time_line.mouseDownMoveBtn(val*width/4)
},
// 日期轴方法
initDay() {
console.log(document.getElementsByClassName('date-axis'))
let allWidth = document.getElementsByClassName('date-axis')[0].clientWidth
let canNum = ((allWidth - 20) / 46) - 3
let startTime = new Date(moment().subtract(this.daySubtractNum*10+canNum, "days").format('YYYY-MM-DD HH:mm:ss')).getTime()
let datList = []
for(let i = 1; i < (canNum+1); i++) {
let oneDate = new Date(startTime + i*24*3600*1000)
let label = oneDate.getDate()
if(i==1||oneDate.getDate()*1 == 1||i==canNum) {
label = (oneDate.getMonth()*1 + 1) + '/' + oneDate.getDate()
}
if(moment(oneDate).format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
label = '今天'
}
if(oneDate.getTime() > new Date().getTime()) {
break;
}
datList.push({
label:label,
value:moment(oneDate).format('YYYY-MM-DD')
})
}
this.dayList = datList
},
// 日期左右按钮点击
dayLineMove(val) {
if(val > 0||(this.daySubtractNum>0&&val < 0)) {
this.daySubtractNum = this.daySubtractNum+val
this.initDay()
}
},
// 原有操作
exitFullScreen(){
this.isFullScreen = false
this.$emit('allVideoExitFullScreen')
},
fullScreen(val){
this.isFullScreen = true
this.$emit('allVideoFullScreen')
},
isFullScreenFun() {
return !!(document.webkitIsFullScreen || this.fullele());
},
fullele() {
return (
document.fullscreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement ||
document.mozFullScreenElement ||
null
);
},
// 时间输入框控制
mouseTimeHourChange(val) {
// console.log(val)
this.mouseTimeHour = (!isNaN(val) && val < 24 && val>=0)?val<10?'0' + (val*1):val:'00';
},
mouseTimeMinChange(val) {
// console.log(val)
this.mouseTimeMin = (!isNaN(val) && val < 60 && val>=0)?val<10?'0' + (val*1):val:'00';
},
mouseTimeSecChange(val) {
// console.log(val)
this.mouseTimeSec = (!isNaN(val) && val < 60 && val>=0)?val<10?'0' + (val*1):val:'00';
// console.log(val)
},
mouseTimeBtnClick() {
// console.log('this.mouseTimeMin',this.mouseTimeMin)
this.mouseTimeHourChange(this.mouseTimeHour)
this.mouseTimeMinChange(this.mouseTimeMin)
this.mouseTimeSecChange(this.mouseTimeSec)
this.startTimeChange(this.mouseTimeHour + ':' + this.mouseTimeMin + ':' + this.mouseTimeSec)
this.$refs.mouseTimeHour.blur()
this.$refs.mouseTimeMin.blur()
this.$refs.mouseTimeSec.blur()
this.mouseMoveTimeFocus = false
},
}
}
</script>
<style scoped lang="less">
.time-page {
// background: rgba(0, 0, 0, 0.9);
width: 100%;
height: 122px;
position: relative;
.time-operation-module {
padding: 0 10px;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
top:3px;
.operation-module-left {
position: relative;
z-index: 2;
display: inline-flex;
align-items: center;
color: #ffffff;
.lookPic{
// margin-left: 20px;
color: #ffffff;
font-size: 15px;
cursor: pointer;
}
}
.operation-module-center{
position: absolute;
top:0px;
left:0px;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
.go-back-realtime-btn {
margin-left: 20px;
}
.time-input-box{
width: 110px;
display: inline-flex;
align-items: center;
height: 26px;
border: 1px solid #dcdcdc;
border-radius: 4px;
color:#fff;
.time-input-list{
width: 85px;
height: 26px;
border-right: 1px solid #dcdcdc;
display: inline-flex;
align-items: center;
justify-content: center;
}
.time-input-btn{
cursor: pointer;
width: 25px;
font-size: 14px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.time-input-line{
height: 26px;
line-height: 26px;
}
/deep/.el-input{
width: 24px;
display: inline-flex;
align-items: center;
}
/deep/.el-input__inner{
padding: 0px!important;
background: transparent!important;
color:#fff!important;
border: 0px!important;
box-shadow: none!important;
text-align: center!important;
}
}
}
.operation-module-right {
position: relative;
z-index: 2;
display: inline-flex;
align-items: center;
color: #ffffff;
.fullScreen{
font-size: 16px;
cursor: pointer;
}
.split-screen-control {
display: inline-flex;
height: 100%;
align-items: center;
color: #ffffff;
margin-right: 20px;
.split-screen-text {
display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
text-align: center;
color: #ffffff;
}
.el-dropdown{
height: 100%;
display: inline-flex;
align-items: center;
cursor: pointer;
}
}
.time-line-accuracy {
height: 100%;
display: inline-flex;
align-items: center;
color: #ffffff;
margin-right: 20px;
.time-accuracy-text {
display: inline-block;
width: 65px;
text-align: center;
color: #ffffff;
}
}
.play-time-show {
font-size: 12px !important;
color: #ffffff;
margin-right: 20px;
}
}
/deep/.el-input {
height: 26px !important;
.el-input__inner {
padding-right: 10px;
}
}
}
.time-axis {
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
border-bottom: 1px solid #666666;
.timeline-icon-box {
display: inline-flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.8);
color: #111;
border-radius: 20px;
height: 24px;
width: 24px;
font-size: 16px;
cursor: pointer;
}
.timeline-canvas-box{
width: 100%;
height: 40px;
position: relative;
}
}
.date-axis{
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
.dayline-icon-box{
display: inline-flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: 20px;
height: 40px;
width: 40px;
font-size: 24px;
cursor: pointer;
}
.dayline-list-box{
width: calc(100% - 80px)!important;
color: #fff;
display: inline-flex;
align-items: center;
justify-content: space-between;
.dayline-list-one{
height: 40px;
width: 60px;
display: inline-flex;
align-items: center;
justify-content: center;
margin: 0 3px;
cursor: pointer;
&:hover{
background: rgba(255, 255, 255, 0.3);
}
}
.dayline-list-one-select{
background: rgba(255, 255, 255, 0.9)!important;
color: #111!important;
}
}
}
.timeline-canvas-bg{
width: 100%;
height: 83px;
position: absolute;
bottom:0px;
left:0px;
z-index: 10;
}
}
/deep/.el-button--primar:hover{
background-color: rgba(64,118,247,0.7) !important;
border-color: rgba(64,118,247,0.7) !important;
}
/deep/.el-input-group__append{
padding: 0 3px!important;
.el-button{
padding: 0px!important;
margin: 0px!important;
}
}
.split-screen-img{
width: 20px;
height: 20px;
}
</style>
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!