当前位置:首页>家电维修>电视>

电视剧中的时间标尺(电视剧的时间长短规定)

电视剧中的时间标尺(电视剧的时间长短规定)

更新时间:2022-03-09 12:59:32

web视频编辑时需要一个时间标尺,方案采用:canvas 完成刻度回话和比例缩放处理

效果

需求:

  • 需要一个表示时间刻度尺,并在刻度上显示时间;
  • 点击刻度可以获得当前的时间;
  • 50%比例以下按1/50 方式显示时间,50以上按约定时间序列构成的抛物线递进显示
  • 允许在5%带100%调节比例尺大小;
  • 允许传入时间获得当前的刻度位置坐标点;

问题:

1、时间和长度如何转换?

2、不同比例,这个比例函数是什么?

源码

<!DOCTYPE html> <html> <style> .btn-rate{ top:5px; } </style> <body> <div> <canvas id="ruler"></canvas> <div class="btn-rate"> <input id='rate' type='text' value="50"></input>% <button onClick='changRate(1)'> </button><button onClick='changRate(-1)'>-</button> </div> </div> </body> <script> (function (scope){ // el 操作组件,标尺长度 var ruler=function(el,cfg){ this.el = el; //画布对象 this.cfg = cfg; //组件配置 this.post ={x:0,y:0}; //当前鼠标位置 this.currentTime =0; //当前鼠标位置 this.init(el,cfg); return this; } ruler.prototype={ // 初始化对象 init:function(){ //标尺参数 this.bgColor= this.cfg.color ||'#000000'; //背景黑色 this.width = parseInt(this.cfg.width) || 2000; //标尺宽度 this.height = parseInt(this.cfg.height) || 70; //标尺高度 //标尺刻度参数 this.lineColor= this.cfg.lineColor ||'#C0C0C0'; //线的颜色 this.lineMaxHeight= parseInt(this.cfg.lineMaxHeight) || 20 //最大高度 this.lineTopHeight= parseInt(this.cfg.lineTopHeight) || 20 //离标尺上边距离 this.lineWidth = parseInt(this.cfg.lineWidth) || 2 //刻线宽度 this.lineTxtTop = parseInt(this.cfg.lineTxtTop) || 10 //刻线底端和刻度文字间距 //时间有关参数,用于长度转换成时间 this.rateTemp = parseInt(this.cfg.rate) || 50; //默认: 50% 比例 this.lineSpace = parseInt(this.cfg.lineSpace) || 10; //默认:在50倍比例尺下,1刻线间距10个像素,10像素=1秒 this.timeUnit = parseInt(this.cfg.timeUnit) || 1 ; //默认: 标尺单位 默认秒 //获取一个实际使用的比例关系:rate this.computeRate(); //初始化一个标尺 this.ctx = this.initCanvas(); this.drawLine(this.ctx); }, computeRate:function(){ if(this.rateTemp >50){ var t = (this.rateTemp-50)/5 //this.rate =( 0.04*Math.pow(this.rateTemp,2)-1.8*this.rateTemp )*0.1; // this.rate = (10*(t 1) (1 t)*t)*10/100 }else{ this.rate = this.rateTemp / 50 } }, //初始化:画布 initCanvas:function(){ var ctx = this.el.getContext('2d'); // ctx.canvas.width = this.width; ctx.canvas.height = this.height; ctx.fillStyle = this.bgcolor; ctx.fillRect(0, 0,this.width,this.height); ctx.stroke(); let that=this; //添加点击事件:获取当前坐标,到时用于转换成当前的时间 this.el.addEventListener("click" , function(e){ that.post.x = e.clientX; that.post.y = e.clientY; that.currentTime = that.getTimeByXy(e.clientX,that) //console.log('ruler--click:',that.formartTime(that.currentTime)) }) return ctx; }, // 设置比例尺: 10% 50% 设置比例尺影响时间 setRate:function(rate){ if(rate<=0){rate=50} ;// 在时间转坐标过程这个rate 最为被除数 不可以等于0或者小于0的 this.rateTemp = parseInt(rate) this.computeRate(); //重新初始化刻度尺 this.ctx=this.initCanvas(); this.drawLine(this.ctx); }, //画标尺刻度线 drawLine:function(ctx){ ctx.beginPath(); ctx.strokeStyle = this.lineColor; //设置线条的样式颜色 ctx.lineWidth = this.lineWidth; //设置描边的线宽 //开始x坐标 var x = 0; //开始y坐标 var y = this.lineMaxHeight this.lineTopHeight; //最小刻线长度 var minlen = this.lineMaxHeight/4; var dh = minlen;//当前刻线长度 for(var i=0;i<this.width/this.lineSpace;i ){ x = i*this.lineSpace; //当前x点位置: i*分割 初始位置 dh =minlen; // 如果是10的倍数 if(i%5==0){ dh = this.lineMaxHeight/1.5 ; //逢5刻度:刻度长度 if(i==0){ dh = this.lineMaxHeight; //逢10刻度长度 //将坐标转成时间 ctx.save() //保存环境 ctx.translate(x,y this.lineTxtTop); //坐标移动 //画:时间文本 this.drawTxt(ctx,this.formartTime(this.getTimeByXy(x,this))); ctx.restore();//恢复环境 } } ctx.moveTo(x, y); //开始点 ctx.lineTo(x, y-dh); //结束点: y点减出当前刻线高度 } ctx.stroke(); ctx.closePath() }, //通过坐标点获取当前的时间值:统一转换成秒 getTimeByXy:function(x,that){ return parseInt(that.rate*x/(that.lineSpace)); }, //通过时间获取当前坐标: time 单位为秒 getPostBytime:function(time){ return parseInt(time*that.lineSpace/that.rate); }, //将时间转成:00:00.00 (分钟:秒) formartTime:function(curTime){ let b = curTime.toString().split("."); let f = b[1] || '00'; //小数位数 let theTime = parseInt(b[0]); //需要转换的时间秒 let second = 0; //秒 let minute = 0; //分 let hour = 0; //小时 if(theTime > 60) { minute = parseInt(theTime/60); second = parseInt(theTime`); //求余 if(minute>60){ hour = parseInt(minute/60); minute = parseInt(minute`); //求余 } }else{ second = curTime; } //时间补零操作 var prefixZero= function(num,n){ return (Array(n).join(0) num).slice(-n); }; return prefixZero(minute,2) ':' prefixZero(second,2) '.' f }, //画一个文本在屏幕的某个位置 drawTxt:function(ctx,str,pos){ ctx.font = "10px sans-serif";//设置字体大小 ctx.textAlign = "center"; ctx.textBaseline = "top"; ctx.fillStyle = "#FFFFFF"; //白色字体 ctx.fillText(str,0,0); } } scope.Ruler=ruler; })(window) // 获取 var el=document.getElementById("ruler"); // 配置参数 var cfg={'name':'ruler','length':60} var ruler=new Ruler(el,cfg); var rate =1; var t=1 function changRate(value){ let el = document.getElementById("rate"); let rate = parseInt(el.value) if(value>0){ //缩小 rate = rate t; }else{ //放大 rate = rate - t; } // 比例大于100设置为100 if(rate>100){rate=100;} // 比例小于5 设置为5 if(rate<5){rate=5;} el.value = rate; if(rate<=0){rate=1} console.log('ruler--changRate',rate) ruler.setRate(rate); } </script> </html>

源码说明:

1、关于50%以下:按1/50每格显示时间

this.rate = this.rateTemp / 50

2、关于50%以上按规定时间序列显示时间

var t = (this.rateTemp-50)/5 //this.rate =( 0.04*Math.pow(this.rateTemp,2)-1.8*this.rateTemp )*0.1; // this.rate = (10*(t 1) (1 t)*t)*10/100

以上两个公式都是正确的,注释掉的公式来自excle 二叉法拟函数获得

实际使用函数是个人推导出来,见下图

图片中A:表示不同的比例尺

A‘ 表示我要在不同比例时在刻度尺第10格要显示的的内容;

例如: 50% 比例尺 在第十个 显示: 10 秒

例如: 65% 比例尺 在第十个 显示: 52 秒

3、关于时间格式:00:00.00 (分:秒)

我们将在web上可编辑的视频的长度定位在1个小时以内,为此秒的小数去两位显示,以下函数非常关键

formartTime:function(curTime){ let b = curTime.toString().split("."); let f = b[1] || '00'; //小数位数 ..... }

4、本js采用匿名函数方式编写,便于在webpack中打包和模块化使用

5、数据类型转换很重要:parseInt

6、画标尺刻度线主要方法

drawLine:function(ctx){ ....}

该方法中才有了:坐标平移方法化刻度时间,这个方法挺好用;但是在坐标系改变时需要对上下文环境进行存储,于是才有了这个两个方法

ctx.save() //保存环境 。。。。 //代码省略 ctx.restore();//恢复环境,