/* * textillate.js * http://jschr.github.com/textillate * mit licensed * * copyright (c) 2012-2013 jordan schroter */ (function ($) { "use strict"; function isineffect (effect) { return /in/.test(effect) || $.inarray(effect, $.fn.textillate.defaults.ineffects) >= 0; }; function isouteffect (effect) { return /out/.test(effect) || $.inarray(effect, $.fn.textillate.defaults.outeffects) >= 0; }; // custom get data api method function getdata (node) { var attrs = node.attributes || [] , data = {}; if (!attrs.length) return data; $.each(attrs, function (i, attr) { if (/^data-in-*/.test(attr.nodename)) { data.in = data.in || {}; data.in[attr.nodename.replace(/data-in-/, '')] = attr.nodevalue; } else if (/^data-out-*/.test(attr.nodename)) { data.out = data.out || {}; data.out[attr.nodename.replace(/data-out-/, '')] = attr.nodevalue; } else if (/^data-*/.test(attr.nodename)) { data[attr.nodename] = attr.nodevalue; //console.log(/^data-*/.test(attr.nodename)+'----'+attr.nodename+'-------------'+data[attr.nodename]) } }) //console.log(data) return data; } function shuffle (o) { for (var j, x, i = o.length; i; j = parseint(math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); return o; } function animate ($c, effect, cb) { $c.addclass('animated ' + effect) .css('visibility', 'visible') .show(); $c.one('animationend webkitanimationend oanimationend', function () { $c.removeclass('animated ' + effect); cb && cb(); }); } function animatechars ($chars, options, cb) { var that = this , count = $chars.length; if (!count) { cb && cb(); return; } if (options.shuffle) $chars = shuffle($chars); if (options.reverse) $chars = $chars.toarray().reverse(); $.each($chars, function (i, c) { var $char = $(c); function complete () { if (isineffect(options.effect)) { $char.css('visibility', 'visible'); } else if (isouteffect(options.effect)) { $char.css('visibility', 'hidden'); } count -= 1; if (!count && cb) cb(); } var delay = options.sync ? options.delay : options.delay * i * options.delayscale; //console.log(options) $char.text() ? settimeout(function () { animate($char, options.effect, complete) }, delay) : complete(); }); }; var textillate = function (element, options) { var base = this , $element = $(element); base.init = function () { base.$texts = $element.find(options.selector); if (!base.$texts.length) { base.$texts = $(''); $element.html(base.$texts); } base.$texts.hide(); base.$current = $('') .text(base.$texts.find(':first-child').html()) .prependto($element); if (isineffect(options.in.effect)) { base.$current.css('visibility', 'hidden'); } else if (isouteffect(options.out.effect)) { base.$current.css('visibility', 'visible'); } base.setoptions(options); base.timeoutrun = null; settimeout(function () { base.options.autostart && base.start(); }, base.options.initialdelay) }; base.setoptions = function (options) { base.options = options; }; base.triggerevent = function (name) { var e = $.event(name + '.tlt'); $element.trigger(e, base); return e; }; base.in = function (index, cb) { index = index || 0; var $elem = base.$texts.find(':nth-child(' + (index + 1) + ')') , options = $.extend({}, base.options, getdata($elem)) , $chars; $elem.addclass('current'); base.triggerevent('inanimationbegin'); base.$current .text($elem.html()) .lettering('words'); base.$current.find('[class^="word"]') .css({ 'display': 'inline-block', // fix for poor ios performance '-webkit-transform': 'translate3d(0,0,0)', '-moz-transform': 'translate3d(0,0,0)', '-o-transform': 'translate3d(0,0,0)', 'transform': 'translate3d(0,0,0)' }) .each(function () { $(this).lettering() }); $chars = base.$current .find('[class^="char"]') .css('display', 'inline-block'); if (isineffect(options.in.effect)) { $chars.css('visibility', 'hidden'); } else if (isouteffect(options.in.effect)) { $chars.css('visibility', 'visible'); } base.currentindex = index; animatechars($chars, options.in, function () { base.triggerevent('inanimationend'); if (options.in.callback) options.in.callback(); if (cb) cb(base); }); }; base.out = function (cb) { var $elem = base.$texts.find(':nth-child(' + (base.currentindex + 1) + ')') , $chars = base.$current.find('[class^="char"]') , options = $.extend({}, base.options, getdata($elem)); base.triggerevent('outanimationbegin'); animatechars($chars, options.out, function () { $elem.removeclass('current'); base.triggerevent('outanimationend'); if (options.out.callback) options.out.callback(); if (cb) cb(base); }); }; base.start = function (index) { base.triggerevent('start'); (function run (index) { base.in(index, function () { var length = base.$texts.children().length; index += 1; if (!base.options.loop && index >= length) { if (base.options.callback) base.options.callback(); base.triggerevent('end'); } else { index = index % length; base.timeoutrun = settimeout(function () { base.out(function () { run(index) }); }, base.options.mindisplaytime); } }); }(index || 0)); }; base.stop = function () { if (base.timeoutrun) { clearinterval(base.timeoutrun); base.timeoutrun = null; } }; base.init(); } $.fn.textillate = function (settings, args) { return this.each(function () { var $this = $(this) , data = $this.data('textillate') , options = $.extend(true, {}, $.fn.textillate.defaults, getdata(this), typeof settings == 'object' && settings); if (!data) { $this.data('textillate', (data = new textillate(this, options))); } else if (typeof settings == 'string') { data[settings].apply(data, [].concat(args)); } else { data.setoptions.call(data, options); } }) }; $.fn.textillate.defaults = { selector: '.texts', loop: false, mindisplaytime: 2000, initialdelay: 0, in: { effect: 'fadeinleftbig', delayscale: 1.5, delay: 50, sync: false, reverse: false, shuffle: false, callback: function () {} }, out: { effect: 'hinge', delayscale: 1.5, delay: 50, sync: false, reverse: false, shuffle: false, callback: function () {} }, autostart: true, ineffects: [], outeffects: [ 'hinge' ], callback: function () {} }; }(jquery));