Team:NCTU Formosa/js/jquery.jticker.js
From 2014.igem.org
// jquery.ticker.js // 0.9.1 - beta // Stephen Band // // Project and documentation site: // http://webdev.stephband.info/jticker/ // // Dependencies: // jQuery 1.2.3 - (www.jquery.com) // // Instantiate and play with: // jQuery(element).ticker({options}).trigger("play");
(function(jQuery) {
// VAR
var name = "ticker"; // Name of the plugin
// FUNCTIONS
function indexify(i, length) {
return (i >= length) ? indexify(i-length, length) : ((i < 0) ? indexify(i+length, length) : i) ;
}
function advanceItem(elem) {
var data = elem.data(name); var length; for (var i=0; i<200; i++) { if (!data.content[i]) {length = i; break;} } data.nextItem = indexify((data.nextItem || 0), length); data.currentItem = data.nextItem; data.elemIndex = [data.currentItem]; data.charIndex = 0; data.nextItem++;
}
function makeFamily(elem) {
var obj = {elem: elem.clone().empty()}; var children = elem.children(); if (children.length) { children.each(function(i){ obj[i] = makeFamily(jQuery(this)); }); return obj; } else { obj.text = elem.text() return obj; }
}
function checkFamily(content, index) {
var newIndex; if (content[index[0]]) { if (content[index[0]].text) {return content[index[0]];} else if (index.length == 1) {return true;} else { newIndex = jQuery.makeArray(index); return checkFamily(content[newIndex[0]], newIndex.splice(1, newIndex.length)); } } else {return false;}
}
function incrementIndex(index) {
if (index.length > 1) {index[index.length-1]++; return index;} else {return false;}
}
function buildIndex(content, index) {
if (index === false) {return false;} var obj = checkFamily(content, index); if (obj === false) {return buildIndex(content, incrementIndex(index.slice(0, index.length-1)));} else if (obj === true) {index[index.length] = 0; return buildIndex(content, index);} else {return index;}
}
function buildFamily(elem, content, index, data) {
var newIndex, newElem; var child = elem.children().eq(index[0]); if (!index.length) { return { readout: elem, text: content.text }; } else if (child.length) {newElem = child;} else {newElem = content[index[0]].elem.appendTo(elem);} newIndex = jQuery.makeArray(index).slice(1, index.length); return buildFamily(newElem, content[index[0]], newIndex, data);
}
function initElem(elem) {
var data = elem.data(name); jQuery("*", elem).empty(); elem.empty(); data.start = 0; data.sum = 0; if (data.cursorIndex) {cursorIndex = 0;}
}
function initChild(elem) {
var data = elem.data(name); data.start = data.sum;
}
function ticker(elem, threadIndex, data) {
var index, letter; // Switch cursor if (data.cursorIndex !== false) {data.cursorIndex = indexify(data.cursorIndex+1, data.cursorList.length); data.cursor.html(data.cursorList[data.cursorIndex]);} else {data.cursor.html(data.cursorList);}
// Add character to readout index = data.charIndex - data.start; letter = data.text.charAt(index-1); data.cursor.before(letter); if (data.charIndex >= data.sum) { data.cursor.remove(); data.elemIndex = incrementIndex(data.elemIndex); return tape(elem, threadIndex); } else { return setTimeout(function(){ if (data.eventIndex == threadIndex) { data.charIndex++; ticker(elem, threadIndex, data); } threadIndex = null; }, data.rate); }
}
function tape(elem, threadIndex) {
var data = elem.data(name);
if (data.eventIndex == threadIndex) { data.elemIndex = buildIndex(data.content, data.elemIndex); //console.log('INDEX '+data.elemIndex); if (data.elemIndex === false) { return setTimeout(function(){ if (data.running && (data.eventIndex == threadIndex)) { advanceItem(elem); return tape(elem, threadIndex); } threadIndex = null; }, data.delay); } else if (!data.charIndex) {initElem(elem);} else {initChild(elem);}
jQuery.extend(data, buildFamily(elem, data.content, data.elemIndex)); data.sum = data.sum + data.text.length; data.readout.append(data.cursor); return ticker(elem, threadIndex, data); }
}
// PLUGIN DEFINITION
jQuery.fn[name] = function(options) {
// Add or overwrite options onto defaults var o = jQuery.extend({}, jQuery.fn.ticker.defaults, options);
// Iterate matched elements return this.each(function() {
var elem = jQuery(this); elem .data(name, { rate: o.rate, delay: o.delay, content: makeFamily(elem), cursor: o.cursor, cursorList: o.cursorList, cursorIndex: (typeof(o.cursorList) == "object") ? 0 : false, nextItem: 0, eventIndex: 0 }) .bind("stop", function(e){ var data = elem.data(name); data.running = false; }) .bind("play", function(e){ var data = elem.data(name); data.eventIndex++; data.running = true; data.nextItem = (e.item || data.nextItem); advanceItem(elem); tape(elem, data.eventIndex); }) .bind("control", function(e){ var data = elem.data(name); jQuery().extend(data, { nextItem: e.item, rate: e.rate, delay: e.delay }); }) .children() .remove(); });
};
// PLUGIN DEFAULTS
jQuery.fn[name].defaults = {
rate: 40, // 打字機出字的速度 delay: 2000, // 自動播放時訊息與訊息中的間隔時間 cursorList: "_", // 這裡不要動 cursor: jQuery('<span class="cursor" />')
}
})(jQuery);