Jump to content
Search Community

ScrollTrigger animations triggered in fixed sections with fade in and out

SpaceHorse test
Moderator Tag

Go to solution Solved by mvaneijgen,

Recommended Posts

Hiya,

 

I can't seem to wrap my head around this so any help would be much appreciated!

 

I want to fade to each section like in this forked example but also have scrolling animations in that section. I was hardcoding the start and end values with a new Timeline and ScrollTrigger but that hardly seemed like an elegant solution and could cause trouble when browser resizes. I think the problem is that since all the sections are fixed, ScrollTrigger thinks that the red section is in view even though it is invisible and thus starts the animation higher than I would want.

See the Pen bGjmyvL by bsadoway (@bsadoway) on CodePen

Link to comment
Share on other sites

  • Solution

Hi @SpaceHorse welcome to the forum!

 

Mix and matching ScrollTriggers is not something that is really possible, what you could do in this scenario is update the timeline that is already being played and add your new tweens to that timeline. The only issue is that this timeline is not being scrubbed and will just play the animation.

 

See the Pen qByQqJd?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

This particular demo is for this exact effect nothing more and nothing less, if you thus want to have different animations per section you'll be better off starting from scratch instead of modifying this demo. 

 

Personally what I would do is removing ScrollTrigger! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in.  I would thus start by writing the animations on a timeline, here is some pseudo code.

 

tl.to(blue, { animate out})

tl.to(red, { animate in})

tl.to(red hello text, { spin around })

tl.to(red, { animate out  })

tl.to(orange, { animate in  })

... ect 

 

Then when you're happy with the animation, add ScrollTrigger to it. Bellow is a great example video, but the only thing is here it is one tween with a ScrollTrigger and I would suggest for you to create a timeline with the ScrollTrigger on that timeline. Hope it helps and happy tweening! 

 

 

Edit: couldn't help my self. Here is a basic setup on how I would go about it. 

 

See the Pen bGjQgWQ?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

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

Animation code can get lengthy, but GSAP exists to make sure it isn't unwieldy.

It's hard to advise without understanding your use case - you can avoid duplicating code by looping around sections, if that suits your animations. But if each section is different, there's nothing wrong with creating a timeline per section with 20+ tweens on

  • Like 4
Link to comment
Share on other sites

  • 1 year later...

Can we have it section by section scroll with fade effect on a single swipe/mouse wheel? Currently when I try to swipe it, it doesn't change the slide immediately, please see the attached.



image.thumb.png.ccbef2f7293cd274deacd421c148d177.png

Thanks,
Farhan

Link to comment
Share on other sites

Hi @Rodrigo

Thank you for providing me with the example. I've already seen this. However, what I'm looking for is a scroll effect that triggers when I reach a specific section containing multiple inner sections. The entire section should fill the screen, and then each inner section should scroll individually with a single swipe or mouse wheel movement. Once I reach the last inner section, it should start normally scrolling the rest of the next sections again. I hope you get my point.

Thank you

Link to comment
Share on other sites

Hi @Rodrigo

Thanks so much! this is very close. One thing I'm noticing is that I've to scroll multiple times to change the slides between the sections. For example when the swiper section starts I've to scroll 3 or 4 times to go to the next section. Could you please let me know what needs to be done here?

Thank you

Link to comment
Share on other sites

23 minutes ago, xtinepak said:

One thing I'm noticing is that I've to scroll multiple times to change the slides between the sections. For example when the swiper section starts I've to scroll 3 or 4 times to go to the next section. Could you please let me know what needs to be done here?

It takes only one wheel/touch event, but the previous animation  has to be completed first and we want to wait for some specific situations:

let allowScroll = true; // sometimes we want to ignore scroll-related stuff, like when an Observer-based section is transitioning.
let scrollTimeout = gsap.delayedCall(1, () => allowScroll = true).pause(); // controls how long we should wait after an Observer-based animation is initiated before we allow another scroll-related action

 

3 minutes ago, xtinepak said:

if we could add fade in/out effect for the swiper section instead of scroll that would be excellent?

Sure thing, just tinker with the logic in the gotoPanel method, that's where everything happens in terms of animations:

function gotoPanel(index, isScrollingDown) {
  // return to normal scroll if we're at the end or back up to the start
  if ((index === swipePanels.length && isScrollingDown) || (index === -1 && !isScrollingDown)) {
    intentObserver.disable(); // resume native scroll
    return;
  }
  allowScroll = false;
  scrollTimeout.restart(true);

  let target = isScrollingDown ? swipePanels[currentIndex] : swipePanels[index];
  gsap.to(target, {
    yPercent: isScrollingDown ? -100 : 0,
    duration: 0.75
  });

  currentIndex = index;
}

