Center current chapter in drawer on open
Chapter drawer now opens with the active row pre-scrolled to the center of the list instead of always starting at chapter #1. useLayoutEffect measures via getBoundingClientRect so the scroll lands before paint — no visible jump. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
43a2a6d3f8
commit
cad59143a3
@ -86,6 +86,8 @@ export function PageReader({
|
||||
const pageElRef = useRef<Map<string, HTMLDivElement>>(new Map());
|
||||
const observerRef = useRef<IntersectionObserver | null>(null);
|
||||
const hiddenByScrollRef = useRef(false);
|
||||
const drawerScrollRef = useRef<HTMLDivElement | null>(null);
|
||||
const drawerActiveRef = useRef<HTMLAnchorElement | null>(null);
|
||||
// Pages currently inside the observer's viewport margin. The scroll tick
|
||||
// walks this small set instead of every loaded page.
|
||||
const intersectingPagesRef = useRef<Map<string, IntersectingPage>>(new Map());
|
||||
@ -322,6 +324,21 @@ export function PageReader({
|
||||
[]
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!showDrawer) return;
|
||||
const scroll = drawerScrollRef.current;
|
||||
const active = drawerActiveRef.current;
|
||||
if (!scroll || !active) return;
|
||||
const scrollRect = scroll.getBoundingClientRect();
|
||||
const activeRect = active.getBoundingClientRect();
|
||||
const delta =
|
||||
activeRect.top -
|
||||
scrollRect.top -
|
||||
scroll.clientHeight / 2 +
|
||||
active.clientHeight / 2;
|
||||
scroll.scrollTop = Math.max(0, scroll.scrollTop + delta);
|
||||
}, [showDrawer]);
|
||||
|
||||
const currentChapter =
|
||||
chapters.find((c) => c.number === currentChapterNum) ??
|
||||
chapters.find((c) => c.number === startChapterNumber);
|
||||
@ -474,12 +491,16 @@ export function PageReader({
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="overflow-y-auto max-h-[calc(75vh-4rem)] pb-safe">
|
||||
<div
|
||||
ref={drawerScrollRef}
|
||||
className="overflow-y-auto max-h-[calc(75vh-4rem)] pb-safe"
|
||||
>
|
||||
{chapters.map((ch) => {
|
||||
const isActive = ch.number === currentChapterNum;
|
||||
return (
|
||||
<Link
|
||||
key={ch.number}
|
||||
ref={isActive ? drawerActiveRef : undefined}
|
||||
href={`/manga/${mangaSlug}/${ch.number}`}
|
||||
scroll={false}
|
||||
className={`flex items-center gap-3 px-5 py-3 text-sm transition-colors ${
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user