text: /**
   * TextFx.js
   * http://www.codrops.com
   *
   * Licensed under the MIT license.
   * http://www.opensource.org/licenses/mit-license.php
   *
   * Copyright 2016, Codrops
   * http://www.codrops.com
   */
  ;(function(window) {
  
  	'use strict';
  
  	/**
  	 * Equation of a line.
  	 */
  	function lineEq(y2, y1, x2, x1, currentVal) {
  		// y = mx + b
  		var m = (y2 - y1) / (x2 - x1),
  			b = y1 - m * x1;
  
  		return m * currentVal + b;
  	}
  
  	function TextFx(el) {
  		this.el = el;
  		this._init();
  	}
  
  	TextFx.prototype.effects = {
  		'fx1' : {
  			in: {
  				duration: 1000,
  				delay: function(el, index) { return 75+index*40; },
  				easing: 'easeOutElastic',
  				elasticity: 650,
  				opacity: {
  					value: 1,
  					easing: 'easeOutExpo',
  				},
  				translateY: ['50%','0%']
  			},
  			out: {
  				duration: 400,
  				delay: function(el, index) { return index*40; },
  				easing: 'easeOutExpo',
  				opacity: 0,
  				translateY: '-100%'
  			}
  		},
  		'fx2' : {
  			in: {
  				duration: 700,
  				delay: function(el, index) { return index*50; },
  				easing: 'easeOutCirc',
  				opacity: 1,
  				translateX: function(el, index) {
  					return [(50+index*10),0]
  				}
  			},
  			out: {
  				duration: 0,
  				opacity: 0
  			}
  		},
  		'fx3' : {
  			in: {
  				duration: 800,
  				delay: function(el, index) { return index*50; },
  				easing: 'easeOutElastic',
  				opacity: 1,
  				translateY: function(el, index) {
  					return index%2 === 0 ? ['-80%', '0%'] : ['80%', '0%'];
  				}
  			},
  			out: {
  				duration: 800,
  				delay: function(el, index) { return index*50; },
  				easing: 'easeOutExpo',
  				opacity: 0,
  				translateY: function(el, index) {
  					return index%2 === 0 ? '80%' : '-80%';
  				}
  			}
  		},
  		'fx4' : {
  			in: {
  				duration: 700,
  				delay: function(el, index) { return (el.parentNode.children.length-index-1)*80; },
  				easing: 'easeOutElastic',
  				opacity: 1,
  				translateY: function(el, index) {
  					return index%2 === 0 ? ['-80%', '0%'] : ['80%', '0%'];
  				},
  				rotateZ: [90,0]
  			},
  			out: {
  				duration: 500,
  				delay: function(el, index) { return (el.parentNode.children.length-index-1)*80; },
  				easing: 'easeOutExpo',
  				opacity: 0,
  				translateY: function(el, index) {
  					return index%2 === 0 ? '80%' : '-80%';
  				},
  				rotateZ: function(el, index) {
  					return index%2 === 0 ? -25 : 25;
  				}
  			}
  		},
  		'fx5' : {
  			perspective: 1000,
  			in: {
  				duration: 700,
  				delay: function(el, index) { return 550+index*50; },
  				easing: 'easeOutQuint',
  				opacity: {
  					value: 1,
  					easing: 'linear',
  				},
  				translateY: ['-150%','0%'],
  				rotateY: [180,0]
  			},
  			out: {
  				duration: 700,
  				delay: function(el, index) { return index*60; },
  				easing: 'easeInQuint',
  				opacity: {
  					value: 0,
  					easing: 'linear',
  				},
  				translateY: '150%',
  				rotateY: -180
  			}
  		},
  		'fx6' : {
  			in: {
  				duration: 600,
  				easing: 'easeOutQuart',
  				opacity: 1,
  				translateY: function(el, index) {
  					return index%2 === 0 ? ['-40%', '0%'] : ['40%', '0%'];
  				},
  				rotateZ: [10,0]
  			},
  			out: {
  				duration: 0,
  				opacity: 0
  			}
  		},
  		'fx7' : {
  			in: {
  				duration: 250,
  				delay: function(el, index) { return 200+index*25; },
  				easing: 'easeOutCubic',
  				opacity: 1,
  				translateY: ['-50%','0%']
  			},
  			out: {
  				duration: 250,
  				delay: function(el, index) { return index*25; },
  				easing: 'easeOutCubic',
  				opacity: 0,
  				translateY: '50%'
  			}
  		},
  		'fx8' : {
  			in: {
  				duration: 400,
  				delay: function(el, index) { return 150+(el.parentNode.children.length-index-1)*20; },
  				easing: 'easeOutQuad',
  				opacity: 1,
  				translateY: ['100%','0%']
  			},
  			out: {
  				duration: 400,
  				delay: function(el, index) { return (el.parentNode.children.length-index-1)*20; },
  				easing: 'easeInOutQuad',
  				opacity: 0,
  				translateY: '-100%'
  			}
  		},
  		'fx9' : {
  			perspective: 1000,
  			origin: '50% 100%',
  			in: {
  				duration: 400,
  				delay: function(el, index) { return index*50; },
  				easing: 'easeOutSine',
  				opacity: 1,
  				rotateY: [-90,0]
  			},
  			out: {
  				duration: 200,
  				delay: function(el, index) { return index*50; },
  				easing: 'easeOutSine',
  				opacity: 0,
  				rotateY: 45
  			}
  		},
  		'fx10' : {
  			in: {
  				duration: 1000,
  				delay: function(el, index) { return 100+index*30; },
  				easing: 'easeOutElastic',
  				elasticity: anime.random(400, 700),
  				opacity: 1,
  				rotateZ: function(el, index) {
  					return [anime.random(20,40),0];
  				}
  			},
  			out: {
  				duration: 0,
  				opacity: 0
  			}
  		},
  		'fx11' : {
  			perspective: 1000,
  			origin: '50% 100%',
  			in: {
  				duration: 400,
  				delay: function(el, index) { return 200+index*20; },
  				easing: 'easeOutExpo',
  				opacity: 1,
  				rotateY: [-90,0]
  			},
  			out: {
  				duration: 400,
  				delay: function(el, index) { return index*20; },
  				easing: 'easeOutExpo',
  				opacity: 0,
  				rotateY: 90
  			}
  		},
  		'fx12' : {
  			perspective: 1000,
  			origin: '50% 100%',
  			in: {
  				duration: 400,
  				delay: function(el, index) { return 200+index*30; },
  				easing: 'easeOutExpo',
  				opacity: 1,
  				rotateX: [90,0]
  			},
  			out: {
  				duration: 400,
  				delay: function(el, index) { return index*30; },
  				easing: 'easeOutExpo',
  				opacity: 0,
  				rotateX: -90
  			}
  		},
  		'fx13' : {
  			in: {
  				duration: 800,
  				easing: 'easeOutExpo',
  				opacity: 1,
  				translateY: function(el, index) {
  					var p = el.parentNode,
  						lastElOffW = p.lastElementChild.offsetWidth,
  						firstElOffL = p.firstElementChild.offsetLeft,
  						w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft),
  						tyVal = lineEq(0, 200, firstElOffL + w/2, firstElOffL, el.offsetLeft);
  
  					return [Math.abs(tyVal)+50+'%','0%'];
  				},
  				rotateZ: function(el, index) {
  					var p = el.parentNode,
  						lastElOffW = p.lastElementChild.offsetWidth,
  						firstElOffL = p.firstElementChild.offsetLeft,
  						w = p.offsetWidth - lastElOffW - p.firstElementChild.offsetLeft - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft),
  						rz = lineEq(90, -90,firstElOffL + w, firstElOffL, el.offsetLeft);
  
  					return [rz,0];
  				}
  			},
  			out: {
  				duration: 500,
  				easing: 'easeOutExpo',
  				opacity: 0,
  				translateY: '-150%'
  			}
  		},
  		'fx14' : {
  			in: {
  				duration: 500,
  				easing: 'easeOutExpo',
  				delay: function(el, index) { return 200+index*30; },
  				opacity: 1,
  				rotateZ: [20,0],
  				translateY: function(el, index) {
  					var p = el.parentNode,
  						lastElOffW = p.lastElementChild.offsetWidth,
  						firstElOffL = p.firstElementChild.offsetLeft,
  						w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft),
  						tyVal = lineEq(-130, -60, firstElOffL+w, firstElOffL, el.offsetLeft);
  
  					return [Math.abs(tyVal)+'%','0%'];
  				}
  			},
  			out: {
  				duration: 400,
  				easing: 'easeOutExpo',
  				delay: function(el, index) { return (el.parentNode.children.length-index-1)*30; },
  				opacity: 0,
  				rotateZ: 20,
  				translateY: function(el, index) {
  					var p = el.parentNode,
  						lastElOffW = p.lastElementChild.offsetWidth,
  						firstElOffL = p.firstElementChild.offsetLeft,
  						w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft),
  						tyVal = lineEq(-60, -130, firstElOffL+w, firstElOffL, el.offsetLeft);
  
  					return tyVal+'%';
  				}
  			}
  		},
  		'fx15' : {
  			perspective: 1000,
  			in: {
  				duration: 400,
  				delay: function(el, index) { return 100+index*50; },
  				easing: 'easeOutExpo',
  				opacity: 1,
  				rotateX: [110,0]
  			},
  			out: {
  				duration: 400,
  				delay: function(el, index) { return index*50; },
  				easing: 'easeOutExpo',
  				opacity: 0,
  				rotateX: -110
  			}
  		},
  		'fx16' : {
  			in: {
  				duration: function(el, index) { return anime.random(800,1000) },
  				delay: function(el, index) { return anime.random(0,75) },
  				easing: 'easeInOutExpo',
  				opacity: 1,
  				translateY: ['-300%','0%'],
  				rotateZ: function(el, index) { return [anime.random(-50,50), 0]; }
  			},
  			out: {
  				duration: function(el, index) { return anime.random(800,1000) },
  				delay: function(el, index) { return anime.random(0,80) },
  				easing: 'easeInOutExpo',
  				opacity: 0,
  				translateY: '300%',
  				rotateZ: function(el, index) { return anime.random(-50,50); }
  			}
  		},
  		'fx17' : {
  			in: {
  				duration: 650,
  				easing: 'easeOutQuint',
  				delay: function(el, index) { return 450+(el.parentNode.children.length-index-1)*30; },
  				opacity: 1,
  				translateX: function(el, index) {
  					return [-1*el.offsetLeft,0];
  				}
  			},
  			out: {
  				duration: 1,
  				delay: 400,
  				opacity: 0
  			}
  		},
  		'fx18' : {
  			in: {
  				duration: 800,
  				delay: function(el, index) { return 600+index*150; },
  				easing: 'easeInOutQuint',
  				opacity: 1,
  				scaleY: [8,1],
  				scaleX: [0.5,1],
  				translateY: ['-100%','0%']
  			},
  			out: {
  				duration: 800,
  				delay: function(el, index) { return index*150; },
  				easing: 'easeInQuint',
  				opacity: 0,
  				scaleY: {
  					value: 8,
  					delay: function(el, index) { return 100+index*150; },
  				},
  				scaleX: 0.5,
  				translateY: '100%'
  			}
  		}
  	};
  
  	TextFx.prototype._init = function() {
  		this.el.classList.add('letter-effect');
  		// Split word(s) into letters/spans.
  		charming(this.el, {classPrefix: 'letter'});
  		this.letters = [].slice.call(this.el.querySelectorAll('span'));
  		this.lettersTotal = this.letters.length;
  	};
  
  	TextFx.prototype._stop = function() {
  		anime.remove(this.letters);
  		this.letters.forEach(function(letter) { letter.style.WebkitTransform = letter.style.transform = ''; });
  	};
  
  	TextFx.prototype.show = function(effect, callback) {
  		this._stop();
  		arguments.length ? this._animate('in', effect, callback) : this.letters.forEach(function(letter) { letter.style.opacity = 1; });
  	};
  
  	TextFx.prototype.hide = function(effect, callback) {
  		this._stop();
  		arguments.length ? this._animate('out', effect, callback) : this.letters.forEach(function(letter) { letter.style.opacity = 0; });
  	};
  
  	TextFx.prototype._animate = function(direction, effect, callback) {
  		var effecSettings = typeof effect === 'string' ? this.effects[effect] : effect;
  
  		if( effecSettings.perspective != undefined ) {
  			this.el.style.WebkitPerspective = this.el.style.perspective = effecSettings.perspective + 'px';
  		}
  		if( effecSettings.origin != undefined ) {
  			this.letters.forEach(function(letter) {
  				letter.style.WebkitTransformOrigin = letter.style.transformOrigin = effecSettings.origin;
  			});
  		}
  
  		// Custom effect
  		var iscustom = this._checkCustomFx(direction, effect, callback);
  
  		var animOpts = effecSettings[direction],
  			target = this.letters;
  
  		target.forEach(function(t,p) {
  			if( t.innerHTML === ' ' ) {
  				target.splice(p, 1);
  			}
  		});
  
  		animOpts.targets = target;
  
  		if( !iscustom ) {
  			animOpts.complete = callback;
  		}
  
  		anime(animOpts);
  	};
  
  	/**
  	 * Extra stuff for an effect.. this is just an example for effect 17.
  	 * TODO! (for now, just some quick way to implement something different only for fx17)
  	 */
  	TextFx.prototype._checkCustomFx = function(direction, effect, callback) {
  		var custom = typeof effect === 'string' && effect === 'fx17' && direction === 'out';
  
  		if( custom ) {
  			var tmp = document.createElement('div');
  			tmp.style.width = tmp.style.height = '100%';
  			tmp.style.top = tmp.style.left = 0;
  			tmp.style.background = '#414343';
  			tmp.style.position = 'absolute';
  			tmp.style.WebkitTransform = tmp.style.transform = 'scale3d(0,1,1)';
  			tmp.style.WebkitTransformOrigin = tmp.style.transformOrigin = '0% 50%';
  			this.el.appendChild(tmp);
  			var self = this;
  			anime({
  				targets: tmp,
  				duration: 400,
  				easing: 'easeInOutCubic',
  				scaleX: [0,1],
  				complete: function() {
  					tmp.style.WebkitTransformOrigin = tmp.style.transformOrigin = '100% 50%';
  					anime({
  						targets: tmp,
  						duration: 400,
  						easing: 'easeInOutCubic',
  						scaleX: [1,0],
  						complete: function() {
  							self.el.removeChild(tmp);
  							if( typeof callback === 'function' ) {
  								callback();
  							}
  						}
  					});
  				}
  			});
  		}
  
  		return custom;
  	};
  
  	window.TextFx = TextFx;
  
  })(window);
  