148 lines
5.2 KiB
JavaScript
148 lines
5.2 KiB
JavaScript
(function () {
|
|
// The constrcutor can be empty or passed in the lrc string
|
|
var Lyricer = function (options) {
|
|
this.divID = "lyricer"; // the default html container id
|
|
this.currentcss = "lyricer-current-line"; // this css for the line current playing
|
|
this.lineidPrefix = "lyricer-line"; // the id prefix for each line
|
|
this.showLines = 8; //lines showing before and after;
|
|
this.clickable = true;
|
|
this.clickEventName = "lyricerclick";
|
|
if( options ) {
|
|
for( var prop in options ) {
|
|
if ( typeof this[prop] != "undefined" && options.hasOwnProperty(prop)) {
|
|
this[prop] = options[prop];
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Lyricer.prototype.setLrc = function(rawLrc) {
|
|
this.tags = {};
|
|
this.lrc = [];
|
|
this.rangeLrc = [];
|
|
|
|
var tagRegex = /\[([a-z]+):(.*)\].*/;
|
|
var lrcAllRegex = /(\[[0-9.:\[\]]*\])+(.*)/;
|
|
var timeRegex = /\[([0-9]+):([0-9.]+)\]/;
|
|
var timeRegexGim = /\[([0-9]+):([0-9.]+)\]/g;
|
|
var rawLrcArray = rawLrc.split(/[\r\n]/);
|
|
for (var i = 0; i < rawLrcArray.length; i++) {
|
|
// handle tags first
|
|
var tag = tagRegex.exec(rawLrcArray[i]);
|
|
if ( tag && tag[0] ) {
|
|
this.tags[tag[1]] = tag[2];
|
|
continue;
|
|
}
|
|
// handle lrc
|
|
var lrc = lrcAllRegex.exec(rawLrcArray[i]);
|
|
if ( lrc && lrc[0] ) {
|
|
var times = lrc[1].replace(/\]\[/g,"],[").split(",");
|
|
for (var j = 0; j < times.length; j++) {
|
|
var time = timeRegex.exec(times[j]);
|
|
if ( time && time[0] ) {
|
|
this.lrc.push( { "starttime": parseInt(time[1],10) * 60 + parseFloat(time[2]), "line": lrc[2].replace(timeRegexGim,'') } );
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
//sort lrc array
|
|
this.lrc.sort(function (a,b) {
|
|
return a.starttime - b.starttime;
|
|
});
|
|
|
|
// crate the range lrc array
|
|
// dummy lines
|
|
for (var i = 0; i < this.showLines; i++) {
|
|
this.rangeLrc.push( { "starttime": -1, "endtime": 0, "line": " " } );
|
|
};
|
|
// real data
|
|
var starttime = 0;
|
|
var line = "";
|
|
for (var i = 0; i < this.lrc.length; i++) {
|
|
endtime = parseFloat(this.lrc[i].starttime);
|
|
this.rangeLrc.push( { "starttime": starttime, "endtime": endtime, "line": line } );
|
|
starttime = endtime;
|
|
line = this.lrc[i].line;
|
|
};
|
|
this.rangeLrc.push( { "starttime": starttime, "endtime": 999.99, "line": line } );
|
|
// dummy lines
|
|
for (var i = 0; i < this.showLines; i++) {
|
|
this.rangeLrc.push( { "starttime": -1, "endtime": 0, "line": " " } );
|
|
};
|
|
this.totalLines = this.rangeLrc.length;
|
|
|
|
// set html and move to start
|
|
setHtml(this);
|
|
this.move(0);
|
|
};
|
|
|
|
var setHtml = function(self) {
|
|
self.currentLine = 0;
|
|
|
|
var container = document.getElementById(self.divID);
|
|
container.innerHTML = "";
|
|
var ul = document.createElement("ul");
|
|
container.appendChild(ul);
|
|
for (var i = 0; i < self.totalLines; i++) {
|
|
var li = document.createElement("li");
|
|
li.innerHTML = self.rangeLrc[i].line;
|
|
if (!li.innerHTML) {li.innerHTML=" "};
|
|
li.setAttribute("id", self.lineidPrefix + i);
|
|
if (self.clickable) {
|
|
li.onclick = lineClicked(self, i);
|
|
li.style.cursor = 'pointer';
|
|
}
|
|
ul.appendChild(li);
|
|
};
|
|
|
|
// hide the later ones
|
|
for (var i = self.showLines; i < self.totalLines; i++) {
|
|
document.getElementById(self.lineidPrefix + i).style.display = "none";
|
|
};
|
|
};
|
|
|
|
var lineClicked = function(self, id) {
|
|
return function(){
|
|
var detail = {"time": self.rangeLrc[id].starttime};
|
|
var e = new CustomEvent(self.clickEventName, {
|
|
'detail': detail,
|
|
"bubbles": true
|
|
});
|
|
var elem = document.getElementById(self.lineidPrefix + id);
|
|
elem.dispatchEvent(e);
|
|
};
|
|
};
|
|
|
|
|
|
Lyricer.prototype.move = function(time) {
|
|
for (var i = 0; i < this.totalLines; i++) {
|
|
if (time >= this.rangeLrc[i].starttime && time < this.rangeLrc[i].endtime) {
|
|
this.currentLine = i;
|
|
moveToLine(this,this.currentLine);
|
|
return;
|
|
};
|
|
};
|
|
};
|
|
|
|
var moveToLine = function (self, line) {
|
|
var startShow = line - self.showLines;
|
|
var endShow = line + self.showLines;
|
|
for (var i = 0; i < self.totalLines; i++) {
|
|
var li = document.getElementById(self.lineidPrefix + i);
|
|
if ( i >= startShow && i <= endShow ) {
|
|
li.style.display = "block";
|
|
} else{
|
|
li.style.display = "none";
|
|
};
|
|
if (i==line) {
|
|
li.className = self.currentcss;
|
|
} else {
|
|
li.className = "";
|
|
};
|
|
};
|
|
};
|
|
|
|
window.Lyricer = Lyricer; //exposed to global
|
|
|
|
})(); |