Jump to content
Search Community

How to get the correct ScrollTo position when using ScrollTrigger pinning

aok test
Moderator Tag

Recommended Posts

Hi folks I'm experiencing two issues when using ScrollTrigger, with pinning, and the ScrollToPlugin.

 

1. Clicking on the nav items is returning a console error with gsap rather than scrolling to the relevant section

2. The pinning involved will affect the scroll position of the section so when the nav items are clicked it'll scroll to the position of the section without taking into consideration the pinning. I've seen a few posts on the forum about this but none of the solutions seem to work for me. Any pointers?

 

Thanks so much.

See the Pen yLrqdQm by richardcool (@richardcool) on CodePen

Link to comment
Share on other sites

Hi,

 

You where using different versions of the ScrollTo plugin and the GSAP core. On top of that the versions of the core and ScrollTrigger were really old 3.3.4.

 

On top of that there seems to be something else that is causing this. This demo uses a similar setup and is working as expected:

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

 

Most likely is the position sticky you're giving to the nav bar, better use ScrollTrigger to pin that.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi @Rodrigo thanks again for your help.

 

I've updated the CodePen (), stopped the sticky header and removed the errors but I'm still getting the issue where it'll scroll to the position of the section without taking into consideration the pinning. Does scrollTo simply scroll to a Y position without taking the pinning into consideration?

Link to comment
Share on other sites

Thanks for the help @GSAP Helper and I think I've implemented this correctly (see updated CodePen) but on click on 'About' or 'Information' it always goes to the top of the projects section.

 

 

Any thoughts?

Link to comment
Share on other sites

Hi,

 

That's because the value returned from the getScrollLookup method is returning -Inifinity, so that definitely is not going to work.

 

I don't have time to dig into this right now, but if you look at the demo I posted it works even with pinning, which makes me think that there is something else in your demo that is causing this. The HTML/CSS of my demo is quite simple, but it works without any issues with a pinned section. My advice would be to maybe create a simpler setup in order to make this work, start stripping some stuff until it works the way you intend and then add things back to it until it breaks, then you'll identify what's causing the problem.

 

Happy Tweening!

Link to comment
Share on other sites

I noticed several problems: 

  1. You had faulty markup (missing closed </div> tags)
  2. You were defining a containerAnimation for the getScrollLookup(), but only some of the elements were in the containerAnimation.  That is not valid.
  3. You were pinning a container element, but you didn't define that in the getScrollLookup() config. 

Is this more of what you wanted?

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

  • Like 1
Link to comment
Share on other sites

Hi @GreenSock thanks so much for the help and reply!

 

I *think* I understand... trying to wrap my head around it. When I click the 'About' and 'Information' nav buttons in the CodePen it only takes the user to the top of the project slides... not the sections with the 'About' and 'Information' text. Are you getting this too?

Link to comment
Share on other sites

That's because you haven't updated your code with the suggestions Jack made, that's all

 

I recommend you to have a better and close look at the code in Jack's demo in order to understand how is actually working.

 

Happy Tweening!

Link to comment
Share on other sites

Hi @Rodrigo and @GreenSock thanks again for the help and comments.

I have updated my code but I think the issue is perhaps this comment from Jack:

On 4/22/2024 at 4:45 AM, GreenSock said:
  • You were defining a containerAnimation for the getScrollLookup(), but only some of the elements were in the containerAnimation.  That is not valid.

The page is made up of different timelines and scrollTriggers, not just one for all, so defining a `containerAnimation` that contains all the elements is a bit tricky, right? However, this is just a landing page of two anchored sections (About and Information) so I thought getting the scroll position to scroll to for two sections would be fairly straightforward.

 

I understand what you're saying @Rodrigo about your initial example working without the `getScrollLookup` function, which would obviously be ideal, but even stripping it back I couldn't get the correct scroll position.

 

In my example the pinned container is the parent container of all sections whereas in other examples the pinned container is the same as the trigger. In order to make mine work I had to make the parent the pin... I wonder if this is causing issues.

 

I'll keep trying and update if I have any success but any help understanding if it's possible to use getScrollLookup for individual parts rather than as a layout that is completely animated would be great.

Link to comment
Share on other sites

Unfortunately it's just not feasible to make ScrollToPlugin accommodate that automatically. There's no way it could understand which elements are affected by which ScrollTriggers. It's essential that you, as the builder of the page, provide that information. But here's a helper function you could try - it lets you create several lookups that get added together into one big lookup. Splitting them up like this allows you to segregate elements according to whether or not they're in a containerAnimation and/or pinnedContainer: 

 

function getScrollLookup(targets, {start, pinnedContainer, containerAnimation}) {
  targets = gsap.utils.toArray(targets);
  let initted,
      triggers = targets.map((el, i) => ScrollTrigger.create({
        trigger: el,
        start: start || "top top",
        pinnedContainer: pinnedContainer,
        refreshPriority: -10,
        onRefresh(self) {
          if (initted && Math.abs(self.start) > 999999) {
            triggers[i].kill();
            triggers[i] = ScrollTrigger.create({
              trigger: el,
              start: start || "start start",
              pinnedContainer: pinnedContainer,
              refreshPriority: -10,
            });
          }
        },
        containerAnimation: containerAnimation
      })),
      st = containerAnimation && containerAnimation.scrollTrigger,
      lookups = [],
      lookup = target => {
        let t = gsap.utils.toArray(target)[0],
            i = targets.indexOf(t);
        if (i < 0) {
          for (i = 0; i < lookups.length; i++) {
            if (lookups[i].targets.indexOf(t) !== -1) {
              return lookups[i](t);
            }
          }
          return console.warn("target not found", target);
        }
        return triggers[i].vars.containerAnimation ? st.start + (triggers[i].start / containerAnimation.duration()) * (st.end - st.start) : triggers[i].start;
      };
  lookup.targets = targets;
  lookup.add = (targets, config) => {
    lookups.push(getScrollLookup(targets, config));
    return lookup;
  };
  initted = true;
  return lookup;
}

 

So you'd use it like: 

let lookup = getScrollLookup("section.project", { containerAnimation: tween, pinnedContainer: el });
lookup.add("section.other", {}); // no containerAnimation or pinnedContainer
lookup.add("section.pinned", {pinnedContainer: el}); // just a pinned container

// then later...
let position = lookup(".any-of-the-above-elements");

Hopefully that helps. 

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