Jump to content
Search Community

GSAP Stagger Reveal on load followed by scroll revealing

ekfuhrmann test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

POST RESOLUTION EDIT: See Zach's comment below for a more modern approach to this problem.

 

----

 

Hi there.

 

I have a responsive site where I want the content to stagger reveal as the user scrolls. The issue I'm having is that on load, the first few items (depending on screen height) are above the trigger and therefore just animate in together as opposed to staggered. Is there a way to have it so that the content that loads immediately staggers, and then the remaining elements animate like normal on scroll via ScrollMagic?

 

ScrollReveal has a pretty good example of what I'm going for, with content staggering in on load, followed by then animating the lower elements in on scroll.

 

Thanks!

See the Pen YeXgXz?editors=1010 by ekfuhrmann (@ekfuhrmann) on CodePen

Link to comment
Share on other sites

Yes but you will need to calculate who's visible and who isn't on load.

 

Either by working out the size of the visible area and visible elements on the screen or by using the something, something API ,that I know exists but cannot for the life of me remember the name, I think @Jonathan knows it. @OSUblake is bound to know as well.

 

Then, after you have worked that out, you can add the rest of the elements to your scrolling events. It should do the trick.

 

Apologies for not making a proof of concept but I'm short on time now.

  • Like 2
Link to comment
Share on other sites

Hello @ekfuhrmann and welcome to the GreenSock forum!

 

I believe @Dipscom was referring to the Intersection Observer API to detect when something is inside the viewport.

 

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

 

Quote

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.

 

Happy Tweening :)

 

 

  • Like 5
Link to comment
Share on other sites

The Intersection Observer API looks really interesting. I'm messing around with it a bit to try and understand it better, but I'm also unsure of how I'd then go about combining it in my timeline. Honestly, it seems more like a replacement for ScrollMagic than anything else, so I'm not entirely sure how it would help in my instance of staggering the first few elements, and then revealing the rest on scroll.

 

I have no issues with the scroll revealing, it's the staggering of the first few that gives me problems - even when I break them out to a new stagger timeline.

 

If this can be done better with the Intersection Observer API, I'm willing to drop ScrollMagic, but I struggled to find working examples of implementing it with GSAP that I could understand.

Link to comment
Share on other sites

  • 3 months later...

Alright, it's been awhile since I last posted in this thread, but I'm back now with an updated Codepen that makes use of the suggested Intersection Observer API, which truly is awesome. @PointC, thank you so much for the article as I found it really helpful for all sorts of other purposes beyond GSAP.

 

In the following Codepen you'll see that initially the animation works as intended, but I'm using an incremented Timeline `delay` to create the stagger effect of elements that are in view. As you can maybe expect, the issue is that the incrementing does not reset upon a new row of elements coming into the view, lending way for some seriously long delays between elements if you scroll slowly.

 

I feel like I'm almost there, but have been struggling to get over this hurdle. Let me know what you think!

 

See the Pen xYwgGm by ekfuhrmann (@ekfuhrmann) on CodePen

 

  • Like 1
Link to comment
Share on other sites

Hello, hello!

 

Happy to hear you're getting somewhere.

 

Nice demo, by the way. And super helpful.

 

Once again, I am dabbing in without full knowledge of what's involved but, such is life. No dare, no learn.

 

See that you are creating a brand new timeline on every iteration of that forEach loop you have. I don't think that's needed. You can just have the timeline itself initialized outside that loop and only add a new tween inside it once it is visible. And as GSAP just plays the timeline automatically, every time a new tween is added into the timeline, it will just play that tween.

 

Your new code would be smalled as well because you don't need to be incrementing anything and won't be initializing new timelines unnecessarily.

 

// no longer needed
// let incrementalDelay = 0.5;
const tl = new TimelineMax()

let observer = new IntersectionObserver(function(entries, self) {

  entries.forEach(entry => {
    if (entry.isIntersecting) {
      tl.to(entry.target, 0.5, { autoAlpha: 1 }, "-=0.2"); // make use of the relative position parameter to create the overlap
      self.unobserve(entry.target);
    }
  });
}, config);

 

And I think you did a great job here. :)

 

  • Like 3
Link to comment
Share on other sites

I actually initially tried that approach but wasn't making proper use of the relative position parameter. This is working significantly better than before, but still a bit strange when new rows come into view. It seems like the first or second box of new rows is ignoring the delay parameter or something along those lines, resulting in some speed up for the boxes staggering in.

 

Forked a new pen, any thoughts?

 

 

See the Pen OZzZNq?editors=1011 by ekfuhrmann (@ekfuhrmann) on CodePen

 

 

EDIT: Upon playing around with it further, I think I know the root of the problem but am not sure how to work around it. Since we're staggering each animation by `-=0.3`, this only works if it has something to stagger against. In a new row, it is starting at 0s, and then the subsequent tween is stating after 0.2s of the first since the animation is 0.5s long. This is causing it to appear to load quicker than intended. Is there a way to identify if the TL is starting up again and then changing the stagger for that first iteration of the new row?

Edited by ekfuhrmann
Added more information
Link to comment
Share on other sites

Indeed, there is!

 

It think you are correct in your investigations as it makes sense, behaviour-wise.

 

To prevent that all you would need to do is check if the timeline is active (the playhead is moving) with the aptly named isActive() method.

 

Then it is just a matter of amending the overlap by the desired amount:

 

let observer = new IntersectionObserver(function(entries, self) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      let overlap = '-=0.3';
      
      if(tl.isActive() === false) {
        overlap = '+=0';
      }
      
      tl.to(entry.target, 0.5, { autoAlpha: 1 }, overlap);
      self.unobserve(entry.target);
    }
  });
}, config);

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

  • 2 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...