You can switch yPercent for opacity/autoAlpha without any issues.

 

Hopefully this clear things up.

Happy Tweening!

Link to comment
Share on other sites

  • 2 weeks later...

Hi @Rodrigo

I'm facing an issue where I can't hover/click on the next elements due to z-index as the previous elements comes on the top of the other elements, please see below:

image.thumb.png.e1ecd5d250ddc7a8a308d98fb4aa5a63.png

image.png.26c724c1ba11f988b656eab2811a2dff.png

Here's my updated code:

 

  document.addEventListener('DOMContentLoaded', function () {


    let allowScroll = true; // sometimes we want to ignore scroll-related stuff, like when an Observer-based section is transitioning.
    let scrollTimeout = gsap.delayedCall(0.8, () => allowScroll = true).pause(); // controls how long we should wait after an Observer-based animation is initiated before we allow another scroll-related action
    let currentIndex = 0;
    let swipePanels = gsap.utils.toArray(".swipe-section .panel");
    
    // set z-index levels for the swipe panels
    gsap.set(swipePanels, { zIndex: i => swipePanels.length - i})
    
    // create an observer and disable it to start
    let intentObserver = ScrollTrigger.observe({
      type: "wheel,touch",
      onUp: () => allowScroll && gotoPanel(currentIndex - 1, false),
      onDown: () => allowScroll && gotoPanel(currentIndex + 1, true),
      tolerance: 10,
      preventDefault: true,
      onEnable(self) {
        allowScroll = false;
        scrollTimeout.restart(true);
        // when enabling, we should save the scroll position and freeze it. This fixes momentum-scroll on Macs, for example.
        let savedScroll = self.scrollY();
        self._restoreScroll = () => self.scrollY(savedScroll); // if the native scroll repositions, force it back to where it should be
        document.addEventListener("scroll", self._restoreScroll, {passive: false});
      },
      onDisable: self => document.removeEventListener("scroll", self._restoreScroll)
    });
    intentObserver.disable();
    
    // handle the panel swipe animations
    function gotoPanel(index, isScrollingDown) {
      // return to normal scroll if we're at the end or back up to the start
      if ((index === swipePanels.length && isScrollingDown) || (index === -1 && !isScrollingDown)) {
        intentObserver.disable(); // resume native scroll
        return;
      }
      allowScroll = false;
      scrollTimeout.restart(true);
    
      let currentPanel = swipePanels[currentIndex];
      let targetPanel = swipePanels[index];
    
      gsap.set(currentPanel, { opacity: 1 }); // Reset opacity of current panel
      gsap.set(targetPanel, { opacity: 0 }); // Set opacity of target panel to 0, so it fades in
    
      gsap.to(currentPanel, { opacity: 0, duration: 0.75 });
      gsap.to(targetPanel, { opacity: 1, duration: 0.75 });
      
      currentIndex = index;
    }
    
    ScrollTrigger.create({
      trigger: ".swipe-section",
      pin: true,
      start: "top top",
      end: "+=100", // just needs to be enough to not risk vibration where a user's fast-scroll shoots way past the end
      onEnter: (self) => {
        if (intentObserver.isEnabled) { return } // in case the native scroll jumped past the end and then we force it back to where it should be.
        self.scroll(self.start + 1); // jump to just one pixel past the start of this section so we can hold there.
        intentObserver.enable(); // STOP native scrolling
      },
      onEnterBack: (self) => {
        if (intentObserver.isEnabled) { return } // in case the native scroll jumped backward past the start and then we force it back to where it should be.
        self.scroll(self.end - 1); // jump to one pixel before the end of this section so we can hold there.
        intentObserver.enable(); // STOP native scrolling
      }
    });
  });


Please advise.

Thanks so much

image.png

Link to comment
Share on other sites

Without a minimal demo, it's very difficult to troubleshoot; the issue could be caused by CSS, markup, a third party library, a 3rd party script, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependencies as possible. Start minimal and then incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen

that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

 

Using a framework/library like React, Vue, Next, etc.? 

CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: 

 

Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Link to comment
Share on other sites

Hi @Rodrigo

Please review the codepen below:

See the Pen pomowor by tyckxpby-the-selector (@tyckxpby-the-selector) on CodePen



Here's I've added the following code:

image.png.138676e66b2aa61d0e5cfee9a385148e.png
So, when you hover the first section it's working fine as you can see below:

image.thumb.png.67d3a7298ba226a7557b3fc641a13f8f.png

But when I hover the next sections (SWIPE SECTION 2 and SWIPE SECTION 3), it doesn't work due to z-index. Could you please take a look?

Thanks

Link to comment
Share on other sites

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...