Jump to content
Search Community

Use my own scroll value with ScrollTrigger?

jesper.landberg test
Moderator Tag

Recommended Posts

3 minutes ago, ZachSaucier said:

Hey Jesper. What do you mean by "inject" your own scroll values? 

 

ScrollTriggers have a .scroll() method where you can set the scroll position of the scroller being used if that's what you're asking about.

 

Hey, basically so I can use it with my own virtual scroll, with my lerped scroll value, instead of using the default event (scroll using scrollTop?).

Link to comment
Share on other sites

1 minute ago, jesper.landberg said:

Hey, basically so I can use it with my own virtual scroll, with my lerped scroll value, instead of using the default event (scroll using scrollTop?).

How would that be helpful? Like...can you help us understand the desired outcome? If you're trying to use ScrollTrigger to control an animation according to certain start/end positions, wouldn't it be simpler to just feed your lerped value into the animation's progress()? What would you be looking for ScrollTrigger to do for you if you're already calculating scroll-related values on your own that are different than the actual scroll position of the page/scrollbar? I'm probably missing something obvious. 

  • Like 1
Link to comment
Share on other sites

2 minutes ago, GreenSock said:

How would that be helpful? Like...can you help us understand the desired outcome? If you're trying to use ScrollTrigger to control an animation according to certain start/end positions, wouldn't it be simpler to just feed your lerped value into the animation's progress()? What would you be looking for ScrollTrigger to do for you if you're already calculating scroll-related values on your own that are different than the actual scroll position of the page/scrollbar? I'm probably missing something obvious. 

 

Well I would assume ScrollTrigger uses cached boundingRects of elements, then comparing that to the scroll value (I might be totally wrong tho) ? In that case why wouldn't it be helpful to allow ppl to pass their own scroll value? 

Pseudo code:
 

ScrollTrigger.useEvents(false)

// In a raf
Scrolltrigger.update(myLerpedScrollValue)


I have my own solution where I do what u say, pass a progress value based on start/end values using my lerped scroll to the progress() method. But with this obviously goes checking if the element is in viewport, doing the calculations etc etc. And ScrollTrigger does all this plus much more than my own solution, so obviously it would be helpful? 

Link to comment
Share on other sites

How it works:

To maximize performance, ScrollTrigger does all the calculations up front to figure out the intersection points and where each start/end is. Yes, it uses getBoundingClientRect() for that...only up front (and on resize events). Then ALL it does on each scroll event is loop through the ScrollTrigger instances and compares their start/end to see if the current scroll position is inbetween any of those. If so, they update. Very fast. We don't constantly check to see if an element is in the viewport or whatever. We don't even cache the bounds. 

 

Back to your question...

If you're doing scroll-jacking, then ScrollTrigger probably isn't a great fit for you. I built ScrollTrigger to avoid scroll-jacking (for the most part at least). It is indeed wired up to directly use the scrollTop/scrollLeft (or some other properties for the window for compatibility). 

 

If you want to tap into ScrollTrigger's capabilities for mapping scroll positions, etc., you could totally do that with the rich callback system and then do whatever kind of lerping/processing to then control your animations however you please. Like...take the trigger's progress value, tweak it, and feed it into your animation.progress(). Does that help? Sorry if I'm still misunderstanding your goal/question. 

  • Like 3
Link to comment
Share on other sites

@ZachSaucier Thanks for the quick reply.
Actually I've been doing a couple of stuff synch the GSAP animations and the SmoothScroll(made by @jesper.landberg) and I'm wondering if is the new ScrollTrigger is compatible to fire/handle  the animations with the SmoothScroll
Examples:

001:

See the Pen vYLBoxK by victorwork (@victorwork) on CodePen



002:

See the Pen WNreVjM by victorwork (@victorwork) on CodePen



003:

See the Pen pogzMWO by victorwork (@victorwork) on CodePen

  • Like 3
Link to comment
Share on other sites

  • 4 weeks later...

