放一个歌词同步的JS UI

2021年1月15日   |   by tgcode

很久没发文,一直想写点东西,整理整理这阵子的心得,很多笔记都在整理中。

最近给公司编写的一个JS UI,用于歌词同步,整理一下放出来,
核心脚本只负责处理lrc格式的歌词和呈现,并提供同步功能。

%title插图%num

%title插图%num
外部呈现等均可以良好定制。
基本调用如下:
var lrc=new LRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:’xx’,lyric:’xxx’,separator:’
‘});
if(lrc.IsLyricValid()) lrc.DoSync(60);

DoSync(t)用于同步,参数t为当前播放进度,从播放器获得。
IsLyricValid()返回歌词是否合法的LRC格式。

贴出代码,附件下载中包含2个定制示例。代码在FF下跑不了,因为音乐播放插件跑不了~

%title插图%num%title插图%numLrc UI
<!–

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

–>1%title插图%num%title插图%num/**//*
2%title插图%num*@author:huangxu
3%title插图%num*@date:2008-11
4%title插图%num*@site:http://wsky.cnblogs.com
5%title插图%num*@descript:syncdisplaythelyric
6%title插图%num*@usage:
7%title插图%num*//importlrc.css
8%title插图%num*varlrc=newLRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:’xx’,lyric:’xxx’,separator:’
‘});
9%title插图%num*if(lrc.IsLyricValid())lrc.DoSync(60);
10%title插图%num*
11%title插图%num*@note:内部变量前缀lrc_,普通变量i,ii,index,arg..
12%title插图%num*/

