Jump to content
GreenSock

Ahmed Elabbasy

ScrollTrigger with smoothScroll

Recommended Posts

I'm not a React guy, but it looks to me like you've got several problems: 

  1. You didn't set the "scroller" property of your ScrollTrigger to the one that you set up for .scrollerProxy(). 
  2. Your start/end values are incoherent. You had start: "top top",  end: "bottom bottom" which means that you want it to start when the top of your element hits the top of the screen, and then end when the bottom of that same element hits the bottom of the screen. But when the top hits the top, the bottom has already gone way past the bottom. I think perhaps you meant start: "bottom bottom", end: "top top"
  3. You're using y: "25%" instead of yPercent: -25 (minor - the other way would work most of the time anyway but I figured I'd mention it as a best practice)
ScrollTrigger.create({
  id: "Scroller",
  trigger: ".hi",
  start: "bottom bottom",
  end: "top top",
  animation: test,
  scroller: ".content-scroll",
  scrub: true
});

Does that help? 

  • Like 1
Link to comment
Share on other sites

First of all, I thank you for the response


It may sound strange, but this worked for a moment and paused

I didn't make any changes until I just reloaded the page and it no longer works

 

Link to comment
Share on other sites

Look in your console - I believe there's a bug with codesandbox.io itself. There are other people who have reported something similar (unrelated to anything with GSAP/ScrollTrigger). So I'd suggest trying locally. 

Link to comment
Share on other sites

It does not run at all locally and does not contain any console messages
Everything looks fine and there is no effect from the scrolltrigger

Link to comment
Share on other sites

That sounds like it must be a React thing, where perhaps it's removing the element that ScrollTrigger is looking at and re-rendering the DOM. Again, I'm not a React guy so I'm not sure how you're expected to pass the correct "scroller" reference instead of just selector text like ".content-scroll". Perhaps @Rodrigo or @elegantseagulls has a suggestion. 

Link to comment
Share on other sites

I tried something similar before creating this topic and it didn't work so I removed it at first inside the link
 

Thank you and sorry for bothering you reading the code

Link to comment
Share on other sites

Hi,

 

To be completely honest I haven't done pretty much anything with ScrollTrigger so I'm totally out of my element here. After a quick glance at the API docs I tried this:

ScrollTrigger.create({
  id: "Scroller",
  trigger: ".hi",
  start: "bottom bottom",
  end: "top top",
  animation: test,
  // scroller: ".content-scroll",
  scroller: scrollersm.current,
  scrub: true,
  onUpdate() {
    console.log("scroll update");
  },
});

Which of course didn't worked.

 

For the React part of your code I see you're wrapping everything and you're passing the reference as a prop to the child component, that's why I tried scrollersm.current, there is no need to use a regular selector (".content-scroll") if you're passing a ref of the actual DOM element, is redundant. The onUpdate callback was never called, so there is definitely nothing happening. What really freaked me out is the fact that if you resize the browser the <p> tag actually gets transformed :huh:.

 

Have you tried something like this, but without React, just a simple vanilla JS sample using another element as proxy. I don't see that you're setting a proxy for the scroll trigger plugin. Hopefully @elegantseagulls can offer more assistance with this.

 

Happy Tweening!!!

  • Like 2
Link to comment
Share on other sites

hi rodrigo thank you for your reply

 

I tried to put everything in one file and this worked and I don't see any difference in passing Scroller as prop 

I'll try this with forwardRef and tell you but still that's weird

 

Link to comment
Share on other sites

https://codesandbox.io/s/proud-pine-y523d?file=/src/test.jsx

 

Take a look here, it works well, but this may affect the performance. This does not return a new component, but I don’t know what is the difference.

 

in the image below this hoc pattern when i pass a ref as prop 

 This passes the right dom,But this does not affect scrolltrigger

ref.png

Link to comment
Share on other sites

Hey, good to see that you got it working.

1 hour ago, Ahmed Elabbasy said:

Take a look here, it works well, but this may affect the performance.

Mhh... I don't see why performance could be an issue with this setup; Care to explain why you think it could?

 

Happy Tweening!!!

Link to comment
Share on other sites

 I will lose the ability to reuse the component because each component has to be located inside the file that passes the reference

 eventually get a loop that will repeat the same component and animation And the size of one component will get bigger

 

Link to comment
Share on other sites

For example, if I own a picture that moves with the scroll
I will not be able to place the animation inside its component, for example if I want to use the image in 4 places then I will write the same animation every time. Measure against this, each component should write its own animation inside the wrapped component

Link to comment
Share on other sites

note: if i pass a ref like this to component who need to make scrolltrigger animation

It ends up happening that this will only work when you change the browser size

<Scroller ref={scrollRef}> // this wrapper component with smooth scroll and scrollTrigger setUp
      <Header scroller={scrollRef} /> // component need to animate in scroll
        
    </Scroller>

 

Link to comment
Share on other sites

3 hours ago, Ahmed Elabbasy said:

I will lose the ability to reuse the component because each component has to be located inside the file that passes the reference

 eventually get a loop that will repeat the same component and animation And the size of one component will get bigger

Mhh... Have you measured such behaviour with the performance tool in dev-tools or the profiler in react dev-tools? It seems more annoying than anything, but keep in mind that a high order component is just a function, so everytime you invoke that function the resulting component (with it's children) is returned to the DOM and all the code inside is executed as well.

 

If I was you I'd be trying to figure how make the setup work with a simpler base without the custom scrollbar, just an event that moves the component in the Y axis and then add more features to it.

  • Like 1
Link to comment
Share on other sites

2 minutes ago, Rodrigo said:

If I was you I'd be trying to figure how make the setup work with a simpler base without the custom scrollbar, just an event that moves the component in the Y axis and then add more features to it.

I don't understand what you mean exactly here

 

2 minutes ago, Rodrigo said:

Mhh... Have you measured such behaviour with the performance tool in dev-tools or the profiler in react dev-tools? It seems more annoying than anything, but keep in mind that a high order component is just a function, so everytime you invoke that function the resulting component (with it's children) is returned to the DOM and all the code inside is executed as well.

I haven't tried the performance but that sounds expensive at first

I ended up having to use this

   bodyScrollBar.current = Scrollbar.init(ref.current, {
      damping: 0.1,
      delegateTo: document,
    });

    bodyScrollBar.current.setPosition(0, 0);
    bodyScrollBar.current.track.xAxis.element.remove();

    ScrollTrigger.scrollerProxy(ref.current, {
      scrollTop(value) {
        if (arguments.length) {
          bodyScrollBar.current.scrollTop = value;
        }
        return bodyScrollBar.current.scrollTop;
      },
    });

    bodyScrollBar.current.addListener(ScrollTrigger.update);
  });
  return (
    <div className="content-scroll" style={{ height: "100vh" }} ref={ref}>
      {props.render(bodyScrollBar, ref) // If i pass this "ref" to the component it will run when resize the browser The lane reference itself must be used }
    </div>
  );
});

It didn't even work, but it did enough, but there is a real problem. Comment on the code above

Link to comment
Share on other sites

I can't believe this only works with one component if I animate more than one component it won't work @Rodrigo

Link to comment
Share on other sites

My previous experience with this was not good but I used ScrollMagic to solve the current problem until there is another solution
Thanks for your interest, I will try this library with Scrolltrigger and let you know

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