When triggering multiple scroll animations, the new animation starts back where the last one finished instead of the current scroll position. In other terms it works as long as the user does not scroll themselves.
Here is more or less how my code looks like:
const [animation, setAnimation, stopAnimation] = useSpring(() => ({
from: { y: 0 }
}));
const ref = useRef(null);
const onNext = () => {
// Completely ignores any scroll from the user.
setAnimation({ to: { y: ref.current.scrollTop + 50 } });
}
return (
<>
<animated.div
ref={ref}
style={{ overflow: 'scroll', height: "50px" }}
scrollTop={animation.y}
onWheel={stopAnimation}
>
{renderContent()}
</animated.div>
<button type="button" onClick={onNext}>Scroll It</button>
</>
);
Ideally, I believe the above animation should increase scrollTop from its current location instead of starting back where it was at the end of the previous animation.
Eventually I have been able to find the following workaround:
const onNext = () => {
setAnimation({
// Reset the state of the animation.
reset: true,
to: { y: ref.current.scrollTop + 50 }
});
}
It is working, but I still believe the above behaviour is buggy. Also, and because I had to use reset, it loses any momentum from the previous animation in the instance it was not completed.
Here is a code sandbox: https://codesandbox.io/s/r5m8ymmqr4 that demonstrates the problem. You want to look at Scroller.js in particular.
that is because user scroll isn't managed or controlled, so you need to do some bookkeeping if you want to adapt to it. as for reset, for that i would need a codesandbox. i don't see why it would be needed right now. useSpring doesn't know or care about scrollTop or the view, it just interpolates a number. if the number changes through a new "setAnimation" it shouldn't loose momentum.
I have updated the post with a code sandbox. You want to look at Scroller.js.
This is the best I have been able to come up with for this use case. Any piece of advice is welcome, I do find it quite convoluted. E.g. manually removing the scrolltop attribute looks very hacky.
If this the recommended way, it might be worth documenting it.
It seems that in the last version clearing the scrolltop attribute is not necessary anymore.
Hi,
I am also facing a similar issue with using this.parallax.scrollTo() function. I wonder if you have any suggestion on fixing this issue?
I see there is bookkeeping mentioned so what state value should I be keeping track when scrolling?
You need to track the current scroll location so you can make sure the animation starts from there instead of its own internal value.
does this.parallax have anything where I can set the current location value when I track?
I just wanted to chime in that I kind of got bitten by this too. Overall, after reading this thread, I'm a little torn.
It seems a little weird to me that I have to use @QuentinRoy's recommendation of resetting + keeping track of the scrollbar's position manually, but it also seems outside of useSpring's responsibility to constantly know the scrollbar position.
If the recommendation is to keep track of the scroll position ourselves and resetting it, I second documenting it somewhere if possible, maybe as an example in the useSpring docs? I can open a PR in react-spring.io if this is the way to go
Most helpful comment
I just wanted to chime in that I kind of got bitten by this too. Overall, after reading this thread, I'm a little torn.
It seems a little weird to me that I have to use @QuentinRoy's recommendation of resetting + keeping track of the scrollbar's position manually, but it also seems outside of
useSpring's responsibility to constantly know the scrollbar position.If the recommendation is to keep track of the scroll position ourselves and resetting it, I second documenting it somewhere if possible, maybe as an example in the
useSpringdocs? I can open a PR in react-spring.io if this is the way to go