Animating Text using jQuery Examples
+++Second Lorem ipsum dolor sit amet, consectetur adipiscing elit.
A client of mine recently wanted the option to have scrolling text for breaking news type items. For the most part I think that scrolling text isn’t the greatest thing to use but there are certain situations where its good. The real simple and fast way to do it is to simply use a <marquee> tag like this <marquee width=”100%;” behavior=”SCROLL” direction=”left” scrollamount=”10″> Lorem ipsum doler </marquee>
The problem with this is it doesn’t do a continuous loop. What I mean by this is that it doesn’t start over till the text has completely finished scrolling. This means you see a lot of white space. Also jQuery seems to be a smoother animation. I knew jQuery had the animate function, so I used that. I found some plugins and examples where they had images being repeated but said they couldn’t do text cause they didn’t know the width. I guess they didn’t know css. So lets start with the css/html part of it.
Scrolling Text to the Left
The first thing we need to do is to get the width of the text that is being scrolled. So we need to create a div wrapper and set the width to be really big. This way the text wont be wrapped because of parent elements. We also set the display to none and visibility to hidden. This is done so that we don’t ever see this text. The display none keeps the browser from rendering the div in the browser, otherwise with just the visibility set to hidden we would see a big white space. Then we add another element inside with the text.
<div id="textwrapper" style="width:5000px; display:none; visibility:hidden;">
<span id="textwidth" style="disply:none;">
+++Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed magna ligula, tempus feugiat pellentesque et,pulvinar
eu tellus.
</span>
</div>
;
Now the html for the actual text being scrolled. We have a scrollwrapper element which contains the width of the the text being scrolled. We also need to set the position to relative so that the text being scrolled will be absolutely positioned relative to this element and not the page. The next element is used to make sure the text doesn’t wrap just like we did previously, we set the width to an arbitrarily large number. Then we have the scrollcontent element. This is the element that is going to be moving. This is positioned absolutely and we set the left position to the width of the scrollwrapper element to make sure it starts on the far right. Then we need one more wrapper inside.
<div id="scrollwrapper" style="overflow:hidden; border:1px solid #004F72;
position:relative; width:500px; height:20px;">
<div style="width:5000px;">
<span id="scrollcontent" style="position:absolute; left:500px;">
<span id="firstcontent" style="float:left; text-align:left;">
+++Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed magna ligula, tempus feugiat pellentesque et, pulvinar
eu tellus.
</span>
</span>
</div>
</div>
Here is the javascript but first let me explain how I am using the jquery animation function. The first object passed to it is what I’m animating. I am changing the property “left” to go to the negative of the scrollwidth. The next thing I pass to it is an object of some of the properties. The first property I am setting is “step”. This is a function that will get called everytime the animation runs. The next property is “duration” which is the amount of time it will take to finish the animation in milliseconds. The next is “easing” which is the equation used to do the animation. jQuery comes with 2 equations: linear and swing. Default is swing but we’ll set it to linear. The last property we’ll set is “complete” which is a function that’ll be called when the animation is done.
$("#textwrapper").css({"display":"block"});
var scrollwidth = $("#textwidth").width();
$("#textwrapper").remove();
var scrollwrapperwidth = $("#scrollwrapper").width();
if(scrollwidth < scrollwrapperwidth) scrollwidth = scrollwrapperwidth;
$("#scrollcontent").css({"width":scrollwidth});
$("#firstcontent").css({"width":scrollwidth});
var appending = scrollwrapperwidth-scrollwidth;
var noappend = 0;
function animatetext(rate){
var dist = scrollwidth+parseFloat($("#scrollcontent").css("left"));
if(!rate)rate = 1;
var duration = Math.abs(dist/(rate/100));
$("#scrollcontent").animate({"left":"-"+scrollwidth},{
step: function() {
if(parseFloat($("#scrollcontent").css("left"))< parseFloat(appending)
&& !noappend){
noappend = 1;
$("#scrollcontent").css({"width":scrollwidth+scrollwidth});
$("#scrollcontent").append("<span style='float:left; text-align:left;
width:"+scrollwidth+"px;'>"
+$("#scrollcontent").children(":first").html()+"</span>");
}
},
duration: duration,
easing: "linear",
complete:function(){
$("#scrollcontent").children(":first").remove();
$("#scrollcontent").css({"left":0});
$("#scrollcontent").css({"width":scrollwidth});
noappend=0;
animatetext(6);
}
});
}
$("#scrollcontent").mouseover(function(e){
$("#scrollcontent").stop();
});
$("#scrollcontent").mouseout(function(e){
animatetext(6);
});
$(document).ready(function(){
animatetext(6);
});
First in the javascript we will get the width of the text. We first need to set the css of the textwrapper to "block" so that it will render the child elements width. Then we will get the width of the inner element "textwidth" and then delete the textwrapper element.
If the javascript variable "scrollwidth" is less than the width that we want it to scroll we need to set it. Then we set 2 variables, appending and noappend. These variables are used in the "step" function. So when the position of the scrolling text is less than the position "appending" and we haven't already appended text (the noappend flag), then we'll set the width of the scrollcontent to double the width since we are appending the same text in there again. Then when the animation is completed we will remove the first element, change the left position to 0, change the width of the scrolling content back to the scrollwidth and then call this function again. Also if we want to stop the animation on mouseover as I have it, we simply call the .stop().
NOTE: since the .animate function takes a duration and not a speed, to keep the same speed we need to calculate the duration. That way if you are dynamically changing the text the speed wont change just because you have more or less text. To do this it is pretty straight forward. Since we are using linear as our easing property, the equation is simply d=rt, where d is the distance we need to travel and r is the rate and t is the time. So we get the distance by taking the scrollwidth and adding it to the current left position of the scrollcontent. Then we simple pass in a rate of 1- whatever and calcuate the time in milliseconds.
Scrolling Text Up
Scolling text up is even easier. The html looks like this. We need a wrapper with position relative and height equal to whatever you want. Then we need the child element which will be the element being moved. Then we need at least one element inside that to contain the text but can have more if you want. Also the line-height needs to be set to whatever the height is of the outerwrapper.
<div id="scrolltextup" style="border:1px ridge #004F72; overflow:hidden;
position:relative; width:500px; height:20px;">
<div id="textup" style="text-align:center; position:absolute; top:0;
left:0; width:500px;">
<div style="line-height:20px;">
+++First Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+++Second Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
Here is the javascript to do it. We get height of the entire thing. This time we are change the "top" property. Since the distance to animate will always be the same we don't need to calculate duration and can just pass in the duration.
var scrollheight = $("#textup").height();
function scrolltextup(dur){
$("#textup").animate({"top":"-=20"},{
duration: dur,
easing: "linear",
complete:function(){
$("#textup").children(":last").after("<div style='line-height:20px;'>"+
$("#textup").children(":first").html()+"</div>");
if($("#textup").children(":first").height() <=
(parseInt($("#textup").css("top"))*-1)){
$("#textup").children(":first").remove();
$("#textup").css({"top":0});
}
setTimeout("scrolltextup(3000)", 500);
}
});
}
And thats it!
Comments are closed.