Text Effects with TimelineMax

Text is one of the most important aspects of web-development, someone may have great pictures, effects, and complex animations but if there is no content in text, chances are that the viewer will start looking elsewhere. So since text is such a great aspect of the website or application why not try and make it a little more appealing and exciting, after all it’s not only what you say (write) but how you present it.

So I thought to create a series of effects and animations that modify and give text a “Wow factor”.

[[code]]czowOlwiXCI7e1smKiZdfQ==[[/code]]<a href="http://codepen.io/netgfx/pen/DpbIy">Check out this Pen!</a>

I have to say that I was inspired by greensock “SplitText” examples that were made with AS3 (not so)back in the day.

These experiments will be divided into three sections, splitting letters, words and lines.

So lets start by adding some html.

Step 1 : The markup

 <div id="menu">
            <div class="menuItem" id="words">SPLIT WORDS!</div>
            <div class="menuItem" id="letters">SPLIT LETTERS!</div>
            <div class="menuItem" id="lines">SPLIT LINES!</div>
            <div class="menuItem" id="reverse">REVERSE!</div>
        </div>
       
        <p class="splitText">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>

Here we added some text inside a

element and we added a menu on top to control our animations.


Now lets add some style into this.

Step 2 : The style…

.splitText{
width: 600px;
float: left;
margin-top: 90px;
margin-left: 20px;
font-size:20px;
}

.splitText>div{
    white-space:pre-line;
    float:left;
    margin-right:5px;
}

#menu{
    width:100%;
    background-color:#222222;
    height:60px;
    position: fixed;
    top:0px;
    left:0px;
    margin-bottom:20px;
}

.menuItem{
    background-color:#105CB6;
    color:#000000;
    text-align:center;
    float:left;
    position:relative;
    margin-right:10px;
    height:40px;
    line-height:40px;
    font-size:20px;
    cursor: pointer;
    top:10px;
    padding-left:10px;
    padding-right:10px;
}

.letter-measure{
    margin-right:0 !important;
}

.blank{
    margin-right:0px !important;
    white-space: pre !important;
}

The important here is the white-space:pre-line; rule because it allows us to manipulate spaces efficiently.


Step 3 : Adding Javascript

Since we have our html and css all covered, we now need to add the script to break the text into letters, words and lines.
Lets start with the easy part which is words.
The trick here is that we split by “space” and we add each word inside a div tag

So first of all we declare 3 global variables

var threeDTimeline = new TimelineMax();
var initialText;
var types = new Array();

We declare the timeline for the animations, a variable to hold the initial text, and an array that will contain the results of the spliting functions.

Following are the functions that split the text into blocks of tags

jQuery.fn.splitLetters = function (userInput){
    var a;
    var arr = userInput.split("");
   
    for(var i=0;i<arr.length;i++) {
       
        if(arr[i] == " "){
                arr[i] = '<div class="letter-measure blank">' + arr[i] + '</div>';
        }
        else{
     
            if(!arr[i].match(/\s\n\t\r/g) && arr[i]!="") arr[i] = '<div class="letter-measure">' + arr[i] + '</div>';
     
        }
   }
   
   return arr.join(" ");
 
};

jQuery.fn.lineText = function (userInput) {
   var a = userInput.replace(/\n/g, " \n<br/> ").split(" ");
   
   $.each(a, function(i, val) {
      if(!val.match(/\n/) && val!="") a[i] = '<div class="word-measure">' + val + '</div>';
   });

   var arr = a.join(" ");
   return arr;
};

jQuery.fn.getLines = function (){
   
   var count = $(this).children(".word-measure").length;
   var lineAcc = [$(this).children(".word-measure:eq(0)").text()];
   var textAcc = [];
   for(var i=1; i<count; i++){
      var prevY = $(this).children(".word-measure:eq("+(i-1)+")").offset().top;
      if($(this).children(".word-measure:eq("+i+")").offset().top==prevY){
         lineAcc.push($(this).children(".word-measure:eq("+i+")").text());
   }
   else {
     textAcc.push({text: lineAcc.join(" "), top: prevY});
     lineAcc = [$(this).children(".word-measure:eq("+i+")").text()];
   }
   }
   textAcc.push({text: lineAcc.join(" "), top: $(this).children(".word-measure:last").offset().top});
   return textAcc;
   
};

