Jump to content
Search Community

Changing Scrolltrigger value on resize

mrcrunchy test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

Hello,

I'm having some problems with my scrolltrigger on screen resize. The 'end' value is not updating when I resize my screen. 

So I'm setting my timeline and trigger in react like this: 

 useEffect(() => {
      FooterFadeIn({
        itemRef: itemRef.current,
        containerRef: outterContainerRef.current,
      });
  }, []);

 

and the animation itself:

export const FooterFadeIn = ({ itemRefcontainerRef }) => {
 
  var tl = gsap.timeline({
    scrollTrigger: {
      scroller"#content",
      triggeritemRef,
      start: `top+=${containerRef.offsetHeight} bottom`,
      scrubtrue,
      end: `top+=${2 * containerRef.offsetHeight} bottom`,
      invalidateOnRefreshtrue,
      id"footer-fade-in",
      markerstrue,
    },
  });
 
  tl.fromTo(
    itemRef,
    {
      y: -containerRef.offsetHeight,
    },
    {
      y0,
    }
  );
};

 

I have tried setting the end with a function and some other things but nothing seems to work.

What did work is creating a resize listener and killing the scrolltrigger and remaking it but that is probably not the correct way to do it.

Hope I can get some insights because I can't get past this. Thanks :)

Link to comment
Share on other sites

Have you tried this?:

start: () => `top+=${containerRef.offsetHeight} bottom`,
end: () => `+=${containerRef.offsetHeight}`,

If you're still having trouble, it'd significantly improve your chances of getting a solid answer if you can provide a minimal demo. :) 

 

Oh, and I imagine you'd want your tween's "y" value to be function-based too so that it changes when you resize:

y: () => -containerRef.offsetHeight,

 

Happy tweening!

Link to comment
Share on other sites

Hello again.

So the problem still remains. Because I couldn't recreate it on CodePen I did it in VSCode and posted it on github. It is a minimal project with only one component. 

So in this project the start and end of scrolltrigger is referencing to so called 'outterContainerRef'. Its height is set on auto so when I click on minimize/maximize icon it keeps the old scroller start and end. This happens most of the time but not always (feels like the scrolltrigger reads the elements height quicker than it actually changes so it still has the height before the resize). There is no problem when the container has fixed height value, but that is not an option in this case because height is changing depending on the inner content.

Link to minimal project: 

https://github.com/sark789/GSAPTestProject

 

Thank you for your time!

Link to comment
Share on other sites

27 minutes ago, mrcrunchy said:

Because I couldn't recreate it on CodePen I did it in VSCode and posted it on github.

 

You can put it on codesandbox.

 

28 minutes ago, mrcrunchy said:

This happens most of the time but not always (feels like the scrolltrigger reads the elements height quicker than it actually changes so it still has the height before the resize).

 

It looks like you're debouncing the height change, so it's not going to be in sync with ScrollTrigger's refresh.

 

Also, this is a faulty assumption. My computer would be considered a touch device because I have a touch screen, even though I'm using my mouse. And browser vendors removed "ontouchstart" from the window object because of assumptions like this.
 

  
function isTouchDevice() {
  return (
    "ontouchstart" in window ||
    navigator.maxTouchPoints > 0 ||
    navigator.msMaxTouchPoints > 0
  );
}

 

 

Link to comment
Share on other sites

27 minutes ago, OSUblake said:

You can put it on codesandbox.

 

Sorry about that. Here is the link:

https://codesandbox.io/s/github/sark789/GSAPTestProject

 

 

 

36 minutes ago, OSUblake said:

It looks like you're debouncing the height change, so it's not going to be in sync with ScrollTrigger's refresh.

 

I'm only using debounce to update body height because the demo code for smooth-scroll on resize is having the exact same problem as this scrolltrigger. This seems to happen 'too early' aswell. 

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

I also changed refreshPriority of smooth-scroll to -1 because if its set to default it messes with other scroll-triggers aswell.

I bet there is something I'm missing because every scrolltrigger is having the same problems and I can't find the solution.

 

 

 

35 minutes ago, OSUblake said:

Also, this is a faulty assumption. My computer would be considered a touch device because I have a touch screen, even though I'm using my mouse. And browser vendors removed "ontouchstart" from the window object because of assumptions like this.

 

I have this method to check is device can scroll with touch because if that is so then I'm disabling the smooth-scroll and some of the animations. Thanks for letting me know that it is wrong so I will try and find a better solution.

 

Link to comment
Share on other sites

  • Solution

Have tried using refresh after setting the height?

https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.refresh()

 

6 minutes ago, mrcrunchy said:

I have this method to check is device can scroll with touch because if that is so then I'm disabling the smooth-scroll and some of the animations. Thanks for letting me know that it is wrong so I will try and find a better solution.

 

There's not a lot of good solutions. The best I've come up with is to also consider the screen size, or to initialize all the fancy animations after the first mousemove or wheel event.

 

  • Like 1
Link to comment
Share on other sites

Okay so what I did is:

in App.js where I have a debounced listener I changed the code from:

 const onResizeHandler = () => {
    var height = document.getElementById("content").offsetHeight;
    document.body.style.height = height + "px";
  };

to:

const onResizeHandler = () => {
    var height = document.getElementById("content").offsetHeight;
    document.body.style.height = height + "px";
 
    ScrollTrigger.refresh(true);
  };

And it works now :) It is still kind of weird that I have to wait few 100ms to recalculate the document.body.height to fix the smooth-scroll issue but whatever works I guess lol.

Was that the solution you suggested?

 

 

49 minutes ago, OSUblake said:

There's not a lot of good solutions. The best I've come up with is to also consider the screen size, or to initialize all the fancy animations after the first mousemove or wheel event.

About this 'touch device'. I noticed that smooth scroll does not work good on touch devices (atleast on my iphone) so that is why I disable it if the device has touch scroll capability.

 

Link to comment
Share on other sites

35 minutes ago, mrcrunchy said:

Was that the solution you suggested?

 

Yep.

 

36 minutes ago, mrcrunchy said:

About this 'touch device'. I noticed that smooth scroll does not work good on touch devices (atleast on my iphone) so that is why I disable it if the device has touch scroll capability.

 

That's why I said it might help to check for the size of the screen, or maybe something like this.

https://github.com/kaimallea/isMobile

 

I'm pretty sure that a laptop that has a touch screen shouldn't have any issues. 

 

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, mrcrunchy said:

And it works now :) It is still kind of weird that I have to wait few 100ms to recalculate the document.body.height to fix the smooth-scroll issue but whatever works I guess lol.

 

Oh, I just noticed that it says it waits 200ms.

Quote

safe: Boolean

If true, it will wait for at least one requestAnimationFrame tick, and up to roughly 200ms before initiating the refresh. This is useful because sometimes the browser doesn't actually render the DOM-related changes immediately, causing measurements to be inaccurate. For example, if you add a "click" event listener to an element that expands other content on the page and you call ScrollTrigger.refresh() in that callback, the changes may not have been fully rendered by that point, so it's the perfect place to enable safe.

 

  • Like 2
Link to comment
Share on other sites

Thank you @OSUblake for your help :)

 

P.S.: I have change the isTouchDevice function to:

navigator.maxTouchPoints > 0 ||
      navigator.msMaxTouchPoints > 0) &&
    window.innerWidth < 1200

That should do it right? Or should I use window.outerWidth < 1200?

 

Do you maybe know if your computer is considered hoverable?

if (window.matchMedia( "(hover: none)" ).matches) {
   // hover unavailable
}
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...