Jump to content
Search Community

smoothScroll() for ScrollTrigger - responsive on resize

mrcrunchy test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hello everyone!

So I started working on a project where I'm using gsap for all animations. I have even integrated the native smooth scroll (the demo from ScrollTrigger.scrollerProxy() documentation) but I have run into a problem. When the browser is resized the 'viewport' of the scroller shrinks.

 

1. When the website is loaded the smooth scroll works as expected, the scrollbar start at the top of the document (start-picture.png)

2. I scroll a bit down on the document and then I minimize/resize it.

3. What happens is: the scrollbar can not move to the top of the actual document. The document gets cut out as much as I have scrolled (picture-after-resize.png).

 

What I basically want is some kind of scroller update on resize so the content does not get cut out at the top.

I hope someone can help me. Have a nice day and thank you in advance :)

start-picture.png

 

picture-after-resize.png

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

Link to comment
Share on other sites

Hello I'm really sorry to bother again. So the horizontal resize works perfectly fine but when I tried to resize my project on vertical axis, I have noticed that the body height is incorrect. 

 

In helper function:

 

I do not know why but on resize the body height is set to previous height of the content.clientHeight and not the new one. Looks like the onresize is still reading the previous value instead of the new one.

function onResize() {
      height = content.clientHeight;
      document.body.style.height = height + "px";
    }

I'm using React if that may cause the problems. My boiler css for smooth-scroll looks like this:

P.S.:  I did not set the height of content to a fixed value because it changes on screen size.

#viewport {
    overflowhidden;
    positionfixed;
    height100%;
    width100%;
    top0;
    left0;
    right0;
    bottom0;
  }
 
  #content {
    overflowvisible;
    width100%;
  }

Thank you in advance, have a nice day.

Link to comment
Share on other sites

7 hours ago, mrcrunchy said:

I'm using React if that may cause the problems.

Yep, that's my guess. I'm not a React guy, but maybe @Rodrigo or @OSUblake can offer some insight. I know that React often takes an extra tick to actually render DOM changes, so perhaps there's a lifecycle method you'd need to tap into.

 

I updated the demo to replace one line in case it helps (because refresh is a bit delayed from the resize events in order to optimize performance):

// old
window.addEventListener("resize", onResize);

// new
ScrollTrigger.addEventListener("refreshInit", onResize);

Does that help at all? 

Link to comment
Share on other sites

12 minutes ago, GreenSock said:

I know that React often takes an extra tick to actually render DOM changes, so perhaps there's a lifecycle method you'd need to tap into.

 

Hard to say without seeing it in context, but I don't see why it would be a React issue if you have reference to the element.

Link to comment
Share on other sites

8 minutes ago, OSUblake said:

I don't see why it would be a React issue if you have reference to the element.

I just meant that React sometimes takes an extra tick to actually render changes - my understanding was that he's saying the "clientHeight" value was stale. So, for example, if the "resize" window event fired and the script tried to read the element's clientHeight...but React hasn't kicked in and rendered its changes yet (until the next tick), that'd explain why it'd be stale. But I might be totally off. I'm only guessing. 

 

Like @OSUblake said, the best way to troubleshoot this is with a minimal demo. :)

Link to comment
Share on other sites

7 minutes ago, GreenSock said:

I just meant that React sometimes takes an extra tick to actually render changes

 

There's just a delay for stuff that React renders, like say the text inside an element. resize events happen outside of React, so there shouldn't be any problem.

  • Like 1
Link to comment
Share on other sites

Okay so I have been debugging and after quite some time I noticed that the smooth-scroll is actually working as expected. It seems like the problem is actually in a scrollTrigger that is pinning an element. 

When I commented out the code below it worked just fine. These two triggers are set when the component mounts but the pin somehow breaks the whole document height on resize. Any idea how to fix that? 

Thanks again for all the help you are providing.

gsap.to(layerRef, {
    scrollTrigger: {
      invalidateOnRefreshtrue,
      id"landing-pin",
      triggerlayerRef,
      start"top top",
      pintrue,
      pinSpacingfalse,
      scroller"#content",
      id"pin-landing-pic",
      markerstrue,
    },
  });
 
  gsap.to(imageRef, {
    scale1.2,
    scrollTrigger: {
      invalidateOnRefreshtrue,
      id"scale-in-landing",
      triggerlayerRef,
      start"top top",
      scroller"#content",
      pintrue,
      pinSpacingfalse,
      scrubtrue,
      id"pin-landing-scale",
      markerstrue,
    },
  });
Link to comment
Share on other sites

8 hours ago, mrcrunchy said:

When I commented out the code below it worked just fine. These two triggers are set when the component mounts but the pin somehow breaks the whole document height on resize. Any idea how to fix that? 

There's really no way for us to know by just looking at that excerpt - we'd need to see a minimal demo to view things in context. If you need more help, please provide a minimal demo

 

I wonder if part of your problem is that you've got trigger set to layerRef - is that a useRef() object? Should it maybe be layerRef.current? 

Link to comment
Share on other sites

Beacuse I couldnt recreate this problem in CodePen, I have created a minimal project and put it on github. The project I'm working on is way 2 big so that is why I created something very minimal. The problem might not be the same but it is still doing some 'weird' stuff after clicking the maximize/minimize icon. It happens to the scrolltrigger that is using pinning.

I hope this helps in resolving this issue.

Minimal project:

https://github.com/sark789/PinAndSmoothScrollTest

Link to comment
Share on other sites

Okay so what actually happened was: some element's height was not updated on resize so the pin triggers were way off and that messed the smooth-scroll viewport. I solved it by killing triggers and recalculating the elements on window resize height like this:

var trig1 = ScrollTrigger.getById("pin-landing-pic");
  if (trig1) {
    trig1.kill();
  }
  var trig2 = ScrollTrigger.getById("pin-landing-scale");
  if (trig2) {
    trig2.kill();
  }
  var test = gsap.getById("landing-pic-height");
  if (test) {
    test.kill();
  }
  gsap.set(layerRef, { heightheight });
  gsap.to(layerRef, {
    id"landing-pic-height",
    scrollTrigger: {
      triggerlayerRef,
      start"top top",
      pintrue,
      pinSpacingfalse,
      scroller"#content",
      id"pin-landing-pic",
      markerstrue,
    },
  });
 
  gsap.fromTo(
    imageRef,
    { scale1 },
    {
      scale1.2,
      scrollTrigger: {
        invalidateOnRefreshtrue,
        triggerlayerRef,
        start"top top",
        scroller"#content",
        pintrue,
        pinSpacingfalse,
        scrubtrue,
        id"pin-landing-scale",
        markerstrue,
      },
    }
  );

 So one last question. Is there a better way to do this? Or is killing the triggers on resize and recreating them good practice? 

Thank you so much for your help 

Link to comment
Share on other sites

It looks like you didn't use the updated smoothScroll() function, or you edited it to remove the invalidateOnRefresh: true value as well as a couple of other things I believe. Once I swapped in the latest version into your demo, it seemed to work flawlessly. Or am I missing something? 

 

I can't think of a reason you'd need to kill() all the ScrollTriggers every time you resize. 

  • Like 1
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...