/************************************************* Function: bindAsEventListener Description: 绑定对象到函数 Input: object 对象, fun 函数 Output: 无 return: 关联后的函数 *************************************************/ var bindAsEventListener = function(object, fun) { var args = Array.prototype.slice.call(arguments).slice(2); return function(event) { return fun.apply(object, [event || window.event].concat(args)); }; }; /************************************************* Function: bind Description: 绑定对象到函数 Input: object 对象, fun 函数 Output: 无 return: 关联后的函数 *************************************************/ var bind = function(object, fun) { return function() { return fun.apply(object, arguments); }; }; /************************************************* Function: addEventHandler Description: 添加事件 Input: oTarget 目标对象, sEventType 事件, fnHandler 函数 Output: 无 return: 无 *************************************************/ var addEventHandler = function(oTarget, sEventType, fnHandler) { oTarget["on" + sEventType] = fnHandler; }; var removeEventHandler = function(oTarget, sEventType, fnHandler) { oTarget["on" + sEventType] = null; }; /************************************************* Function: getObjLeft Description: 获取对象相对网页的左上角坐标 Input: obj 对象 Output: 无 return: 坐标 *************************************************/ function getObjLeft(obj) { var x = obj.offsetLeft; while(obj=obj.offsetParent) { x += obj.offsetLeft; } return x; } /************************************************* Function: getObjTop Description: 获取对象相对网页的左上角坐标 Input: obj 对象 Output: 无 return: 坐标 *************************************************/ function getObjTop(obj) { var y = obj.offsetTop; while(obj=obj.offsetParent) { y += obj.offsetTop; } return y; } function ScaleInfo(x, y, iSeconds) { this.f_ix = x; this.f_iy = y; this.f_ixMin; this.f_ixMax; this.f_iHour = parseInt(iSeconds / 3600, 10); this.f_iMinute = parseInt(iSeconds % 3600 / 60, 10); this.f_iSecond = parseInt(iSeconds % 3600 % 60, 10); this.f_szTime = ""; if(this.f_iHour < 10 && this.f_iMinute < 10) { this.f_szTime = "0" + this.f_iHour + ":0" + this.f_iMinute; } else if(this.f_iHour < 10 && this.f_iMinute >= 10) { this.f_szTime = "0" + this.f_iHour + ":" + this.f_iMinute; } else if(this.f_iHour >= 10 && this.f_iMinute >= 10) { this.f_szTime = "" + this.f_iHour + ":" + this.f_iMinute; } else { this.f_szTime = "" + this.f_iHour + ":0" + this.f_iMinute; } } /************************************************* Function: setPos Description: 设置刻度的位置 Input: x 横坐标, y 纵坐标 Output: 无 return: 无 *************************************************/ ScaleInfo.prototype.setPos = function(x, y) { // this.x = x; if (x < this.f_ixMin) { x = this.f_ixMax - (this.f_ixMin - x); } else if (x > this.f_ixMax) { x = this.f_ixMin + (x - this.f_ixMax); } this.f_ix = x; this.f_iy = y; }; /************************************************* Function: setPosRange Description: 设置刻度显示的范围 Input: ixMin 最小横坐标, ixMax 最大横坐标 Output: 无 return: 无 *************************************************/ ScaleInfo.prototype.setPosRange = function(ixMin, ixMax) { this.f_ixMin = ixMin; this.f_ixMax = ixMax; }; /************************************************* Function: isInRange Description: 是否在范围内 Input: ixMin 最小横坐标, ixMax 最大横坐标 Output: 无 return: bool *************************************************/ ScaleInfo.prototype.isInRange = function(iMin, iMax) { if (this.f_ix >= iMin && this.f_ix <= iMax) { return true; } else { return false; } }; /************************************************* Function: update Description: 更新刻度时间 Input: iSeconds Output: 无 return: 无 *************************************************/ ScaleInfo.prototype.update = function(iSeconds) { this.f_iHour = parseInt(iSeconds / 3600, 10); this.f_iMinute = parseInt(iSeconds % 3600 / 60, 10); this.f_iSecond = parseInt(iSeconds % 3600 % 60, 10); if(this.f_iHour < 10 && this.f_iMinute < 10) { this.f_szTime = "0" + this.f_iHour + ":0" + this.f_iMinute; } else if(this.f_iHour < 10 && this.f_iMinute >= 10) { this.f_szTime = "0" + this.f_iHour + ":" + this.f_iMinute; } else if(this.f_iHour >= 10 && this.f_iMinute >= 10) { this.f_szTime = "" + this.f_iHour + ":" + this.f_iMinute; } else { this.f_szTime = "" + this.f_iHour + ":0" + this.f_iMinute; } }; function Time() { var tCurrentTime = new Date(); this.f_iYear = tCurrentTime.getFullYear(); this.f_iMonth = tCurrentTime.getMonth()+1; this.f_iDay = tCurrentTime.getDate(); this.f_iHour = tCurrentTime.getHours(); this.f_iMinute = tCurrentTime.getMinutes(); this.f_iSecond = tCurrentTime.getSeconds(); this.f_iMilliseconds = tCurrentTime.getTime(); //返回 1970 年 1 月 1 日至今的毫秒数 } /************************************************* Function: setTimeByMis Description: 设置时间 Input: iMilliseconds: 1970 年 1 月 1 日至今的毫秒数 Output: 无 return: 无 *************************************************/ Time.prototype.setTimeByMis = function(iMilliseconds) { var tSetTime = new Date(iMilliseconds); this.f_iYear = tSetTime.getFullYear(); this.f_iMonth = tSetTime.getMonth()+1; this.f_iDay = tSetTime.getDate(); this.f_iHour = tSetTime.getHours(); this.f_iMinute = tSetTime.getMinutes(); this.f_iSecond = tSetTime.getSeconds(); this.f_iMilliseconds = iMilliseconds; }; /************************************************* Function: getStringTime Description: 获取时间字符串 Input: 无 Output: 无 return: string yyyy-MM-dd HH:mm:ss *************************************************/ Time.prototype.getStringTime = function() { var szYear = "" + this.f_iYear; var szMonth; if(this.f_iMonth < 10) { szMonth = "0" + this.f_iMonth; } else { szMonth = "" + this.f_iMonth; } var szDay; if(this.f_iDay < 10) { szDay = "0" + this.f_iDay; } else { szDay = "" + this.f_iDay; } var szHour; if(this.f_iHour < 10) { szHour = "0" + this.f_iHour; } else { szHour = "" + this.f_iHour; } var szMinute; if(this.f_iMinute < 10) { szMinute = "0" + this.f_iMinute; } else { szMinute = "" + this.f_iMinute; } var szSecond; if(this.f_iSecond < 10) { szSecond = "0" + this.f_iSecond; } else { szSecond = "" + this.f_iSecond; } var szCurrentTime = szYear + "-" + szMonth + "-" + szDay + " " + szHour + ":" + szMinute + ":" + szSecond; return szCurrentTime; }; /************************************************* Function: parseTime Description: 通过时间字符串设置时间 Input: szTime 时间 yyyy-MM-dd HH:mm:ss Output: 无 return: 无 *************************************************/ Time.prototype.parseTime = function(szTime) { var aDate = szTime.split(' ')[0].split('-'); var aTime = szTime.split(' ')[1].split(':'); this.f_iYear = parseInt(aDate[0],10); this.f_iMonth = parseInt(aDate[1],10); this.f_iDay = parseInt(aDate[2],10); this.f_iHour = parseInt(aTime[0],10); this.f_iMinute = parseInt(aTime[1],10); this.f_iSecond = parseInt(aTime[2],10); var tTime = new Date(); tTime.setFullYear(this.f_iYear); tTime.setMonth(this.f_iMonth - 1, this.f_iDay); tTime.setHours(this.f_iHour); tTime.setMinutes(this.f_iMinute); tTime.setSeconds(this.f_iSecond); this.f_iMilliseconds = tTime.getTime(); }; function FileInfo(iX, iY, iWidth, iHeight, iType, cColor, tStartTime, tStopTime) { this.f_iX = iX; this.f_ixMin = 0; this.f_ixMax = 0; this.f_iY = iY; this.f_iWidth = iWidth; this.f_iHeight = iHeight; this.f_cColor = cColor; this.f_iType = iType; this.f_tStartTime = tStartTime; this.f_tStopTime = tStopTime; } /************************************************* Function: isInRange Description: 是否在范围之内 Input: left 左起始点 right 右终点 Output: 无 return: 无 *************************************************/ FileInfo.prototype.isInRange = function(left, right) { if ((this.f_iX+this.f_iWidth) <= left || this.f_iX >= right) { return false; } else { return true; } }; /************************************************* Function: setPos Description: 设置位置内 Input: iX iY左起始点坐标 iWidth 宽度 iHeight高度 Output: 无 return: 无 *************************************************/ FileInfo.prototype.setPos = function(iX, iY, iWidth, iHeight) { this.f_iX = iX; this.f_iWidth = iWidth; this.f_iY = iY; this.f_iHeight = iHeight; }; /************************************************* Function: setPosRange Description: 设置范围 Input: ixMin, ixMax Output: 无 return: 无 *************************************************/ FileInfo.prototype.setPosRange = function(ixMin, ixMax) { this.f_ixMin = ixMin; this.f_ixMax = ixMax; }; /************************************************* Function: draw Description: 画文件信息 Input: g 设备资源 Output: 无 return: 无 *************************************************/ FileInfo.prototype.draw = function(g) { if (this.isInRange(this.f_ixMin, this.f_ixMax)) { var colorOld = g.fillStyle; g.fillStyle = this.f_cColor; if ((this.f_iX >= this.f_ixMin) && (this.f_iX+this.f_iWidth) <= this.f_ixMax) { g.fillRect(this.f_iX, this.f_iY, this.f_iWidth, this.f_iHeight); } else if ((this.f_iX < this.f_ixMax) && ((this.f_iX+this.f_iWidth) > this.f_ixMax)) { g.fillRect(this.f_iX, this.f_iY, this.f_ixMax - this.f_iX, this.f_iHeight); } else { g.fillRect(this.f_ixMin, this.f_iY, (this.f_iX+this.f_iWidth) - this.f_ixMin, this.f_iHeight); } g.fillStyle = colorOld; } }; var g_nLastClientX = null; function TimeBar(canvas, iWidth, iHeight) { if(arguments.length >= 3) { canvas.width = arguments[1]; canvas.height = arguments[2]; } else { canvas.width = 1200; canvas.height = 70; } this.f_canvas = canvas; this.f_ctx = canvas.getContext("2d"); this.f_iMinFileWidth = 1; //文件的最小宽度 this.backgroundColor = 'rgb(27, 27, 27)'; //时间条背景颜色 this.partLineColor = 'rgb(48,48,48)'; //分割线颜色 this.channelNameColor = 'rgb(150, 150, 150)'; //通道名称颜色 this.timebarBackColor = '#263D5A'//'#cfd3de'; //背景颜色 this.timeScaleColor = 'rgb(150, 150, 150)'; //时间条刻度颜色 this.middleLineColor = '#ffffff' //'#1aa5f0'; //中轴线颜色 this.middleLineTimeColor = '#ffffff' //'rgb(30,144,255)';//中轴时间颜色 this.mouseOverTimeColor = '#5261de' //'rgb(255, 255, 255)';//鼠标悬浮时间颜色 this.defaultFileColor = 'rgb(0, 255, 0)';//'#2bf6a3'; //默认录像类型颜色 this.cmdFileColor = 'rgb(21, 184, 155)'; //命令触发录像颜色 this.scheFileColor = 'rgb(0,0,255)'; // 排程录像颜色 this.timeVideoColor = '#3ED5BA'; // 定时录像颜色 this.mdVideoColor = '#2cbef1'; // 移动侦测录像颜色 this.alarmFileColor = '#F37272'; // 报警录像颜色 this.manualFileColor = 'rgb(247, 199, 5)'; //手动录像颜色 this.f_fMidTimeFont = '14px arial'; //中线时间字体及大小 this.f_fCurTimeFont = '11px Verdana'; //鼠标当前时间字体及大小 this.f_fScaleFont = '10px Verdana'; //刻度字体及大小 sans-serif this.f_fChannelNameFont = '14px Verdana'; //通道名称字体 // canvas.style.backgroundColor = this.backgroundColor; this.f_szCurChannelName = ''; //当前通道名称 this.f_fCellTime = parseFloat(1.0); //每个代表几个小时 this.ScaleInfo = new Array(); this.ScaleInfoNum = parseInt(24/this.f_fCellTime, 10); //总的刻度数量 this.ScaleInfoDisNum = 12; //显示的刻度数量 //初始化刻度 for(var i = 0; i < this.ScaleInfoNum; i++) { this.ScaleInfo.push(new ScaleInfo(0, 0, parseInt(i * 3600 * this.f_fCellTime))); } this.f_iMaxWndNum = 16; //最大窗口数 this.f_iSelWnd = 0; //选中的窗口号 this.FileInfoSet = new Array(this.f_iMaxWndNum); //文件信息集合 //初始化文件信息集合 for(i = 0; i < this.f_iMaxWndNum; i++) { this.FileInfoSet[i] = new Array(); } this.f_iHeight = parseInt(canvas.height, 10); this.f_iWidth = parseInt(canvas.width, 10); this.f_iFileListStartPos = 0; // 文件列表起始位置 this.f_iBlankHeight = 4; // 中间及底边空白宽度 this.f_iTimeRectHeight = 0; //parseInt(this.f_iHeight * 4 / 7) 时间块的高度 this.f_iFileRectHeight = 20 - this.f_iBlankHeight * 2; //文件块的高度 this.f_iMiddleLinePos = parseInt((this.f_iFileListStartPos + this.f_iWidth) / 2, 10); //中轴线的位置 this.f_iCellWidth = Math.floor((this.f_iWidth - this.f_iFileListStartPos)/this.ScaleInfoDisNum); //每个像素的秒数 this.f_iCellMilliseconds = parseInt((3600 * this.f_fCellTime * 1000)/this.f_iCellWidth, 10); //每个像素的毫秒数 this.f_tCurrentMidTime = new Time(); //当前中轴线的时间 this.f_ctx.font = this.f_fMidTimeFont; this.f_iTextWidth = this.f_ctx.measureText(this.f_tCurrentMidTime.getStringTime()).width; this.f_tMouseCurTime = new Time(); //当前鼠标点的时间 this.f_ctx.font = this.f_fCurTimeFont; this.f_iCurTextWidth = this.f_ctx.measureText(this.f_tMouseCurTime.getStringTime()).width; this.f_iCanvasLeft = getObjLeft(this.f_canvas); this.f_iCanvasTop = getObjTop(this.f_canvas); //初始化时间刻度信息 for (i = 0; i < this.ScaleInfoNum; i++) { // 计算与中轴线的时间差(只计算时分秒) var seconds = (this.ScaleInfo[i].f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (this.ScaleInfo[i].f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (this.ScaleInfo[i].f_iSecond - this.f_tCurrentMidTime.f_iSecond); var iScalePos = this.f_iMiddleLinePos + parseInt(parseFloat(seconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); // 设置刻度位置范围 this.ScaleInfo[i].setPosRange(this.f_iFileListStartPos, this.f_iFileListStartPos + parseInt(this.f_iCellWidth * this.ScaleInfoNum)); this.ScaleInfo[i].setPos(iScalePos, this.f_iTimeRectHeight + this.f_iFileRectHeight); } //注册消息响应 this.f_ieventX = 0; this.f_iMousePosX = 0; this.f_nLastClientX = 0; this.f_bMOuseDown = false; this.f_bMouseOver = false; this.f_hasMove = false; this.f_iMove = 0; this.f_iMiddleLineTime = 0; this.Start = function(oEvent) { this.f_ieventX = oEvent.clientX; this.f_iMiddleLineTime = this.f_tCurrentMidTime.f_iMilliseconds; this.f_bMOuseDown = true; addEventHandler(document, 'mousemove', bindAsEventListener(this, this.Move)); addEventHandler(document, 'mouseup', bind(this, this.Stop)); //焦点丢失 addEventHandler(window, "blur", bindAsEventListener(this, bindAsEventListener(this, this.Stop))); //阻止默认动作 if(oEvent.preventDefault) oEvent.preventDefault(); else oEvent.returnValue = false; removeEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove)); }; this.mouseUpCallbackFunc = function(){}; this.Stop = function() { document.body.style.cursor='default'; this.f_canvas.style.cursor="url(./static/sxplayer/css/img/H_point1.cur),pointer"; this.f_bMOuseDown = false; this.mouseUpCallbackFunc(); removeEventHandler(document, 'mousemove', bindAsEventListener(this, this.Move)); removeEventHandler(document, 'mouseup', bindAsEventListener(this, this.Stop)); removeEventHandler(window, "blur", bindAsEventListener(this, this.Stop)); addEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove)); if(!this.f_hasMove){ //清除选择 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); this.f_tCurrentMidTime.setTimeByMis(this.f_tMouseCurTime.f_iMilliseconds); this.repaint(); } this.f_hasMove = false; }; this.onMouseMoveIn = true; this.Move = function(oEvent) { this.f_hasMove = true; document.body.style.cursor="url(./static/sxplayer/css/img/H_point.cur),pointer"; this.f_canvas.style.cursor="url(./static/sxplayer/css/img/H_point.cur),pointer"; if(this.f_nLastClientX == oEvent.clientX) return ; this.f_nLastClientX = oEvent.clientX; this.f_iMove = oEvent.clientX - this.f_ieventX; if(this.f_bMOuseDown) { //清除选择 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); this.f_tCurrentMidTime.setTimeByMis(this.f_iMiddleLineTime - this.f_iMove * this.f_iCellMilliseconds); this.repaint(); } }; this.f_canvas.style.cursor="url(./static/sxplayer/css/img/H_point1.cur),pointer"; this.onMouseMove = function(oEvent) { if(this.f_nLastClientX == oEvent.clientX) return; this.f_iMousePosX = oEvent.clientX - this.f_iCanvasLeft; this.f_nLastClientX = oEvent.clientX; this.f_tMouseCurTime.setTimeByMis((this.f_iMousePosX - this.f_iMiddleLinePos) * this.f_iCellMilliseconds + this.f_tCurrentMidTime.f_iMilliseconds); this.repaint(); var szCurMouseTime = this.f_tMouseCurTime.getStringTime(); this.f_ctx.font = this.f_fCurTimeFont; let x = (this.f_iMousePosX - parseInt(this.f_iCurTextWidth/2)) < 0 ? 0 : ((this.f_iMousePosX + parseInt(this.f_iCurTextWidth/2)) > this.f_iWidth ? this.f_iWidth - parseInt(this.f_iCurTextWidth) : (this.f_iMousePosX - parseInt(this.f_iCurTextWidth/2))); let y = this.f_iFileRectHeight; this.f_ctx.fillStyle = '#ffffff'; this.f_ctx.fillRect(x, y-10, 123, 10); this.f_ctx.fillStyle = this.mouseOverTimeColor; this.f_ctx.fillText(szCurMouseTime, x, y); }; this.onMouseOut = function(oEvent) { this.repaint(); }; addEventHandler(canvas, 'mousedown', bindAsEventListener(this, this.Start)); addEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove)); addEventHandler(canvas, 'mouseout', bindAsEventListener(this, this.onMouseOut)); //this.setMidLineTime('2011-04-20 10:00:00'); this.repaint(); } /************************************************* Function: repaint Description: 重绘 Input: 无 Output: 无 return: 无 *************************************************/ TimeBar.prototype.repaint = function() { var szCurrentTime = this.f_tCurrentMidTime.getStringTime(); this.updateScalePos(); this.updateFileListPos(); this.f_iCanvasLeft = getObjLeft(this.f_canvas); this.f_ctx.clearRect(0, 0, this.f_iWidth, this.f_iHeight); //显示通道名称 this.f_ctx.fillStyle = this.channelNameColor; this.f_ctx.font = this.f_fChannelNameFont; this.f_ctx.fillText(this.f_szCurChannelName, 0, this.f_iTimeRectHeight + this.f_iBlankHeight + parseInt(this.f_iFileRectHeight / 2) - 10, 90); this.f_ctx.strokeStyle = this.timeScaleColor; this.f_ctx.font = this.f_fScaleFont; this.f_ctx.lineWidth = 1; //画时间刻度 for (i = 0; i < this.ScaleInfoNum; i++) { if (this.ScaleInfo[i].isInRange(this.f_iFileListStartPos, this.f_iWidth)) { this.f_ctx.beginPath(); this.f_ctx.moveTo(this.ScaleInfo[i].f_ix, this.f_iTimeRectHeight + 17); this.f_ctx.lineTo(this.ScaleInfo[i].f_ix, this.f_iTimeRectHeight - 4); this.f_ctx.stroke(); this.f_ctx.fillText(this.ScaleInfo[i].f_szTime, this.ScaleInfo[i].f_ix - 15, this.f_iTimeRectHeight + 25); } } this.f_ctx.fillStyle = this.timebarBackColor; this.f_ctx.fillRect(0, parseInt(this.f_iBlankHeight/2)-6, this.f_iWidth, this.f_iFileRectHeight + this.f_iBlankHeight); //画文件信息区域 for(i = 0; i < this.FileInfoSet[this.f_iSelWnd].length; i++) { this.FileInfoSet[this.f_iSelWnd][i].draw(this.f_ctx); } //画中轴线 this.f_ctx.strokeStyle = this.middleLineColor; this.f_ctx.lineWidth = 4; this.f_ctx.beginPath(); this.f_ctx.moveTo(this.f_iMiddleLinePos, 0); this.f_ctx.lineTo(this.f_iMiddleLinePos, 12); this.f_ctx.stroke(); //画中轴时间 this.f_ctx.globalAlpha = 0.7; this.f_ctx.fillStyle = 'rgb(51 51 51)'; this.f_ctx.font = this.f_fMidTimeFont; this.f_iTextWidth = this.f_ctx.measureText(szCurrentTime).width; let x = (this.f_iMiddleLinePos - parseInt(this.f_iTextWidth/2)); let y = this.f_iHeight - 10; // this.f_ctx.fillRect(x-10, y-10, 150, 20); this.f_ctx.beginPath(); this.f_ctx.moveTo(this.f_iMiddleLinePos,13); this.f_ctx.lineTo(this.f_iMiddleLinePos - 5,19); this.f_ctx.lineTo(this.f_iMiddleLinePos + 5,19); this.f_ctx.closePath(); this.f_ctx.fill(); fillRoundRect(this.f_ctx,x-6, y-9, 142, 19,4); this.f_ctx.fillStyle = this.middleLineTimeColor; this.f_ctx.fillText(szCurrentTime, (this.f_iMiddleLinePos - parseInt(this.f_iTextWidth/2)), y+6); this.f_ctx.globalAlpha = 1; }; /************************************************* Function: updateScalePos Description: 更新刻度 Input: 无 Output: 无 return: 无 *************************************************/ TimeBar.prototype.updateScalePos = function() { if (this.ScaleInfo.length == 0) { return; } // 以00:00移动的距离为准 var seconds = (this.ScaleInfo[0].f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (this.ScaleInfo[0].f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (this.ScaleInfo[0].f_iSecond - this.f_tCurrentMidTime.f_iSecond); var iPos0 = this.f_iMiddleLinePos + parseInt(parseFloat(seconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); if (iPos0 < this.ScaleInfo[0].f_ixMin) { iPos0 = this.ScaleInfo[0].f_ixMax - (this.ScaleInfo[0].f_ixMin - iPos0); } else if (iPos0 > this.ScaleInfo[0].f_ixMax) { iPos0 = this.ScaleInfo[0].f_ixMin + (iPos0 - this.ScaleInfo[0].f_ixMax); } var iMoved = iPos0 - this.ScaleInfo[0].f_ix; //没有移动直接返回 if(iMoved == 0) { return; } // 更新所有的刻度 for (var i = 0; i < this.ScaleInfoNum; i++) { var iScalePos = this.ScaleInfo[i].f_ix + iMoved; // 设置刻度位置范围 this.ScaleInfo[i].setPosRange(this.f_iFileListStartPos, this.f_iFileListStartPos + parseInt(this.f_iCellWidth * this.ScaleInfoNum)); this.ScaleInfo[i].setPos(iScalePos, this.f_iTimeRectHeight); } }; /************************************************* Function: updateFileListPos Description: 更新文件 Input: 无 Output: 无 return: 无 *************************************************/ TimeBar.prototype.updateFileListPos= function() { var iFileLength = this.FileInfoSet[this.f_iSelWnd].length; if(iFileLength == 0) { return; } var tStartTime = this.FileInfoSet[this.f_iSelWnd][0].f_tStartTime; var seconds = parseInt((tStartTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFile0Pos = this.f_iMiddleLinePos + parseInt(parseFloat(seconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); var iMoved = iFile0Pos - this.FileInfoSet[this.f_iSelWnd][0].f_iX; //没有移动直接返回 if(iMoved == 0) { return; } // 更新所有 for (i = 0; i < iFileLength; i++) { var iX = this.FileInfoSet[this.f_iSelWnd][i].f_iX + iMoved; var iY = this.FileInfoSet[this.f_iSelWnd][i].f_iY; var iWidth = this.FileInfoSet[this.f_iSelWnd][i].f_iWidth; var iHeight = this.FileInfoSet[this.f_iSelWnd][i].f_iHeight; this.FileInfoSet[this.f_iSelWnd][i].setPos(iX, iY, iWidth, iHeight); } }; /************************************************* Function: resize Description: 重置大小 Input: iWidth宽度, iHeight高度 Output: 无 return: 无 *************************************************/ TimeBar.prototype.resize = function(iWidth, iHeight) { this.f_canvas.height = iHeight; this.f_canvas.width = iWidth; this.f_iHeight = iHeight; this.f_iWidth = iWidth; this.f_iTimeRectHeight = 0; //parseInt(this.f_iHeight * 4 / 7) 时间块的高度 this.f_iFileRectHeight = 20 - this.f_iBlankHeight * 2; this.f_iMiddleLinePos = parseInt((this.f_iFileListStartPos + this.f_iWidth) / 2); this.f_iCellWidth = Math.floor((this.f_iWidth - this.f_iFileListStartPos)/this.ScaleInfoDisNum); this.f_iCellMilliseconds = parseInt((3600 * this.f_fCellTime * 1000)/this.f_iCellWidth, 10); //初始化时间刻度信息 for (i = 0; i < this.ScaleInfoNum; i++) { // 计算与中轴线的时间差(只计算时分秒) var seconds = (this.ScaleInfo[i].f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (this.ScaleInfo[i].f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (this.ScaleInfo[i].f_iSecond - this.f_tCurrentMidTime.f_iSecond); var iScalePos = this.f_iMiddleLinePos + parseInt(parseFloat(seconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); // 设置刻度位置范围 this.ScaleInfo[i].setPosRange(this.f_iFileListStartPos, this.f_iFileListStartPos + parseInt(this.f_iCellWidth * this.ScaleInfoNum)); this.ScaleInfo[i].setPos(iScalePos, this.f_iTimeRectHeight + this.f_iFileRectHeight); } //初始化文件列表信息 for (i = 0; i < this.FileInfoSet[this.f_iSelWnd].length; i++) { var FileInfoSetSel = this.FileInfoSet[this.f_iSelWnd][i]; var iXLeftSeconds = parseInt((FileInfoSetSel.f_tStartTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFilePosLeft = this.f_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); /*var iXRightSeconds = (tStopTime.f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (tStopTime.f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (tStopTime.f_iSecond - this.f_tCurrentMidTime.f_iSecond);*/ var iXRightSeconds = parseInt((FileInfoSetSel.f_tStopTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFilePosRight = this.f_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); if((iFilePosRight - iFilePosLeft) < this.f_iMinFileWidth) { iFilePosRight = iFilePosLeft + this.f_iMinFileWidth; } FileInfoSetSel.setPos(iFilePosLeft, parseInt(this.f_iBlankHeight/2) - 5, iFilePosRight - iFilePosLeft, this.f_iFileRectHeight + 2); } this.repaint(); }; /************************************************* Function: SetSpantype Description: 设置时间条的显示样式 Input: 无 Output: 无 return: 无 *************************************************/ TimeBar.prototype.SetSpantype = function(iSpanType) { switch(iSpanType) { case 6://每2小时一格 this.ScaleInfoDisNum = 12; this.f_fCellTime = parseFloat(2.0); break; case 7://每小时一格 this.ScaleInfoDisNum = 12; this.f_fCellTime = parseFloat(1.0); break; case 8://每半小时一格 this.ScaleInfoDisNum = 12; this.f_fCellTime = parseFloat(0.5); break; case 9://每半小时一格 this.ScaleInfoDisNum = 8; this.f_fCellTime = parseFloat(0.5); break; case 10://每10分钟一格 this.ScaleInfoDisNum = 12; this.f_fCellTime = parseFloat(1/6); break; case 11://每5分钟一格 this.ScaleInfoDisNum = 12; this.f_fCellTime = parseFloat(1/12); break; case 12://每5分钟一格 this.ScaleInfoDisNum = 6; this.f_fCellTime = parseFloat(1/12); break; default: this.ScaleInfoDisNum = 12; this.f_fCellTime = parseFloat(1.0); return; } this.ScaleInfoNum = parseInt(24/this.f_fCellTime, 10); this.f_iCellWidth = Math.floor((this.f_iWidth - this.f_iFileListStartPos)/this.ScaleInfoDisNum); this.f_iCellMilliseconds = parseInt((3600 * this.f_fCellTime * 1000)/this.f_iCellWidth, 10); //初始化刻度 this.ScaleInfo.length = 0; for(var i = 0; i < this.ScaleInfoNum; i++) { this.ScaleInfo.push(new ScaleInfo(0, 0, parseInt(i * 3600 * this.f_fCellTime))); } //初始化时间刻度信息 for (i = 0; i < this.ScaleInfoNum; i++) { // 计算与中轴线的时间差(只计算时分秒) var seconds = (this.ScaleInfo[i].f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (this.ScaleInfo[i].f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (this.ScaleInfo[i].f_iSecond - this.f_tCurrentMidTime.f_iSecond); var iScalePos = this.f_iMiddleLinePos + parseInt(parseFloat(seconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); // 设置刻度位置范围 this.ScaleInfo[i].setPosRange(this.f_iFileListStartPos, this.f_iFileListStartPos + parseInt(this.f_iCellWidth * this.ScaleInfoNum)); this.ScaleInfo[i].setPos(iScalePos, this.f_iTimeRectHeight + this.f_iTimeRectHeight); } //初始化文件列表信息 for (i = 0; i < this.FileInfoSet[this.f_iSelWnd].length; i++) { var FileInfoSetSel = this.FileInfoSet[this.f_iSelWnd][i]; var iXLeftSeconds = parseInt((FileInfoSetSel.f_tStartTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFilePosLeft = this.f_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); /*var iXRightSeconds = (tStopTime.f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (tStopTime.f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (tStopTime.f_iSecond - this.f_tCurrentMidTime.f_iSecond);*/ var iXRightSeconds = parseInt((FileInfoSetSel.f_tStopTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFilePosRight = this.f_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); if((iFilePosRight - iFilePosLeft) < this.f_iMinFileWidth) { iFilePosRight = iFilePosLeft + this.f_iMinFileWidth; } FileInfoSetSel.setPos(iFilePosLeft, this.f_iTimeRectHeight + parseInt(this.f_iBlankHeight/2) - 5, iFilePosRight - iFilePosLeft, this.f_iFileRectHeight + 2); } this.repaint(); }; /************************************************* Function: addFile Description: 添加文件 Input: StartTime 开始时间, StopTime 结束时间, iType 类型, iWndNum 默认当前窗口 添加到某个窗口 Output: 无 return: 无 *************************************************/ TimeBar.prototype.addFile = function(StartTime, StopTime, iType/*, iWndNum*/) { var tStartTime = new Time(); var tStopTime = new Time(); tStartTime.parseTime(StartTime); tStopTime.parseTime(StopTime); var fileColor; switch (iType) { case 1: fileColor = this.scheFileColor; break; case 2: fileColor = this.alarmFileColor; break; case 3: fileColor = this.cmdFileColor; break; case 4: fileColor = this.manualFileColor; break; case 5: fileColor = this.mdVideoColor; break; case 6: fileColor = this.timeVideoColor; break; default: fileColor = this.defaultFileColor; break; } /*var iXLeftSeconds = (tStartTime.f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (tStartTime.f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (tStartTime.f_iSecond - this.f_tCurrentMidTime.f_iSecond);*/ var iXLeftSeconds = parseInt((tStartTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFilePosLeft = this.f_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); /*var iXRightSeconds = (tStopTime.f_iHour - this.f_tCurrentMidTime.f_iHour) * 3600 + (tStopTime.f_iMinute - this.f_tCurrentMidTime.f_iMinute) * 60 + (tStopTime.f_iSecond - this.f_tCurrentMidTime.f_iSecond);*/ var iXRightSeconds = parseInt((tStopTime.f_iMilliseconds - this.f_tCurrentMidTime.f_iMilliseconds)/1000); var iFilePosRight = this.f_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600*this.f_fCellTime)) * this.f_iCellWidth); var fileInfo = new FileInfo(iFilePosLeft, this.f_iTimeRectHeight + parseInt(this.f_iBlankHeight/2) - 5, iFilePosRight - iFilePosLeft, this.f_iFileRectHeight + 2, iType, fileColor, tStartTime, tStopTime); fileInfo.setPosRange(this.f_iFileListStartPos, this.f_iFileListStartPos + parseInt(this.f_iCellWidth * this.ScaleInfoNum)); if(arguments.length >= 4) { this.FileInfoSet[arguments[3]].push(fileInfo); } else { this.FileInfoSet[this.f_iSelWnd].push(fileInfo); } }; /************************************************* Function: clearWndFileList Description: 清空某个窗口的文件信息 Input: iWndNum 窗口号 0-15 默认当前选中窗口 Output: 无 return: 无 *************************************************/ TimeBar.prototype.clearWndFileList = function()/*iWndNum*/ { var iWndParam; if(arguments.length == 0) { iWndParam = this.f_iSelWnd; } else { iWndParam = arguments[0]; } if(iWndParam < 0) { iWndParam = 0; } if(iWndParam >= 16) { iWndParam = 15; } this.FileInfoSet[iWndParam].length = 0; }; /************************************************* Function: setMidLineTime Description: 设置中轴线时间 Input: szTime yyyy-MM-dd HH:mm:ss Output: 无 return: 无 *************************************************/ TimeBar.prototype.setMidLineTime = function(szTime) { var tCurTime = new Time(); tCurTime.parseTime(szTime); this.f_tCurrentMidTime.setTimeByMis(tCurTime.f_iMilliseconds); /*this.updateScalePos(); this.updateFileListPos();*/ this.repaint(); }; /************************************************* Function: setMouseUpCallback Description: 设置鼠标弹起回调函数 Input: func 回调函数 function(tStartTime, tStopTime) Output: 无 return: 无 *************************************************/ TimeBar.prototype.setMouseUpCallback = function(callbackFunc) { this.mouseUpCallbackFunc = callbackFunc; }; /**该方法用来绘制一个有填充色的圆角矩形 *@param cxt:canvas的上下文环境 *@param x:左上角x轴坐标 *@param y:左上角y轴坐标 *@param width:矩形的宽度 *@param height:矩形的高度 *@param radius:圆的半径 *@param fillColor:填充颜色 **/ function fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) { //圆的直径必然要小于矩形的宽高 if (2 * radius > width || 2 * radius > height) { return false; } cxt.save(); cxt.translate(x, y); //绘制圆角矩形的各个边 drawRoundRectPath(cxt, width, height, radius); if(fillColor){ cxt.fillStyle = fillColor } cxt.fill(); cxt.restore(); } /**该方法用来绘制圆角矩形 *@param cxt:canvas的上下文环境 *@param x:左上角x轴坐标 *@param y:左上角y轴坐标 *@param width:矩形的宽度 *@param height:矩形的高度 *@param radius:圆的半径 *@param lineWidth:线条粗细 *@param strokeColor:线条颜色 **/ function strokeRoundRect(cxt, x, y, width, height, radius, /*optional*/ lineWidth, /*optional*/ strokeColor) { //圆的直径必然要小于矩形的宽高 if (2 * radius > width || 2 * radius > height) { return false; } cxt.save(); cxt.translate(x, y); //绘制圆角矩形的各个边 drawRoundRectPath(cxt, width, height, radius); cxt.lineWidth = lineWidth || 2; //若是给定了值就用给定的值否则给予默认值2 if(strokeColor){ cxt.strokeStyle = strokeColor; } cxt.stroke(); cxt.restore(); } function drawRoundRectPath(cxt, width, height, radius) { cxt.beginPath(0); //从右下角顺时针绘制,弧度从0到1/2PI cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2); //矩形下边线 cxt.lineTo(radius, height); //左下角圆弧,弧度从1/2PI到PI cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI); //矩形左边线 cxt.lineTo(0, radius); //左上角圆弧,弧度从PI到3/2PI cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2); //上边线 cxt.lineTo(width - radius, 0); //右上角圆弧 cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2); //右边线 cxt.lineTo(width, height - radius); cxt.closePath(); }