44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
import { useLayoutEffect, type RefObject } from 'react';
|
|
|
|
/** 봉 시간축 — 시간 레일이 스크롤 영역 중앙(세로·가로)에 오도록 조정 */
|
|
export function useCenterAxisTimelineScroll(
|
|
scrollRef: RefObject<HTMLElement | null>,
|
|
trackRef: RefObject<HTMLElement | null>,
|
|
enabled: boolean,
|
|
deps: unknown[] = [],
|
|
): void {
|
|
useLayoutEffect(() => {
|
|
if (!enabled) return;
|
|
const scroll = scrollRef.current;
|
|
const track = trackRef.current;
|
|
if (!scroll || !track) return;
|
|
|
|
const center = () => {
|
|
const rail = track.querySelector('.arp-timeline-axis-rail') as HTMLElement | null;
|
|
if (rail) {
|
|
const scrollRect = scroll.getBoundingClientRect();
|
|
const railRect = rail.getBoundingClientRect();
|
|
const railMidInContent =
|
|
scroll.scrollTop + (railRect.top - scrollRect.top) + railRect.height / 2;
|
|
const targetTop = railMidInContent - scroll.clientHeight / 2;
|
|
scroll.scrollTop = Math.max(0, Math.min(
|
|
targetTop,
|
|
scroll.scrollHeight - scroll.clientHeight,
|
|
));
|
|
}
|
|
|
|
const targetLeft = (scroll.scrollWidth - scroll.clientWidth) / 2;
|
|
scroll.scrollLeft = Math.max(0, targetLeft);
|
|
};
|
|
|
|
center();
|
|
requestAnimationFrame(center);
|
|
|
|
const ro = new ResizeObserver(() => center());
|
|
ro.observe(scroll);
|
|
ro.observe(track);
|
|
return () => ro.disconnect();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [enabled, scrollRef, trackRef, ...deps]);
|
|
}
|