Jump to content
Search Community

Problem Scrolltrigger native with scrub

Umberto test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi, I use native Scrolltrigger, but I have a problem with scrub.


With the old version (example 1) the scrub works fine.


In the new version (example 2), when I scroll it works fine, but when I go back up and scroll down, you can see that the animation waits a few seconds before restarting.

 

Can you help me?

Thanks

 

Old Version

 

 

 

See the Pen vYZXbbv by umberto (@umberto) on CodePen

Link to comment
Share on other sites

If I understand your question correctly, the problem is that you set scrub: 3 but you are ALSO applying a smooth scroll to the ENTIRE page so you're compounding the delay it takes for things to "catch up". It's all working exactly as it's supposed to, so I would recommend setting scrub: true instead. 

  • Like 2
Link to comment
Share on other sites

I thank you for the answer.


I had already tried to set all the animations to scrub: true and everything works, but I wanted to increase the scrub to have a different effect.

 

I ask you 2 questions:

 

1 Is it possible to eliminate this problem in the future as in the old version of native Scrolltrigger?

2 If I were to use the old version, will I have problems such as efficiency?

 

Link to comment
Share on other sites

1 hour ago, Umberto said:

1 Is it possible to eliminate this problem in the future as in the old version of native Scrolltrigger?

I don't understand what you mean - do you think that an older version of ScrollTrigger somehow works better (or differently) than a newer version of ScrollTrigger? I'm not aware of anything like that. The difference I saw in your CodePen demos is that you used a completely different approach (your code, not ScrollTrigger). In the 2nd, you used the helper function to smooth the ENTIRE page. Perhaps I am misunderstanding your question/comment.

 

2 hours ago, Umberto said:

2 If I were to use the old version, will I have problems such as efficiency?

If you're asking whether or not your first technique with the .forEach() is problematic efficiency-wise, no, I don't see a problem with it. If you have a lot of elements, though, it would likely be more efficient to apply 1 smoothing algorithm to the entire page instead of applying 1 for each and every element but of course they are entirely different effects so it really depends what you're looking for functionality-wise. 

 

2 hours ago, Umberto said:

but I wanted to increase the scrub to have a different effect.

If you want to make the smoothing more strong, you can do that with the helper function like smoothScroll("#content", "#viewport", 5) would make the smoothing take 5 seconds to catch up to the scroll position. 

Link to comment
Share on other sites

I apologize for my bad English.

In the second question I simply asked if using this (the old version of Scrolltrigger Native, used in the 1st example):

 

console.clear ();

var container = document.querySelector ("# scroll-container");
var height;
function setHeight () {
  height = container.clientHeight;
  document.body.style.height = height + "px";
}
ScrollTrigger.addEventListener ("refreshInit", setHeight);
gsap.to (container, {
  y: () => - (height - document.documentElement.clientHeight),
  ease: "none",
  scrollTrigger: {
    trigger: document.body,
    start: "top top",
    end: "bottom bottom",
    scrub: 1.7,
    invalidateOnRefresh: true,
  },
});

 

I will have problems with efficiency, compared to the new version:

smoothScroll("#content");