And a function for getting random:
function getRandom(max, min){
return Math.floor(Math.random() * (1 + max – min) + min);
}

So lets do some explaining, the basic idea here is to split the words, letters and lines and re-enter them as blocks of html code, for the lines split we use the already split text by words and we split again by “\n or \r” (change line).


Step 4 : Animating

Now all we need to do is write down the functions for the animations.

function animateLines(){
    $(".split-lines").each(function(){
           
        var w = $(this).width();
        $(this).css({'white-space':'nowrap'});
        threeDTimeline.add(TweenMax.to($(this),1,{autoAlpha:0,marginLeft:w,ease:Circ.easeIn}),"-=0.45");
           
    });
}

function explodeWords(){
    threeDTimeline = new TimelineMax();
    var children = $('.splitText').children().length;
   
    for(var i=0;i<children;i++){
      threeDTimeline.to($(".splitText").children().eq(i), 1.4, {rotationY:getRandom(-270,360), top:80, transformOrigin: "50% 50% -80", rotationX:getRandom(-360, 600), rotationY:getRandom(-360, -600),
        autoAlpha:0}, "explode");
    }
}

function explodeLetters(){
   
    threeDTimeline = new TimelineMax({align:'start'});
   
    var children = $('.splitText').children().length;
    for(var i=0;i<children;i++){
         
         for(var i=0;i<children;i++){
           
            var element = $(".splitText").children().eq(i);
            var pos = element.offset();
            element.css({'left':pos.left,'top':pos.top});
           
            threeDTimeline.insert(TweenMax.to(element, 1.4, {
            'position':'absolute',
            left:Math.random() * 650 - 100,
            top:Math.random() * 350 - 100,
            fontSize:"+=35",
            ease:Expo.easeInOut,
            autoAlpha:0}));
           
        }
       
        threeDTimeline.play();
    }
}

So here we have the code for the animations based on moving, scaling, rotating the letters to create some interesting effects.


Step 5 : Events

Now lets define some event listeners to control the effects from the menu.

initialText = $(".splitText").text();
    // lets get the assosiated splits and store them
    types[0] = $(".splitText").splitLetters(initialText);
    types[1] = $(".splitText").lineText(initialText);
   
    $("#letters").on('click',function(){
        $(".splitText").empty();
        $(".splitText").html(types[0]);
        explodeLetters();
    });
   
    $("#words").on('click',function(){
        $(".splitText").empty();
        $(".splitText").html(types[1]);
        explodeWords();
    });
   
    $("#lines").on('click',function(){
       
        var a = $(".splitText").lineText(initialText);
       
        $(".splitText").html(a);
       
        var obj = $(".splitText").getLines();
        $(".splitText").empty();
       
        threeDTimeline = new TimelineMax({align:'normal'});
       
        $.each(obj,function(index,value){
           
            var item = "<div class='split-lines'>"+value.text+"</div>";
           
            $(".splitText").append(item);
           
        });
       
        animateLines();
       
    });
   
   
    $("#reverse").on('click',function(){
        threeDTimeline.reverse();
    });

And with that final code we have completed our experiments.

You can view a working example here with the full code used in this tutorial.

I have also posted the “split letters” example on CODEPEN for everyone who wishes to experiment a bit.

CodePen –> http://cdpn.io/DpbIy

Enjoy!

Tagged . Bookmark the permalink.

4 Responses to Text Effects with TimelineMax

  1. Ico Dimchev says:

    Great tutorial, Michael! I did something similar, but using a quite different technique : http://blog.bassta.bg/2013/05/text-animation-with-tweenmax/

  2. Yes I have seen your work, truly some awesome stuff in there. I wonder if we could somehow create a massive TextAnimation plugin for JQuery. Feel free to email me @ contact[at]netgfx.com

  3. Michael says:

    And now Jack’s ported SplitText to the JS! That guy is astounding. http://www.greensock.com/splittext/

  4. Yes it looks quite promising, I might just port my effects to the new SplitText

Leave a Reply

Your email address will not be published. Required fields are marked *