probablybest
probablybest

Reputation: 1445

Find first class then gradually add class to all divs with same name

I have a selection of dots which I'm making from a table like the below:

<div class="steps-wrapper">
    <table class="steps">
        <tbody>
            <tr>

                <td></td>
                <td></td>
                <td class="active"></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td class="active"></td>
            </tr>
            <tr>
                <td class="active"></td>
                <td class="active"></td>
                <td class="active"></td>
            </tr>
            <tr>
                <td class="active"></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td class="active"></td>
                <td></td>
                <td></td>
            </tr>
        </tbody>
    </table>
</div>

Here is a fiddle to view aswell.

I would like it so that when the td's are visible they gradually load in. So I would find the first td with the class active and fade it in. It would then find the next td with the class active and fade that in 0.2s after the last one and so on.

Looking at the jsFiddle the first dot to load in would be top right and then it would gradually load in from the right, across and down to bottom left. However the shape of the dots will change so sometimes it could load from top left down to bottom right.

This is my jQuery so far:

$(document).ready(function () {
$(function($, win) {
  $.fn.inViewport = function(cb) {
     return this.each(function(i,el){
       function visPx(){
         var H = $(this).height(),
             r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
         return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));  
       } visPx();
       $(win).on("resize scroll", visPx);
     });
  };
}(jQuery, window));

$(".steps-wrapper").inViewport(function(px){
    if(px) $('td.active').addClass("o-fade-in");
});

});

I'm not sure how to make each individual dot load in. Im currently loading in all the td's at the same time when visible.


Update: The animation now works perfectly. However if one .steps-wrapper is activated it then activates all on the page. How can I make it so that other dots on the page dont animate until they are seen in the viewport just like the first one?

Here is a new fiddle showing the issue.

Upvotes: 1

Views: 152

Answers (1)

DaniP
DaniP

Reputation: 38252

Well I have made a few changes to your code in order to work the way you want:

1. Make your table dots rtl that way when we apply the class will get from right to left:

.steps {
  direction:rtl;
}

Also check the markup for the table on the fiddle

2. Adding the fade effect with transition:

.steps td {
  width: 25px;
  height: 25px;
  opacity: 0;
  visibility: hidden;
  /*Add this*/
  transition:2s linear;
}

3. Add the class one at time:

$(".steps-wrapper").inViewport(function(px){
    if(px) fadeDots()
});

function fadeDots() {
  var i = 0;
  setInterval(function(){
    $('td.active').eq(i).addClass('o-fade-in');
    i++
  },100)
}

Fiddle Demo


Edit::

After testing I see that the setInterval keeps running and can mess up your performance so also we can check when all dots are visible and then stop the interval:

function fadeDots() {
  var i = 0,
      l = $('td.active').length;

  var m = setInterval(function(){
      $('td.active').eq(i).addClass('o-fade-in');
      i++
      if(i == l) {
        clearInterval(m);
      }
  },100)
}

NewFiddle

Upvotes: 3

Related Questions