amoeboar
amoeboar

Reputation: 355

jQuery and Greensock animations -- animate all elements on screen with classname

I'm trying to animate all elements that match the class "customers" on my page once they are scrolled into view.

My current version:

$(window).on('scroll', function() {
  if(!$('.customers').hasClass('animated')) {
    if($('.customers').isOnScreen(0.45, 0.45)) {
      TweenMax.staggerTo($('.customer'), 0.3, {bottom:"+=50px", opacity:1,  ease: Power2.easeOut}, 0.15);
      $('.customers').addClass('animated');
    }
  }
})

Works to animate the first element when it enters the screen, and unfortunately as a result also animates the others while they are offscreen. What I want to happen is that each element that matches "customers" animates when it is scrolled into view.

(note that isOnScreen is a custom function that does element detection within the window).

I've tried using jquery's each function as such:

$(window).on('scroll', function() {
    $('.customers').each(function( i ) {  
      if(!this.hasClass('animated')) {
        if(this.isOnScreen(0.45, 0.45)) {
          TweenMax.staggerTo($('.customer'), 0.3, {bottom:"+=50px", opacity:1,  ease: Power2.easeOut}, 0.15);
          this.addClass('animated');
        }
      }
})

And Ive also tried wrapping each "this" statement as a jquery element as $(this).

I'm getting unexpected behavior in that the elements conitnue to animate as I scroll, even though they should have had their "animated" class removed (I want them to animate only the first time they enter the screen).

What I'm thinking I may need to do is create an array of customers, and then perform the TweenMax to each element in the array, but I'm not sure if this will work.

Upvotes: 0

Views: 1036

Answers (1)

Tahir Ahmed
Tahir Ahmed

Reputation: 5737

All right here is what I think you needed to do.

  • There had to be a listener for the scroll event on the window object to begin with in the first place of course. Stating the obvious.
  • Then you loop through the .customers elements using an each.
  • Then you check if each of those .customers elements already have a animated class on them. If, they do, then nothing happens but if they don't, the rest follows.
  • The current .customers element is then checked if it is in a defined viewport area using the custom function .isonScreen().
  • Then TweenMax animates .customer elements found within the current .customers element that we are currently looping through. Notice the difference between .customers, the parent element, and the child .cusotmer elements. Remember, we are inside a loop, so each of the .customers element is looped through and then we further try to find .customer elements within each of them. The jQuery that helps us find inner .customer elements is: $(this).find('.customer').
  • Next up, in your CSS, opacity: 0; line was previously commented out for .customer elements. I uncommented it back on.
  • We then use .staggerFromTo method of TweenMax to define a set of initial properties to begin our tween with, and end of another set of properties, all with a little bit of stagger between the animations so they don't just come up all the same time, neither do they wait for each other to finish before the next one plays. It is an overlapping animation.
  • Another thing to note here is that we are animating y property of the elements which is a special property provided by TweenMax which is basically a short-cut to animate translateY(...) property as if you did that using CSS.
  • Finally, you apply the .animated class on the currently looped .customers element.

JavaScript:

$(window).on('scroll', function() {
    $('.customers').each(function() {
        if (!$(this).hasClass('animated')) {
            if ($(this).isOnScreen(0.45, 0.45)) {
                TweenMax.staggerFromTo($(this).find('.customer'), 0.3, {
                    y: 200,
                    opacity: 0
                }, {
                    y: 0,
                    opacity: 1,
                    ease: Power2.easeOut
                }, 0.15);
                $(this).addClass('animated');
            }
        }
    });
});

Here is the fiddle. Hope this helps.

Upvotes: 1

Related Questions