try something different for stats scroll
This commit is contained in:
@@ -116,6 +116,9 @@ const PlayerListItem = memo(({ stat, onPlayerClick, mmr, onRegisterViewport, onU
|
|||||||
viewport: {
|
viewport: {
|
||||||
WebkitOverflowScrolling: 'touch',
|
WebkitOverflowScrolling: 'touch',
|
||||||
scrollBehavior: 'auto',
|
scrollBehavior: 'auto',
|
||||||
|
willChange: 'scroll-position',
|
||||||
|
transform: 'translateZ(0)',
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -150,33 +153,48 @@ const PlayerStatsTable = () => {
|
|||||||
|
|
||||||
const viewportsRef = useRef<Set<HTMLDivElement>>(new Set());
|
const viewportsRef = useRef<Set<HTMLDivElement>>(new Set());
|
||||||
const scrollHandlersRef = useRef<Map<HTMLDivElement, (e: Event) => void>>(new Map());
|
const scrollHandlersRef = useRef<Map<HTMLDivElement, (e: Event) => void>>(new Map());
|
||||||
const isSyncingRef = useRef(false);
|
const scrollLeaderRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const scrollTimeoutRef = useRef<number | null>(null);
|
||||||
|
|
||||||
const handleRegisterViewport = useCallback((viewport: HTMLDivElement) => {
|
const handleRegisterViewport = useCallback((viewport: HTMLDivElement) => {
|
||||||
viewportsRef.current.add(viewport);
|
viewportsRef.current.add(viewport);
|
||||||
|
|
||||||
|
const handleScrollStart = () => {
|
||||||
|
scrollLeaderRef.current = viewport;
|
||||||
|
};
|
||||||
|
|
||||||
const handleScroll = (e: Event) => {
|
const handleScroll = (e: Event) => {
|
||||||
const target = e.target as HTMLDivElement;
|
const target = e.target as HTMLDivElement;
|
||||||
|
|
||||||
// Prevent infinite loops
|
if (scrollLeaderRef.current !== target) {
|
||||||
if (isSyncingRef.current) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSyncingRef.current = true;
|
|
||||||
const scrollLeft = target.scrollLeft;
|
const scrollLeft = target.scrollLeft;
|
||||||
|
|
||||||
// Synchronize all other viewports immediately
|
|
||||||
viewportsRef.current.forEach((vp) => {
|
viewportsRef.current.forEach((vp) => {
|
||||||
if (vp !== target) {
|
if (vp !== target) {
|
||||||
|
if (Math.abs(vp.scrollLeft - scrollLeft) > 0.5) {
|
||||||
|
const wasLeader = scrollLeaderRef.current;
|
||||||
|
scrollLeaderRef.current = null;
|
||||||
vp.scrollLeft = scrollLeft;
|
vp.scrollLeft = scrollLeft;
|
||||||
|
scrollLeaderRef.current = wasLeader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
isSyncingRef.current = false;
|
if (scrollTimeoutRef.current) {
|
||||||
|
clearTimeout(scrollTimeoutRef.current);
|
||||||
|
}
|
||||||
|
scrollTimeoutRef.current = window.setTimeout(() => {
|
||||||
|
scrollLeaderRef.current = null;
|
||||||
|
}, 150);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
viewport.addEventListener('touchstart', handleScrollStart, { passive: true });
|
||||||
|
viewport.addEventListener('mousedown', handleScrollStart, { passive: true });
|
||||||
viewport.addEventListener('scroll', handleScroll, { passive: true });
|
viewport.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
|
||||||
scrollHandlersRef.current.set(viewport, handleScroll);
|
scrollHandlersRef.current.set(viewport, handleScroll);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -186,6 +204,8 @@ const PlayerStatsTable = () => {
|
|||||||
const handler = scrollHandlersRef.current.get(viewport);
|
const handler = scrollHandlersRef.current.get(viewport);
|
||||||
if (handler) {
|
if (handler) {
|
||||||
viewport.removeEventListener('scroll', handler);
|
viewport.removeEventListener('scroll', handler);
|
||||||
|
viewport.removeEventListener('touchstart', handler);
|
||||||
|
viewport.removeEventListener('mousedown', handler);
|
||||||
scrollHandlersRef.current.delete(viewport);
|
scrollHandlersRef.current.delete(viewport);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
Reference in New Issue
Block a user