.scrollerProxy seems to work well with smooth scrolling libraries (I've only done a couple of basic tests so far).

 

With Baptiste Briel's smooth scroll:

See the Pen 92b9b1d92053d7905fe6056654e10f96?editors=0010 by GreenSock (@GreenSock) on CodePen

 

With Locomotive Scroll:

See the Pen da1d36b83c758c3c4bf5c98c4fa70d8d?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Slightly more complicated Locomotive Scroll demo (with pinning):

See the Pen 1dc38ca14811bc76e25c4b8c686b653d by GreenSock (@GreenSock) on CodePen

  • Like 1
Link to comment
Share on other sites

Good catch, @knalle

 

It looks like LocomotiveScroll handles things completely differently on mobile devices - it doesn't do any kind of clipping and translating of the container element. Instead, it lets the mobile device's browser just do its normal scroll. That's a problem because most browsers handle the main window scrolling on a different thread, so it's literally IMPOSSIBLE to have it synchronized with JavaScript! When you swipe-scroll, the browser renders the screen on another thread and then at a totally different interval, it updates the JavaScript thread. That's why you saw jitters. 

 

It doesn't do that on nested elements that have their own scroll. It's just the main page scrolling that's the problem. 

 

The ONLY way to avoid this is to pin things using position: fixed, but keep in mind that if you set position: fixed on an element that has an ancestor with ANY transform (even translate(0, 0)), it won't work properly. It'll scroll with that element instead of remaining fixed in the viewport. Ah, the joys of scrolling technologies. 

 

I've updated the beta of ScrollTrigger so that you can set a pinType: "fixed" on the scrollerProxy(). But of course you'd only want to do that when the parent isn't getting transformed. With LocomotiveScroll, that means only on mobile. I added this conditional logic to sense it automatically in the demos above: 

// LocomotiveScroll handles things completely differently on mobile devices - it doesn't even transform the container at all! So to get the correct behavior and avoid jitters, we should pin things with position: fixed on mobile. We sense it by checking to see if there's a transform applied to the container (the LocomotiveScroll-controlled element).
pinType: document.querySelector(".smooth-scroll").style.transform ? "transform" : "fixed"

Seems to work nicely. 

 

So to be clear, this wasn't a bug or issue with ScrollTrigger - the jittering was caused by LocomotiveScroll handling things very differently on mobile AND the fact that the browser performs scrolling on the main page via a totally different thread. 

  • Like 2
Link to comment
Share on other sites

7 hours ago, GreenSock said:

It looks like LocomotiveScroll handles things completely differently on mobile devices - it doesn't do any kind of clipping and translating of the container element. Instead, it lets the mobile device's browser just do its normal scroll.

You can set smoothMobile: true in the Locomotive Scroll settings to get it to work on mobile.

Link to comment
Share on other sites

3 hours ago, ZachSaucier said:

You can set smoothMobile: true in the Locomotive Scroll settings to get it to work on mobile.

I saw that, but it didn't work properly on my devices. It acted rather strangely. The ScrollTrigger stuff worked perfectly, but the overall scrolling behavior was pretty funky and there was cropping/clipping that LocomotiveScroll applied so it was relatively unusable. Maybe I did something wrong, but I simply set smoothMobile: true. 

Link to comment
Share on other sites

I've noticed that you'd of course have to specify a custom scroller property for every scrollTrigger you create and for typical virtual scroll setups that would be the same element each time. Is there a way to override that globally? If not I think that'd be super helpful in this scenario. It can then be overridden at the lower level when needed, and you'd update the global element again if navigating via PJAX for example.

Link to comment
Share on other sites

@GreenSock hey, so i'm checking out some scrollProxy examples, and just have a question, what does the passed element do? Is there any reason we can't just send our custom scroll position in? Is the proxy element the transformed element? Like In my case where I have multiple scroll sections (pages are divided into sections and each has their own transforms, which is being transformed when the section is visible) I don't have the one transformed proxy. 

 

scrollerProxy(".proxy", { <!-- what does this do here? -->
  scrollTop: mySmoothScrollPos,
});

 

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