Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing text with jquery, can't get the transitions right

I am working on a text effect but the transition is not completely to my liking.

I am replacing a single word in a line of centered text, I make the old word fade out and the new one fade in, but the surrounding text "jumps". I have been trying for a while to figure out how to make it slide to it's new spot somehow by using an animation on margins or width, but I cannot seem to figure it out.

Here is a JSfiddle of what I have right now http://jsfiddle.net/DEk7m/3/

What I am trying to achieve is something similar to what is seen in the big title here: https://gumroad.com/

And here is the code:

HTML:

<h1 id="changingtext">This is <span>changing</span> text</h1>

CSS:

h1 {
text-align: center;
font-family: helvetica, arial, sans-serif;
}

JavaScript (using jQuery):

$(function() {
  var t1 = new Array("changing", "dynamic", "cool");
  var i = 0;
  var tid = setInterval(
      function() {
        $("#changingtext span").animate({'opacity': 0}, 1000, function () {
            $(this).text(t1[i]);
        }).animate({'opacity': 1}, 1000);

        if(i < t1.length -1) 
            i++;
        else i = 0;

      }, 3000 );

});

many thanks!

like image 799
KennyV Avatar asked May 05 '13 13:05

KennyV


2 Answers

Width is missing in your demo, Have a look at this,

HTML

<body>
    <h1><span id="chkWidth" style="display: none;"></span></h1>
    <h1 id="changingtext">This is <span>changing</span> text</h1>
</body>

Script

$(function() {
  var t1 = new Array("changing", "dynamic", "cool");
  var i = 0;
  var width;
  var tid = setInterval(
      function() {
          $("#changingtext span").animate({'opacity': 0}, 1000, function () {
            $(this).text(t1[i]);
            width = $('#chkWidth').text(t1[i]).width();
            $(this).animate({'opacity': 1, 'width': width}, 1000);
        });

        if(i < t1.length -1) 
            i++;
        else i = 0;

      }, 3000 );

});

http://jsfiddle.net/DEk7m/8/

Hope this will help you.

like image 197
moustacheman Avatar answered Sep 23 '22 06:09

moustacheman


SEE ANOTHER ANSWER COVERING THE SAME QUESTION

BON! No need for setInterval when you deal with .animate()
An even better approach without the first change gap/jump
and with dynamically calculated span widths:

LIVE DEMO

CSS:

h1 span{
    /* To prevent a jumpy misaligned SPAN due to widths change. */
    vertical-align:top; 
}

jQ:

$(function() {

  var t=["changing", "dynamic", "cool"],
      $h1 = $("#changingtext"),
      $sp = $h1.find("span"),
      i=0,
      widths=[];

  $.each(t, function(i, v){
      var el = $('<span />', {text:v}).appendTo($h1);
      widths.push(el.width());
      el.remove();
  });

  $sp.css({opacity:0});

  (function loop(){
     i = ++i%t.length;    
     $sp.text(t[i]).animate({width:widths[i]}, 1000, function(){
       $(this).animate({opacity:1},1000).delay(3000).animate({opacity: 0}, 1000, loop); 
      });     
  })(); 

});

This code group

  $.each(t, function(i, v){
      var el = $('<span />', {text:v}).appendTo($h1);
      widths.push(el.width());
      el.remove();
  });

stores inside our widths[] array all the needed widths we need.
We'll treat the widths[] iterations same as you already do for t[]

than we create a recursive self-invoking function (no need for setInterval !) where we'll test for i to become 0 using a simple Modulo Operator (Reminder) %

i = ++i%t.length;

The function "looping" is simply achieved recalling that function inside the last chained animation callback.

like image 38
Roko C. Buljan Avatar answered Sep 22 '22 06:09

Roko C. Buljan