Jump to content
Search Community

GSAP onUpdate callback doesn't provide consistent progress value

willdzoan31 test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

I have a piece of code like this:

 

    tl.current = gsap.timeline({
      scrollTrigger: {
        trigger: "#appContainer",
        start: "top top",
        end: "bottom bottom",
        pin: "#app",
        srub: 1,
        onUpdate: (e) => {
          if (e.direction === 1) {
            for (let index in elements.children) {
              let mesh = elements.children[index]
              let position = mesh.position
              position.z += 0.05 * e.progress
            }
          }
          else {
            for (let index in elements.children) {
              let mesh = elements.children[index]
              let position = mesh.position
              position.z -= 0.05 * e.progress
            }
          }
        }
      }
    })

 

Basically what I'm trying to do is animate an object inside a threejs scene during scrolling, 2 ifs to make that object return to the normal position when scroll up.

But I notice that whenever I console.log the e.progress value, it's not the same (might be because of debounce or throttle?), especially when I scroll fast. Can you guys help me to see if there's a better way to do it? Essentially  I want that value of position.z to be the same as starting when the user scroll up.

 

 

Link to comment
Share on other sites

  • Solution

Hi @willdzoan31. Yeah, the way you're setting up that logic can't possibly work the way you're describing. Your code depends on the onUpdate getting called at exactly the same progress values in both directions. That's not how it works - an onUpdate gets called when the scroll position changes. If you scroll slowly, that might be 114 times (or whatever), and if you scroll super fast it might be 1 or 2. 

 

I think you're actually overcomplicating things quite a bit - is there a reason you don't just animate the position.z with a GSAP tween? It's hard to offer a solution without a minimal demo, but something like: 

let positions = elements.children.map(child => child.position);
gsap.to(positions, {
  z: "+=100", // or an absolute value or whatever
  ease: "none",
  scrollTrigger: {
    trigger: "#appContainer",
    start: "top top",
    end: "bottom bottom",
    pin: "#app",
    srub: 1
  }
});

That way, it'll always interpolate exactly the same way up and down. No complicated conditional logic inside an onUpdate attempting to increment values. 👍

 

Also, be careful about this: 

start: "top top",
end: "bottom bottom"

If, for example, the element is 100vh tall, the top would hit the top of the viewport at exactly the same time the bottom hits the bottom of the viewport, thus it wouldn't last at all. Maybe it's fine in your project because the element is much taller - I just thought I'd mention it because I've seen people make that logic mistake before. They often mean to do end: "bottom top"

  • Like 1
Link to comment
Share on other sites

I'm not entirely sure what you mean by "react state", but literally any property of any object can be animated. It doesn't matter if it's a React object, generic, whatever. 

 

let obj = {myProp: 100};

gsap.to(obj, {
  myProp: 500,
  duration: 2,
  onUpdate: () => console.log(obj.myProp)
});

 

Link to comment
Share on other sites

So in a React application like this for example:

const [state, setState] = useState(0)

the state can only be changed/updated via the setState(value).

 

And in your example, you're changing the value directly, which won't work in a React application I believe. So I'm just curious, is there anyway for me to call the setState(value) during that?

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