mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-01 04:22:15 +08:00
1423b88839
Added material design checkbox component Added lang changing animation
332 lines
8.9 KiB
JavaScript
332 lines
8.9 KiB
JavaScript
(function ($) {
|
|
|
|
"use strict";
|
|
|
|
var LetterFx = function (element, options) {
|
|
|
|
this.options = $.extend({}, $.fn.letterfx.defaults, options);
|
|
|
|
this.num_completed_fx = 0;
|
|
|
|
this.is_done = false;
|
|
|
|
this.monitor_timer = null;
|
|
|
|
this.killswitch=null;
|
|
|
|
this.$element = $(element);
|
|
|
|
if(this.options.restore)
|
|
this.original_html = this.$element.html();
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
LetterFx.prototype.init = function(){
|
|
|
|
this.new_html = this.$element.text().replace( this.options.pattern, this.options.replacement );
|
|
|
|
this.$element.addClass(this.options.css.element.base).addClass( this.options.css.element.before );
|
|
|
|
this.$element.html( this.new_html );
|
|
|
|
this.$letters = this.$element.find(this.options.selector);
|
|
|
|
this.$letters
|
|
.css('transition-duration', this.options.fx_duration)
|
|
.addClass(this.options.css.letters.base)
|
|
.addClass(this.options.css.letters.before);
|
|
|
|
this.bindLetterFxEnd();
|
|
|
|
this.num_letters = this.$letters.length;
|
|
|
|
|
|
this.fx();
|
|
|
|
return this;
|
|
}
|
|
|
|
LetterFx.prototype.bindLetterFxEnd = function(){
|
|
var options = this.options;
|
|
var lfx = this;
|
|
this.$letters.bind("transitionend", function(){
|
|
options.onLetterComplete( $(this), lfx.$element, lfx );
|
|
lfx.notifyFXEnd( );
|
|
|
|
switch(options.letter_end){
|
|
case "destroy":
|
|
$(this).remove();
|
|
break;
|
|
|
|
case "rewind":
|
|
lfx.applyLetterFx( $(this), options.timing, options.css.letters.after, options.css.letters.before );
|
|
break;
|
|
|
|
case "stay":
|
|
break;
|
|
|
|
// restore
|
|
default:
|
|
$(this).replaceWith( $(this).text() );
|
|
}
|
|
|
|
});
|
|
return lfx;
|
|
}
|
|
|
|
LetterFx.prototype.terminate=function(){
|
|
this.is_done = true;
|
|
this.options.onElementComplete(this.$element, this);
|
|
|
|
clearTimeout(this.killswitch);
|
|
|
|
switch(this.options.element_end){
|
|
case "destroy":
|
|
this.$element.remove();
|
|
break;
|
|
|
|
case "stay":
|
|
break;
|
|
|
|
// restore
|
|
default:
|
|
this.$element.html( this.original_html );
|
|
this.$element.removeClass( this.options.css.element.base ).removeClass(this.options.css.element.after);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
LetterFx.prototype.notifyFXEnd=function(){
|
|
clearTimeout(this.monitor_timer);
|
|
this.num_completed_fx++;
|
|
|
|
var lfx = this;
|
|
this.monitor_timer = setTimeout(
|
|
function(){
|
|
if(lfx.num_completed_fx % lfx.num_letters===0){
|
|
lfx.terminate();
|
|
}
|
|
},
|
|
Math.max(this.options.timing+10, 50)
|
|
);
|
|
|
|
return this;
|
|
}
|
|
|
|
LetterFx.prototype.startKillWatch = function(){
|
|
var fx_duration = this.options.fx_duration.match(/\d+s/) ? parseInt(this.options.fx_duration) : 1;
|
|
var time = Math.ceil(1.5 * this.num_letters * this.options.timing * fx_duration );
|
|
var lfx = this;
|
|
this.killswitch = window.setTimeout(function(){
|
|
if(!lfx.isDone()){
|
|
lfx.terminate()
|
|
}
|
|
}, time)
|
|
}
|
|
|
|
LetterFx.prototype.fx = function(){
|
|
var lfx = this;
|
|
this.startKillWatch();
|
|
this.$element.removeClass(this.options.css.element.before).addClass(this.options.css.element.after);
|
|
var $letters = this.options.sort(this.$letters);
|
|
var options = this.options;
|
|
|
|
|
|
|
|
$letters.each(
|
|
function(i, letter){
|
|
lfx.applyLetterFx( $(letter), (i+1)*options.timing, options.css.letters.before, options.css.letters.after);
|
|
}
|
|
);
|
|
return this;
|
|
}
|
|
|
|
LetterFx.prototype.applyLetterFx = function($letter, timing, css_before, css_after){
|
|
var options = this.options;
|
|
|
|
window.setTimeout(
|
|
function(){
|
|
$letter.removeClass(css_before).addClass(css_after);
|
|
},
|
|
timing
|
|
);
|
|
return this
|
|
}
|
|
|
|
LetterFx.prototype.isDone = function(){
|
|
return this.is_done;
|
|
}
|
|
|
|
|
|
|
|
|
|
var LetterFxConfig = function(conf){
|
|
this.config = $.extend({}, $.fn.letterfx.defaults, conf);
|
|
this.buildCss(this.config.backwards);
|
|
|
|
// check & change to word pattern
|
|
if(this.config.words)
|
|
this.config.pattern=/(\S+)/g;
|
|
|
|
|
|
}
|
|
|
|
|
|
LetterFxConfig.prototype.buildCss = function(flip){
|
|
var options = this.config;
|
|
var before = flip ? 'after' : 'before';
|
|
var after = flip ? 'before' : 'after';
|
|
|
|
|
|
var css = { element:{}, letters:{} };
|
|
|
|
css.element.base=options.element_class+ "-container " + options.fx.replace(/(\S+)/g, options.element_class + "-$1-container");
|
|
css.element[before]=options.fx.replace(/(\S+)/g, options.element_class + "-$1-before-container");
|
|
css.element[after]=options.fx.replace(/(\S+)/g, options.element_class + "-$1-after-container");
|
|
|
|
css.letters.base = options.element_class;
|
|
css.letters[before] = options.fx.replace(/(\S+)/g, options.element_class + "-$1-before")
|
|
css.letters[after] = options.fx.replace(/(\S+)/g, options.element_class + "-$1-after")
|
|
|
|
this.config = $.extend( options, {'css':css} );
|
|
}
|
|
|
|
LetterFxConfig.prototype.getConfig = function(){
|
|
return this.config;
|
|
}
|
|
|
|
LetterFxConfig.parse=function(config){
|
|
return (new LetterFxConfig( config )).getConfig();
|
|
}
|
|
|
|
|
|
|
|
|
|
$.fn.letterfx=function(config){
|
|
|
|
config = LetterFxConfig.parse( config );
|
|
|
|
return $(this).each(function(){
|
|
var $element = $(this);
|
|
if (! $element.data('letterfx-obj') || $element.data('letterfx-obj').isDone() ){
|
|
$element.data('letterfx-obj', new LetterFx( $element, config ) );
|
|
}
|
|
});
|
|
|
|
};
|
|
|
|
$.fn.letterfx.sort={
|
|
random:function(array){
|
|
var currentIndex = array.length, temporaryValue, randomIndex;
|
|
|
|
// While there remain elements to shuffle...
|
|
while (0 !== currentIndex) {
|
|
|
|
// Pick a remaining element...
|
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
currentIndex -= 1;
|
|
|
|
// And swap it with the current element.
|
|
temporaryValue = array[currentIndex];
|
|
array[currentIndex] = array[randomIndex];
|
|
array[randomIndex] = temporaryValue;
|
|
}
|
|
|
|
return array;
|
|
},
|
|
reverse:function($array){
|
|
return $array.toArray().reverse();
|
|
}
|
|
}
|
|
|
|
$.fn.letterfx.patterns={
|
|
letters:/(\S)/gi
|
|
}
|
|
|
|
// Plugin Configurables
|
|
$.fn.letterfx.defaults = {
|
|
|
|
// Default fx
|
|
fx:'spin fly-top',
|
|
|
|
// defaults to selecting all characters
|
|
pattern:/(\S)/gi,
|
|
|
|
// switch from letter FX to word FX.
|
|
word:false,
|
|
|
|
// fx, like fly or fade, can happen in (eg fade-in) or out (eg fade-out).
|
|
// The default is in; change backwards to true to reverse the order of the effects.
|
|
backwards:false,
|
|
|
|
// defaults to injecting spans, can be any inline element
|
|
replacement:"<span>$1</span>",
|
|
|
|
//selector -- should match replacement above
|
|
selector:'span',
|
|
|
|
// letter fx start sequentially: letters start their fx one after another.
|
|
// this sets time between the letters
|
|
timing:50,
|
|
|
|
//duration of each fx
|
|
// options the same as css property for transition-duration ("1ms", "1s", etc)
|
|
fx_duration:"1s",
|
|
|
|
|
|
// stabile dimensions
|
|
// stabilize:true,
|
|
|
|
// sort callback for custom sorting elements
|
|
sort:function($letters){ return $letters; },
|
|
|
|
|
|
// Callback when letter is done animating. Runs after each letter
|
|
onLetterComplete:function($letter, $element, LetterFXObj){},
|
|
|
|
// Runs after all are done.
|
|
onElementComplete:function($element, LetterFXObj){},
|
|
|
|
|
|
// what to do when a letter completes its animation.
|
|
// options include
|
|
// restore: return letter to plain text (default)
|
|
// destroy: get rid of the letter.
|
|
// stay: leave it as is.
|
|
// rewind: reverse the animation
|
|
letter_end:"restore",
|
|
|
|
|
|
// what to do when the entire element has completed all its letter effects
|
|
// options include:
|
|
// restore: return element to its pre-fx state (default)
|
|
// stay: do nothing
|
|
// destroy: get rid of the element... FOREVER
|
|
element_end:"restore",
|
|
|
|
// Restore container element back to original state.
|
|
// options: true, false, "element" ("element" waits until all letters complete fx before restoring)
|
|
restore:true,
|
|
|
|
// destroy element/letters after fx, useful on {out:true} fx
|
|
// options: true, false, "letters" ("letters" destroys each letter after fx, but elements original content may be restored after all letters complete fx)
|
|
destroy:false,
|
|
|
|
// default class for injected elements
|
|
element_class:'letterfx',
|
|
|
|
// placeholder values that are calculated on launch
|
|
css:{
|
|
element:{ base:'', before:'', after:''},
|
|
letters:{ base:'', before:'', after:''}
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
}(jQuery));
|
|
|