Jump to content
Search Community

[SOLVED] ScrollTrigger - How to set progress programmatically to an element?

Ayush Singh test
Moderator Tag

Recommended Posts

Hi all, 

 

Thanks for amazing plugin, been waiting for a long time.

 

As per my understanding we can use st.scroll() method to get/set the position.

 

I used to jump to a progress using this method earlier in ScrollMagic. (See how I get the triggerPosition and add it to progress * duration)

this.controller.scrollTo(this.controller.Scene.triggerPosition() + progress * this.controller.Scene.duration());

 

This is my code

 

  this.controller = ScrollTrigger.create({
      trigger: '.how-it-works',
      animation: this.howitworksTimeline,
      pin: true,
      start: 'top top',
      end: '+=500%',
      scrub: true,
      markers: { startColor: 'green', endColor: 'red', fontSize: '12px' }
    });

const progress = this.progressMap(idx);
    const top = this.howitworksController.start + (progress * 5000);
    window.scrollTo({ top, behavior: 'smooth' });

 

I have written 5000 explicitly as I know scene duration. How do I programmatically get scene duration?

 

EDIT: I figured it out, Here is the solution:

 

const progress = this.progressMap(idx);
const top = this.howitworksController.start + (progress * (this.howitworksController.end - this.howitworksController.start));
window.scrollTo({ top, behavior: 'smooth' });

 

* .end - .start is the duration for the scene so this should work fine.

 

Thanks again!

  • Like 1
Link to comment
Share on other sites

Actually, ScrollTriggers have a "scroll()" method that serves as a getter and setter. You could tap into that:

 

let controller = ScrollTrigger.create({...});
let progress = 0.5; // or whatever
controller.scroll(controller.start + progress * (controller.end - controller.start));

👍

  • Like 3
Link to comment
Share on other sites

  • 3 years later...

Sorry to reopen this topic @GreenSock, but there's something I can't quite wrap my head around, and it's probably because of thinking about it the wrong way: To use the scroll() method (let's say to make a horizontal scrollTrigger scroll to a certain element contained within) I need to know the corresponding progress value of each element to then convert it into pixel value and the scroll to it.

Isn't there a better way to calculate a pixel position on an element inside a scrollTrigger so that we can use the scroll() method more freely?

Thank you very much!

Link to comment
Share on other sites

Hi @Rodrigo, thank you for your answer.

They both make sense, but I can't understand how to apply this to my solution. I'll try to explain better:

I have 1 scrollTrigger that scrolls a section horizontally (which is 100vw and 100vh) and it contains different sections with variable widths.

I need to have a navigator like in your examples, and I wanted to use the scrollTrigger.scroll() method to make the container scroll to the correspondent section.

Now the problem is, that to use the scroll() method I need to know the distance in pixel that I want to be scrolled beforehand, therefore I was wondering if there was any way to either obtain the pixel distance from start of any element inside the scrollTrigger, or at least its corresponding .progress value after page load, to bind the navigator to a function that will computed this distance after the click.

Something on the lines of a .getBoundingClientRect().left inside the scrollTrigger.

I hope it makes more sense now. Thank you very much!

Link to comment
Share on other sites

It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or Stackblitz that demonstrates 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 dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

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

 

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

They are inconsistent because you are trying to scroll to a value that is by no means mapped to the scroll distance. 

 

You get the offset width of the elements, and then set that to the scroll, but your scroll distance variable has a value of around 1500px (on my screen), I've logged all the values you are using and marked them with a ⚠️ to show what the culprits are.

 

So the issue is your total scroll distance is 1500px (the ScrollTrigger)  and you move the the elements in the tween by around 1800px, so this will never line up. Then you scroll to (lets take the last panel) and scroll to 2700px, but there is only 1500px of total scroll distance. 

 

What I think should happen is that the total scroll distance needs to be 2700, you need to move the tween a total distance of 2700 and only then will the buttons line up. You could take an other route and use the GSAP util mapRange() https://greensock.com/docs/v3/GSAP/UtilityMethods/mapRange() to map the values to the total scroll distance. 

 

The pen below is an attempt to get them inline and is by no means optimised code. Hope it helps and happy tweening! 

See the Pen XWorGgp?editors=0011 by mvaneijgen (@mvaneijgen) on CodePen

Link to comment
Share on other sites

@mvaneijgen Thank you so much. Your solution is extremely clear, but this way I would basically "justify" the offsetLeft method instead of reading the correct value within the scroll distance available.

The ideal solution would be to find out how dynamically find the correct "scrollLeft" value to apply to the container, so that it scrolls exactly to where the wanted element is but within the available scroll space. For instance, the third/fourth section probably will never make it to the left side of the screen since there's not enough scrollable distance to allow that, but in that case it should just scroll to the extreme right and that's it (So basically there would not be blank space after the last section to the right).

So basically I would have to find a way to proportionate the offsetLeft value of the element within its container's available scroll distance, finding how much I should tell the scrollTrigger to scroll() in order to have that desired section at the left edge of the screen.

Does it make sense? I'd be extremely grateful if you have any idea how to maybe achieve this, but I don't want to burden you too much.

Thank you very much!
 

Link to comment
Share on other sites

I've used your slider.scrollWidth - document.documentElement.clientWidth as the bases for everything and this is called length. I then check in the  button loop if the offset is bigger then to total scroll distance and if that is the case I set the offset to the .end of the ScrollTrigger. 

 

If the lengt of the ScrollTrigger needs to be something bigger I recommend using this function mapRange() https://greensock.com/docs/v3/GSAP/UtilityMethods/mapRange() and maps the values 

 

This seems to work. Hope it helps and happy tweening! 

 

See the Pen OJrLGWM?editors=0011 by mvaneijgen (@mvaneijgen) on CodePen

  • Like 2
Link to comment
Share on other sites

Oh my god man, you're officially my hero. I just saw what you did with the end() parameter, I feel like a complete dumb***!

I was looking at it from a completely wrong perspective... the road I chose was a complete dead end, and I understand why now.

Seriously, thank you so much for your patience and dedication! Super appreciated!

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