13%title插图%num
14%title插图%num%title插图%numLRC=function()%title插图%num{this.initialize.apply(this,arguments);}
15%title插图%num%title插图%numLRC.prototype=%title插图%num{
16%title插图%numarrLyricTime:[],
17%title插图%numarrLyric:[],//全局可用,必须执行初始化
18%title插图%num%title插图%numinitialize:function(arg)%title插图%num{
19%title插图%num//私有
20%title插图%numthis.lyricTable=arg.lyricTable;//目标歌词table
21%title插图%numthis.lyricWrapper=arg.lyricWrapper;//目标歌词容器div
22%title插图%numthis.curRowClassName=arg.curRowClassName;//选择行css样式名
23%title插图%numthis.separatgcodetor=arg.separator;//歌词行分隔符如:

24%title插图%num//执行初始化
25%title插图%numthis.arrLyricTime=[];
26%title插图%numthis.arrLyric=[];
27%title插图%numthis.initArray(arg.lyric);
28%title插图%numthis.arrLyricTime=this.sort(this.arrLyricTime);
29%title插图%numthis.setLyricTable(this.arrLyric);
30%title插图%num}
,
31%title插图%num%title插图%numinitArray:function(lyric)%title插图%num{
32%title插图%numvarlrc_re=newRegExp([[0-9:.]*],g);//g全局标志,获取所有匹配结果必须
33%title插图%numvarlrc_arr=lyric.split(this.separator);
34%title插图%numvarlrc_temp=0;
35%title插图%numvarlrc_filter=0;//无效行过滤标记
36%title插图%num%title插图%numfor(vari=0;ilrc_arr.length;i++)%title插图%num{
37%title插图%numvarlrc_txt=lrc_arr[i].replace(/[[wW]*]/g,).Trim();//addtolyrictextarray
38%title插图%num%title插图%numif(lrc_txt==)%title插图%num{
39%title插图%numlrc_filter++;
40%title插图%numcontinue;
41%title插图%num}

42%title插图%numthis.arrLyric[ilrc_filttgcodeer]=lrc_txt;
43%title插图%num%title插图%numwhile((lrc_result=lrc_re.exec(lrc_arr[i]))!=null)%title插图%num{
44%title插图%numvarlrc_second=this.parseSecond(lrc_result.toString().replace(/[|]/g,));
45%title插图%numif(!isNaN(lrc_second))
46%title插图%numthis.arrLyricTime[lrc_temp++]=(ilrc_filter)+|+lrc_second;//arrLyricTime格式为”行号|秒”,如:1|50,2|60
47%title插图%num}

48%title插图%num}

49%title插图%num}
,
50%title插图%num/////////////////////////////////////////////////////////////////////////////////////////
51%title插图%num//公开函数
52%title插图%num//IsLyricValid()判断是否合法lrc歌词
53%title插图%num//DoSync()定位歌词
54%title插图%num/////////////////////////////////////////////////////////////////////////////////////////
55%title插图%num%title插图%numIsLyricValid:function(arrLyricTime)%title插图%num{
56%title插图%numreturnthis.arrLyricTime.length>0;
57%title插图%num}
,
58%title插图%num%title插图%numDoSync:function(curPosition)%title插图%num{
59%title插图%numvarlrc_times=this.arrLyricTime;
60%title插图%num%title插图%numfor(vari=0;ilrc_times.length;i++)%title插图%num{
61%title插图%numvarlrc_arrPre=lrc_times[i].split(|);
62%title插图%num
63%title插图%numif(i==0&&curPositionlrc_arrPre[1])break;//防止抖动
64%title插图%num
65%title插图%num%title插图%numif(lrc_times[i+1]==undefined)%title插图%num{
66%title插图%numthis.setRow(lrc_arrPre[0]);
67%title插图%numbreak;
68%title插图%num}

69%title插图%num
70%title插图%numvarlrc_arrNext=lrc_times[i+1].split(|);
71%title插图%num%title插图%numif(curPosition>=lrc_arrPre[1]&&curPositionlrc_arrNext[1])%title插图%num{
72%title插图%numthis.setRow(lrc_arrPre[0]);
73%title插图%numbreak;
74%title插图%num}

75%title插图%num}

76%title插图%num}
,
77%title插图%num/////////////////////////////////////////////////////////////////////////////////////////
78%title插图%num//以下为内部辅助函数
79%title插图%num/////////////////////////////////////////////////////////////////////////////////////////
80%title插图%num%title插图%numparseSecond:function(time)%title插图%num{
81%title插图%num%title插图%numtry%title插图%num{
82%title插图%numvarlrc_arr=time.split(:);//time格式为时间格式00:00
83%title插图%numreturnparseInt(lrc_arr[0])*60+parseFloat(lrc_arr[1]);
84%title插图%num%title插图%num}
catch(ex)%title插图%num{
85%title插图%numreturn0;
86%title插图%num}

87%title插图%num}
,
88%title插图%num%title插图%numsetLyricTable:function(arrLyric)%title插图%num{
89%title插图%numthis.lyricWrapper.scrollTop=0;//滚动条置顶
90%title插图%num
91%title插图%num%title插图%numif(this.lyricTable.rows.length>0)%title插图%num{
92%title插图%numthis.clearTable(this.lyricTable);
93%title插图%num}

94%title插图%num%title插图%numfor(vari=0;iarrLyric.length;i++)%title插图%num{
95%title插图%numvarlrc_tr=this.lyricTable.insertRow();
96%title插图%numvarlrc_cell=lrc_tr.insertCell(0);
97%title插图%numlrc_cell.innerHTML=arrLyric[i];
98%title插图%num}

99%title插图%num}
,
100%title插图%num%title插图%numclearTable:function(lyricTable)%title插图%num{
101%title插图%numvarlrc_rowNum=lyricTable.rows.length;
102%title插图%num%title插图%numfor(vari=0;ilrc_rowNum;i++)%title插图%num{
103%title插图%numlyricTable.deleteRow(i);
104%title插图%numlrc_rowNum=lrc_rowNum1;
105%title插图%numi=i1;
106%title插图%num}

107%title插图%num}
,
108%title插图%num%title插图%numsetRow:function(index)%title插图%num{
109%title插图%numthis.setRowClass(index);
110%title插图%numthis.setScroll(index);
111%title插图%num}
,
112%title插图%num%title插图%numsetRowClass:function(index)%title插图%num{
113%title插图%numvarlrc_rows=this.lyricTable.rows;
114%title插图%num%title插图%numfor(vari=0;ilrc_rows.length;i++)%title插图%num{
115%title插图%numlrc_rows[i].className=;//TODO:直接添加样式至元素,防止外部css干扰
116%title插图%num}

117%title插图%numlrc_rows[index].className=this.curRowClassName;
118%title插图%num}
,
119%title插图%num%title插图%numsetScroll:function(index)%title插图%num{
120%title插图%numthis.lyricWrapper.scrollTop=this.lyricTable.rows[index].offsetTopthis.lyricWrapper.offsetHeight/3;
121%title插图%num}
,
122%title插图%num%title插图%numsort:function(arrLyricTime)%title插图%num{
123%title插图%num%title插图%numfor(vari=0;iarrLyricTime.length1;i++)%title插图%num{
124%title插图%num%title插图%numfor(varii=i+1;iiarrLyricTime.length;ii++)%title插图%num{
125%title插图%numvarlrc_cur=parseFloat(arrLyricTime[i].split(|)[1]);
126%title插图%numvarlrc_next=parseFloat(arrLyricTime[ii].split(|)[1]);
127%title插图%num%title插图%numif(lrc_cur>lrc_next)%title插图%num{
128%title插图%numvarlrc_temp=arrLyricTime[i];
129%title插图%numarrLyricTime[i]=arrLyricTime[ii];
130%title插图%numarrLyricTime[ii]=lrc_temp;
131%title插图%num}

132%title插图%num}

133%title插图%num}

134%title插图%numreturnarrLyricTime;
135%title插图%num}

136%title插图%num}

137%title插图%num
138%title插图%num
139%title插图%num/////////////////////////////////////////////////////////////
140%title插图%num//外部函数
141%title插图%num/////////////////////////////////////////////////////////////
142%title插图%numString.prototype.Trim=function()
143%title插图%num%title插图%num%title插图%num{
144%title插图%numreturnthis.replace(/^s*|s*$/g,“”);
145%title插图%num}

146%title插图%num

Demo下载:http://files.cnbltgcodeogs.com/wsky/lrcUI_wsky.rar

相关推荐: 大型Web架构思想系列专题之-未雨绸缪

首先要感谢诸多朋友对鄙人的一些拙见表示关注,不少朋友反应上一篇的分享有点意犹未尽,我的理解可能是大家觉得我写的不够快。呵呵…由于系统整理相关资料需要一段时间,另外要尽量保持原创的风格。所以周期会稍微长一点点,但我尽量会一周写1-2篇相关专题。 上篇看到不少…

Tags: ,