fix(app): auto-scroll on iOS using scrollBy with integer accumulator
This commit is contained in:
@@ -24,14 +24,21 @@ export function AutoScrollControls({ scrollRef }: Props) {
|
|||||||
const lastTimeRef = useRef<number>(0);
|
const lastTimeRef = useRef<number>(0);
|
||||||
const cancelledByUser = useRef(false);
|
const cancelledByUser = useRef(false);
|
||||||
|
|
||||||
|
const accumulatorRef = useRef(0);
|
||||||
|
|
||||||
const tick = useCallback(
|
const tick = useCallback(
|
||||||
(time: number) => {
|
(time: number) => {
|
||||||
if (!scrollRef.current) return;
|
const el = scrollRef.current;
|
||||||
|
if (!el) return;
|
||||||
if (lastTimeRef.current) {
|
if (lastTimeRef.current) {
|
||||||
const dt = (time - lastTimeRef.current) / 1000;
|
const dt = (time - lastTimeRef.current) / 1000;
|
||||||
scrollRef.current.scrollTop += speed * dt;
|
accumulatorRef.current += speed * dt;
|
||||||
|
const px = Math.floor(accumulatorRef.current);
|
||||||
|
if (px >= 1) {
|
||||||
|
accumulatorRef.current -= px;
|
||||||
|
el.scrollBy({ top: px });
|
||||||
|
}
|
||||||
|
|
||||||
const el = scrollRef.current;
|
|
||||||
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 1) {
|
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 1) {
|
||||||
setPlaying(false);
|
setPlaying(false);
|
||||||
return;
|
return;
|
||||||
@@ -46,6 +53,7 @@ export function AutoScrollControls({ scrollRef }: Props) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (playing) {
|
if (playing) {
|
||||||
lastTimeRef.current = 0;
|
lastTimeRef.current = 0;
|
||||||
|
accumulatorRef.current = 0;
|
||||||
cancelledByUser.current = false;
|
cancelledByUser.current = false;
|
||||||
rafRef.current = requestAnimationFrame(tick);
|
rafRef.current = requestAnimationFrame(tick);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user