// this is the helper function that sets it all up. Pass in the content <div> and then the wrapping viewport <div> (can be the elements or selector text). It also sets the default "scroller" to the content so you don't have to do that on all your ScrollTriggers.
function smoothScroll(content, viewport, smoothness) {
  content = gsap.utils.toArray(content)[0];
  smoothness = smoothness || 2;

  gsap.set(viewport || content.parentNode, {overflow: "hidden", position: "fixed", height: "100%", width: "100%", top: 0, left: 0, right: 0, bottom: 0});
  gsap.set(content, {overflow: "visible", width: "100%"});

  let getProp = gsap.getProperty(content),
    setProp = gsap.quickSetter(content, "y", "px"),
    setScroll = ScrollTrigger.getScrollFunc(window),
    removeScroll = () => content.style.overflow = "visible",
    killScrub = trigger => {
      let scrub = trigger.getTween ? trigger.getTween() : gsap.getTweensOf(trigger.animation)[0]; // getTween() was added in 3.6.2
      scrub && scrub.kill();
      trigger.animation.progress(trigger.progress);
    },
    height, isProxyScrolling;

  function onResize() {
    height = content.clientHeight;
    content.style.overflow = "visible"
    document.body.style.height = height + "px";
  }
  onResize();
  ScrollTrigger.addEventListener("refreshInit", onResize);
  ScrollTrigger.addEventListener("refresh", () => {
    removeScroll();
    requestAnimationFrame(removeScroll);
  })
  ScrollTrigger.defaults({scroller: content});
  ScrollTrigger.prototype.update = p => p; // works around an issue in ScrollTrigger 3.6.1 and earlier (fixed in 3.6.2, so this line could be deleted if you're using 3.6.2 or later)

  ScrollTrigger.scrollerProxy(content, {
    scrollTop(value) {
      if (arguments.length) {
        isProxyScrolling = true; // otherwise, if snapping was applied (or anything that attempted to SET the scroll proxy's scroll position), we'd set the scroll here which would then (on the next tick) update the content tween/ScrollTrigger which would try to smoothly animate to that new value, thus the scrub tween would impede the progress. So we use this flag to respond accordingly in the ScrollTrigger's onUpdate and effectively force the scrub to its end immediately.
        setProp(-value);
        setScroll(value);
        return;
      }
      return -getProp("y");
    },
    getBoundingClientRect() {
      return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight};
    }
  });

  return ScrollTrigger.create({
    animation: gsap.fromTo(content, {y:0}, {
      y: () => document.documentElement.clientHeight - height,
      ease: "none",
      onUpdate: ScrollTrigger.update
    }),
    scroller: window,
    invalidateOnRefresh: true,
    start: 0,
    end: () => height - document.documentElement.clientHeight,
    scrub: smoothness,
    onUpdate: self => {
      if (isProxyScrolling) {
        killScrub(self);
        isProxyScrolling = false;
      }
    },
    onRefresh: killScrub // when the screen resizes, we just want the animation to immediately go to the appropriate spot rather than animating there, so basically kill the scrub.
  });
}

 

Thanks

Link to comment
Share on other sites

I think I already answered that question: 

1 hour ago, GreenSock said:

If you're asking whether or not your first technique with the .forEach() is problematic efficiency-wise, no, I don't see a problem with it. If you have a lot of elements, though, it would likely be more efficient to apply 1 smoothing algorithm to the entire page instead of applying 1 for each and every element but of course they are entirely different effects so it really depends what you're looking for functionality-wise. 

Was there something that wasn't clear? 

Link to comment
Share on other sites

  • Solution
2 hours ago, Umberto said:

In my project there are many techniques with the .forEach (), so if I am not mistaken, the advice is to use the latest version of native Scrolltrigger.

I don't understand your question because you keep saying "the latest version of native ScrollTrigger" and of course I recommend using the latest version of ScrollTrigger but your demos have nothing to do with the version of ScrollTrigger - they are completely different effects. One uses .forEach() to create individual ScrollTriggers for a bunch of elements and the other applies smooth scrolling to the entire page. You can use whichever effect you prefer; they won't look the same. I don't know which effect you want, so I can't tell you which you should use. 

 

Did I misunderstand your question? 

Link to comment
Share on other sites

On 9/6/2021 at 5:03 AM, GreenSock said:

If I understand your question correctly, the problem is that you set scrub: 3 but you are ALSO applying a smooth scroll to the ENTIRE page so you're compounding the delay it takes for things to "catch up". It's all working exactly as it's supposed to, so I would recommend setting scrub: true instead. 

Worth repeating this I think.

I think the misunderstanding is that scrub:3 is an old version of smooth scrolling as opposed to techniques that do different things?

Maybe?

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