Task:
On touch devices get .container.scrollLeft
and transform: translateX
image depending on current horizontal scroll position. .container
width bigger than its .wrapper
.
Here you can check live example.
Problem:
Image moves but with an extremely low fps.
Expected behavior:
Fast and smooth movement.
Detailed description:
Thank you very much for reading this! I really get stacked with this issue. On desktop version, I'm just binding images position with onMouseMove
events and everything is great. But with mobile version I tried onTouch
events and native scroll event but nothing work as expected. I was looking for a solution or some working example and found nothing. So, here I am.
In this useEffect
you're adding the scroll event listener on every render. So as it scrolls, it re-renders (as it should), but it re-adds the listener many times.
useEffect(() => {
handleScroll();
wrapperEl.current.addEventListener("scroll", handleScroll, {
passive: true
});
});
It's far more efficient (and less likely to cause lumpy scrolling) to add the listener once on first render (using []
as the dependency array). You should also clean it up by returning a function that removes it on dismount:
useEffect(() => {
const el = wrapperEl.current;
el.addEventListener("scroll", handleScroll, {
passive: true
});
return () => el.removeEventListener("scroll", handleScroll);
}, []);
This is probably enough to get things running smoothly. If not, then you can also throttle your handleScroll
calls - there are many hooks-based examples available.