Grid Animation - Clickbank Style Coundup

From this post, I will start to study various grid animation effects with javascript. The 1st tutorial I'd like to introduce here is a Clickbank style countup. Clickbank uses an image, but here I don't use any image.

How does it work?

The 1st digit is the most complicated. The numbers move up in the order of 8 5 2 9 6 3 0 7 4 1. I gives the interval of the moving 700 milliseconds. After the number is changed, delay another 300 milliseconds. The 2nd digit counts up one digit every 1000 milliseconds. When it counts up to 10, the 3rd digit moves up one digit. And so on ...

HTML

The HTML code looks like duplicated. If you like to simplify the code, you could use DOM to create the code. The following HTML code creates a number of 5 digits.

<ul id="wrp">
    
    <li class="wp">
       <ul id="c5">
            <li>0</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li> 6</li><li>7</li> <li>8</li><li>9</li>
            <li>0</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li> 6</li><li>7</li> <li>8</li><li>9</li>
       </ul>
    </li>
    
    ... c4 ... c3 ... c2 ...


    <li class="wp">
        <ul id="c1">
            <li>0</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li> 6</li><li>7</li> <li>8</li><li>9</li>
            <li>0</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li> 6</li><li>7</li> <li>8</li><li>9</li>
        </ul>
    </li>    
    
  </ul>

CSS

Note the <li> elements with the class name wp are floated while the inside <li> elements are not floated.

li{list-style-type: none;}
.wp{
    position:relative;
    width:20px;
    height:20px;
    float:left;
    background-color:#000;
    margin-right:10px;
    overflow:hidden;
    color:#fff;
}
.wp ul{
    position:absolute;
    width:20px;
    height:20px;
    margin:0;
    padding:0;
}
.wp li {
    height:20px;
    width:16px;
    padding: 0 5px;
}

Javascript

In order to make the countup, I modified the script for div move for static class. All setTimeOut ids are cleared after the completeion of the move. This is not necessary for simple setTimeout actions. But it's very necessary for more complicated actions.

countup object

The construction function receives 2 parameters - one is the id of the wrapper. Another is the initial number - here a 5-digit number. Then it initializes the position of each digit <ul> elements

function countup(id,num){

this.ul = document.getElementById(id);
this.uls = this.ul.getElementsByTagName("UL");
this.uls_len = this.uls.length;
this.lis = this.uls[0].getElementsByTagName("LI");
this.height = 10*this.lis[0].offsetHeight;

var nm = num.split("");
this.k1 = nm[4];
this.k2 = nm[3];
this.k3 = nm[2];
this.k4 = nm[1];
this.k5 = nm[0];

this.uls[this.uls_len-1].style.top = -this.height - this.k1*this.lis[0].offsetHeight +"px";
this.uls[this.uls_len-2].style.top = -this.height - this.k2*this.lis[0].offsetHeight+"px";
this.uls[this.uls_len-3].style.top = -this.height - this.k3*this.lis[0].offsetHeight+"px";
this.uls[this.uls_len-4].style.top = -this.height - this.k4*this.lis[0].offsetHeight+"px";
this.uls[this.uls_len-5].style.top = -this.height - this.k5*this.lis[0].offsetHeight+"px";

this.t1 =0;
this.t2 = 0;
this.delay =300;

}

Then add additional methods for the digits change in prototype property of the constructor.

The 1st digit move

As said above, the 1st digit moves in 700 milliseconds to change the number and then delay another 300 milliseconds. This process is reiterated by setTimeout every 1000 milliseconds.

...
move1: function(){
   
    clearTimeout(_this.t1);
    var top = parseInt(_this.uls[_this.uls_len-1].style.top) - _this.lis[0].offsetHeight*7;
  
     $(_this.uls[_this.uls_len-1]).move({delay:_this.delay,to:{left:0,top:top}} ,function(){
         var t = parseInt(this.style.top);
          if ( t < - _this.height)     
          this.style.top = t + _this.height  +"px";
    
    }); 
    
    _this.t1 = setTimeout(_this.move1,1000); 
      
},...

I first used setInterval to reiterate, but setInterval is not guaranteed. It went to mess in FF, Chrome, Safari in a moment.

The 2nd digit

The 2nd digit moves in 200 milliseconds to change the number and then delay another 800 milliseconds. This cycle is also reiterated by setTimeout every 1000 milliseconds. When the number reaches 10, the 3rd digit moves one digit.

...
move2: function(){  
     
      clearTimeout(_this.t2);
      var tp = parseInt(_this.uls[_this.uls_len-2].style.top);
      var top = tp - _this.lis[0].offsetHeight;
     
      if ( tp == - 2*_this.height+_this.lis[0].offsetHeight)  _this.move3();     
     
      $(_this.uls[_this.uls_len-2]).move({delay:200,to:{left:0,top:top}},function(){
        
        if ( tp == - 2*_this.height+_this.lis[0].offsetHeight) {
            this.style.top = parseInt(this.style.top) + _this.lis[0].offsetHeight * 10  +"px";          
         }
      
      });
         
     _this.t2 = setTimeout(_this.move2,1000); 
}, ...

The rest of digits act similar to the 2nd digit. Maybe they can be simplied into one function with the 2nd one.

Conclusion

From this example, we have learned,

Demo

Clickbank style countup.

I tested it in IE 6, 7, FF 3.5, Chrome 6.0.472.63, Safari 4.05. In IE, sometimes the 1st digit drifts a little after a long time of running.

Last updated on Oct.10, 2010
www.pagecolumn.com