/*!
* webTicker 2.2.0
* Examples and documentation at:
* http://jonmifsud.com/open-source/jquery/jquery-webticker/
* 2011 Jonathan Mifsud
* Version: 2.2.0 (15-FEB-2016)
* Dual licensed under the Creative Commons and DonationWare licenses:
* http://creativecommons.org/licenses/by-nc/3.0/
* https://github.com/jonmifsud/Web-Ticker/blob/master/licence.md
* Requires:
* jQuery v1.4.2 or later
*
*/
(function( $ ){
var cssTransitionsSupported = (function() {
var s = document.createElement('p').style,
v = ['ms','O','Moz','Webkit'];
if( s.transition === '' ){ return true; }
while( v.length ){
if( v.pop() + 'Transition' in s ){
return true;
}
}
return false;
})();
function getStripWidth($strip){
var stripWidth=0;
$strip.children('li').each(function(){
stripWidth += $(this).outerWidth( true );
});
return stripWidth;
}
function getItemWidth($strip){
return Math.max.apply(Math, $strip.children().map(function(){ return $(this).width(); }).get());
}
function animationSettings($strip){
var settings = $strip.data('settings') || { direction: 'left', speed: 50 };
var first = $strip.children().first();
var distance = Math.abs(-$strip.css(settings.direction).replace('px','').replace('auto','0') - first.outerWidth(true));
var timeToComplete = distance * 1000 / settings.speed;
var animationSettings = {};
animationSettings[settings.direction] = $strip.css(settings.direction).replace('px','').replace('auto','0') - distance;
return {'css':animationSettings,'time':timeToComplete};
}
function moveFirstElement($strip){
var settings = $strip.data('settings') || { direction: 'left' };
$strip.css('transition-duration','0s').css(settings.direction, '0');
var $first = $strip.children().first();
if ($first.hasClass('webticker-init')){
$first.remove();
}
else{
$strip.children().last().after($first);
}
}
function scrollitems($strip,moveFirst){
var settings = $strip.data('settings') || { direction: 'left' };
if (typeof moveFirst === 'undefined'){
moveFirst = false;
}
if (moveFirst){
moveFirstElement($strip);
}
var options = animationSettings($strip);
$strip.animate(options.css, options.time, 'linear', function(){
$strip.css(settings.direction, '0');
scrollitems($strip,true);
});
}
function css3Scroll($strip,moveFirst){
if (typeof moveFirst === 'undefined'){
moveFirst = false;
}
if (moveFirst){
moveFirstElement($strip);
}
var options = animationSettings($strip);
var time = options.time/1000;
time += 's';
$strip.css(options.css).css('transition-duration',time);
}
function updaterss(rssurl,type,$strip){
var list = [];
$.get(rssurl, function(data) {
var $xml = $(data);
$xml.find('item').each(function() {
var $this = $(this),
item = {
title: $this.find('title').text(),
link: $this.find('link').text()
};
var listItem = '
'+item.title+'';
list += listItem;
//Do something with item here...
});
$strip.webTicker('update', list, type);
});
}
function initialize($strip, init){
if ($strip.children('li').length < 1) {
if (window.console) {
// console.log('no items to initialize');
}
return false;
}
var settings = $strip.data('settings');
settings.duplicateLoops = settings.duplicateLoops || 0;
$strip.width('auto');
//Find the real width of all li elements
var stripWidth = 0;
$strip.children('li').each(function(){
stripWidth += $(this).outerWidth( true );
});
var height = $strip.find('li:first').height();
var itemWidth;
// if(stripWidth < $strip.parent().width() || $strip.children().length == 1){
//if duplicate items
if (settings.duplicate){
//Check how many times to duplicate depending on width.
itemWidth = getItemWidth($strip);
var duplicateLoops = 0;
while (stripWidth - itemWidth < $strip.parent().width() || $strip.children().length === 1 || duplicateLoops < settings.duplicateLoops){
var listItems = $strip.children().clone();
$strip.append(listItems);
stripWidth = 0;
stripWidth = getStripWidth($strip);
itemWidth = getItemWidth($strip);
duplicateLoops++;
}
settings.duplicateLoops = duplicateLoops;
}else {
//if fill with empty padding
var emptySpace = $strip.parent().width() - stripWidth;
emptySpace += $strip.find('li:first').width();
// $strip.append('');
if ($strip.find('.ticker-spacer').length > 0){
// console.log('test');
$strip.find('.ticker-spacer').width(emptySpace);
}
else{
// console.log('test2');
$strip.append('');
}
// }
}
if (settings.startEmpty && init){
$strip.prepend('');
}
//extra width to be able to move items without any jumps $strip.find("li:first").width()
stripWidth = 0;
stripWidth = getStripWidth($strip);
$strip.width(stripWidth+200);
var widthCompare = 0;
widthCompare = getStripWidth($strip);
//loop to find weather the items inside the list are actually bigger then the size of the whole list. Increments in 200px.
//only required when a single item is bigger then the whole list
while (widthCompare >= $strip.width()){
$strip.width($strip.width()+200);
widthCompare = 0;
widthCompare = getStripWidth($strip);
}
return true;
}
var methods = {
init : function( settings ) { // THIS
settings = jQuery.extend({
speed: 50, //pixels per second
direction: 'left',
moving: true,
startEmpty: true,
duplicate: false,
rssurl: false,
hoverpause: true,
rssfrequency: 0,
updatetype: 'reset',
transition: 'linear',
height: '30px',
maskleft: '', // maskleft and maskright require a width setting in your css to work
maskright: '',
maskwidth: 0
}, settings);
//set data-ticker a unique ticker identifier if it does not exist
return this.each(function(){
jQuery(this).data('settings',settings);
var $strip = jQuery(this);
var $mask = $strip.wrap('');
$mask.after(' ');
var $tickercontainer = $strip.parent().wrap('');
var resizeEvt;
$(window).resize(function() {
clearTimeout(resizeEvt);
resizeEvt = setTimeout(function() {
console.log('window was resized');
initialize($strip,false);
}, 500);
});
//adding required css rules
$strip.children('li').css('white-space','nowrap');
$strip.children('li').css('float',settings.direction);
$strip.children('li').css('padding','0 7px');
$strip.children('li').css('line-height',settings.height);
$mask.css('position','relative');
$mask.css('overflow','hidden');
$strip.closest('.tickercontainer').css('height', settings.height);
$strip.closest('.tickercontainer').css('overflow', 'hidden');
$strip.css('float',settings.direction);
$strip.css('position','relative');
$strip.css('font', 'bold 10px Verdana');
$strip.css('list-style-type', 'none');
$strip.css('margin', '0');
$strip.css('padding', '0');
if ((settings.maskleft !== '') && (settings.maskright !== '')){
var backgroundimage='url("'+settings.maskleft+'")';
$tickercontainer.find('.tickeroverlay-left').css('background-image',backgroundimage);
$tickercontainer.find('.tickeroverlay-left').css('display','block');
$tickercontainer.find('.tickeroverlay-left').css('pointer-events','none');
$tickercontainer.find('.tickeroverlay-left').css('position','absolute');
$tickercontainer.find('.tickeroverlay-left').css('z-index','30');
$tickercontainer.find('.tickeroverlay-left').css('height',settings.height);
$tickercontainer.find('.tickeroverlay-left').css('width',settings.maskwidth);
$tickercontainer.find('.tickeroverlay-left').css('top','0');
$tickercontainer.find('.tickeroverlay-left').css('left','-2px');
backgroundimage='url("'+settings.maskright+'")';
$tickercontainer.find('.tickeroverlay-right').css('background-image',backgroundimage);
$tickercontainer.find('.tickeroverlay-right').css('display','block');
$tickercontainer.find('.tickeroverlay-right').css('pointer-events','none');
$tickercontainer.find('.tickeroverlay-right').css('position','absolute');
$tickercontainer.find('.tickeroverlay-right').css('z-index','30');
$tickercontainer.find('.tickeroverlay-right').css('height',settings.height);
$tickercontainer.find('.tickeroverlay-right').css('width',settings.maskwidth);
$tickercontainer.find('.tickeroverlay-right').css('top','0');
$tickercontainer.find('.tickeroverlay-right').css('right','-2px');
}
else{
$tickercontainer.find('.tickeroverlay-left').css('display','none');
$tickercontainer.find('.tickeroverlay-right').css('display','none');
}
//adding the 'last' class will help for future duplicate functions
$strip.children('li').last().addClass('last');
var started = initialize($strip,true);
if (settings.rssurl){
updaterss(settings.rssurl,settings.type,$strip);
if (settings.rssfrequency>0){
window.setInterval(function(){updaterss(settings.rssurl,settings.type,$strip);},settings.rssfrequency*1000*60);
}
}
if (cssTransitionsSupported){
//fix for firefox not animating default transitions
$strip.css('transition-timing-function',settings.transition);
$strip.css('transition-duration','0s').css(settings.direction, '0');
if (started){
//if list has items and set up start scrolling
css3Scroll($strip,false);
}
//started or not still bind on the transition end event so it works after update
$strip.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend', function(event) {
if (!$strip.is(event.target)) {
return false;
}
css3Scroll($(this),true);
});
} else {
if (started){
//if list has items and set up start scrolling
scrollitems($(this));
}
}
if (settings.hoverpause){
$strip.hover(function(){
if (cssTransitionsSupported){
var currentPosition = $(this).css(settings.direction);
$(this).css('transition-duration','0s').css(settings.direction,currentPosition);
} else{
jQuery(this).stop();
}
},
function(){
if (jQuery(this).data('settings').moving){
if (cssTransitionsSupported){
css3Scroll($(this),false);
// $(this).css("-webkit-animation-play-state", "running");
} else {
//usual continue stuff
scrollitems($strip);
}
}
});
}
});
},
stop : function( ) {
var settings = $(this).data('settings');
if (settings.moving){
settings.moving = false;
return this.each(function(){
if (cssTransitionsSupported){
var currentPosition = $(this).css(settings.direction);
$(this).css('transition-duration','0s').css(settings.direction,currentPosition);
} else{
$(this).stop();
}
});
}
},
cont : function( ) {
var settings = $(this).data('settings');
if (!settings.moving){
settings.moving = true;
return this.each(function(){
if (cssTransitionsSupported){
css3Scroll($(this),false);
} else {
scrollitems($(this));
}
});
}
},
transition : function(transition){
var $strip = $(this);
if (cssTransitionsSupported){
//fix for firefox not animating default transitions
$strip.css('transition-timing-function',transition);
}
},
update : function( list, type, insert, remove) {
type = type || 'reset';
if (typeof insert === 'undefined'){
insert = true;
}
if (typeof remove === 'undefined'){
remove = false;
}
if( typeof list === 'string' ) {
list = $(list);
}
var $strip = $(this);
$strip.webTicker('stop');
var settings = $(this).data('settings');
if (type === 'reset'){
//this does a 'restart of the ticker'
$strip.html(list);
initialize($strip,true);
} else if (type === 'swap'){
var id;
var match;
var $listItem;
var stripWidth;
if (window.console) {
// console.log('trying to update');
}
if ($strip.children('li').length < 1){
//no items found. Treat as new
$strip.html(list);
$strip.css(settings.direction, '0');
initialize($strip,true);
}
else if (settings.duplicate === true)
{
// should the update be a 'hot-swap' or use replacement for IDs (in which case remove new ones)
$strip.children('li').addClass('old');
for (var i = list.length - 1; i >= 0; i--) {
id = $(list[i]).data('update');
match = $strip.find('[data-update="'+id+'"]');//should try find the id or data-attribute.
if (match.length < 1){
if (insert){
//we need to move this item into the dom
if ($strip.find('.ticker-spacer:first-child').length === 0 && $strip.find('.ticker-spacer').length > 0){
$strip.children('li.ticker-spacer').before(list[i]);
}
else {
//check for last class ...
//$strip.append(list[i]));
$listItem = $(list[i]);
if(i===list.length-1)
{
$listItem.addClass('last');
}
$strip.find('last').after($listItem);
$strip.find('last').removeClass('last');
}
}
} else{
$strip.find('[data-update="'+id+'"]').replaceWith(list[i]);
}
}
$strip.children('li.webticker-init, li.ticker-spacer').removeClass('old');
if (remove){
$strip.children('li').remove('.old');
}
stripWidth = 0;
stripWidth = getStripWidth($strip);
$strip.width(stripWidth+200);
//resetting $strip so that duplication works according to new width
if ($strip.find('li.webticker-init').length < 1){ // checks if the strip's width is populated and handles the update accordingly
settings.startEmpty=false;
}
$strip.html(list);
//setting the css rules
$strip.children('li').css('white-space','nowrap');
$strip.children('li').css('float',settings.direction);
$strip.children('li').css('padding','0 7px');
$strip.children('li').css('line-height',settings.height);
initialize($strip,true);
}
else
{
// should the update be a 'hot-swap' or use replacement for IDs (in which case remove new ones)
$strip.children('li').addClass('old');
for (var x = 0 ; x < list.length; x++) {
id = $(list[x]).data('update');
match = $strip.find('[data-update="'+id+'"]');//should try find the id or data-attribute.
if (match.length < 1){
if (insert){
//we need to move this item into the dom
if ($strip.find('.ticker-spacer:first-child').length === 0 && $strip.find('.ticker-spacer').length > 0){
$strip.children('li.ticker-spacer').before(list[x]);
}
else {
//check for last class ...
//$strip.append(list[i]));
$listItem = $(list[x]);
if(x===list.length-1)
{
$listItem.addClass('last');
}
$strip.find('.old.last').after($listItem);
$strip.find('.old.last').removeClass('last');
}
}
} else {
$strip.find('[data-update="'+id+'"]').replaceWith(list[x]);
}
}
$strip.children('li.webticker-init, li.ticker-spacer').removeClass('old');
//setting the css rules
$strip.children('li').css('white-space','nowrap');
$strip.children('li').css('float',settings.direction);
$strip.children('li').css('padding','0 7px');
$strip.children('li').css('line-height',settings.height);
if (remove){
$strip.children('li').remove('.old');
}
stripWidth = 0;
stripWidth = getStripWidth($strip);
$strip.width(stripWidth+200);
}
}
$strip.webTicker('cont');
}
};
$.fn.webTicker = function( method ) {
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.webTicker' );
}
};
})( jQuery );