/** * Typewriter.js 0.0.1 * @author Kyle Foster (@hkfoster) * @license MIT (http://www.opensource.org/licenses/mit-license.php/) */ var typewriter = ( function() { var headline = document.querySelector( '.typewriter' ); if ( !headline ) { return; } /** * Behaves the same as setTimeout except uses requestAnimationFrame() where possible for better performance * @param {function} fn The callback function * @param {int} delay The delay in milliseconds */ window.requestTimeout = function( fn, delay ) { var start = new Date().getTime(), handle = new Object(); function loop() { var current = new Date().getTime(), delta = current - start; delta >= delay ? fn.call() : handle.value = requestAnimationFrame( loop ); }; handle.value = requestAnimationFrame( loop ); return handle; }; var animationDelay = 2500, typeLettersDelay = 150, selectionDuration = 500, typeAnimationDelay = selectionDuration + 800, headlineWords = headline.querySelectorAll( '.words > .word' ); // Init function function initHeadline() { setupWords( headlineWords ); setupLetters( headlineWords ); pause( headline ); animateHeadline( headline ); } // Initial show/hide of words function setupWords( words ) { for ( var wordIndex = 0; wordIndex < words.length; wordIndex++ ) { hide( words[ wordIndex ] ); show( words[ 0 ] ); } } // Initial wrap/show/hide of letters function setupLetters( words ) { for ( var wordIndex = 0; wordIndex < words.length; wordIndex++ ) { var word = words[ wordIndex ], letters = word.textContent.split( '' ), selected = classie.has( word, 'shown' ); for ( var letterIndex = 0; letterIndex < letters.length; letterIndex++ ) { letters[ letterIndex ] = ( selected ) ? '' + letters[ letterIndex ] + '': ''; } word.innerHTML = letters.join( '' ); } } // Main animation function function animateHeadline( headline ) { requestTimeout( function() { hideWord( headline.querySelector( '.shown' ) ); }, animationDelay ); } // Hide word function hideWord( word ) { var nextWord = takeNext( word ), wordLetters = word.querySelectorAll( 'span' ), parentSpan = word.parentNode; select( parentSpan ); unpause( headline ); requestTimeout( function() { deselect( parentSpan ); hide( word ); for ( var letterIndex = 0; letterIndex < wordLetters.length; letterIndex++ ) { hide( wordLetters[ letterIndex ] ); } }, selectionDuration ); requestTimeout( function() { showWord( nextWord, typeLettersDelay ); }, typeAnimationDelay ); } // Show word function showWord( word, duration ) { showLetter( word.querySelector( 'span' ), word, false, duration ); show( word ); } // Show letter function showLetter( letter, word, bool, duration ) { show( letter ); if ( letter !== letter.parentNode.lastChild ) { requestTimeout( function() { showLetter( letter.nextElementSibling, word, bool, duration ); }, duration ); } else { requestTimeout( function() { pause( headline ); }, 200 ); if ( !bool ) { requestTimeout( function() { hideWord( word ); }, animationDelay ); } } } // Choose next word function takeNext( word ) { return ( word !== word.parentNode.lastChild.previousSibling ? word.nextElementSibling : word.parentNode.firstChild.nextElementSibling ); } // Select function select( elem ) { classie.add( elem, 'selected' ); } // Deselect function deselect( elem ) { classie.remove( elem, 'selected' ); } // Pause function pause( elem ) { classie.add( elem, 'paused' ); } // Unpause function unpause( elem ) { classie.remove( elem, 'paused' ); } // Hide function hide( elem ) { classie.remove( elem, 'shown' ); classie.add( elem, 'hidden' ); } // Show function show( elem ) { classie.remove( elem, 'hidden' ); classie.add( elem, 'shown' ); } // Instantiate initHeadline(); })();