Skip to content

Instantly share code, notes, and snippets.

@hkfoster
Last active August 29, 2015 14:22
Show Gist options
  • Save hkfoster/9223cc2930a5b68b3778 to your computer and use it in GitHub Desktop.
Save hkfoster/9223cc2930a5b68b3778 to your computer and use it in GitHub Desktop.
Headline Typewriter Animation
/**
* 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 ) ? '<span class="shown">' + letters[ letterIndex ] + '</span>': '<span class="hidden">' + letters[ letterIndex ] + '</span>';
}
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();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment